{"action":"created","comment":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments/38964563","id":38964563,"diff_hunk":"@@ -15,6 +17,34 @@ def has_object_permission(self, request, view, obj):\n             return obj.can_edit(auth)\n \n \n+class AdminOrPublic(permissions.BasePermission):\n+\n+    def has_object_permission(self, request, view, obj):\n+        assert isinstance(obj, (Node, User)), 'obj must be a Node or User, got {}'.format(obj)\n+        auth = get_user_auth(request)\n+        node = Node.load(request.parser_context['kwargs']['node_id'])\n+        if request.method in permissions.SAFE_METHODS:\n+            return node.is_public or node.can_view(auth)\n+        else:\n+            return node.has_permission(auth.user, osf_permissions.ADMIN)\n+\n+\n+class ContributorDetailPermissions(permissions.BasePermission):\n+    \"\"\"Permissions for contributor detail page.\"\"\"\n+\n+    def has_object_permission(self, request, view, obj):\n+        assert isinstance(obj, (Node, User)), 'obj must be User or Node, got {}'.format(obj)\n+        auth = get_user_auth(request)\n+        node = Node.load(request.parser_context['kwargs']['node_id'])\n+        user = User.load(request.parser_context['kwargs']['user_id'])\n+        if request.method in permissions.SAFE_METHODS:\n+            return node.is_public or node.can_view(auth)\n+        elif request.method == 'DELETE':\n+            return node.has_permission(auth.user, osf_permissions.ADMIN) or auth.user == user","path":"api/nodes/permissions.py","position":38,"original_position":38,"commit_id":"1a89896f875e5326c767b542cff48801563f83f0","original_commit_id":"1a89896f875e5326c767b542cff48801563f83f0","user":{"login":"samchrisinger","id":2207561,"avatar_url":"https://avatars.githubusercontent.com/u/2207561?v=3","gravatar_id":"","url":"https://api.github.com/users/samchrisinger","html_url":"https://github.com/samchrisinger","followers_url":"https://api.github.com/users/samchrisinger/followers","following_url":"https://api.github.com/users/samchrisinger/following{/other_user}","gists_url":"https://api.github.com/users/samchrisinger/gists{/gist_id}","starred_url":"https://api.github.com/users/samchrisinger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samchrisinger/subscriptions","organizations_url":"https://api.github.com/users/samchrisinger/orgs","repos_url":"https://api.github.com/users/samchrisinger/repos","events_url":"https://api.github.com/users/samchrisinger/events{/privacy}","received_events_url":"https://api.github.com/users/samchrisinger/received_events","type":"User","site_admin":false},"body":"@abought If the existing tests:\r\n- https://github.com/CenterForOpenScience/osf.io/pull/4235/files#diff-14619b95d1761b6ed098d90acc33b79eR1327\r\n- https://github.com/CenterForOpenScience/osf.io/pull/4235/files#diff-14619b95d1761b6ed098d90acc33b79eR1373\r\n\r\nAre inadequate, can you please explain what you'd like to see changed? ","created_at":"2015-09-08T18:50:07Z","updated_at":"2015-09-08T18:50:07Z","html_url":"https://github.com/CenterForOpenScience/osf.io/pull/4235#discussion_r38964563","pull_request_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235","_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments/38964563"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/4235#discussion_r38964563"},"pull_request":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235"}}},"pull_request":{"url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235","id":44032982,"html_url":"https://github.com/CenterForOpenScience/osf.io/pull/4235","diff_url":"https://github.com/CenterForOpenScience/osf.io/pull/4235.diff","patch_url":"https://github.com/CenterForOpenScience/osf.io/pull/4235.patch","issue_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/4235","number":4235,"state":"open","locked":false,"title":"[WIP] Feature/api/node contrib crud","user":{"login":"samchrisinger","id":2207561,"avatar_url":"https://avatars.githubusercontent.com/u/2207561?v=3","gravatar_id":"","url":"https://api.github.com/users/samchrisinger","html_url":"https://github.com/samchrisinger","followers_url":"https://api.github.com/users/samchrisinger/followers","following_url":"https://api.github.com/users/samchrisinger/following{/other_user}","gists_url":"https://api.github.com/users/samchrisinger/gists{/gist_id}","starred_url":"https://api.github.com/users/samchrisinger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samchrisinger/subscriptions","organizations_url":"https://api.github.com/users/samchrisinger/orgs","repos_url":"https://api.github.com/users/samchrisinger/repos","events_url":"https://api.github.com/users/samchrisinger/events{/privacy}","received_events_url":"https://api.github.com/users/samchrisinger/received_events","type":"User","site_admin":false},"body":"# Purpose\r\nBring https://github.com/CenterForOpenScience/osf.io/pull/3990/ up to date with develop. \r\n\r\nAllows user to add, edit, and remove users through API requests.\r\n\r\n# Changes\r\n\r\nAdded new serializer for contributor, removing old one. Created ability to add a contributor to a node in node contributor list. Added serializer for contributor detail where user can edit contributor bibliographic and permissions.\r\n\r\n# Side Effects\r\n\r\nAPI user can now add, remove, and update contributors as well as view contributor permission level and view contributor details separate from list\r\n\r\n```json\r\n\r\n{\r\n    \"data\": [\r\n        {\r\n            \"id\": \"j84ad\",\r\n            \"type\": \"users\",\r\n            \"attributes\": {\r\n                \"fullname\": \"Samuel Chrisinger\",\r\n                \"given_name\": \"Samuel\",\r\n                \"middle_name\": \"\",\r\n                \"family_name\": \"Chrisinger\",\r\n                \"suffix\": \"\",\r\n                \"date_registered\": \"2015-08-12T15:34:00.814000\",\r\n                \"gravatar_url\": \"https://secure.gravatar.com/avatar/474539e4281a2712b321cd5c433fe2f9?d=identicon&size=40\",\r\n                \"social_accounts\": {},\r\n                \"bibliographic\": true,\r\n                \"permission\": \"admin\"\r\n            },\r\n            \"links\": {\r\n                \"nodes\": {\r\n                    \"relation\": \"http://localhost:8000/v2/users/j84ad/nodes/\"\r\n                },\r\n                \"html\": \"http://localhost:5000/j84ad/\",\r\n                \"detail\": \"http://localhost:8000/v2/nodes/23ehy/contributors/j84ad/\",\r\n                \"self\": \"http://localhost:8000/v2/users/j84ad/\"\r\n            }\r\n        }\r\n    ],\r\n    \"links\": {\r\n        \"first\": null,\r\n        \"last\": null,\r\n        \"prev\": null,\r\n        \"next\": null,\r\n        \"meta\": {\r\n            \"total\": 1,\r\n            \"per_page\": 10\r\n        }\r\n    }\r\n}\r\n```\r\n\r\n![screen shot 2015-09-03 at 10 10 31 am](https://cloud.githubusercontent.com/assets/2207561/9660578/4d4ed7fc-5224-11e5-8b89-a7236e13d6a7.png)\r\n\r\n![screen shot 2015-09-03 at 10 11 56 am](https://cloud.githubusercontent.com/assets/2207561/9660567/3e20aeea-5224-11e5-8d9a-628371cf9a12.png)\r\n\r\n![screen shot 2015-09-03 at 10 12 52 am](https://cloud.githubusercontent.com/assets/2207561/9660589/5d12b9c4-5224-11e5-83a2-30dd6cff283e.png)\r\n\r\n![screen shot 2015-09-03 at 10 13 10 am](https://cloud.githubusercontent.com/assets/2207561/9660595/6f18735c-5224-11e5-88cf-1ec112ee72f3.png)\r\n\r\n![screen shot 2015-09-03 at 10 13 17 am](https://cloud.githubusercontent.com/assets/2207561/9660602/7663b464-5224-11e5-9428-73ccdd3e650b.png)\r\n","created_at":"2015-09-02T19:37:04Z","updated_at":"2015-09-08T18:50:07Z","closed_at":null,"merged_at":null,"merge_commit_sha":"01fb830a18d647714124be26e158634dbae4ac02","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235/commits","review_comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235/comments","review_comment_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/4235/comments","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/1a89896f875e5326c767b542cff48801563f83f0","head":{"label":"samchrisinger:feature/api/node-contrib-crud","ref":"feature/api/node-contrib-crud","sha":"1a89896f875e5326c767b542cff48801563f83f0","user":{"login":"samchrisinger","id":2207561,"avatar_url":"https://avatars.githubusercontent.com/u/2207561?v=3","gravatar_id":"","url":"https://api.github.com/users/samchrisinger","html_url":"https://github.com/samchrisinger","followers_url":"https://api.github.com/users/samchrisinger/followers","following_url":"https://api.github.com/users/samchrisinger/following{/other_user}","gists_url":"https://api.github.com/users/samchrisinger/gists{/gist_id}","starred_url":"https://api.github.com/users/samchrisinger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samchrisinger/subscriptions","organizations_url":"https://api.github.com/users/samchrisinger/orgs","repos_url":"https://api.github.com/users/samchrisinger/repos","events_url":"https://api.github.com/users/samchrisinger/events{/privacy}","received_events_url":"https://api.github.com/users/samchrisinger/received_events","type":"User","site_admin":false},"repo":{"id":30772672,"name":"osf.io","full_name":"samchrisinger/osf.io","owner":{"login":"samchrisinger","id":2207561,"avatar_url":"https://avatars.githubusercontent.com/u/2207561?v=3","gravatar_id":"","url":"https://api.github.com/users/samchrisinger","html_url":"https://github.com/samchrisinger","followers_url":"https://api.github.com/users/samchrisinger/followers","following_url":"https://api.github.com/users/samchrisinger/following{/other_user}","gists_url":"https://api.github.com/users/samchrisinger/gists{/gist_id}","starred_url":"https://api.github.com/users/samchrisinger/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samchrisinger/subscriptions","organizations_url":"https://api.github.com/users/samchrisinger/orgs","repos_url":"https://api.github.com/users/samchrisinger/repos","events_url":"https://api.github.com/users/samchrisinger/events{/privacy}","received_events_url":"https://api.github.com/users/samchrisinger/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/samchrisinger/osf.io","description":"Facilitating Open Science","fork":true,"url":"https://api.github.com/repos/samchrisinger/osf.io","forks_url":"https://api.github.com/repos/samchrisinger/osf.io/forks","keys_url":"https://api.github.com/repos/samchrisinger/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/samchrisinger/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/samchrisinger/osf.io/teams","hooks_url":"https://api.github.com/repos/samchrisinger/osf.io/hooks","issue_events_url":"https://api.github.com/repos/samchrisinger/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/samchrisinger/osf.io/events","assignees_url":"https://api.github.com/repos/samchrisinger/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/samchrisinger/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/samchrisinger/osf.io/tags","blobs_url":"https://api.github.com/repos/samchrisinger/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/samchrisinger/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/samchrisinger/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/samchrisinger/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/samchrisinger/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/samchrisinger/osf.io/languages","stargazers_url":"https://api.github.com/repos/samchrisinger/osf.io/stargazers","contributors_url":"https://api.github.com/repos/samchrisinger/osf.io/contributors","subscribers_url":"https://api.github.com/repos/samchrisinger/osf.io/subscribers","subscription_url":"https://api.github.com/repos/samchrisinger/osf.io/subscription","commits_url":"https://api.github.com/repos/samchrisinger/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/samchrisinger/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/samchrisinger/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/samchrisinger/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/samchrisinger/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/samchrisinger/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/samchrisinger/osf.io/merges","archive_url":"https://api.github.com/repos/samchrisinger/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/samchrisinger/osf.io/downloads","issues_url":"https://api.github.com/repos/samchrisinger/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/samchrisinger/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/samchrisinger/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/samchrisinger/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/samchrisinger/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/samchrisinger/osf.io/releases{/id}","created_at":"2015-02-13T19:40:14Z","updated_at":"2015-02-27T18:03:37Z","pushed_at":"2015-09-08T18:34:29Z","git_url":"git://github.com/samchrisinger/osf.io.git","ssh_url":"git@github.com:samchrisinger/osf.io.git","clone_url":"https://github.com/samchrisinger/osf.io.git","svn_url":"https://github.com/samchrisinger/osf.io","homepage":"http://osf.io","size":106573,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":3,"forks":0,"open_issues":3,"watchers":0,"default_branch":"develop"}},"base":{"label":"CenterForOpenScience:develop","ref":"develop","sha":"e0440f222ba0b600d0fe1db263889a8f5399ddc1","user":{"login":"CenterForOpenScience","id":3344584,"avatar_url":"https://avatars.githubusercontent.com/u/3344584?v=3","gravatar_id":"","url":"https://api.github.com/users/CenterForOpenScience","html_url":"https://github.com/CenterForOpenScience","followers_url":"https://api.github.com/users/CenterForOpenScience/followers","following_url":"https://api.github.com/users/CenterForOpenScience/following{/other_user}","gists_url":"https://api.github.com/users/CenterForOpenScience/gists{/gist_id}","starred_url":"https://api.github.com/users/CenterForOpenScience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CenterForOpenScience/subscriptions","organizations_url":"https://api.github.com/users/CenterForOpenScience/orgs","repos_url":"https://api.github.com/users/CenterForOpenScience/repos","events_url":"https://api.github.com/users/CenterForOpenScience/events{/privacy}","received_events_url":"https://api.github.com/users/CenterForOpenScience/received_events","type":"Organization","site_admin":false},"repo":{"id":10199599,"name":"osf.io","full_name":"CenterForOpenScience/osf.io","owner":{"login":"CenterForOpenScience","id":3344584,"avatar_url":"https://avatars.githubusercontent.com/u/3344584?v=3","gravatar_id":"","url":"https://api.github.com/users/CenterForOpenScience","html_url":"https://github.com/CenterForOpenScience","followers_url":"https://api.github.com/users/CenterForOpenScience/followers","following_url":"https://api.github.com/users/CenterForOpenScience/following{/other_user}","gists_url":"https://api.github.com/users/CenterForOpenScience/gists{/gist_id}","starred_url":"https://api.github.com/users/CenterForOpenScience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CenterForOpenScience/subscriptions","organizations_url":"https://api.github.com/users/CenterForOpenScience/orgs","repos_url":"https://api.github.com/users/CenterForOpenScience/repos","events_url":"https://api.github.com/users/CenterForOpenScience/events{/privacy}","received_events_url":"https://api.github.com/users/CenterForOpenScience/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CenterForOpenScience/osf.io","description":"Facilitating Open Science","fork":false,"url":"https://api.github.com/repos/CenterForOpenScience/osf.io","forks_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/forks","keys_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/teams","hooks_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/hooks","issue_events_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/events{/number}","events_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/events","assignees_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/assignees{/user}","branches_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/branches{/branch}","tags_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/tags","blobs_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/{sha}","languages_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/languages","stargazers_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/stargazers","contributors_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/contributors","subscribers_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/subscribers","subscription_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/subscription","commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/contents/{+path}","compare_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/merges","archive_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/downloads","issues_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues{/number}","pulls_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls{/number}","milestones_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/milestones{/number}","notifications_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/labels{/name}","releases_url":"https://api.github.com/repos/CenterForOpenScience/osf.io/releases{/id}","created_at":"2013-05-21T15:53:37Z","updated_at":"2015-09-07T14:16:12Z","pushed_at":"2015-09-08T18:35:03Z","git_url":"git://github.com/CenterForOpenScience/osf.io.git","ssh_url":"git@github.com:CenterForOpenScience/osf.io.git","clone_url":"https://github.com/CenterForOpenScience/osf.io.git","svn_url":"https://github.com/CenterForOpenScience/osf.io","homepage":"http://osf.io","size":229275,"stargazers_count":133,"watchers_count":133,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":114,"mirror_url":null,"open_issues_count":426,"forks":114,"open_issues":426,"watchers":133,"default_branch":"develop"}},"_links":{"self":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235"},"html":{"href":"https://github.com/CenterForOpenScience/osf.io/pull/4235"},"issue":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/4235"},"comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/issues/4235/comments"},"review_comments":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235/comments"},"review_comment":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/pulls/4235/commits"},"statuses":{"href":"https://api.github.com/repos/CenterForOpenScience/osf.io/statuses/1a89896f875e5326c767b542cff48801563f83f0"}}}}