{"action":"created","comment":{"url":"https://api.github.com/repos/google/keytransparency/pulls/comments/233278080","pull_request_review_id":174652174,"id":233278080,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIzMzI3ODA4MA==","diff_hunk":"@@ -276,7 +277,93 @@ func (s *Server) ListEntryHistory(ctx context.Context, in *pb.ListEntryHistoryRe\n // ListUserRevisions returns a list of revisions covering a period of time.\n func (s *Server) ListUserRevisions(ctx context.Context, in *pb.ListUserRevisionsRequest) (\n \t*pb.ListUserRevisionsResponse, error) {\n-\treturn nil, status.Error(codes.Unimplemented, \"not implemented\")\n+\toffset := int64(0)\n+\tlastVerified := in.GetLastVerifiedTreeSize()\n+\tif in.GetPageToken() != \"\" {\n+\t\ttoken := &rtpb.ListUserRevisionsToken{}\n+\t\tif err := DecodeToken(in.GetPageToken(), token); err != nil {\n+\t\t\tglog.Errorf(\"invalid page token %v: %v\", in.GetPageToken(), err)\n+\t\t\treturn nil, status.Errorf(codes.InvalidArgument, \"Invalid page_token provided\")\n+\t\t}\n+\t\t// last_verified_tree_size and page_token are allowed to change between paginated requests.\n+\t\t// Clear them here both for comparison and for encoding next_page_token in the response.\n+\t\tin.LastVerifiedTreeSize = 0\n+\t\tin.PageToken = \"\"\n+\t\tif !proto.Equal(in, token.Request) {\n+\t\t\treturn nil, status.Errorf(codes.InvalidArgument, \"Request fields changed during pagination\")\n+\t\t}\n+\t\toffset = token.RevisionsReturned\n+\t}\n+\n+\t// Lookup log and map info.\n+\tdirectoryID := in.GetDirectoryId()\n+\tif directoryID == \"\" {\n+\t\treturn nil, status.Errorf(codes.InvalidArgument, \"Please specify a directory_id\")\n+\t}\n+\td, err := s.directories.Read(ctx, directoryID, false)\n+\tif err != nil {\n+\t\tglog.Errorf(\"adminstorage.Read(%v): %v\", directoryID, err)\n+\t\treturn nil, status.Errorf(codes.Internal, \"Cannot fetch directory info\")\n+\t}\n+\n+\t// Fetch latest revision.\n+\tsth, consistencyProof, err := s.latestLogRootProof(ctx, d, lastVerified)\n+\tif err != nil {\n+\t\treturn nil, err\n+\t}\n+\tcurrentRevision, err := mapRevisionFor(sth)","path":"core/keyserver/keyserver.go","position":47,"original_position":47,"commit_id":"176a3120c25b002fbc933dda76fb98aba494e219","original_commit_id":"176a3120c25b002fbc933dda76fb98aba494e219","user":{"login":"therealdrake","id":8302057,"node_id":"MDQ6VXNlcjgzMDIwNTc=","avatar_url":"https://avatars3.githubusercontent.com/u/8302057?v=4","gravatar_id":"","url":"https://api.github.com/users/therealdrake","html_url":"https://github.com/therealdrake","followers_url":"https://api.github.com/users/therealdrake/followers","following_url":"https://api.github.com/users/therealdrake/following{/other_user}","gists_url":"https://api.github.com/users/therealdrake/gists{/gist_id}","starred_url":"https://api.github.com/users/therealdrake/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/therealdrake/subscriptions","organizations_url":"https://api.github.com/users/therealdrake/orgs","repos_url":"https://api.github.com/users/therealdrake/repos","events_url":"https://api.github.com/users/therealdrake/events{/privacy}","received_events_url":"https://api.github.com/users/therealdrake/received_events","type":"User","site_admin":false},"body":"add a consistency check here that currentRevision == in.EndRevision if in.EndRevision != 0?","created_at":"2018-11-14T00:43:51Z","updated_at":"2018-11-14T00:58:13Z","html_url":"https://github.com/google/keytransparency/pull/1114#discussion_r233278080","pull_request_url":"https://api.github.com/repos/google/keytransparency/pulls/1114","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/google/keytransparency/pulls/comments/233278080"},"html":{"href":"https://github.com/google/keytransparency/pull/1114#discussion_r233278080"},"pull_request":{"href":"https://api.github.com/repos/google/keytransparency/pulls/1114"}}},"pull_request":{"url":"https://api.github.com/repos/google/keytransparency/pulls/1114","id":230670957,"node_id":"MDExOlB1bGxSZXF1ZXN0MjMwNjcwOTU3","html_url":"https://github.com/google/keytransparency/pull/1114","diff_url":"https://github.com/google/keytransparency/pull/1114.diff","patch_url":"https://github.com/google/keytransparency/pull/1114.patch","issue_url":"https://api.github.com/repos/google/keytransparency/issues/1114","number":1114,"state":"open","locked":false,"title":"Implement ListUserRevisions","user":{"login":"jtoohill","id":41021725,"node_id":"MDQ6VXNlcjQxMDIxNzI1","avatar_url":"https://avatars2.githubusercontent.com/u/41021725?v=4","gravatar_id":"","url":"https://api.github.com/users/jtoohill","html_url":"https://github.com/jtoohill","followers_url":"https://api.github.com/users/jtoohill/followers","following_url":"https://api.github.com/users/jtoohill/following{/other_user}","gists_url":"https://api.github.com/users/jtoohill/gists{/gist_id}","starred_url":"https://api.github.com/users/jtoohill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtoohill/subscriptions","organizations_url":"https://api.github.com/users/jtoohill/orgs","repos_url":"https://api.github.com/users/jtoohill/repos","events_url":"https://api.github.com/users/jtoohill/events{/privacy}","received_events_url":"https://api.github.com/users/jtoohill/received_events","type":"User","site_admin":false},"body":"Fixes #1101. Still needs integration tests, and should eventually use a batch API in Trillian for efficiency.","created_at":"2018-11-14T00:23:52Z","updated_at":"2018-11-14T00:58:13Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9862b8cc6f4e4a4ed2d26524217786c9b09debd9","assignee":null,"assignees":[],"requested_reviewers":[{"login":"gdbelvin","id":198478,"node_id":"MDQ6VXNlcjE5ODQ3OA==","avatar_url":"https://avatars1.githubusercontent.com/u/198478?v=4","gravatar_id":"","url":"https://api.github.com/users/gdbelvin","html_url":"https://github.com/gdbelvin","followers_url":"https://api.github.com/users/gdbelvin/followers","following_url":"https://api.github.com/users/gdbelvin/following{/other_user}","gists_url":"https://api.github.com/users/gdbelvin/gists{/gist_id}","starred_url":"https://api.github.com/users/gdbelvin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gdbelvin/subscriptions","organizations_url":"https://api.github.com/users/gdbelvin/orgs","repos_url":"https://api.github.com/users/gdbelvin/repos","events_url":"https://api.github.com/users/gdbelvin/events{/privacy}","received_events_url":"https://api.github.com/users/gdbelvin/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/google/keytransparency/pulls/1114/commits","review_comments_url":"https://api.github.com/repos/google/keytransparency/pulls/1114/comments","review_comment_url":"https://api.github.com/repos/google/keytransparency/pulls/comments{/number}","comments_url":"https://api.github.com/repos/google/keytransparency/issues/1114/comments","statuses_url":"https://api.github.com/repos/google/keytransparency/statuses/176a3120c25b002fbc933dda76fb98aba494e219","head":{"label":"jtoohill:pagination","ref":"pagination","sha":"176a3120c25b002fbc933dda76fb98aba494e219","user":{"login":"jtoohill","id":41021725,"node_id":"MDQ6VXNlcjQxMDIxNzI1","avatar_url":"https://avatars2.githubusercontent.com/u/41021725?v=4","gravatar_id":"","url":"https://api.github.com/users/jtoohill","html_url":"https://github.com/jtoohill","followers_url":"https://api.github.com/users/jtoohill/followers","following_url":"https://api.github.com/users/jtoohill/following{/other_user}","gists_url":"https://api.github.com/users/jtoohill/gists{/gist_id}","starred_url":"https://api.github.com/users/jtoohill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtoohill/subscriptions","organizations_url":"https://api.github.com/users/jtoohill/orgs","repos_url":"https://api.github.com/users/jtoohill/repos","events_url":"https://api.github.com/users/jtoohill/events{/privacy}","received_events_url":"https://api.github.com/users/jtoohill/received_events","type":"User","site_admin":false},"repo":{"id":146945713,"node_id":"MDEwOlJlcG9zaXRvcnkxNDY5NDU3MTM=","name":"keytransparency","full_name":"jtoohill/keytransparency","private":false,"owner":{"login":"jtoohill","id":41021725,"node_id":"MDQ6VXNlcjQxMDIxNzI1","avatar_url":"https://avatars2.githubusercontent.com/u/41021725?v=4","gravatar_id":"","url":"https://api.github.com/users/jtoohill","html_url":"https://github.com/jtoohill","followers_url":"https://api.github.com/users/jtoohill/followers","following_url":"https://api.github.com/users/jtoohill/following{/other_user}","gists_url":"https://api.github.com/users/jtoohill/gists{/gist_id}","starred_url":"https://api.github.com/users/jtoohill/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jtoohill/subscriptions","organizations_url":"https://api.github.com/users/jtoohill/orgs","repos_url":"https://api.github.com/users/jtoohill/repos","events_url":"https://api.github.com/users/jtoohill/events{/privacy}","received_events_url":"https://api.github.com/users/jtoohill/received_events","type":"User","site_admin":false},"html_url":"https://github.com/jtoohill/keytransparency","description":"A transparent and secure way to look up public keys.","fork":true,"url":"https://api.github.com/repos/jtoohill/keytransparency","forks_url":"https://api.github.com/repos/jtoohill/keytransparency/forks","keys_url":"https://api.github.com/repos/jtoohill/keytransparency/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jtoohill/keytransparency/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jtoohill/keytransparency/teams","hooks_url":"https://api.github.com/repos/jtoohill/keytransparency/hooks","issue_events_url":"https://api.github.com/repos/jtoohill/keytransparency/issues/events{/number}","events_url":"https://api.github.com/repos/jtoohill/keytransparency/events","assignees_url":"https://api.github.com/repos/jtoohill/keytransparency/assignees{/user}","branches_url":"https://api.github.com/repos/jtoohill/keytransparency/branches{/branch}","tags_url":"https://api.github.com/repos/jtoohill/keytransparency/tags","blobs_url":"https://api.github.com/repos/jtoohill/keytransparency/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jtoohill/keytransparency/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jtoohill/keytransparency/git/refs{/sha}","trees_url":"https://api.github.com/repos/jtoohill/keytransparency/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jtoohill/keytransparency/statuses/{sha}","languages_url":"https://api.github.com/repos/jtoohill/keytransparency/languages","stargazers_url":"https://api.github.com/repos/jtoohill/keytransparency/stargazers","contributors_url":"https://api.github.com/repos/jtoohill/keytransparency/contributors","subscribers_url":"https://api.github.com/repos/jtoohill/keytransparency/subscribers","subscription_url":"https://api.github.com/repos/jtoohill/keytransparency/subscription","commits_url":"https://api.github.com/repos/jtoohill/keytransparency/commits{/sha}","git_commits_url":"https://api.github.com/repos/jtoohill/keytransparency/git/commits{/sha}","comments_url":"https://api.github.com/repos/jtoohill/keytransparency/comments{/number}","issue_comment_url":"https://api.github.com/repos/jtoohill/keytransparency/issues/comments{/number}","contents_url":"https://api.github.com/repos/jtoohill/keytransparency/contents/{+path}","compare_url":"https://api.github.com/repos/jtoohill/keytransparency/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jtoohill/keytransparency/merges","archive_url":"https://api.github.com/repos/jtoohill/keytransparency/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jtoohill/keytransparency/downloads","issues_url":"https://api.github.com/repos/jtoohill/keytransparency/issues{/number}","pulls_url":"https://api.github.com/repos/jtoohill/keytransparency/pulls{/number}","milestones_url":"https://api.github.com/repos/jtoohill/keytransparency/milestones{/number}","notifications_url":"https://api.github.com/repos/jtoohill/keytransparency/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jtoohill/keytransparency/labels{/name}","releases_url":"https://api.github.com/repos/jtoohill/keytransparency/releases{/id}","deployments_url":"https://api.github.com/repos/jtoohill/keytransparency/deployments","created_at":"2018-08-31T21:56:50Z","updated_at":"2018-11-11T00:40:44Z","pushed_at":"2018-11-14T00:23:21Z","git_url":"git://github.com/jtoohill/keytransparency.git","ssh_url":"git@github.com:jtoohill/keytransparency.git","clone_url":"https://github.com/jtoohill/keytransparency.git","svn_url":"https://github.com/jtoohill/keytransparency","homepage":"https://security.googleblog.com/2017/01/security-through-transparency.html","size":23888,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"google:master","ref":"master","sha":"3d41ce008585fd3113776e3fab4d9f74096b5c08","user":{"login":"google","id":1342004,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzNDIwMDQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1342004?v=4","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":37165115,"node_id":"MDEwOlJlcG9zaXRvcnkzNzE2NTExNQ==","name":"keytransparency","full_name":"google/keytransparency","private":false,"owner":{"login":"google","id":1342004,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEzNDIwMDQ=","avatar_url":"https://avatars1.githubusercontent.com/u/1342004?v=4","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},"html_url":"https://github.com/google/keytransparency","description":"A transparent and secure way to look up public keys.","fork":false,"url":"https://api.github.com/repos/google/keytransparency","forks_url":"https://api.github.com/repos/google/keytransparency/forks","keys_url":"https://api.github.com/repos/google/keytransparency/keys{/key_id}","collaborators_url":"https://api.github.com/repos/google/keytransparency/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/google/keytransparency/teams","hooks_url":"https://api.github.com/repos/google/keytransparency/hooks","issue_events_url":"https://api.github.com/repos/google/keytransparency/issues/events{/number}","events_url":"https://api.github.com/repos/google/keytransparency/events","assignees_url":"https://api.github.com/repos/google/keytransparency/assignees{/user}","branches_url":"https://api.github.com/repos/google/keytransparency/branches{/branch}","tags_url":"https://api.github.com/repos/google/keytransparency/tags","blobs_url":"https://api.github.com/repos/google/keytransparency/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/google/keytransparency/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/google/keytransparency/git/refs{/sha}","trees_url":"https://api.github.com/repos/google/keytransparency/git/trees{/sha}","statuses_url":"https://api.github.com/repos/google/keytransparency/statuses/{sha}","languages_url":"https://api.github.com/repos/google/keytransparency/languages","stargazers_url":"https://api.github.com/repos/google/keytransparency/stargazers","contributors_url":"https://api.github.com/repos/google/keytransparency/contributors","subscribers_url":"https://api.github.com/repos/google/keytransparency/subscribers","subscription_url":"https://api.github.com/repos/google/keytransparency/subscription","commits_url":"https://api.github.com/repos/google/keytransparency/commits{/sha}","git_commits_url":"https://api.github.com/repos/google/keytransparency/git/commits{/sha}","comments_url":"https://api.github.com/repos/google/keytransparency/comments{/number}","issue_comment_url":"https://api.github.com/repos/google/keytransparency/issues/comments{/number}","contents_url":"https://api.github.com/repos/google/keytransparency/contents/{+path}","compare_url":"https://api.github.com/repos/google/keytransparency/compare/{base}...{head}","merges_url":"https://api.github.com/repos/google/keytransparency/merges","archive_url":"https://api.github.com/repos/google/keytransparency/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/google/keytransparency/downloads","issues_url":"https://api.github.com/repos/google/keytransparency/issues{/number}","pulls_url":"https://api.github.com/repos/google/keytransparency/pulls{/number}","milestones_url":"https://api.github.com/repos/google/keytransparency/milestones{/number}","notifications_url":"https://api.github.com/repos/google/keytransparency/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/google/keytransparency/labels{/name}","releases_url":"https://api.github.com/repos/google/keytransparency/releases{/id}","deployments_url":"https://api.github.com/repos/google/keytransparency/deployments","created_at":"2015-06-09T23:55:20Z","updated_at":"2018-11-13T22:46:57Z","pushed_at":"2018-11-14T00:23:53Z","git_url":"git://github.com/google/keytransparency.git","ssh_url":"git@github.com:google/keytransparency.git","clone_url":"https://github.com/google/keytransparency.git","svn_url":"https://github.com/google/keytransparency","homepage":"https://security.googleblog.com/2017/01/security-through-transparency.html","size":23904,"stargazers_count":1333,"watchers_count":1333,"language":"Go","has_issues":true,"has_projects":true,"has_downloads":false,"has_wiki":false,"has_pages":false,"forks_count":111,"mirror_url":null,"archived":false,"open_issues_count":59,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0","node_id":"MDc6TGljZW5zZTI="},"forks":111,"open_issues":59,"watchers":1333,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/google/keytransparency/pulls/1114"},"html":{"href":"https://github.com/google/keytransparency/pull/1114"},"issue":{"href":"https://api.github.com/repos/google/keytransparency/issues/1114"},"comments":{"href":"https://api.github.com/repos/google/keytransparency/issues/1114/comments"},"review_comments":{"href":"https://api.github.com/repos/google/keytransparency/pulls/1114/comments"},"review_comment":{"href":"https://api.github.com/repos/google/keytransparency/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/google/keytransparency/pulls/1114/commits"},"statuses":{"href":"https://api.github.com/repos/google/keytransparency/statuses/176a3120c25b002fbc933dda76fb98aba494e219"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"therealdrake"}}