{"action":"created","comment":{"url":"https://api.github.com/repos/GPII/universal/pulls/comments/41382319","id":41382319,"diff_hunk":"@@ -0,0 +1,51 @@\n+## User login and Logout flow\n+\n+This document describes the flow on a locally installed GPII system when the user logs in and logs out. First an overview of the endpoints and related semantics are given and this will be followed by a more in-depth technical walkthrough of the flow.\n+\n+### Overview and APIs\n+We support 3 different logon related URLs, namely:\n+* `/user/:token/logonChange` - change the logon state of the given token (ie. log in or out)\n+ ** If no user is logged in, user <mytoken> will be logged in\n+ ** If <mytoken> is logged in, <mytoken> will be logged out\n+ ** If another user is logged in, nothing happens\n+\n+* `/user/:token/login` - log the token in\n+ ** If no user is logged in, <mytoken> will be logged in\n+ ** If another user is logged in, nothing will happen\n+\n+* `/user/:token/logout` - log the token out\n+ ** If no user is logged in, nothing happens\n+ ** if user mytoken is logged in, he will be used out\n+ ** If another user is logged in, nothing will happen\n+\n+In general, the the `logonChange` URL should be used. This will take the appropriate action depending on whether the user is logged into the system or not (ie. if the user is currently logged in, he/she will be logged out, else he/she will be logged in).\n+\n+The reason for preferring the `/logonChange` URL over the `/logout` and `/login` URL, is that we support multiple user listeners and means of logging in and out of the system, so unless the service calling these URLs does a lot of work checking for currently logged in users, eg. a `/logout` call when no user (or some other user) is logged in becomes meaningless. The implementation allows for these kinds of bogus calls to login and logout, simply resulting in an error response to the request.\n+\n+The reason for continuing to support the specific /login and /logout is that, instead of only supporting the `/logonChange` URL is that they make sense for some user listeners, for example when using the the USB listener, one wouldn't expect to log a user out when inserting the USB, or log a user in when pulling the USB out. So for that, it seems to make sense that it attempts to log in (ie. call `/login`) or log out (ie. call `/logout` when inserting/removing the USB, respectively\n+\n+\n+\n+\n+### Technical description\n+\n+The core part of the flow is defined in two files:\n+\n+* `UserLogonStateChange.js` which contains thehandling of the logon related endpoints are gathered in the flowmanagers  file and kicks off the process. This file contains individual handlers for the `login`, `logout` and `logonChange` endpoints. These handlers all have the `gpii.request.flowManager.userLogonStateChange.stateChangeHandler` grade, which is the component that contains the functionality for the actual logging in and logging off.","path":"documentation/loginAndLogoutFlow.md","position":34,"original_position":34,"commit_id":"792d73f253e098f704773af9c62b0a22ee1dc16b","original_commit_id":"792d73f253e098f704773af9c62b0a22ee1dc16b","user":{"login":"amb26","id":561418,"avatar_url":"https://avatars.githubusercontent.com/u/561418?v=3","gravatar_id":"","url":"https://api.github.com/users/amb26","html_url":"https://github.com/amb26","followers_url":"https://api.github.com/users/amb26/followers","following_url":"https://api.github.com/users/amb26/following{/other_user}","gists_url":"https://api.github.com/users/amb26/gists{/gist_id}","starred_url":"https://api.github.com/users/amb26/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amb26/subscriptions","organizations_url":"https://api.github.com/users/amb26/orgs","repos_url":"https://api.github.com/users/amb26/repos","events_url":"https://api.github.com/users/amb26/events{/privacy}","received_events_url":"https://api.github.com/users/amb26/received_events","type":"User","site_admin":false},"body":"thehandling, also double verb in this sentence - \"which contains ... are gathered\"","created_at":"2015-10-07T12:13:56Z","updated_at":"2015-10-07T12:13:56Z","html_url":"https://github.com/GPII/universal/pull/393#discussion_r41382319","pull_request_url":"https://api.github.com/repos/GPII/universal/pulls/393","_links":{"self":{"href":"https://api.github.com/repos/GPII/universal/pulls/comments/41382319"},"html":{"href":"https://github.com/GPII/universal/pull/393#discussion_r41382319"},"pull_request":{"href":"https://api.github.com/repos/GPII/universal/pulls/393"}}},"pull_request":{"url":"https://api.github.com/repos/GPII/universal/pulls/393","id":45818470,"html_url":"https://github.com/GPII/universal/pull/393","diff_url":"https://github.com/GPII/universal/pull/393.diff","patch_url":"https://github.com/GPII/universal/pull/393.patch","issue_url":"https://api.github.com/repos/GPII/universal/issues/393","number":393,"state":"open","locked":false,"title":"GPII-529: User state tracking in the system instead of in listeners","user":{"login":"kaspermarkus","id":167427,"avatar_url":"https://avatars.githubusercontent.com/u/167427?v=3","gravatar_id":"","url":"https://api.github.com/users/kaspermarkus","html_url":"https://github.com/kaspermarkus","followers_url":"https://api.github.com/users/kaspermarkus/followers","following_url":"https://api.github.com/users/kaspermarkus/following{/other_user}","gists_url":"https://api.github.com/users/kaspermarkus/gists{/gist_id}","starred_url":"https://api.github.com/users/kaspermarkus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaspermarkus/subscriptions","organizations_url":"https://api.github.com/users/kaspermarkus/orgs","repos_url":"https://api.github.com/users/kaspermarkus/repos","events_url":"https://api.github.com/users/kaspermarkus/events{/privacy}","received_events_url":"https://api.github.com/users/kaspermarkus/received_events","type":"User","site_admin":false},"body":"* Added a new URL: /userKeyaction/<token> for logging in and out without defining which of these actions it is (ie. this is managed by the system). Tests added as well","created_at":"2015-09-23T19:07:46Z","updated_at":"2015-10-07T12:13:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"743ca8cb2d6d0b0d047ef6af873ae6884c3b9a7e","assignee":{"login":"amb26","id":561418,"avatar_url":"https://avatars.githubusercontent.com/u/561418?v=3","gravatar_id":"","url":"https://api.github.com/users/amb26","html_url":"https://github.com/amb26","followers_url":"https://api.github.com/users/amb26/followers","following_url":"https://api.github.com/users/amb26/following{/other_user}","gists_url":"https://api.github.com/users/amb26/gists{/gist_id}","starred_url":"https://api.github.com/users/amb26/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/amb26/subscriptions","organizations_url":"https://api.github.com/users/amb26/orgs","repos_url":"https://api.github.com/users/amb26/repos","events_url":"https://api.github.com/users/amb26/events{/privacy}","received_events_url":"https://api.github.com/users/amb26/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/GPII/universal/pulls/393/commits","review_comments_url":"https://api.github.com/repos/GPII/universal/pulls/393/comments","review_comment_url":"https://api.github.com/repos/GPII/universal/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GPII/universal/issues/393/comments","statuses_url":"https://api.github.com/repos/GPII/universal/statuses/792d73f253e098f704773af9c62b0a22ee1dc16b","head":{"label":"kaspermarkus:GPII-529","ref":"GPII-529","sha":"792d73f253e098f704773af9c62b0a22ee1dc16b","user":{"login":"kaspermarkus","id":167427,"avatar_url":"https://avatars.githubusercontent.com/u/167427?v=3","gravatar_id":"","url":"https://api.github.com/users/kaspermarkus","html_url":"https://github.com/kaspermarkus","followers_url":"https://api.github.com/users/kaspermarkus/followers","following_url":"https://api.github.com/users/kaspermarkus/following{/other_user}","gists_url":"https://api.github.com/users/kaspermarkus/gists{/gist_id}","starred_url":"https://api.github.com/users/kaspermarkus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaspermarkus/subscriptions","organizations_url":"https://api.github.com/users/kaspermarkus/orgs","repos_url":"https://api.github.com/users/kaspermarkus/repos","events_url":"https://api.github.com/users/kaspermarkus/events{/privacy}","received_events_url":"https://api.github.com/users/kaspermarkus/received_events","type":"User","site_admin":false},"repo":{"id":3630398,"name":"universal","full_name":"kaspermarkus/universal","owner":{"login":"kaspermarkus","id":167427,"avatar_url":"https://avatars.githubusercontent.com/u/167427?v=3","gravatar_id":"","url":"https://api.github.com/users/kaspermarkus","html_url":"https://github.com/kaspermarkus","followers_url":"https://api.github.com/users/kaspermarkus/followers","following_url":"https://api.github.com/users/kaspermarkus/following{/other_user}","gists_url":"https://api.github.com/users/kaspermarkus/gists{/gist_id}","starred_url":"https://api.github.com/users/kaspermarkus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaspermarkus/subscriptions","organizations_url":"https://api.github.com/users/kaspermarkus/orgs","repos_url":"https://api.github.com/users/kaspermarkus/repos","events_url":"https://api.github.com/users/kaspermarkus/events{/privacy}","received_events_url":"https://api.github.com/users/kaspermarkus/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kaspermarkus/universal","description":"Cross platform, core components of the GPII personalization infrastructure","fork":true,"url":"https://api.github.com/repos/kaspermarkus/universal","forks_url":"https://api.github.com/repos/kaspermarkus/universal/forks","keys_url":"https://api.github.com/repos/kaspermarkus/universal/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kaspermarkus/universal/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kaspermarkus/universal/teams","hooks_url":"https://api.github.com/repos/kaspermarkus/universal/hooks","issue_events_url":"https://api.github.com/repos/kaspermarkus/universal/issues/events{/number}","events_url":"https://api.github.com/repos/kaspermarkus/universal/events","assignees_url":"https://api.github.com/repos/kaspermarkus/universal/assignees{/user}","branches_url":"https://api.github.com/repos/kaspermarkus/universal/branches{/branch}","tags_url":"https://api.github.com/repos/kaspermarkus/universal/tags","blobs_url":"https://api.github.com/repos/kaspermarkus/universal/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kaspermarkus/universal/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kaspermarkus/universal/git/refs{/sha}","trees_url":"https://api.github.com/repos/kaspermarkus/universal/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kaspermarkus/universal/statuses/{sha}","languages_url":"https://api.github.com/repos/kaspermarkus/universal/languages","stargazers_url":"https://api.github.com/repos/kaspermarkus/universal/stargazers","contributors_url":"https://api.github.com/repos/kaspermarkus/universal/contributors","subscribers_url":"https://api.github.com/repos/kaspermarkus/universal/subscribers","subscription_url":"https://api.github.com/repos/kaspermarkus/universal/subscription","commits_url":"https://api.github.com/repos/kaspermarkus/universal/commits{/sha}","git_commits_url":"https://api.github.com/repos/kaspermarkus/universal/git/commits{/sha}","comments_url":"https://api.github.com/repos/kaspermarkus/universal/comments{/number}","issue_comment_url":"https://api.github.com/repos/kaspermarkus/universal/issues/comments{/number}","contents_url":"https://api.github.com/repos/kaspermarkus/universal/contents/{+path}","compare_url":"https://api.github.com/repos/kaspermarkus/universal/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kaspermarkus/universal/merges","archive_url":"https://api.github.com/repos/kaspermarkus/universal/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kaspermarkus/universal/downloads","issues_url":"https://api.github.com/repos/kaspermarkus/universal/issues{/number}","pulls_url":"https://api.github.com/repos/kaspermarkus/universal/pulls{/number}","milestones_url":"https://api.github.com/repos/kaspermarkus/universal/milestones{/number}","notifications_url":"https://api.github.com/repos/kaspermarkus/universal/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kaspermarkus/universal/labels{/name}","releases_url":"https://api.github.com/repos/kaspermarkus/universal/releases{/id}","created_at":"2012-03-05T19:15:52Z","updated_at":"2015-04-15T09:45:40Z","pushed_at":"2015-10-07T12:03:28Z","git_url":"git://github.com/kaspermarkus/universal.git","ssh_url":"git@github.com:kaspermarkus/universal.git","clone_url":"https://github.com/kaspermarkus/universal.git","svn_url":"https://github.com/kaspermarkus/universal","homepage":"gpii.net","size":6547,"stargazers_count":1,"watchers_count":1,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"GPII:master","ref":"master","sha":"39d06c9389befd8b344467589faba9890ed28b40","user":{"login":"GPII","id":1343050,"avatar_url":"https://avatars.githubusercontent.com/u/1343050?v=3","gravatar_id":"","url":"https://api.github.com/users/GPII","html_url":"https://github.com/GPII","followers_url":"https://api.github.com/users/GPII/followers","following_url":"https://api.github.com/users/GPII/following{/other_user}","gists_url":"https://api.github.com/users/GPII/gists{/gist_id}","starred_url":"https://api.github.com/users/GPII/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GPII/subscriptions","organizations_url":"https://api.github.com/users/GPII/orgs","repos_url":"https://api.github.com/users/GPII/repos","events_url":"https://api.github.com/users/GPII/events{/privacy}","received_events_url":"https://api.github.com/users/GPII/received_events","type":"Organization","site_admin":false},"repo":{"id":3623720,"name":"universal","full_name":"GPII/universal","owner":{"login":"GPII","id":1343050,"avatar_url":"https://avatars.githubusercontent.com/u/1343050?v=3","gravatar_id":"","url":"https://api.github.com/users/GPII","html_url":"https://github.com/GPII","followers_url":"https://api.github.com/users/GPII/followers","following_url":"https://api.github.com/users/GPII/following{/other_user}","gists_url":"https://api.github.com/users/GPII/gists{/gist_id}","starred_url":"https://api.github.com/users/GPII/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GPII/subscriptions","organizations_url":"https://api.github.com/users/GPII/orgs","repos_url":"https://api.github.com/users/GPII/repos","events_url":"https://api.github.com/users/GPII/events{/privacy}","received_events_url":"https://api.github.com/users/GPII/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GPII/universal","description":"Cross platform, core components of the GPII personalization infrastructure","fork":false,"url":"https://api.github.com/repos/GPII/universal","forks_url":"https://api.github.com/repos/GPII/universal/forks","keys_url":"https://api.github.com/repos/GPII/universal/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GPII/universal/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GPII/universal/teams","hooks_url":"https://api.github.com/repos/GPII/universal/hooks","issue_events_url":"https://api.github.com/repos/GPII/universal/issues/events{/number}","events_url":"https://api.github.com/repos/GPII/universal/events","assignees_url":"https://api.github.com/repos/GPII/universal/assignees{/user}","branches_url":"https://api.github.com/repos/GPII/universal/branches{/branch}","tags_url":"https://api.github.com/repos/GPII/universal/tags","blobs_url":"https://api.github.com/repos/GPII/universal/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GPII/universal/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GPII/universal/git/refs{/sha}","trees_url":"https://api.github.com/repos/GPII/universal/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GPII/universal/statuses/{sha}","languages_url":"https://api.github.com/repos/GPII/universal/languages","stargazers_url":"https://api.github.com/repos/GPII/universal/stargazers","contributors_url":"https://api.github.com/repos/GPII/universal/contributors","subscribers_url":"https://api.github.com/repos/GPII/universal/subscribers","subscription_url":"https://api.github.com/repos/GPII/universal/subscription","commits_url":"https://api.github.com/repos/GPII/universal/commits{/sha}","git_commits_url":"https://api.github.com/repos/GPII/universal/git/commits{/sha}","comments_url":"https://api.github.com/repos/GPII/universal/comments{/number}","issue_comment_url":"https://api.github.com/repos/GPII/universal/issues/comments{/number}","contents_url":"https://api.github.com/repos/GPII/universal/contents/{+path}","compare_url":"https://api.github.com/repos/GPII/universal/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GPII/universal/merges","archive_url":"https://api.github.com/repos/GPII/universal/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GPII/universal/downloads","issues_url":"https://api.github.com/repos/GPII/universal/issues{/number}","pulls_url":"https://api.github.com/repos/GPII/universal/pulls{/number}","milestones_url":"https://api.github.com/repos/GPII/universal/milestones{/number}","notifications_url":"https://api.github.com/repos/GPII/universal/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GPII/universal/labels{/name}","releases_url":"https://api.github.com/repos/GPII/universal/releases{/id}","created_at":"2012-03-05T04:01:44Z","updated_at":"2015-06-03T18:28:28Z","pushed_at":"2015-10-07T12:03:29Z","git_url":"git://github.com/GPII/universal.git","ssh_url":"git@github.com:GPII/universal.git","clone_url":"https://github.com/GPII/universal.git","svn_url":"https://github.com/GPII/universal","homepage":"gpii.net","size":95349,"stargazers_count":21,"watchers_count":21,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":47,"mirror_url":null,"open_issues_count":35,"forks":47,"open_issues":35,"watchers":21,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GPII/universal/pulls/393"},"html":{"href":"https://github.com/GPII/universal/pull/393"},"issue":{"href":"https://api.github.com/repos/GPII/universal/issues/393"},"comments":{"href":"https://api.github.com/repos/GPII/universal/issues/393/comments"},"review_comments":{"href":"https://api.github.com/repos/GPII/universal/pulls/393/comments"},"review_comment":{"href":"https://api.github.com/repos/GPII/universal/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GPII/universal/pulls/393/commits"},"statuses":{"href":"https://api.github.com/repos/GPII/universal/statuses/792d73f253e098f704773af9c62b0a22ee1dc16b"}}}}