Skip to content

Commit

Permalink
feat: global security (#1620)
Browse files Browse the repository at this point in the history
* global security

* improve test
  • Loading branch information
nameoffnv committed Jul 18, 2023
1 parent 575963e commit 1bf0078
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 0 deletions.
5 changes: 5 additions & 0 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,11 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {

// ParseSecurityComment parses comment for given `security` comment string.
func (operation *Operation) ParseSecurityComment(commentLine string) error {
if len(commentLine) == 0 {
operation.Security = []map[string][]string{}
return nil
}

var (
securityMap = make(map[string][]string)
securitySource = commentLine[strings.Index(commentLine, "@Security")+1:]
Expand Down
31 changes: 31 additions & 0 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {

parser.swagger.SecurityDefinitions[value] = scheme

case securityAttr:
parser.swagger.Security = append(parser.swagger.Security, parseSecurity(value))

case "@query.collection.format":
parser.collectionFormatInQuery = TransToValidCollectionFormat(value)

Expand Down Expand Up @@ -768,6 +771,34 @@ func parseSecAttributes(context string, lines []string, index *int) (*spec.Secur
return scheme, nil
}

func parseSecurity(commentLine string) map[string][]string {
securityMap := make(map[string][]string)

for _, securityOption := range strings.Split(commentLine, "||") {
securityOption = strings.TrimSpace(securityOption)

left, right := strings.Index(securityOption, "["), strings.Index(securityOption, "]")

if !(left == -1 && right == -1) {
scopes := securityOption[left+1 : right]

var options []string

for _, scope := range strings.Split(scopes, ",") {
options = append(options, strings.TrimSpace(scope))
}

securityKey := securityOption[0:left]
securityMap[securityKey] = append(securityMap[securityKey], options...)
} else {
securityKey := strings.TrimSpace(securityOption)
securityMap[securityKey] = []string{}
}
}

return securityMap
}

func initIfEmpty(license *spec.License) *spec.License {
if license == nil {
return new(spec.License)
Expand Down
15 changes: 15 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2157,6 +2157,21 @@ func TestParseTypeOverrides(t *testing.T) {
assert.Equal(t, string(expected), string(b))
}

func TestGlobalSecurity(t *testing.T) {
t.Parallel()

searchDir := "testdata/global_security"
p := New()
err := p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth)
assert.NoError(t, err)

expected, err := os.ReadFile(filepath.Join(searchDir, "expected.json"))
assert.NoError(t, err)

b, _ := json.MarshalIndent(p.swagger, "", " ")
assert.Equal(t, string(expected), string(b))
}

func TestParseNested(t *testing.T) {
t.Parallel()

Expand Down
34 changes: 34 additions & 0 deletions testdata/global_security/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package api

import (
"net/http"
)

// @Summary default security
// @Success 200
// @Router /testapi/application [get]
func GetApplication(w http.ResponseWriter, r *http.Request) {}

// @Summary no security
// @Security
// @Success 200
// @Router /testapi/nosec [get]
func GetNoSec(w http.ResponseWriter, r *http.Request) {}

// @Summary basic security
// @Security BasicAuth
// @Success 200
// @Router /testapi/basic [get]
func GetBasic(w http.ResponseWriter, r *http.Request) {}

// @Summary oauth2 write
// @Security OAuth2Application[write]
// @Success 200
// @Router /testapi/oauth/write [get]
func GetOAuthWrite(w http.ResponseWriter, r *http.Request) {}

// @Summary oauth2 admin
// @Security OAuth2Application[admin]
// @Success 200
// @Router /testapi/oauth/admin [get]
func GetOAuthAdmin(w http.ResponseWriter, r *http.Request) {}
105 changes: 105 additions & 0 deletions testdata/global_security/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
{
"swagger": "2.0",
"info": {
"title": "Swagger Example API",
"contact": {},
"version": "1.0"
},
"paths": {
"/testapi/application": {
"get": {
"summary": "default security",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/testapi/basic": {
"get": {
"security": [
{
"BasicAuth": []
}
],
"summary": "basic security",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/testapi/nosec": {
"get": {
"security": [],
"summary": "no security",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/testapi/oauth/admin": {
"get": {
"security": [
{
"OAuth2Application": [
"admin"
]
}
],
"summary": "oauth2 admin",
"responses": {
"200": {
"description": "OK"
}
}
}
},
"/testapi/oauth/write": {
"get": {
"security": [
{
"OAuth2Application": [
"write"
]
}
],
"summary": "oauth2 write",
"responses": {
"200": {
"description": "OK"
}
}
}
}
},
"securityDefinitions": {
"APIKeyAuth": {
"type": "apiKey",
"name": "Authorization",
"in": "header"
},
"BasicAuth": {
"type": "basic"
},
"OAuth2Application": {
"type": "oauth2",
"flow": "application",
"tokenUrl": "https://example.com/oauth/token",
"scopes": {
"admin": " Grants read and write access to administrative information",
"write": " Grants write access"
}
}
},
"security": [
{
"APIKeyAuth": [],
"OAuth2Application": []
}
]
}
18 changes: 18 additions & 0 deletions testdata/global_security/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package global_security

// @title Swagger Example API
// @version 1.0

// @securityDefinitions.apikey APIKeyAuth
// @in header
// @name Authorization

// @securityDefinitions.basic BasicAuth

// @securityDefinitions.oauth2.application OAuth2Application
// @tokenUrl https://example.com/oauth/token
// @scope.write Grants write access
// @scope.admin Grants read and write access to administrative information

// @security APIKeyAuth || OAuth2Application
func main() {}

0 comments on commit 1bf0078

Please sign in to comment.