{"action":"created","comment":{"url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/comments/220353395","pull_request_review_id":158742942,"id":220353395,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyMDM1MzM5NQ==","diff_hunk":"@@ -103,27 +120,68 @@ def run(input)\n \n           # Load, resolve, and validate puppet config settings\n           settings_overrides = {}\n-          # Since puppet expects the key to be called 'dns_alt_names', we need to use that here\n-          # to ensure that the overriding works correctly.\n-          settings_overrides[:dns_alt_names] = input['subject-alt-names'] unless input['subject-alt-names'].empty?\n           puppet = Config::Puppet.new(config_path)\n           puppet.load(settings_overrides)\n           return 1 if CliParsing.handle_errors(@logger, puppet.errors)\n \n+          # We don't want generate to respect the alt names setting, since it is usually\n+          # used to generate certs for other nodes\n+          alt_names = input['subject-alt-names']\n+\n           # Load most secure signing digest we can for csr signing.\n           signer = SigningDigest.new\n           return 1 if CliParsing.handle_errors(@logger, signer.errors)\n \n           # Generate and save certs and associated keys\n-          all_passed = generate_certs(certnames, puppet.settings, signer.digest)\n+          if input['ca-client']\n+            all_passed = generate_authorized_certs(certnames, alt_names, puppet.settings, signer.digest)\n+          else\n+            all_passed = generate_certs(certnames, alt_names, puppet.settings, signer.digest)\n+          end\n           return all_passed ? 0 : 1\n         end\n \n+        # Certs authorized to talk to the CA API need to be signed offline,\n+        # in order to securely add the special auth extension.\n+        def generate_authorized_certs(certnames, alt_names, settings, digest)\n+          # Make sure we have all the directories where we will be writing files\n+          FileSystem.ensure_dirs([settings[:ssldir],\n+                                  settings[:certdir],\n+                                  settings[:privatekeydir],\n+                                  settings[:publickeydir]])\n+\n+          ca = Puppetserver::Ca::LocalCertificateAuthority.new(digest, settings)\n+          ca_cert, ca_key = ca.load_ca\n+          return 1 if CliParsing.handle_errors(@logger, ca.errors)\n+\n+          passed = certnames.map do |certname|\n+            if !alt_names.empty?\n+              # When validating the cert, OpenSSL will ignore the CN field if\n+              # altnames are present, so we need to ensure that the certname is\n+              # also listed among the alt names.\n+              alt_names += \",DNS:#{certname}\"\n+              alt_names = Puppetserver::Ca::Utils::Config.munge_alt_names(alt_names)\n+            end\n+\n+            # For certs signed offline, any alt names are added directly to the cert,\n+            # rather than to the CSR.\n+            key, csr = generate_key_csr(certname, settings, digest)\n+            return false unless csr","path":"lib/puppetserver/ca/action/generate.rb","position":103,"original_position":103,"commit_id":"a74212d581fd39b4f429fb2771cd2a54acbae625","original_commit_id":"a74212d581fd39b4f429fb2771cd2a54acbae625","user":{"login":"justinstoller","id":241423,"node_id":"MDQ6VXNlcjI0MTQyMw==","avatar_url":"https://avatars0.githubusercontent.com/u/241423?v=4","gravatar_id":"","url":"https://api.github.com/users/justinstoller","html_url":"https://github.com/justinstoller","followers_url":"https://api.github.com/users/justinstoller/followers","following_url":"https://api.github.com/users/justinstoller/following{/other_user}","gists_url":"https://api.github.com/users/justinstoller/gists{/gist_id}","starred_url":"https://api.github.com/users/justinstoller/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justinstoller/subscriptions","organizations_url":"https://api.github.com/users/justinstoller/orgs","repos_url":"https://api.github.com/users/justinstoller/repos","events_url":"https://api.github.com/users/justinstoller/events{/privacy}","received_events_url":"https://api.github.com/users/justinstoller/received_events","type":"User","site_admin":false},"body":"I think this will break out of the certnames loop and directly return false from `generate_authorized_certs`?","created_at":"2018-09-25T20:59:44Z","updated_at":"2018-09-25T20:59:44Z","html_url":"https://github.com/puppetlabs/puppetserver-ca-cli/pull/38#discussion_r220353395","pull_request_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/comments/220353395"},"html":{"href":"https://github.com/puppetlabs/puppetserver-ca-cli/pull/38#discussion_r220353395"},"pull_request":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38"}}},"pull_request":{"url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38","id":217804674,"node_id":"MDExOlB1bGxSZXF1ZXN0MjE3ODA0Njc0","html_url":"https://github.com/puppetlabs/puppetserver-ca-cli/pull/38","diff_url":"https://github.com/puppetlabs/puppetserver-ca-cli/pull/38.diff","patch_url":"https://github.com/puppetlabs/puppetserver-ca-cli/pull/38.patch","issue_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues/38","number":38,"state":"open","locked":false,"title":"(SERVER-2320) Allow generation of an authorized cert offline","user":{"login":"Magisus","id":839145,"node_id":"MDQ6VXNlcjgzOTE0NQ==","avatar_url":"https://avatars3.githubusercontent.com/u/839145?v=4","gravatar_id":"","url":"https://api.github.com/users/Magisus","html_url":"https://github.com/Magisus","followers_url":"https://api.github.com/users/Magisus/followers","following_url":"https://api.github.com/users/Magisus/following{/other_user}","gists_url":"https://api.github.com/users/Magisus/gists{/gist_id}","starred_url":"https://api.github.com/users/Magisus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Magisus/subscriptions","organizations_url":"https://api.github.com/users/Magisus/orgs","repos_url":"https://api.github.com/users/Magisus/repos","events_url":"https://api.github.com/users/Magisus/events{/privacy}","received_events_url":"https://api.github.com/users/Magisus/received_events","type":"User","site_admin":false},"body":"The cert used by the CA CLI needs to have a special auth extension that\r\nis disallowed by the Puppet Server CA, to prevent any node from\r\nrequesting a cert with the special permissions. Previously, this cert\r\nwas always created along with the rest of the CA files.\r\n\r\nThis commit adds a way to generate an authorized cert with the special\r\nextension, from an existing CA. The special cert is signed offline, not\r\nthrough the main Puppet CA. It can be generated with values for the\r\nmaster, or with values for other nodes. In the latter case the cert and\r\nkeys will need to be distributed manually.\r\n\r\nThis also updates `generate` to not use the `subject_alt_names`\r\nsetting. This setting is supposed to be specific to the master node, but\r\n`generate` can be used to create certs for any node, and those shouldn't\r\nnecessarily have the master's alt names. When using `generate`, the user\r\nneeds to specify both certname and any alt names manually.","created_at":"2018-09-24T22:18:21Z","updated_at":"2018-09-25T20:59:44Z","closed_at":null,"merged_at":null,"merge_commit_sha":"0e2bb8ecab07992c452dd64a589b98586aef6637","assignee":null,"assignees":[],"requested_reviewers":[{"login":"jpartlow","id":183241,"node_id":"MDQ6VXNlcjE4MzI0MQ==","avatar_url":"https://avatars1.githubusercontent.com/u/183241?v=4","gravatar_id":"","url":"https://api.github.com/users/jpartlow","html_url":"https://github.com/jpartlow","followers_url":"https://api.github.com/users/jpartlow/followers","following_url":"https://api.github.com/users/jpartlow/following{/other_user}","gists_url":"https://api.github.com/users/jpartlow/gists{/gist_id}","starred_url":"https://api.github.com/users/jpartlow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jpartlow/subscriptions","organizations_url":"https://api.github.com/users/jpartlow/orgs","repos_url":"https://api.github.com/users/jpartlow/repos","events_url":"https://api.github.com/users/jpartlow/events{/privacy}","received_events_url":"https://api.github.com/users/jpartlow/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38/commits","review_comments_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38/comments","review_comment_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/comments{/number}","comments_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues/38/comments","statuses_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/statuses/a74212d581fd39b4f429fb2771cd2a54acbae625","head":{"label":"Magisus:master-generate","ref":"master-generate","sha":"a74212d581fd39b4f429fb2771cd2a54acbae625","user":{"login":"Magisus","id":839145,"node_id":"MDQ6VXNlcjgzOTE0NQ==","avatar_url":"https://avatars3.githubusercontent.com/u/839145?v=4","gravatar_id":"","url":"https://api.github.com/users/Magisus","html_url":"https://github.com/Magisus","followers_url":"https://api.github.com/users/Magisus/followers","following_url":"https://api.github.com/users/Magisus/following{/other_user}","gists_url":"https://api.github.com/users/Magisus/gists{/gist_id}","starred_url":"https://api.github.com/users/Magisus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Magisus/subscriptions","organizations_url":"https://api.github.com/users/Magisus/orgs","repos_url":"https://api.github.com/users/Magisus/repos","events_url":"https://api.github.com/users/Magisus/events{/privacy}","received_events_url":"https://api.github.com/users/Magisus/received_events","type":"User","site_admin":false},"repo":{"id":141457836,"node_id":"MDEwOlJlcG9zaXRvcnkxNDE0NTc4MzY=","name":"puppetserver-ca-cli","full_name":"Magisus/puppetserver-ca-cli","private":false,"owner":{"login":"Magisus","id":839145,"node_id":"MDQ6VXNlcjgzOTE0NQ==","avatar_url":"https://avatars3.githubusercontent.com/u/839145?v=4","gravatar_id":"","url":"https://api.github.com/users/Magisus","html_url":"https://github.com/Magisus","followers_url":"https://api.github.com/users/Magisus/followers","following_url":"https://api.github.com/users/Magisus/following{/other_user}","gists_url":"https://api.github.com/users/Magisus/gists{/gist_id}","starred_url":"https://api.github.com/users/Magisus/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Magisus/subscriptions","organizations_url":"https://api.github.com/users/Magisus/orgs","repos_url":"https://api.github.com/users/Magisus/repos","events_url":"https://api.github.com/users/Magisus/events{/privacy}","received_events_url":"https://api.github.com/users/Magisus/received_events","type":"User","site_admin":false},"html_url":"https://github.com/Magisus/puppetserver-ca-cli","description":"A simple Ruby CLI tool to interact with the Puppet Server's included Certificate Authority","fork":true,"url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli","forks_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/forks","keys_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/teams","hooks_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/hooks","issue_events_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/issues/events{/number}","events_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/events","assignees_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/assignees{/user}","branches_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/branches{/branch}","tags_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/tags","blobs_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/git/refs{/sha}","trees_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/statuses/{sha}","languages_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/languages","stargazers_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/stargazers","contributors_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/contributors","subscribers_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/subscribers","subscription_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/subscription","commits_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/commits{/sha}","git_commits_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/git/commits{/sha}","comments_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/comments{/number}","issue_comment_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/issues/comments{/number}","contents_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/contents/{+path}","compare_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/merges","archive_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/downloads","issues_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/issues{/number}","pulls_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/pulls{/number}","milestones_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/milestones{/number}","notifications_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/labels{/name}","releases_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/releases{/id}","deployments_url":"https://api.github.com/repos/Magisus/puppetserver-ca-cli/deployments","created_at":"2018-07-18T15:58:09Z","updated_at":"2018-08-29T15:14:57Z","pushed_at":"2018-09-25T18:44:49Z","git_url":"git://github.com/Magisus/puppetserver-ca-cli.git","ssh_url":"git@github.com:Magisus/puppetserver-ca-cli.git","clone_url":"https://github.com/Magisus/puppetserver-ca-cli.git","svn_url":"https://github.com/Magisus/puppetserver-ca-cli","homepage":null,"size":341,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_projects":true,"has_downloads":true,"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":"puppetlabs:master","ref":"master","sha":"be085a5e14c68601e92a2b83d94bcc8b4003fd9e","user":{"login":"puppetlabs","id":234268,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNDI2OA==","avatar_url":"https://avatars0.githubusercontent.com/u/234268?v=4","gravatar_id":"","url":"https://api.github.com/users/puppetlabs","html_url":"https://github.com/puppetlabs","followers_url":"https://api.github.com/users/puppetlabs/followers","following_url":"https://api.github.com/users/puppetlabs/following{/other_user}","gists_url":"https://api.github.com/users/puppetlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/puppetlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/puppetlabs/subscriptions","organizations_url":"https://api.github.com/users/puppetlabs/orgs","repos_url":"https://api.github.com/users/puppetlabs/repos","events_url":"https://api.github.com/users/puppetlabs/events{/privacy}","received_events_url":"https://api.github.com/users/puppetlabs/received_events","type":"Organization","site_admin":false},"repo":{"id":135350068,"node_id":"MDEwOlJlcG9zaXRvcnkxMzUzNTAwNjg=","name":"puppetserver-ca-cli","full_name":"puppetlabs/puppetserver-ca-cli","private":false,"owner":{"login":"puppetlabs","id":234268,"node_id":"MDEyOk9yZ2FuaXphdGlvbjIzNDI2OA==","avatar_url":"https://avatars0.githubusercontent.com/u/234268?v=4","gravatar_id":"","url":"https://api.github.com/users/puppetlabs","html_url":"https://github.com/puppetlabs","followers_url":"https://api.github.com/users/puppetlabs/followers","following_url":"https://api.github.com/users/puppetlabs/following{/other_user}","gists_url":"https://api.github.com/users/puppetlabs/gists{/gist_id}","starred_url":"https://api.github.com/users/puppetlabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/puppetlabs/subscriptions","organizations_url":"https://api.github.com/users/puppetlabs/orgs","repos_url":"https://api.github.com/users/puppetlabs/repos","events_url":"https://api.github.com/users/puppetlabs/events{/privacy}","received_events_url":"https://api.github.com/users/puppetlabs/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/puppetlabs/puppetserver-ca-cli","description":"A simple Ruby CLI tool to interact with the Puppet Server's included Certificate Authority","fork":false,"url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli","forks_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/forks","keys_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/keys{/key_id}","collaborators_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/teams","hooks_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/hooks","issue_events_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues/events{/number}","events_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/events","assignees_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/assignees{/user}","branches_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/branches{/branch}","tags_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/tags","blobs_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/git/refs{/sha}","trees_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/git/trees{/sha}","statuses_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/statuses/{sha}","languages_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/languages","stargazers_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/stargazers","contributors_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/contributors","subscribers_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/subscribers","subscription_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/subscription","commits_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/commits{/sha}","git_commits_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/git/commits{/sha}","comments_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/comments{/number}","issue_comment_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues/comments{/number}","contents_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/contents/{+path}","compare_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/compare/{base}...{head}","merges_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/merges","archive_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/downloads","issues_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues{/number}","pulls_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls{/number}","milestones_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/milestones{/number}","notifications_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/labels{/name}","releases_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/releases{/id}","deployments_url":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/deployments","created_at":"2018-05-29T20:35:19Z","updated_at":"2018-09-24T22:49:48Z","pushed_at":"2018-09-25T18:44:50Z","git_url":"git://github.com/puppetlabs/puppetserver-ca-cli.git","ssh_url":"git@github.com:puppetlabs/puppetserver-ca-cli.git","clone_url":"https://github.com/puppetlabs/puppetserver-ca-cli.git","svn_url":"https://github.com/puppetlabs/puppetserver-ca-cli","homepage":null,"size":317,"stargazers_count":0,"watchers_count":0,"language":"Ruby","has_issues":false,"has_projects":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":4,"mirror_url":null,"archived":false,"open_issues_count":2,"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":4,"open_issues":2,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38"},"html":{"href":"https://github.com/puppetlabs/puppetserver-ca-cli/pull/38"},"issue":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues/38"},"comments":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/issues/38/comments"},"review_comments":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38/comments"},"review_comment":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/pulls/38/commits"},"statuses":{"href":"https://api.github.com/repos/puppetlabs/puppetserver-ca-cli/statuses/a74212d581fd39b4f429fb2771cd2a54acbae625"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"justinstoller"}}