{"action":"closed","number":30,"pull_request":{"url":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/30","id":46322470,"html_url":"https://github.com/Harvard-ATG/annotationsx/pull/30","diff_url":"https://github.com/Harvard-ATG/annotationsx/pull/30.diff","patch_url":"https://github.com/Harvard-ATG/annotationsx/pull/30.patch","issue_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/30","number":30,"state":"closed","locked":false,"title":"Fixes issue with LTI launches from Canvas that contain query parameters.","user":{"login":"arthurian","id":1165361,"avatar_url":"https://avatars.githubusercontent.com/u/1165361?v=3","gravatar_id":"","url":"https://api.github.com/users/arthurian","html_url":"https://github.com/arthurian","followers_url":"https://api.github.com/users/arthurian/followers","following_url":"https://api.github.com/users/arthurian/following{/other_user}","gists_url":"https://api.github.com/users/arthurian/gists{/gist_id}","starred_url":"https://api.github.com/users/arthurian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arthurian/subscriptions","organizations_url":"https://api.github.com/users/arthurian/orgs","repos_url":"https://api.github.com/users/arthurian/repos","events_url":"https://api.github.com/users/arthurian/events{/privacy}","received_events_url":"https://api.github.com/users/arthurian/received_events","type":"User","site_admin":false},"body":"This fixes an issue with LTI launches that contain query parameters. If the LTI launch contains query parameters, the tool will reject the request as invalid because oauth signature doesn't match, but that's because of a quirk (?) in the way Canvas signs launch requests.\r\n\r\nAssuming that the launch URL looks like this: \r\n\r\n```\r\n/lti_init/launch_lti/?collection_id=152af0fd-f276-43d5-8839-b7f2ef7fdf86&object_id=2\r\n```\r\n\r\nCanvas constructs the launch parameters and oauth signature like this:\r\n\r\n1. Canvas creates a form to contain the LTI launch parameters: ```<form method=\"POST\" action=\"/lti_init/launch_lti/?collection_id=152af0fd-f276-43d5-8839-b7f2ef7fdf86&object_id=2\">```.\r\n2. Canvas adds the ```collection_id``` and ```object_id``` query parameters to the form as hidden fields to be POSTed along with the other LTI launch parameters.\r\n3. Canvas POSTs the form.\r\n4. The tool receives the POST request with POST parameters *and* the query string parameters.\r\n5. The tool validates the LTI launch by checking the value of the ```oauth_signature``` against the signature that it generates. But here's where we get into trouble: the tool's *oauth2* library generates the signature based on the query string parameters *and* the POST parameters. Since the query string parameters were duplicated as POST parameters, this means the signature that is generated won't match the one that Canvas submitted.\r\n\r\nNow normally, this issue won't come up because the LTI launch URL won't contain any GET parameters, but we might want to use GET parameters to have the tool load a specific assignment rather than show the list of assignments (i.e. the example shown above). So this workaround fixes the issue by clearing the QUERY_STRING before the validation step, and then restoring it afterward.\r\n\r\n@jazahn Can you review this?\r\n\r\n---\r\n\r\nNote: I submitted a separate [pull request](https://github.com/joestump/python-oauth2/pull/195) to the [python-oauth2](https://github.com/joestump/python-oauth2) project that would remove the need for this workaround.","created_at":"2015-09-29T19:43:42Z","updated_at":"2015-10-14T20:06:19Z","closed_at":"2015-10-14T20:06:19Z","merged_at":"2015-10-14T20:06:18Z","merge_commit_sha":"e8d6f02843559b5dd79769c07e92eb5158fc539b","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/30/commits","review_comments_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/30/comments","review_comment_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/30/comments","statuses_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/statuses/1b1704b87d13f2d7882b0ac0e81138bede29e00c","head":{"label":"Harvard-ATG:feature/fix-lti-launch-with-query","ref":"feature/fix-lti-launch-with-query","sha":"1b1704b87d13f2d7882b0ac0e81138bede29e00c","user":{"login":"Harvard-ATG","id":2099831,"avatar_url":"https://avatars.githubusercontent.com/u/2099831?v=3","gravatar_id":"","url":"https://api.github.com/users/Harvard-ATG","html_url":"https://github.com/Harvard-ATG","followers_url":"https://api.github.com/users/Harvard-ATG/followers","following_url":"https://api.github.com/users/Harvard-ATG/following{/other_user}","gists_url":"https://api.github.com/users/Harvard-ATG/gists{/gist_id}","starred_url":"https://api.github.com/users/Harvard-ATG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Harvard-ATG/subscriptions","organizations_url":"https://api.github.com/users/Harvard-ATG/orgs","repos_url":"https://api.github.com/users/Harvard-ATG/repos","events_url":"https://api.github.com/users/Harvard-ATG/events{/privacy}","received_events_url":"https://api.github.com/users/Harvard-ATG/received_events","type":"Organization","site_admin":false},"repo":{"id":37616200,"name":"annotationsx","full_name":"Harvard-ATG/annotationsx","owner":{"login":"Harvard-ATG","id":2099831,"avatar_url":"https://avatars.githubusercontent.com/u/2099831?v=3","gravatar_id":"","url":"https://api.github.com/users/Harvard-ATG","html_url":"https://github.com/Harvard-ATG","followers_url":"https://api.github.com/users/Harvard-ATG/followers","following_url":"https://api.github.com/users/Harvard-ATG/following{/other_user}","gists_url":"https://api.github.com/users/Harvard-ATG/gists{/gist_id}","starred_url":"https://api.github.com/users/Harvard-ATG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Harvard-ATG/subscriptions","organizations_url":"https://api.github.com/users/Harvard-ATG/orgs","repos_url":"https://api.github.com/users/Harvard-ATG/repos","events_url":"https://api.github.com/users/Harvard-ATG/events{/privacy}","received_events_url":"https://api.github.com/users/Harvard-ATG/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Harvard-ATG/annotationsx","description":"Contains the currently-in-development project by HarvardX to bring the annotation tool currently living in the edX platform to a more accessible LTI implementation. ","fork":true,"url":"https://api.github.com/repos/Harvard-ATG/annotationsx","forks_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/forks","keys_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/teams","hooks_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/hooks","issue_events_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/events{/number}","events_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/events","assignees_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/assignees{/user}","branches_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/branches{/branch}","tags_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/tags","blobs_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/refs{/sha}","trees_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/statuses/{sha}","languages_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/languages","stargazers_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/stargazers","contributors_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/contributors","subscribers_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/subscribers","subscription_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/subscription","commits_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/commits{/sha}","git_commits_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/commits{/sha}","comments_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/comments{/number}","issue_comment_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/comments{/number}","contents_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/contents/{+path}","compare_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/merges","archive_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/downloads","issues_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues{/number}","pulls_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls{/number}","milestones_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/milestones{/number}","notifications_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/labels{/name}","releases_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/releases{/id}","created_at":"2015-06-17T19:27:52Z","updated_at":"2015-09-03T14:52:54Z","pushed_at":"2015-10-14T20:06:18Z","git_url":"git://github.com/Harvard-ATG/annotationsx.git","ssh_url":"git@github.com:Harvard-ATG/annotationsx.git","clone_url":"https://github.com/Harvard-ATG/annotationsx.git","svn_url":"https://github.com/Harvard-ATG/annotationsx","homepage":null,"size":4430,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":1,"default_branch":"residential"}},"base":{"label":"Harvard-ATG:residential","ref":"residential","sha":"60dff9010f2e4e8dc456c5291ed223870ce273a6","user":{"login":"Harvard-ATG","id":2099831,"avatar_url":"https://avatars.githubusercontent.com/u/2099831?v=3","gravatar_id":"","url":"https://api.github.com/users/Harvard-ATG","html_url":"https://github.com/Harvard-ATG","followers_url":"https://api.github.com/users/Harvard-ATG/followers","following_url":"https://api.github.com/users/Harvard-ATG/following{/other_user}","gists_url":"https://api.github.com/users/Harvard-ATG/gists{/gist_id}","starred_url":"https://api.github.com/users/Harvard-ATG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Harvard-ATG/subscriptions","organizations_url":"https://api.github.com/users/Harvard-ATG/orgs","repos_url":"https://api.github.com/users/Harvard-ATG/repos","events_url":"https://api.github.com/users/Harvard-ATG/events{/privacy}","received_events_url":"https://api.github.com/users/Harvard-ATG/received_events","type":"Organization","site_admin":false},"repo":{"id":37616200,"name":"annotationsx","full_name":"Harvard-ATG/annotationsx","owner":{"login":"Harvard-ATG","id":2099831,"avatar_url":"https://avatars.githubusercontent.com/u/2099831?v=3","gravatar_id":"","url":"https://api.github.com/users/Harvard-ATG","html_url":"https://github.com/Harvard-ATG","followers_url":"https://api.github.com/users/Harvard-ATG/followers","following_url":"https://api.github.com/users/Harvard-ATG/following{/other_user}","gists_url":"https://api.github.com/users/Harvard-ATG/gists{/gist_id}","starred_url":"https://api.github.com/users/Harvard-ATG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Harvard-ATG/subscriptions","organizations_url":"https://api.github.com/users/Harvard-ATG/orgs","repos_url":"https://api.github.com/users/Harvard-ATG/repos","events_url":"https://api.github.com/users/Harvard-ATG/events{/privacy}","received_events_url":"https://api.github.com/users/Harvard-ATG/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/Harvard-ATG/annotationsx","description":"Contains the currently-in-development project by HarvardX to bring the annotation tool currently living in the edX platform to a more accessible LTI implementation. ","fork":true,"url":"https://api.github.com/repos/Harvard-ATG/annotationsx","forks_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/forks","keys_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/teams","hooks_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/hooks","issue_events_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/events{/number}","events_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/events","assignees_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/assignees{/user}","branches_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/branches{/branch}","tags_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/tags","blobs_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/refs{/sha}","trees_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/statuses/{sha}","languages_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/languages","stargazers_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/stargazers","contributors_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/contributors","subscribers_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/subscribers","subscription_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/subscription","commits_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/commits{/sha}","git_commits_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/git/commits{/sha}","comments_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/comments{/number}","issue_comment_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/comments{/number}","contents_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/contents/{+path}","compare_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/merges","archive_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/downloads","issues_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues{/number}","pulls_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls{/number}","milestones_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/milestones{/number}","notifications_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/labels{/name}","releases_url":"https://api.github.com/repos/Harvard-ATG/annotationsx/releases{/id}","created_at":"2015-06-17T19:27:52Z","updated_at":"2015-09-03T14:52:54Z","pushed_at":"2015-10-14T20:06:18Z","git_url":"git://github.com/Harvard-ATG/annotationsx.git","ssh_url":"git@github.com:Harvard-ATG/annotationsx.git","clone_url":"https://github.com/Harvard-ATG/annotationsx.git","svn_url":"https://github.com/Harvard-ATG/annotationsx","homepage":null,"size":4430,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":3,"forks":1,"open_issues":3,"watchers":1,"default_branch":"residential"}},"_links":{"self":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/30"},"html":{"href":"https://github.com/Harvard-ATG/annotationsx/pull/30"},"issue":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/30"},"comments":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/issues/30/comments"},"review_comments":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/30/comments"},"review_comment":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/pulls/30/commits"},"statuses":{"href":"https://api.github.com/repos/Harvard-ATG/annotationsx/statuses/1b1704b87d13f2d7882b0ac0e81138bede29e00c"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"arthurian","id":1165361,"avatar_url":"https://avatars.githubusercontent.com/u/1165361?v=3","gravatar_id":"","url":"https://api.github.com/users/arthurian","html_url":"https://github.com/arthurian","followers_url":"https://api.github.com/users/arthurian/followers","following_url":"https://api.github.com/users/arthurian/following{/other_user}","gists_url":"https://api.github.com/users/arthurian/gists{/gist_id}","starred_url":"https://api.github.com/users/arthurian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/arthurian/subscriptions","organizations_url":"https://api.github.com/users/arthurian/orgs","repos_url":"https://api.github.com/users/arthurian/repos","events_url":"https://api.github.com/users/arthurian/events{/privacy}","received_events_url":"https://api.github.com/users/arthurian/received_events","type":"User","site_admin":false},"comments":3,"review_comments":0,"commits":1,"additions":15,"deletions":1,"changed_files":1}}