{"action":"closed","number":21,"pull_request":{"url":"https://api.github.com/repos/euphoria-io/heim/pulls/21","id":38935147,"html_url":"https://github.com/euphoria-io/heim/pull/21","diff_url":"https://github.com/euphoria-io/heim/pull/21.diff","patch_url":"https://github.com/euphoria-io/heim/pull/21.patch","issue_url":"https://api.github.com/repos/euphoria-io/heim/issues/21","number":21,"state":"closed","locked":false,"title":"An account system and major refactoring of capability system","user":{"login":"logan","id":9101,"avatar_url":"https://avatars.githubusercontent.com/u/9101?v=3","gravatar_id":"","url":"https://api.github.com/users/logan","html_url":"https://github.com/logan","followers_url":"https://api.github.com/users/logan/followers","following_url":"https://api.github.com/users/logan/following{/other_user}","gists_url":"https://api.github.com/users/logan/gists{/gist_id}","starred_url":"https://api.github.com/users/logan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/logan/subscriptions","organizations_url":"https://api.github.com/users/logan/orgs","repos_url":"https://api.github.com/users/logan/repos","events_url":"https://api.github.com/users/logan/events{/privacy}","received_events_url":"https://api.github.com/users/logan/received_events","type":"User","site_admin":false},"body":"This is too enormous to review, but I'm posting it as a pull request anyway to coordinate consensus for deployment, and as a kernel of documentation for all the new features.\r\n\r\n# Agents and Accounts\r\n\r\n*Accounts* can now be registered with one or more *personal identities*, like an email address (in fact that's all that's supported so far). Eventually we'll add a concept of *verification* for identities and accounts.\r\n\r\nAn account has a secret key, which is encrypted by the account password (which the server doesn't store) *and* by our KMS. This secret key is in turn used to encrypt the private half of an accont key-pair. It is this key-pair that is used as the basis for capability grants to accounts.\r\n\r\n*Agents* are a preexisting concept that are further elaborated in the new account system. New agent cookies will include a randomly generated key that isn't stored by the servers. When a user logs in or registers an account, the key derived from their password is encrypted by the secret agent key and stored in the database. Subsequent connections using the same agent cookie can therefore unlock the client.\r\n\r\n# Account Capabilities\r\n\r\nGranting a capability to an account is implemented as an encrypted transmission between two asymmetric key-pairs, i.e. the room and the account. A number of attributes have been added to the room, and a create-room command must be used now to initialize the various keys.\r\n\r\nAn agent affiliated with an account acquires all of that account's capabilities. If a room has both password and account grants for access, then either or both kinds can be held.\r\n\r\n# New websocket commands\r\n\r\nNew event:\r\n\r\n* disconnect-event\r\n\r\nFor accounts:\r\n\r\n* register-account\r\n* login\r\n* logout\r\n\r\nFor room managers:\r\n\r\n* edit-message (only deletion is properly supported)\r\n* grant-access (target is account_id or passcode)\r\n* grant-manager\r\n* revoke-access (same as grant-access)\r\n* revoke-manager\r\n\r\nFor staff:\r\n\r\n* staff-upgrade-room (no arguments, current room)\r\n* staff-create-room\r\n* staff-lock-room (current room, doesn't kick people, doesn't roll old capabilities forward)\r\n* staff-grant-manager (current room)\r\n* staff-revoke-manager (current room)\r\n* staff-revoke-access (current room)\r\n* unlock-staff-capability (not yet required)\r\n\r\n# Console command changes\r\n\r\nThe following console commands have been removed:\r\n\r\n* lock-room\r\n* set-room-passcode\r\n\r\nTwo new commands have been added:\r\n\r\n* grant-staff\r\n* revoke-staff","created_at":"2015-06-30T23:25:21Z","updated_at":"2015-07-01T18:32:16Z","closed_at":"2015-07-01T18:32:16Z","merged_at":"2015-07-01T18:32:16Z","merge_commit_sha":"57d8e3e646e7b4cc86f7edbd14e578037b597b68","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/euphoria-io/heim/pulls/21/commits","review_comments_url":"https://api.github.com/repos/euphoria-io/heim/pulls/21/comments","review_comment_url":"https://api.github.com/repos/euphoria-io/heim/pulls/comments{/number}","comments_url":"https://api.github.com/repos/euphoria-io/heim/issues/21/comments","statuses_url":"https://api.github.com/repos/euphoria-io/heim/statuses/f39d7feb9c2084028befb3c3800de43e3a081a68","head":{"label":"euphoria-io:dev/logan","ref":"dev/logan","sha":"f39d7feb9c2084028befb3c3800de43e3a081a68","user":{"login":"euphoria-io","id":10294553,"avatar_url":"https://avatars.githubusercontent.com/u/10294553?v=3","gravatar_id":"","url":"https://api.github.com/users/euphoria-io","html_url":"https://github.com/euphoria-io","followers_url":"https://api.github.com/users/euphoria-io/followers","following_url":"https://api.github.com/users/euphoria-io/following{/other_user}","gists_url":"https://api.github.com/users/euphoria-io/gists{/gist_id}","starred_url":"https://api.github.com/users/euphoria-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/euphoria-io/subscriptions","organizations_url":"https://api.github.com/users/euphoria-io/orgs","repos_url":"https://api.github.com/users/euphoria-io/repos","events_url":"https://api.github.com/users/euphoria-io/events{/privacy}","received_events_url":"https://api.github.com/users/euphoria-io/received_events","type":"Organization","site_admin":false},"repo":{"id":27980281,"name":"heim","full_name":"euphoria-io/heim","owner":{"login":"euphoria-io","id":10294553,"avatar_url":"https://avatars.githubusercontent.com/u/10294553?v=3","gravatar_id":"","url":"https://api.github.com/users/euphoria-io","html_url":"https://github.com/euphoria-io","followers_url":"https://api.github.com/users/euphoria-io/followers","following_url":"https://api.github.com/users/euphoria-io/following{/other_user}","gists_url":"https://api.github.com/users/euphoria-io/gists{/gist_id}","starred_url":"https://api.github.com/users/euphoria-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/euphoria-io/subscriptions","organizations_url":"https://api.github.com/users/euphoria-io/orgs","repos_url":"https://api.github.com/users/euphoria-io/repos","events_url":"https://api.github.com/users/euphoria-io/events{/privacy}","received_events_url":"https://api.github.com/users/euphoria-io/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/euphoria-io/heim","description":"A real-time community platform.","fork":false,"url":"https://api.github.com/repos/euphoria-io/heim","forks_url":"https://api.github.com/repos/euphoria-io/heim/forks","keys_url":"https://api.github.com/repos/euphoria-io/heim/keys{/key_id}","collaborators_url":"https://api.github.com/repos/euphoria-io/heim/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/euphoria-io/heim/teams","hooks_url":"https://api.github.com/repos/euphoria-io/heim/hooks","issue_events_url":"https://api.github.com/repos/euphoria-io/heim/issues/events{/number}","events_url":"https://api.github.com/repos/euphoria-io/heim/events","assignees_url":"https://api.github.com/repos/euphoria-io/heim/assignees{/user}","branches_url":"https://api.github.com/repos/euphoria-io/heim/branches{/branch}","tags_url":"https://api.github.com/repos/euphoria-io/heim/tags","blobs_url":"https://api.github.com/repos/euphoria-io/heim/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/euphoria-io/heim/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/euphoria-io/heim/git/refs{/sha}","trees_url":"https://api.github.com/repos/euphoria-io/heim/git/trees{/sha}","statuses_url":"https://api.github.com/repos/euphoria-io/heim/statuses/{sha}","languages_url":"https://api.github.com/repos/euphoria-io/heim/languages","stargazers_url":"https://api.github.com/repos/euphoria-io/heim/stargazers","contributors_url":"https://api.github.com/repos/euphoria-io/heim/contributors","subscribers_url":"https://api.github.com/repos/euphoria-io/heim/subscribers","subscription_url":"https://api.github.com/repos/euphoria-io/heim/subscription","commits_url":"https://api.github.com/repos/euphoria-io/heim/commits{/sha}","git_commits_url":"https://api.github.com/repos/euphoria-io/heim/git/commits{/sha}","comments_url":"https://api.github.com/repos/euphoria-io/heim/comments{/number}","issue_comment_url":"https://api.github.com/repos/euphoria-io/heim/issues/comments{/number}","contents_url":"https://api.github.com/repos/euphoria-io/heim/contents/{+path}","compare_url":"https://api.github.com/repos/euphoria-io/heim/compare/{base}...{head}","merges_url":"https://api.github.com/repos/euphoria-io/heim/merges","archive_url":"https://api.github.com/repos/euphoria-io/heim/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/euphoria-io/heim/downloads","issues_url":"https://api.github.com/repos/euphoria-io/heim/issues{/number}","pulls_url":"https://api.github.com/repos/euphoria-io/heim/pulls{/number}","milestones_url":"https://api.github.com/repos/euphoria-io/heim/milestones{/number}","notifications_url":"https://api.github.com/repos/euphoria-io/heim/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/euphoria-io/heim/labels{/name}","releases_url":"https://api.github.com/repos/euphoria-io/heim/releases{/id}","created_at":"2014-12-14T02:04:42Z","updated_at":"2015-06-21T19:24:33Z","pushed_at":"2015-07-01T18:32:16Z","git_url":"git://github.com/euphoria-io/heim.git","ssh_url":"git@github.com:euphoria-io/heim.git","clone_url":"https://github.com/euphoria-io/heim.git","svn_url":"https://github.com/euphoria-io/heim","homepage":"https://euphoria.io","size":3756,"stargazers_count":13,"watchers_count":13,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":2,"forks":5,"open_issues":2,"watchers":13,"default_branch":"master"}},"base":{"label":"euphoria-io:master","ref":"master","sha":"cf15053f39d0b09359336583161d734338cac482","user":{"login":"euphoria-io","id":10294553,"avatar_url":"https://avatars.githubusercontent.com/u/10294553?v=3","gravatar_id":"","url":"https://api.github.com/users/euphoria-io","html_url":"https://github.com/euphoria-io","followers_url":"https://api.github.com/users/euphoria-io/followers","following_url":"https://api.github.com/users/euphoria-io/following{/other_user}","gists_url":"https://api.github.com/users/euphoria-io/gists{/gist_id}","starred_url":"https://api.github.com/users/euphoria-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/euphoria-io/subscriptions","organizations_url":"https://api.github.com/users/euphoria-io/orgs","repos_url":"https://api.github.com/users/euphoria-io/repos","events_url":"https://api.github.com/users/euphoria-io/events{/privacy}","received_events_url":"https://api.github.com/users/euphoria-io/received_events","type":"Organization","site_admin":false},"repo":{"id":27980281,"name":"heim","full_name":"euphoria-io/heim","owner":{"login":"euphoria-io","id":10294553,"avatar_url":"https://avatars.githubusercontent.com/u/10294553?v=3","gravatar_id":"","url":"https://api.github.com/users/euphoria-io","html_url":"https://github.com/euphoria-io","followers_url":"https://api.github.com/users/euphoria-io/followers","following_url":"https://api.github.com/users/euphoria-io/following{/other_user}","gists_url":"https://api.github.com/users/euphoria-io/gists{/gist_id}","starred_url":"https://api.github.com/users/euphoria-io/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/euphoria-io/subscriptions","organizations_url":"https://api.github.com/users/euphoria-io/orgs","repos_url":"https://api.github.com/users/euphoria-io/repos","events_url":"https://api.github.com/users/euphoria-io/events{/privacy}","received_events_url":"https://api.github.com/users/euphoria-io/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/euphoria-io/heim","description":"A real-time community platform.","fork":false,"url":"https://api.github.com/repos/euphoria-io/heim","forks_url":"https://api.github.com/repos/euphoria-io/heim/forks","keys_url":"https://api.github.com/repos/euphoria-io/heim/keys{/key_id}","collaborators_url":"https://api.github.com/repos/euphoria-io/heim/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/euphoria-io/heim/teams","hooks_url":"https://api.github.com/repos/euphoria-io/heim/hooks","issue_events_url":"https://api.github.com/repos/euphoria-io/heim/issues/events{/number}","events_url":"https://api.github.com/repos/euphoria-io/heim/events","assignees_url":"https://api.github.com/repos/euphoria-io/heim/assignees{/user}","branches_url":"https://api.github.com/repos/euphoria-io/heim/branches{/branch}","tags_url":"https://api.github.com/repos/euphoria-io/heim/tags","blobs_url":"https://api.github.com/repos/euphoria-io/heim/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/euphoria-io/heim/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/euphoria-io/heim/git/refs{/sha}","trees_url":"https://api.github.com/repos/euphoria-io/heim/git/trees{/sha}","statuses_url":"https://api.github.com/repos/euphoria-io/heim/statuses/{sha}","languages_url":"https://api.github.com/repos/euphoria-io/heim/languages","stargazers_url":"https://api.github.com/repos/euphoria-io/heim/stargazers","contributors_url":"https://api.github.com/repos/euphoria-io/heim/contributors","subscribers_url":"https://api.github.com/repos/euphoria-io/heim/subscribers","subscription_url":"https://api.github.com/repos/euphoria-io/heim/subscription","commits_url":"https://api.github.com/repos/euphoria-io/heim/commits{/sha}","git_commits_url":"https://api.github.com/repos/euphoria-io/heim/git/commits{/sha}","comments_url":"https://api.github.com/repos/euphoria-io/heim/comments{/number}","issue_comment_url":"https://api.github.com/repos/euphoria-io/heim/issues/comments{/number}","contents_url":"https://api.github.com/repos/euphoria-io/heim/contents/{+path}","compare_url":"https://api.github.com/repos/euphoria-io/heim/compare/{base}...{head}","merges_url":"https://api.github.com/repos/euphoria-io/heim/merges","archive_url":"https://api.github.com/repos/euphoria-io/heim/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/euphoria-io/heim/downloads","issues_url":"https://api.github.com/repos/euphoria-io/heim/issues{/number}","pulls_url":"https://api.github.com/repos/euphoria-io/heim/pulls{/number}","milestones_url":"https://api.github.com/repos/euphoria-io/heim/milestones{/number}","notifications_url":"https://api.github.com/repos/euphoria-io/heim/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/euphoria-io/heim/labels{/name}","releases_url":"https://api.github.com/repos/euphoria-io/heim/releases{/id}","created_at":"2014-12-14T02:04:42Z","updated_at":"2015-06-21T19:24:33Z","pushed_at":"2015-07-01T18:32:16Z","git_url":"git://github.com/euphoria-io/heim.git","ssh_url":"git@github.com:euphoria-io/heim.git","clone_url":"https://github.com/euphoria-io/heim.git","svn_url":"https://github.com/euphoria-io/heim","homepage":"https://euphoria.io","size":3756,"stargazers_count":13,"watchers_count":13,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":2,"forks":5,"open_issues":2,"watchers":13,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/euphoria-io/heim/pulls/21"},"html":{"href":"https://github.com/euphoria-io/heim/pull/21"},"issue":{"href":"https://api.github.com/repos/euphoria-io/heim/issues/21"},"comments":{"href":"https://api.github.com/repos/euphoria-io/heim/issues/21/comments"},"review_comments":{"href":"https://api.github.com/repos/euphoria-io/heim/pulls/21/comments"},"review_comment":{"href":"https://api.github.com/repos/euphoria-io/heim/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/euphoria-io/heim/pulls/21/commits"},"statuses":{"href":"https://api.github.com/repos/euphoria-io/heim/statuses/f39d7feb9c2084028befb3c3800de43e3a081a68"}},"merged":true,"mergeable":null,"mergeable_state":"unknown","merged_by":{"login":"logan","id":9101,"avatar_url":"https://avatars.githubusercontent.com/u/9101?v=3","gravatar_id":"","url":"https://api.github.com/users/logan","html_url":"https://github.com/logan","followers_url":"https://api.github.com/users/logan/followers","following_url":"https://api.github.com/users/logan/following{/other_user}","gists_url":"https://api.github.com/users/logan/gists{/gist_id}","starred_url":"https://api.github.com/users/logan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/logan/subscriptions","organizations_url":"https://api.github.com/users/logan/orgs","repos_url":"https://api.github.com/users/logan/repos","events_url":"https://api.github.com/users/logan/events{/privacy}","received_events_url":"https://api.github.com/users/logan/received_events","type":"User","site_admin":false},"comments":0,"review_comments":0,"commits":69,"additions":5564,"deletions":905,"changed_files":49}}