{"action":"created","comment":{"url":"https://api.github.com/repos/goadesign/goa/pulls/comments/55931420","id":55931420,"diff_hunk":"@@ -0,0 +1,308 @@\n+package apidsl\n+\n+import (\n+\t\"github.com/goadesign/goa/design\"\n+\t\"github.com/goadesign/goa/dslengine\"\n+)\n+\n+// Security defines an authentication method required to access a goa\n+// Action.  When defined on a Resource, it applies to all Actions,\n+// unless overriden by individual actions.  When defined at the API\n+// level, it will apply to all resources by default, following the\n+// same logic.\n+//\n+// The method name refers to what you have passed to the different\n+// OAuth2Security(), BasicAuthSecurity() and APIKeySecurity()\n+// declarations.\n+func Security(method string, dsl ...func()) {\n+\tdef := &design.SecurityDefinition{Method: method}\n+\n+\tif len(dsl) != 0 {\n+\t\tif !dslengine.Execute(dsl[0], def) {\n+\t\t\treturn\n+\t\t}\n+\t}\n+\n+\tparentDef := dslengine.CurrentDefinition()\n+\tswitch parent := parentDef.(type) {\n+\tcase *design.ActionDefinition:\n+\t\tparent.Security = def\n+\tcase *design.ResourceDefinition:\n+\t\tparent.Security = def\n+\tcase *design.APIDefinition:\n+\t\tparent.Security = def\n+\tdefault:\n+\t\tdslengine.IncompatibleDSL()\n+\t\treturn\n+\t}\n+}\n+\n+// NoSecurity resets the authentication methods for an Action or a\n+// Resource. It also prevents fallback to Resource or API-defined\n+// Security().\n+func NoSecurity() {\n+\tdef := &design.SecurityDefinition{NoSecurity: true}\n+\n+\tparentDef := dslengine.CurrentDefinition()\n+\tswitch parent := parentDef.(type) {\n+\tcase *design.ActionDefinition:\n+\t\tparent.Security = def\n+\tcase *design.ResourceDefinition:\n+\t\tparent.Security = def\n+\tdefault:\n+\t\tdslengine.IncompatibleDSL()\n+\t\treturn\n+\t}\n+}\n+\n+// BasicAuthSecurity defines a \"basic\" security method for the API.\n+//\n+// Example:\n+//\n+//     BasicAuthSecurity(\"password\", func() {\n+//         Description(\"Use your own password!\")\n+//     })\n+//\n+func BasicAuthSecurity(name string, dsl ...func()) {\n+\tif _, ok := dslengine.CurrentDefinition().(*design.APIDefinition); !ok {","path":"design/apidsl/security.go","position":67,"original_position":67,"commit_id":"26aef680a745695bdecce5b9463eca49548ddf87","original_commit_id":"26aef680a745695bdecce5b9463eca49548ddf87","user":{"login":"abourget","id":93424,"avatar_url":"https://avatars.githubusercontent.com/u/93424?v=3","gravatar_id":"","url":"https://api.github.com/users/abourget","html_url":"https://github.com/abourget","followers_url":"https://api.github.com/users/abourget/followers","following_url":"https://api.github.com/users/abourget/following{/other_user}","gists_url":"https://api.github.com/users/abourget/gists{/gist_id}","starred_url":"https://api.github.com/users/abourget/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/abourget/subscriptions","organizations_url":"https://api.github.com/users/abourget/orgs","repos_url":"https://api.github.com/users/abourget/repos","events_url":"https://api.github.com/users/abourget/events{/privacy}","received_events_url":"https://api.github.com/users/abourget/received_events","type":"User","site_admin":false},"body":"Again, this would be in order to reuse the thing as a var, returned by the `*Security()`, right ?\r\n\r\nI can make sure it's in before merge if you like. Would we keep the option of having it inside API too ?\r\n\r\n","created_at":"2016-03-13T02:59:21Z","updated_at":"2016-03-13T02:59:21Z","html_url":"https://github.com/goadesign/goa/pull/351#discussion_r55931420","pull_request_url":"https://api.github.com/repos/goadesign/goa/pulls/351","_links":{"self":{"href":"https://api.github.com/repos/goadesign/goa/pulls/comments/55931420"},"html":{"href":"https://github.com/goadesign/goa/pull/351#discussion_r55931420"},"pull_request":{"href":"https://api.github.com/repos/goadesign/goa/pulls/351"}}},"pull_request":{"url":"https://api.github.com/repos/goadesign/goa/pulls/351","id":62441556,"html_url":"https://github.com/goadesign/goa/pull/351","diff_url":"https://github.com/goadesign/goa/pull/351.diff","patch_url":"https://github.com/goadesign/goa/pull/351.patch","issue_url":"https://api.github.com/repos/goadesign/goa/issues/351","number":351,"state":"open","locked":false,"title":"Security handlers, per-action middleware","user":{"login":"abourget","id":93424,"avatar_url":"https://avatars.githubusercontent.com/u/93424?v=3","gravatar_id":"","url":"https://api.github.com/users/abourget","html_url":"https://github.com/abourget","followers_url":"https://api.github.com/users/abourget/followers","following_url":"https://api.github.com/users/abourget/following{/other_user}","gists_url":"https://api.github.com/users/abourget/gists{/gist_id}","starred_url":"https://api.github.com/users/abourget/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/abourget/subscriptions","organizations_url":"https://api.github.com/users/abourget/orgs","repos_url":"https://api.github.com/users/abourget/repos","events_url":"https://api.github.com/users/abourget/events{/privacy}","received_events_url":"https://api.github.com/users/abourget/received_events","type":"User","site_admin":false},"body":"This implements `Security()` at the `API`, `Resource` and `Action` level. `OAuth2Security()`, `BasicAuthSecurity()`, `APIKeySecurity()` and `OtherSecurity()` at the API definition level.\r\n\r\nRemaining:\r\n* [x] Implement DSL validation, ensuring `SecurityMethod`s exist for all `Security` invocations.\r\n* [x] Add tests for DSL\r\n* [ ] Add tests for `gen_app` generation.\r\n* [x] Add example in `goa-cellar`, using /auth with BasicAuth and some endpoints with a JWT.\r\n* [ ] Swagger generation\r\n* [ ] Support variable assignment of `var whateverSecurity = OAuth2Security(\"whatever\")` and reuse with `Security(whateverSecurity)`  in the Resources/Actions.\r\n* [x] Implement `NoSecurity()` that would cancel the resource-defined fallback.\r\n","created_at":"2016-03-10T19:23:03Z","updated_at":"2016-03-13T02:59:21Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c05d534777036a3841490db4ea8f4cf953ec03df","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/goadesign/goa/pulls/351/commits","review_comments_url":"https://api.github.com/repos/goadesign/goa/pulls/351/comments","review_comment_url":"https://api.github.com/repos/goadesign/goa/pulls/comments{/number}","comments_url":"https://api.github.com/repos/goadesign/goa/issues/351/comments","statuses_url":"https://api.github.com/repos/goadesign/goa/statuses/26aef680a745695bdecce5b9463eca49548ddf87","head":{"label":"abourget:feature/security","ref":"feature/security","sha":"26aef680a745695bdecce5b9463eca49548ddf87","user":{"login":"abourget","id":93424,"avatar_url":"https://avatars.githubusercontent.com/u/93424?v=3","gravatar_id":"","url":"https://api.github.com/users/abourget","html_url":"https://github.com/abourget","followers_url":"https://api.github.com/users/abourget/followers","following_url":"https://api.github.com/users/abourget/following{/other_user}","gists_url":"https://api.github.com/users/abourget/gists{/gist_id}","starred_url":"https://api.github.com/users/abourget/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/abourget/subscriptions","organizations_url":"https://api.github.com/users/abourget/orgs","repos_url":"https://api.github.com/users/abourget/repos","events_url":"https://api.github.com/users/abourget/events{/privacy}","received_events_url":"https://api.github.com/users/abourget/received_events","type":"User","site_admin":false},"repo":{"id":48859618,"name":"goa","full_name":"abourget/goa","owner":{"login":"abourget","id":93424,"avatar_url":"https://avatars.githubusercontent.com/u/93424?v=3","gravatar_id":"","url":"https://api.github.com/users/abourget","html_url":"https://github.com/abourget","followers_url":"https://api.github.com/users/abourget/followers","following_url":"https://api.github.com/users/abourget/following{/other_user}","gists_url":"https://api.github.com/users/abourget/gists{/gist_id}","starred_url":"https://api.github.com/users/abourget/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/abourget/subscriptions","organizations_url":"https://api.github.com/users/abourget/orgs","repos_url":"https://api.github.com/users/abourget/repos","events_url":"https://api.github.com/users/abourget/events{/privacy}","received_events_url":"https://api.github.com/users/abourget/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/abourget/goa","description":"Design-based HTTP microservices in Go","fork":true,"url":"https://api.github.com/repos/abourget/goa","forks_url":"https://api.github.com/repos/abourget/goa/forks","keys_url":"https://api.github.com/repos/abourget/goa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/abourget/goa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/abourget/goa/teams","hooks_url":"https://api.github.com/repos/abourget/goa/hooks","issue_events_url":"https://api.github.com/repos/abourget/goa/issues/events{/number}","events_url":"https://api.github.com/repos/abourget/goa/events","assignees_url":"https://api.github.com/repos/abourget/goa/assignees{/user}","branches_url":"https://api.github.com/repos/abourget/goa/branches{/branch}","tags_url":"https://api.github.com/repos/abourget/goa/tags","blobs_url":"https://api.github.com/repos/abourget/goa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/abourget/goa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/abourget/goa/git/refs{/sha}","trees_url":"https://api.github.com/repos/abourget/goa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/abourget/goa/statuses/{sha}","languages_url":"https://api.github.com/repos/abourget/goa/languages","stargazers_url":"https://api.github.com/repos/abourget/goa/stargazers","contributors_url":"https://api.github.com/repos/abourget/goa/contributors","subscribers_url":"https://api.github.com/repos/abourget/goa/subscribers","subscription_url":"https://api.github.com/repos/abourget/goa/subscription","commits_url":"https://api.github.com/repos/abourget/goa/commits{/sha}","git_commits_url":"https://api.github.com/repos/abourget/goa/git/commits{/sha}","comments_url":"https://api.github.com/repos/abourget/goa/comments{/number}","issue_comment_url":"https://api.github.com/repos/abourget/goa/issues/comments{/number}","contents_url":"https://api.github.com/repos/abourget/goa/contents/{+path}","compare_url":"https://api.github.com/repos/abourget/goa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/abourget/goa/merges","archive_url":"https://api.github.com/repos/abourget/goa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/abourget/goa/downloads","issues_url":"https://api.github.com/repos/abourget/goa/issues{/number}","pulls_url":"https://api.github.com/repos/abourget/goa/pulls{/number}","milestones_url":"https://api.github.com/repos/abourget/goa/milestones{/number}","notifications_url":"https://api.github.com/repos/abourget/goa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/abourget/goa/labels{/name}","releases_url":"https://api.github.com/repos/abourget/goa/releases{/id}","deployments_url":"https://api.github.com/repos/abourget/goa/deployments","created_at":"2015-12-31T19:07:51Z","updated_at":"2016-01-21T00:54:57Z","pushed_at":"2016-03-12T22:00:08Z","git_url":"git://github.com/abourget/goa.git","ssh_url":"git@github.com:abourget/goa.git","clone_url":"https://github.com/abourget/goa.git","svn_url":"https://github.com/abourget/goa","homepage":"http://goa.design","size":12593,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"goadesign:master","ref":"master","sha":"61f7880125a98ab2f6880932cfc1ea9088a7862a","user":{"login":"goadesign","id":16568515,"avatar_url":"https://avatars.githubusercontent.com/u/16568515?v=3","gravatar_id":"","url":"https://api.github.com/users/goadesign","html_url":"https://github.com/goadesign","followers_url":"https://api.github.com/users/goadesign/followers","following_url":"https://api.github.com/users/goadesign/following{/other_user}","gists_url":"https://api.github.com/users/goadesign/gists{/gist_id}","starred_url":"https://api.github.com/users/goadesign/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/goadesign/subscriptions","organizations_url":"https://api.github.com/users/goadesign/orgs","repos_url":"https://api.github.com/users/goadesign/repos","events_url":"https://api.github.com/users/goadesign/events{/privacy}","received_events_url":"https://api.github.com/users/goadesign/received_events","type":"Organization","site_admin":false},"repo":{"id":27579614,"name":"goa","full_name":"goadesign/goa","owner":{"login":"goadesign","id":16568515,"avatar_url":"https://avatars.githubusercontent.com/u/16568515?v=3","gravatar_id":"","url":"https://api.github.com/users/goadesign","html_url":"https://github.com/goadesign","followers_url":"https://api.github.com/users/goadesign/followers","following_url":"https://api.github.com/users/goadesign/following{/other_user}","gists_url":"https://api.github.com/users/goadesign/gists{/gist_id}","starred_url":"https://api.github.com/users/goadesign/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/goadesign/subscriptions","organizations_url":"https://api.github.com/users/goadesign/orgs","repos_url":"https://api.github.com/users/goadesign/repos","events_url":"https://api.github.com/users/goadesign/events{/privacy}","received_events_url":"https://api.github.com/users/goadesign/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/goadesign/goa","description":"Design-based microservices in Go","fork":false,"url":"https://api.github.com/repos/goadesign/goa","forks_url":"https://api.github.com/repos/goadesign/goa/forks","keys_url":"https://api.github.com/repos/goadesign/goa/keys{/key_id}","collaborators_url":"https://api.github.com/repos/goadesign/goa/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/goadesign/goa/teams","hooks_url":"https://api.github.com/repos/goadesign/goa/hooks","issue_events_url":"https://api.github.com/repos/goadesign/goa/issues/events{/number}","events_url":"https://api.github.com/repos/goadesign/goa/events","assignees_url":"https://api.github.com/repos/goadesign/goa/assignees{/user}","branches_url":"https://api.github.com/repos/goadesign/goa/branches{/branch}","tags_url":"https://api.github.com/repos/goadesign/goa/tags","blobs_url":"https://api.github.com/repos/goadesign/goa/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/goadesign/goa/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/goadesign/goa/git/refs{/sha}","trees_url":"https://api.github.com/repos/goadesign/goa/git/trees{/sha}","statuses_url":"https://api.github.com/repos/goadesign/goa/statuses/{sha}","languages_url":"https://api.github.com/repos/goadesign/goa/languages","stargazers_url":"https://api.github.com/repos/goadesign/goa/stargazers","contributors_url":"https://api.github.com/repos/goadesign/goa/contributors","subscribers_url":"https://api.github.com/repos/goadesign/goa/subscribers","subscription_url":"https://api.github.com/repos/goadesign/goa/subscription","commits_url":"https://api.github.com/repos/goadesign/goa/commits{/sha}","git_commits_url":"https://api.github.com/repos/goadesign/goa/git/commits{/sha}","comments_url":"https://api.github.com/repos/goadesign/goa/comments{/number}","issue_comment_url":"https://api.github.com/repos/goadesign/goa/issues/comments{/number}","contents_url":"https://api.github.com/repos/goadesign/goa/contents/{+path}","compare_url":"https://api.github.com/repos/goadesign/goa/compare/{base}...{head}","merges_url":"https://api.github.com/repos/goadesign/goa/merges","archive_url":"https://api.github.com/repos/goadesign/goa/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/goadesign/goa/downloads","issues_url":"https://api.github.com/repos/goadesign/goa/issues{/number}","pulls_url":"https://api.github.com/repos/goadesign/goa/pulls{/number}","milestones_url":"https://api.github.com/repos/goadesign/goa/milestones{/number}","notifications_url":"https://api.github.com/repos/goadesign/goa/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/goadesign/goa/labels{/name}","releases_url":"https://api.github.com/repos/goadesign/goa/releases{/id}","deployments_url":"https://api.github.com/repos/goadesign/goa/deployments","created_at":"2014-12-05T07:17:53Z","updated_at":"2016-03-12T13:49:09Z","pushed_at":"2016-03-13T00:22:20Z","git_url":"git://github.com/goadesign/goa.git","ssh_url":"git@github.com:goadesign/goa.git","clone_url":"https://github.com/goadesign/goa.git","svn_url":"https://github.com/goadesign/goa","homepage":"http://goa.design","size":12639,"stargazers_count":672,"watchers_count":672,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":50,"mirror_url":null,"open_issues_count":23,"forks":50,"open_issues":23,"watchers":672,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/goadesign/goa/pulls/351"},"html":{"href":"https://github.com/goadesign/goa/pull/351"},"issue":{"href":"https://api.github.com/repos/goadesign/goa/issues/351"},"comments":{"href":"https://api.github.com/repos/goadesign/goa/issues/351/comments"},"review_comments":{"href":"https://api.github.com/repos/goadesign/goa/pulls/351/comments"},"review_comment":{"href":"https://api.github.com/repos/goadesign/goa/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/goadesign/goa/pulls/351/commits"},"statuses":{"href":"https://api.github.com/repos/goadesign/goa/statuses/26aef680a745695bdecce5b9463eca49548ddf87"}}}}