{"action":"created","comment":{"url":"https://api.github.com/repos/scalableminds/webknossos/pulls/comments/152605752","pull_request_review_id":78492851,"id":152605752,"diff_hunk":"@@ -0,0 +1,99 @@\n+package oxalis.security\n+\n+import javax.inject.Inject\n+\n+import com.scalableminds.util.tools.{Fox, FoxImplicits}\n+import controllers.routes\n+import models.user.{MongoUserTokenDao, User, UserService}\n+import net.liftweb.common.{Empty, Full}\n+import play.api.Play.current\n+import play.api.libs.concurrent.Execution.Implicits._\n+import play.api.libs.json.Json._\n+import com.mohiva.play.silhouette.api.{Environment, LoginInfo, SecuredErrorHandler, Silhouette}\n+import com.mohiva.play.silhouette.impl.authenticators.{BearerTokenAuthenticator, _}\n+import com.mohiva.play.silhouette.impl.daos.AuthenticatorDAO\n+import com.scalableminds.util.reactivemongo.{DBAccessContext, GlobalAccessContext}\n+import models.basics.SecuredBaseDAO\n+import org.joda.time.DateTime\n+import play.api.libs.json._\n+import play.modules.reactivemongo.ReactiveMongoApi\n+import reactivemongo.play.json.collection.JSONCollection\n+import play.api.libs.functional.syntax._\n+\n+import scala.concurrent.{ExecutionContext, Future}\n+import scala.concurrent.duration._\n+import play.api.libs.json._\n+import play.api.libs.json.Reads._\n+import play.api.libs.json.Writes._\n+import reactivemongo.api.commands.WriteResult\n+import reactivemongo.bson.BSONObjectID\n+import net.ceedubs.ficus.Ficus._\n+import net.ceedubs.ficus.readers.ArbitraryTypeReader._\n+import play.api.libs.json.Json\n+/**\n+  * Created by robert on 14.11.17.\n+  */\n+class CombinedAuthenticatorDAO extends AuthenticatorDAO[CombinedAuthenticator] with SecuredBaseDAO[CombinedAuthenticator]{\n+  override def collectionName: String = \"combinedAuthenticators\"\n+\n+  implicit object FiniteDurationFormat extends Format[FiniteDuration] {\n+    def reads(json: JsValue): JsResult[FiniteDuration] = LongReads.reads(json).map(_.seconds)\n+    def writes(o: FiniteDuration): JsValue = LongWrites.writes(o.toSeconds)\n+  }\n+\n+  implicit def optionFormat[T: Format]: Format[Option[T]] = new Format[Option[T]]{\n+    override def reads(json: JsValue): JsResult[Option[T]] = json.validateOpt[T]\n+\n+    override def writes(o: Option[T]): JsValue = o match {\n+      case Some(t) ⇒ implicitly[Writes[T]].writes(t)\n+      case None ⇒ JsNull\n+    }\n+  }\n+\n+  override protected implicit def formatter: OFormat[CombinedAuthenticator] = JsonUtil.oFormat(Json.format[CombinedAuthenticator])\n+\n+  override def findOne[V](attribute: String, value: V)(implicit w: Writes[V], ctx: DBAccessContext): Fox[CombinedAuthenticator] = findOne(Json.obj(attribute -> w.writes(value)))\n+\n+  override def find(id: String): Future[Option[CombinedAuthenticator]] = findOne(\"id\", id)(implicitly[Writes[String]],GlobalAccessContext).futureBox.map(box => box.toOption)\n+\n+  //adds the new token (and removes the old one)\n+  override def add(authenticator: CombinedAuthenticator): Future[CombinedAuthenticator] = for{\n+    maybeOldAuthenticator <- findByLoginInfo(authenticator.loginInfo)\n+    _ <- insert(authenticator)(GlobalAccessContext).futureBox\n+  }yield{\n+    if(maybeOldAuthenticator.isDefined) remove(maybeOldAuthenticator.get.id)","path":"app/oxalis/security/CombinedAuthenticatorDAO.scala","position":64,"original_position":64,"commit_id":"6a13e6be2cc62f2bf9b71946892bb4f801e9d088","original_commit_id":"6a13e6be2cc62f2bf9b71946892bb4f801e9d088","user":{"login":"rschwanhold","id":22892968,"avatar_url":"https://avatars3.githubusercontent.com/u/22892968?v=4","gravatar_id":"","url":"https://api.github.com/users/rschwanhold","html_url":"https://github.com/rschwanhold","followers_url":"https://api.github.com/users/rschwanhold/followers","following_url":"https://api.github.com/users/rschwanhold/following{/other_user}","gists_url":"https://api.github.com/users/rschwanhold/gists{/gist_id}","starred_url":"https://api.github.com/users/rschwanhold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rschwanhold/subscriptions","organizations_url":"https://api.github.com/users/rschwanhold/orgs","repos_url":"https://api.github.com/users/rschwanhold/repos","events_url":"https://api.github.com/users/rschwanhold/events{/privacy}","received_events_url":"https://api.github.com/users/rschwanhold/received_events","type":"User","site_admin":false},"body":"Yes it is. I changed it","created_at":"2017-11-22T15:55:01Z","updated_at":"2017-11-22T15:55:01Z","html_url":"https://github.com/scalableminds/webknossos/pull/2149#discussion_r152605752","pull_request_url":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/scalableminds/webknossos/pulls/comments/152605752"},"html":{"href":"https://github.com/scalableminds/webknossos/pull/2149#discussion_r152605752"},"pull_request":{"href":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149"}},"in_reply_to_id":152259140},"pull_request":{"url":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149","id":153377184,"html_url":"https://github.com/scalableminds/webknossos/pull/2149","diff_url":"https://github.com/scalableminds/webknossos/pull/2149.diff","patch_url":"https://github.com/scalableminds/webknossos/pull/2149.patch","issue_url":"https://api.github.com/repos/scalableminds/webknossos/issues/2149","number":2149,"state":"open","locked":false,"title":"Silhouette combined authenticator","user":{"login":"rschwanhold","id":22892968,"avatar_url":"https://avatars3.githubusercontent.com/u/22892968?v=4","gravatar_id":"","url":"https://api.github.com/users/rschwanhold","html_url":"https://github.com/rschwanhold","followers_url":"https://api.github.com/users/rschwanhold/followers","following_url":"https://api.github.com/users/rschwanhold/following{/other_user}","gists_url":"https://api.github.com/users/rschwanhold/gists{/gist_id}","starred_url":"https://api.github.com/users/rschwanhold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rschwanhold/subscriptions","organizations_url":"https://api.github.com/users/rschwanhold/orgs","repos_url":"https://api.github.com/users/rschwanhold/repos","events_url":"https://api.github.com/users/rschwanhold/events{/privacy}","received_events_url":"https://api.github.com/users/rschwanhold/received_events","type":"User","site_admin":false},"body":"### Mailable description of changes:\r\n - implemented a combinedAuthenticator and combinedAuthenticatorService\r\n - combines cookie and token behavior\r\n - the default is cookie\r\n - the token is stored in the request header (in the \"X-Auth-Token\"-field)\r\n - tokens are saved in the DB (in the combinedAuthenticator collection)\r\n - cookies get (un)serialized and not saved in the DB. (Alternatively they could also be save in the DB) \r\n\r\n### Steps to test:\r\n- try to log in \r\n- try to get a token (/api/getToken) (you need be be logged in)\r\n- try to get another token (the old token should be deleted)\r\n- try to authenticate yourself with the token\r\n- delete token (/api/deleteToken)\r\n- logout\r\n- try autologin in dev mode\r\n\r\n------\r\n- [x] Ready for review\r\n","created_at":"2017-11-17T19:36:20Z","updated_at":"2017-11-22T15:55:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f16fbc14c5890f0e0fe690dadb657688c1498d14","assignee":{"login":"rschwanhold","id":22892968,"avatar_url":"https://avatars3.githubusercontent.com/u/22892968?v=4","gravatar_id":"","url":"https://api.github.com/users/rschwanhold","html_url":"https://github.com/rschwanhold","followers_url":"https://api.github.com/users/rschwanhold/followers","following_url":"https://api.github.com/users/rschwanhold/following{/other_user}","gists_url":"https://api.github.com/users/rschwanhold/gists{/gist_id}","starred_url":"https://api.github.com/users/rschwanhold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rschwanhold/subscriptions","organizations_url":"https://api.github.com/users/rschwanhold/orgs","repos_url":"https://api.github.com/users/rschwanhold/repos","events_url":"https://api.github.com/users/rschwanhold/events{/privacy}","received_events_url":"https://api.github.com/users/rschwanhold/received_events","type":"User","site_admin":false},"assignees":[{"login":"rschwanhold","id":22892968,"avatar_url":"https://avatars3.githubusercontent.com/u/22892968?v=4","gravatar_id":"","url":"https://api.github.com/users/rschwanhold","html_url":"https://github.com/rschwanhold","followers_url":"https://api.github.com/users/rschwanhold/followers","following_url":"https://api.github.com/users/rschwanhold/following{/other_user}","gists_url":"https://api.github.com/users/rschwanhold/gists{/gist_id}","starred_url":"https://api.github.com/users/rschwanhold/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rschwanhold/subscriptions","organizations_url":"https://api.github.com/users/rschwanhold/orgs","repos_url":"https://api.github.com/users/rschwanhold/repos","events_url":"https://api.github.com/users/rschwanhold/events{/privacy}","received_events_url":"https://api.github.com/users/rschwanhold/received_events","type":"User","site_admin":false}],"requested_reviewers":[{"login":"hotzenklotz","id":1105056,"avatar_url":"https://avatars2.githubusercontent.com/u/1105056?v=4","gravatar_id":"","url":"https://api.github.com/users/hotzenklotz","html_url":"https://github.com/hotzenklotz","followers_url":"https://api.github.com/users/hotzenklotz/followers","following_url":"https://api.github.com/users/hotzenklotz/following{/other_user}","gists_url":"https://api.github.com/users/hotzenklotz/gists{/gist_id}","starred_url":"https://api.github.com/users/hotzenklotz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hotzenklotz/subscriptions","organizations_url":"https://api.github.com/users/hotzenklotz/orgs","repos_url":"https://api.github.com/users/hotzenklotz/repos","events_url":"https://api.github.com/users/hotzenklotz/events{/privacy}","received_events_url":"https://api.github.com/users/hotzenklotz/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149/commits","review_comments_url":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149/comments","review_comment_url":"https://api.github.com/repos/scalableminds/webknossos/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scalableminds/webknossos/issues/2149/comments","statuses_url":"https://api.github.com/repos/scalableminds/webknossos/statuses/6a13e6be2cc62f2bf9b71946892bb4f801e9d088","head":{"label":"scalableminds:silhouette-combined-authenticator","ref":"silhouette-combined-authenticator","sha":"6a13e6be2cc62f2bf9b71946892bb4f801e9d088","user":{"login":"scalableminds","id":1648557,"avatar_url":"https://avatars1.githubusercontent.com/u/1648557?v=4","gravatar_id":"","url":"https://api.github.com/users/scalableminds","html_url":"https://github.com/scalableminds","followers_url":"https://api.github.com/users/scalableminds/followers","following_url":"https://api.github.com/users/scalableminds/following{/other_user}","gists_url":"https://api.github.com/users/scalableminds/gists{/gist_id}","starred_url":"https://api.github.com/users/scalableminds/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scalableminds/subscriptions","organizations_url":"https://api.github.com/users/scalableminds/orgs","repos_url":"https://api.github.com/users/scalableminds/repos","events_url":"https://api.github.com/users/scalableminds/events{/privacy}","received_events_url":"https://api.github.com/users/scalableminds/received_events","type":"Organization","site_admin":false},"repo":{"id":4326197,"name":"webknossos","full_name":"scalableminds/webknossos","owner":{"login":"scalableminds","id":1648557,"avatar_url":"https://avatars1.githubusercontent.com/u/1648557?v=4","gravatar_id":"","url":"https://api.github.com/users/scalableminds","html_url":"https://github.com/scalableminds","followers_url":"https://api.github.com/users/scalableminds/followers","following_url":"https://api.github.com/users/scalableminds/following{/other_user}","gists_url":"https://api.github.com/users/scalableminds/gists{/gist_id}","starred_url":"https://api.github.com/users/scalableminds/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scalableminds/subscriptions","organizations_url":"https://api.github.com/users/scalableminds/orgs","repos_url":"https://api.github.com/users/scalableminds/repos","events_url":"https://api.github.com/users/scalableminds/events{/privacy}","received_events_url":"https://api.github.com/users/scalableminds/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scalableminds/webknossos","description":"A fully cloud- and browser-based 3D annotation tool for distributed large-scale data analysis in light- and electron-microscopy based Connectomics","fork":false,"url":"https://api.github.com/repos/scalableminds/webknossos","forks_url":"https://api.github.com/repos/scalableminds/webknossos/forks","keys_url":"https://api.github.com/repos/scalableminds/webknossos/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scalableminds/webknossos/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scalableminds/webknossos/teams","hooks_url":"https://api.github.com/repos/scalableminds/webknossos/hooks","issue_events_url":"https://api.github.com/repos/scalableminds/webknossos/issues/events{/number}","events_url":"https://api.github.com/repos/scalableminds/webknossos/events","assignees_url":"https://api.github.com/repos/scalableminds/webknossos/assignees{/user}","branches_url":"https://api.github.com/repos/scalableminds/webknossos/branches{/branch}","tags_url":"https://api.github.com/repos/scalableminds/webknossos/tags","blobs_url":"https://api.github.com/repos/scalableminds/webknossos/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scalableminds/webknossos/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scalableminds/webknossos/git/refs{/sha}","trees_url":"https://api.github.com/repos/scalableminds/webknossos/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scalableminds/webknossos/statuses/{sha}","languages_url":"https://api.github.com/repos/scalableminds/webknossos/languages","stargazers_url":"https://api.github.com/repos/scalableminds/webknossos/stargazers","contributors_url":"https://api.github.com/repos/scalableminds/webknossos/contributors","subscribers_url":"https://api.github.com/repos/scalableminds/webknossos/subscribers","subscription_url":"https://api.github.com/repos/scalableminds/webknossos/subscription","commits_url":"https://api.github.com/repos/scalableminds/webknossos/commits{/sha}","git_commits_url":"https://api.github.com/repos/scalableminds/webknossos/git/commits{/sha}","comments_url":"https://api.github.com/repos/scalableminds/webknossos/comments{/number}","issue_comment_url":"https://api.github.com/repos/scalableminds/webknossos/issues/comments{/number}","contents_url":"https://api.github.com/repos/scalableminds/webknossos/contents/{+path}","compare_url":"https://api.github.com/repos/scalableminds/webknossos/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scalableminds/webknossos/merges","archive_url":"https://api.github.com/repos/scalableminds/webknossos/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scalableminds/webknossos/downloads","issues_url":"https://api.github.com/repos/scalableminds/webknossos/issues{/number}","pulls_url":"https://api.github.com/repos/scalableminds/webknossos/pulls{/number}","milestones_url":"https://api.github.com/repos/scalableminds/webknossos/milestones{/number}","notifications_url":"https://api.github.com/repos/scalableminds/webknossos/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scalableminds/webknossos/labels{/name}","releases_url":"https://api.github.com/repos/scalableminds/webknossos/releases{/id}","deployments_url":"https://api.github.com/repos/scalableminds/webknossos/deployments","created_at":"2012-05-14T16:26:17Z","updated_at":"2017-11-08T14:40:04Z","pushed_at":"2017-11-22T15:33:30Z","git_url":"git://github.com/scalableminds/webknossos.git","ssh_url":"git@github.com:scalableminds/webknossos.git","clone_url":"https://github.com/scalableminds/webknossos.git","svn_url":"https://github.com/scalableminds/webknossos","homepage":"http://webknossos.brain.mpg.de","size":73100,"stargazers_count":11,"watchers_count":11,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":78,"forks":1,"open_issues":78,"watchers":11,"default_branch":"master"}},"base":{"label":"scalableminds:silhouette","ref":"silhouette","sha":"cedca8f5a6ba2151f9f79f848bfd5247e01a581f","user":{"login":"scalableminds","id":1648557,"avatar_url":"https://avatars1.githubusercontent.com/u/1648557?v=4","gravatar_id":"","url":"https://api.github.com/users/scalableminds","html_url":"https://github.com/scalableminds","followers_url":"https://api.github.com/users/scalableminds/followers","following_url":"https://api.github.com/users/scalableminds/following{/other_user}","gists_url":"https://api.github.com/users/scalableminds/gists{/gist_id}","starred_url":"https://api.github.com/users/scalableminds/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scalableminds/subscriptions","organizations_url":"https://api.github.com/users/scalableminds/orgs","repos_url":"https://api.github.com/users/scalableminds/repos","events_url":"https://api.github.com/users/scalableminds/events{/privacy}","received_events_url":"https://api.github.com/users/scalableminds/received_events","type":"Organization","site_admin":false},"repo":{"id":4326197,"name":"webknossos","full_name":"scalableminds/webknossos","owner":{"login":"scalableminds","id":1648557,"avatar_url":"https://avatars1.githubusercontent.com/u/1648557?v=4","gravatar_id":"","url":"https://api.github.com/users/scalableminds","html_url":"https://github.com/scalableminds","followers_url":"https://api.github.com/users/scalableminds/followers","following_url":"https://api.github.com/users/scalableminds/following{/other_user}","gists_url":"https://api.github.com/users/scalableminds/gists{/gist_id}","starred_url":"https://api.github.com/users/scalableminds/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scalableminds/subscriptions","organizations_url":"https://api.github.com/users/scalableminds/orgs","repos_url":"https://api.github.com/users/scalableminds/repos","events_url":"https://api.github.com/users/scalableminds/events{/privacy}","received_events_url":"https://api.github.com/users/scalableminds/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scalableminds/webknossos","description":"A fully cloud- and browser-based 3D annotation tool for distributed large-scale data analysis in light- and electron-microscopy based Connectomics","fork":false,"url":"https://api.github.com/repos/scalableminds/webknossos","forks_url":"https://api.github.com/repos/scalableminds/webknossos/forks","keys_url":"https://api.github.com/repos/scalableminds/webknossos/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scalableminds/webknossos/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scalableminds/webknossos/teams","hooks_url":"https://api.github.com/repos/scalableminds/webknossos/hooks","issue_events_url":"https://api.github.com/repos/scalableminds/webknossos/issues/events{/number}","events_url":"https://api.github.com/repos/scalableminds/webknossos/events","assignees_url":"https://api.github.com/repos/scalableminds/webknossos/assignees{/user}","branches_url":"https://api.github.com/repos/scalableminds/webknossos/branches{/branch}","tags_url":"https://api.github.com/repos/scalableminds/webknossos/tags","blobs_url":"https://api.github.com/repos/scalableminds/webknossos/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scalableminds/webknossos/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scalableminds/webknossos/git/refs{/sha}","trees_url":"https://api.github.com/repos/scalableminds/webknossos/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scalableminds/webknossos/statuses/{sha}","languages_url":"https://api.github.com/repos/scalableminds/webknossos/languages","stargazers_url":"https://api.github.com/repos/scalableminds/webknossos/stargazers","contributors_url":"https://api.github.com/repos/scalableminds/webknossos/contributors","subscribers_url":"https://api.github.com/repos/scalableminds/webknossos/subscribers","subscription_url":"https://api.github.com/repos/scalableminds/webknossos/subscription","commits_url":"https://api.github.com/repos/scalableminds/webknossos/commits{/sha}","git_commits_url":"https://api.github.com/repos/scalableminds/webknossos/git/commits{/sha}","comments_url":"https://api.github.com/repos/scalableminds/webknossos/comments{/number}","issue_comment_url":"https://api.github.com/repos/scalableminds/webknossos/issues/comments{/number}","contents_url":"https://api.github.com/repos/scalableminds/webknossos/contents/{+path}","compare_url":"https://api.github.com/repos/scalableminds/webknossos/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scalableminds/webknossos/merges","archive_url":"https://api.github.com/repos/scalableminds/webknossos/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scalableminds/webknossos/downloads","issues_url":"https://api.github.com/repos/scalableminds/webknossos/issues{/number}","pulls_url":"https://api.github.com/repos/scalableminds/webknossos/pulls{/number}","milestones_url":"https://api.github.com/repos/scalableminds/webknossos/milestones{/number}","notifications_url":"https://api.github.com/repos/scalableminds/webknossos/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scalableminds/webknossos/labels{/name}","releases_url":"https://api.github.com/repos/scalableminds/webknossos/releases{/id}","deployments_url":"https://api.github.com/repos/scalableminds/webknossos/deployments","created_at":"2012-05-14T16:26:17Z","updated_at":"2017-11-08T14:40:04Z","pushed_at":"2017-11-22T15:33:30Z","git_url":"git://github.com/scalableminds/webknossos.git","ssh_url":"git@github.com:scalableminds/webknossos.git","clone_url":"https://github.com/scalableminds/webknossos.git","svn_url":"https://github.com/scalableminds/webknossos","homepage":"http://webknossos.brain.mpg.de","size":73100,"stargazers_count":11,"watchers_count":11,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":78,"forks":1,"open_issues":78,"watchers":11,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149"},"html":{"href":"https://github.com/scalableminds/webknossos/pull/2149"},"issue":{"href":"https://api.github.com/repos/scalableminds/webknossos/issues/2149"},"comments":{"href":"https://api.github.com/repos/scalableminds/webknossos/issues/2149/comments"},"review_comments":{"href":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149/comments"},"review_comment":{"href":"https://api.github.com/repos/scalableminds/webknossos/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scalableminds/webknossos/pulls/2149/commits"},"statuses":{"href":"https://api.github.com/repos/scalableminds/webknossos/statuses/6a13e6be2cc62f2bf9b71946892bb4f801e9d088"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"rschwanhold"}}