{"action":"created","issue":{"url":"https://api.github.com/repos/cjlee112/socraticqs2/issues/42","labels_url":"https://api.github.com/repos/cjlee112/socraticqs2/issues/42/labels{/name}","comments_url":"https://api.github.com/repos/cjlee112/socraticqs2/issues/42/comments","events_url":"https://api.github.com/repos/cjlee112/socraticqs2/issues/42/events","html_url":"https://github.com/cjlee112/socraticqs2/pull/42","id":89254272,"number":42,"title":"Create course PR","user":{"login":"maxsocl","id":877401,"avatar_url":"https://avatars.githubusercontent.com/u/877401?v=3","gravatar_id":"","url":"https://api.github.com/users/maxsocl","html_url":"https://github.com/maxsocl","followers_url":"https://api.github.com/users/maxsocl/followers","following_url":"https://api.github.com/users/maxsocl/following{/other_user}","gists_url":"https://api.github.com/users/maxsocl/gists{/gist_id}","starred_url":"https://api.github.com/users/maxsocl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maxsocl/subscriptions","organizations_url":"https://api.github.com/users/maxsocl/orgs","repos_url":"https://api.github.com/users/maxsocl/repos","events_url":"https://api.github.com/users/maxsocl/events{/privacy}","received_events_url":"https://api.github.com/users/maxsocl/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-06-18T10:19:13Z","updated_at":"2015-07-16T06:22:42Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/cjlee112/socraticqs2/pulls/42","html_url":"https://github.com/cjlee112/socraticqs2/pull/42","diff_url":"https://github.com/cjlee112/socraticqs2/pull/42.diff","patch_url":"https://github.com/cjlee112/socraticqs2/pull/42.patch"},"body":"@cjlee112 \r\n\r\nThis PR added create Course feature.\r\n\r\nCourse creation feature\r\n=======================\r\n\r\nTool Consumer Instructor's can create Courses on Socraticqs2 Tool Provider remotely.\r\n\r\nFor this purpose it is necessary to enter `/lti/` url as `LaunchURL` on Tool Consumer External Tool edit page.\r\n\r\nThis PR added ability to handle such url's by looking at LTI request for `context_id`, `context_title`, `tool_consumer_instance_guid` and `roles` parameters.\r\n\r\nTo implement this we follow the next logic:\r\n * First of all, we look at the `roles` LTI param of the user to decide whether the user can create courses or not.\r\n * Next we look for `context_id` LTI param to search our CourseRef models. That models is a link between Course and particular University identified by ``context_id``.\r\n * If we find a CourseRef entry we just redirect user to a Course.\r\n * If there is no CourseRef and user has role `Instructor` in `roles` LTI param we direct user to the `create_courseref` view.\r\n\r\nThat view do the following:\r\n  * creates a new Course with ``context_title`` title\r\n  * creates Instructor ``Role`` for a django user with which the LTI user is associated\r\n  * creates ``CourseRef`` entry to link Tool Consumer with this Course\r\n  * adds LTI user to Instructor's set of that Course\r\n  * redirects user to Course edit page\r\n\r\nAlso we ensure that user requests for Course creation only from LTI session.\r\nFinally Instructor can change `LaunchURL` to a `/lti/unit/{unit_id}/` pattern to point directly to a particular unit of the Course if he has created one previously.\r\n\r\n\r\nUpdate for @cjlee112 \r\nI have fixed @auraz code review questions and you can continue this PR code review."},"comment":{"url":"https://api.github.com/repos/cjlee112/socraticqs2/issues/comments/121845209","html_url":"https://github.com/cjlee112/socraticqs2/pull/42#issuecomment-121845209","issue_url":"https://api.github.com/repos/cjlee112/socraticqs2/issues/42","id":121845209,"user":{"login":"cjlee112","id":59820,"avatar_url":"https://avatars.githubusercontent.com/u/59820?v=3","gravatar_id":"","url":"https://api.github.com/users/cjlee112","html_url":"https://github.com/cjlee112","followers_url":"https://api.github.com/users/cjlee112/followers","following_url":"https://api.github.com/users/cjlee112/following{/other_user}","gists_url":"https://api.github.com/users/cjlee112/gists{/gist_id}","starred_url":"https://api.github.com/users/cjlee112/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cjlee112/subscriptions","organizations_url":"https://api.github.com/users/cjlee112/orgs","repos_url":"https://api.github.com/users/cjlee112/repos","events_url":"https://api.github.com/users/cjlee112/events{/privacy}","received_events_url":"https://api.github.com/users/cjlee112/received_events","type":"User","site_admin":false},"created_at":"2015-07-16T06:22:42Z","updated_at":"2015-07-16T06:22:42Z","body":"@maxsocl See my additional comments on the code.  Nothing major."}}