{"action":"created","comment":{"url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments/45391692","id":45391692,"diff_hunk":"@@ -64,7 +64,7 @@ public ICodeReceiver CodeReceiver\n \r\n             // If the stored token is null or it doesn't have a refresh token and the access token is expired we need \r\n             // to retrieve a new authorization code.\r\n-            if (token == null || (token.RefreshToken == null && token.IsExpired(flow.Clock)))\r\n+            if (Flow.ShouldForceTokenRetrieval() || token == null || (token.RefreshToken == null && token.IsExpired(flow.Clock)))\r","path":"Src/GoogleApis.Auth/OAuth2/AuthorizationCodeInstalledApp.cs","position":5,"original_position":5,"commit_id":"48a9ec1963290b6ef8593ba9d0e55dace836b0ae","original_commit_id":"48a9ec1963290b6ef8593ba9d0e55dace836b0ae","user":{"login":"squid808","id":7298254,"avatar_url":"https://avatars.githubusercontent.com/u/7298254?v=3","gravatar_id":"","url":"https://api.github.com/users/squid808","html_url":"https://github.com/squid808","followers_url":"https://api.github.com/users/squid808/followers","following_url":"https://api.github.com/users/squid808/following{/other_user}","gists_url":"https://api.github.com/users/squid808/gists{/gist_id}","starred_url":"https://api.github.com/users/squid808/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/squid808/subscriptions","organizations_url":"https://api.github.com/users/squid808/orgs","repos_url":"https://api.github.com/users/squid808/repos","events_url":"https://api.github.com/users/squid808/events{/privacy}","received_events_url":"https://api.github.com/users/squid808/received_events","type":"User","site_admin":false},"body":"Done. I thought far too long on this but eventually decided to throw it in a separate function to keep it a bit cleaner. I kept and adjusted the in-line comments since I figure they were there for a reason. Part of me wanted to find a way to only check for a token if ```Flow.ShouldForceTokenRetrieval()``` is false anyways, but this should be just fine for now.","created_at":"2015-11-19T19:54:27Z","updated_at":"2015-11-19T19:54:27Z","html_url":"https://github.com/google/google-api-dotnet-client/pull/624#discussion_r45391692","pull_request_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624","_links":{"self":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments/45391692"},"html":{"href":"https://github.com/google/google-api-dotnet-client/pull/624#discussion_r45391692"},"pull_request":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624"}}},"pull_request":{"url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624","id":49741217,"html_url":"https://github.com/google/google-api-dotnet-client/pull/624","diff_url":"https://github.com/google/google-api-dotnet-client/pull/624.diff","patch_url":"https://github.com/google/google-api-dotnet-client/pull/624.patch","issue_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/624","number":624,"state":"open","locked":false,"title":"Incremental auth support","user":{"login":"squid808","id":7298254,"avatar_url":"https://avatars.githubusercontent.com/u/7298254?v=3","gravatar_id":"","url":"https://api.github.com/users/squid808","html_url":"https://github.com/squid808","followers_url":"https://api.github.com/users/squid808/followers","following_url":"https://api.github.com/users/squid808/following{/other_user}","gists_url":"https://api.github.com/users/squid808/gists{/gist_id}","starred_url":"https://api.github.com/users/squid808/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/squid808/subscriptions","organizations_url":"https://api.github.com/users/squid808/orgs","repos_url":"https://api.github.com/users/squid808/repos","events_url":"https://api.github.com/users/squid808/events{/privacy}","received_events_url":"https://api.github.com/users/squid808/received_events","type":"User","site_admin":false},"body":"This adds support of the library to authenticate with the [```include_granted_scopes```](https://developers.google.com/identity/protocols/OAuth2InstalledApp#incrementalAuth) parameter which [does not currently exist](http://stackoverflow.com/questions/33470699/how-to-implement-incremental-authorization-with-google-api#comment54766478_33470699).\r\n\r\nUsage is intended to be exposed to a user of the library who is already using ```GoogleWebAuthorizationBroker.AuthorizeAsync()``` by adding a single new parameter - ```includeGrantedScopes``` - which is a nullable bool and set to null by default. For example:\r\n\r\n```\r\nuserCredentials = await GoogleWebAuthorizationBroker.AuthorizeAsync(\r\n                    MyClientSecrets, scopes, userName,\r\n                    System.Threading.CancellationToken.None, new DataStore(),\r\n                    true //this will set the include_granted_scopes=true in the url\r\n                    );\r\n```\r\n\r\nIf the user omits this optional parameter the null is trickled down and is ignored when building the authorization request URL (thereby defaulting to false in the request). When explicitly included, the query parameter is included in the URL with the value supplied, even if false.\r\n\r\nI have tested it up to the point of verifying that it creates the url with the appropriate query parameters as expected, and ensured that the URL resolves and supplies an appropriate authentication page in the browser. I have not been able to test the resulting tokens however due to my applications being all installed applications at this time, which do not work with [Incremental Authorization](http://stackoverflow.com/questions/33514722/how-to-supply-scopes-as-part-of-post-body-rather-than-url-params/33516367?noredirect=1#comment54831247_33516367) to my knowledge.\r\n\r\nA proper test could likely be set up to ensure that the resulting url contains the parameter when expected, however I haven't fully wrapped my head around the mocking setup used in the project's tests. If someone would be willing to guide me through it I'd be more than happy to work on that as well, though my experience with tests is somewhat limited.\r\n\r\nThis also fixes two minor typos I came across for which I saw no need for a separate pull request. It's also my first pull request, so please let me know if I have done something incorrectly during the process.","created_at":"2015-11-04T20:31:49Z","updated_at":"2015-11-19T19:54:27Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bac92f8de6ab7bb478e4ac25ce1f88ff7cbc987b","assignee":null,"milestone":{"url":"https://api.github.com/repos/google/google-api-dotnet-client/milestones/3","html_url":"https://github.com/google/google-api-dotnet-client/milestones/1.10","labels_url":"https://api.github.com/repos/google/google-api-dotnet-client/milestones/3/labels","id":1369383,"number":3,"title":"1.10","description":null,"creator":{"login":"peleyal","id":3082873,"avatar_url":"https://avatars.githubusercontent.com/u/3082873?v=3","gravatar_id":"","url":"https://api.github.com/users/peleyal","html_url":"https://github.com/peleyal","followers_url":"https://api.github.com/users/peleyal/followers","following_url":"https://api.github.com/users/peleyal/following{/other_user}","gists_url":"https://api.github.com/users/peleyal/gists{/gist_id}","starred_url":"https://api.github.com/users/peleyal/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peleyal/subscriptions","organizations_url":"https://api.github.com/users/peleyal/orgs","repos_url":"https://api.github.com/users/peleyal/repos","events_url":"https://api.github.com/users/peleyal/events{/privacy}","received_events_url":"https://api.github.com/users/peleyal/received_events","type":"User","site_admin":false},"open_issues":4,"closed_issues":13,"state":"open","created_at":"2015-10-21T22:45:37Z","updated_at":"2015-11-19T04:41:36Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624/commits","review_comments_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624/comments","review_comment_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/624/comments","statuses_url":"https://api.github.com/repos/google/google-api-dotnet-client/statuses/48a9ec1963290b6ef8593ba9d0e55dace836b0ae","head":{"label":"squid808:IncrementalAuthSupport","ref":"IncrementalAuthSupport","sha":"48a9ec1963290b6ef8593ba9d0e55dace836b0ae","user":{"login":"squid808","id":7298254,"avatar_url":"https://avatars.githubusercontent.com/u/7298254?v=3","gravatar_id":"","url":"https://api.github.com/users/squid808","html_url":"https://github.com/squid808","followers_url":"https://api.github.com/users/squid808/followers","following_url":"https://api.github.com/users/squid808/following{/other_user}","gists_url":"https://api.github.com/users/squid808/gists{/gist_id}","starred_url":"https://api.github.com/users/squid808/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/squid808/subscriptions","organizations_url":"https://api.github.com/users/squid808/orgs","repos_url":"https://api.github.com/users/squid808/repos","events_url":"https://api.github.com/users/squid808/events{/privacy}","received_events_url":"https://api.github.com/users/squid808/received_events","type":"User","site_admin":false},"repo":{"id":45563609,"name":"google-api-dotnet-client","full_name":"squid808/google-api-dotnet-client","owner":{"login":"squid808","id":7298254,"avatar_url":"https://avatars.githubusercontent.com/u/7298254?v=3","gravatar_id":"","url":"https://api.github.com/users/squid808","html_url":"https://github.com/squid808","followers_url":"https://api.github.com/users/squid808/followers","following_url":"https://api.github.com/users/squid808/following{/other_user}","gists_url":"https://api.github.com/users/squid808/gists{/gist_id}","starred_url":"https://api.github.com/users/squid808/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/squid808/subscriptions","organizations_url":"https://api.github.com/users/squid808/orgs","repos_url":"https://api.github.com/users/squid808/repos","events_url":"https://api.github.com/users/squid808/events{/privacy}","received_events_url":"https://api.github.com/users/squid808/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/squid808/google-api-dotnet-client","description":"Google APIs Client Library for .NET","fork":true,"url":"https://api.github.com/repos/squid808/google-api-dotnet-client","forks_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/forks","keys_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/teams","hooks_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/hooks","issue_events_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/issues/events{/number}","events_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/events","assignees_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/assignees{/user}","branches_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/branches{/branch}","tags_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/tags","blobs_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/statuses/{sha}","languages_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/languages","stargazers_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/stargazers","contributors_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/contributors","subscribers_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/subscribers","subscription_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/subscription","commits_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/contents/{+path}","compare_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/merges","archive_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/downloads","issues_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/issues{/number}","pulls_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/pulls{/number}","milestones_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/milestones{/number}","notifications_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/labels{/name}","releases_url":"https://api.github.com/repos/squid808/google-api-dotnet-client/releases{/id}","created_at":"2015-11-04T19:53:36Z","updated_at":"2015-11-04T19:53:38Z","pushed_at":"2015-11-19T02:54:57Z","git_url":"git://github.com/squid808/google-api-dotnet-client.git","ssh_url":"git@github.com:squid808/google-api-dotnet-client.git","clone_url":"https://github.com/squid808/google-api-dotnet-client.git","svn_url":"https://github.com/squid808/google-api-dotnet-client","homepage":"https://developers.google.com/api-client-library/dotnet","size":8830,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"4efcebd8b1e6940e981b21e0207d6d90ae843c5b","user":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"repo":{"id":33947900,"name":"google-api-dotnet-client","full_name":"google/google-api-dotnet-client","owner":{"login":"google","id":1342004,"avatar_url":"https://avatars.githubusercontent.com/u/1342004?v=3","gravatar_id":"","url":"https://api.github.com/users/google","html_url":"https://github.com/google","followers_url":"https://api.github.com/users/google/followers","following_url":"https://api.github.com/users/google/following{/other_user}","gists_url":"https://api.github.com/users/google/gists{/gist_id}","starred_url":"https://api.github.com/users/google/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/google/subscriptions","organizations_url":"https://api.github.com/users/google/orgs","repos_url":"https://api.github.com/users/google/repos","events_url":"https://api.github.com/users/google/events{/privacy}","received_events_url":"https://api.github.com/users/google/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/google/google-api-dotnet-client","description":"Google APIs Client Library for .NET","fork":false,"url":"https://api.github.com/repos/google/google-api-dotnet-client","forks_url":"https://api.github.com/repos/google/google-api-dotnet-client/forks","keys_url":"https://api.github.com/repos/google/google-api-dotnet-client/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/google-api-dotnet-client/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/google-api-dotnet-client/teams","hooks_url":"https://api.github.com/repos/google/google-api-dotnet-client/hooks","issue_events_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/events{/number}","events_url":"https://api.github.com/repos/google/google-api-dotnet-client/events","assignees_url":"https://api.github.com/repos/google/google-api-dotnet-client/assignees{/user}","branches_url":"https://api.github.com/repos/google/google-api-dotnet-client/branches{/branch}","tags_url":"https://api.github.com/repos/google/google-api-dotnet-client/tags","blobs_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/google-api-dotnet-client/statuses/{sha}","languages_url":"https://api.github.com/repos/google/google-api-dotnet-client/languages","stargazers_url":"https://api.github.com/repos/google/google-api-dotnet-client/stargazers","contributors_url":"https://api.github.com/repos/google/google-api-dotnet-client/contributors","subscribers_url":"https://api.github.com/repos/google/google-api-dotnet-client/subscribers","subscription_url":"https://api.github.com/repos/google/google-api-dotnet-client/subscription","commits_url":"https://api.github.com/repos/google/google-api-dotnet-client/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/google-api-dotnet-client/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/google-api-dotnet-client/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/google-api-dotnet-client/contents/{+path}","compare_url":"https://api.github.com/repos/google/google-api-dotnet-client/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/google-api-dotnet-client/merges","archive_url":"https://api.github.com/repos/google/google-api-dotnet-client/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/google-api-dotnet-client/downloads","issues_url":"https://api.github.com/repos/google/google-api-dotnet-client/issues{/number}","pulls_url":"https://api.github.com/repos/google/google-api-dotnet-client/pulls{/number}","milestones_url":"https://api.github.com/repos/google/google-api-dotnet-client/milestones{/number}","notifications_url":"https://api.github.com/repos/google/google-api-dotnet-client/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/google-api-dotnet-client/labels{/name}","releases_url":"https://api.github.com/repos/google/google-api-dotnet-client/releases{/id}","created_at":"2015-04-14T17:56:22Z","updated_at":"2015-11-19T17:10:54Z","pushed_at":"2015-11-19T02:54:58Z","git_url":"git://github.com/google/google-api-dotnet-client.git","ssh_url":"git@github.com:google/google-api-dotnet-client.git","clone_url":"https://github.com/google/google-api-dotnet-client.git","svn_url":"https://github.com/google/google-api-dotnet-client","homepage":"https://developers.google.com/api-client-library/dotnet","size":9957,"stargazers_count":126,"watchers_count":126,"language":"C#","has_issues":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":67,"mirror_url":null,"open_issues_count":90,"forks":67,"open_issues":90,"watchers":126,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624"},"html":{"href":"https://github.com/google/google-api-dotnet-client/pull/624"},"issue":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/issues/624"},"comments":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/issues/624/comments"},"review_comments":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624/comments"},"review_comment":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/pulls/624/commits"},"statuses":{"href":"https://api.github.com/repos/google/google-api-dotnet-client/statuses/48a9ec1963290b6ef8593ba9d0e55dace836b0ae"}}}}