Skip to content

Commit 1bf0078

Browse files
authoredJul 18, 2023
feat: global security (#1620)
* global security * improve test
1 parent 575963e commit 1bf0078

File tree

6 files changed

+208
-0
lines changed

6 files changed

+208
-0
lines changed
 

‎operation.go

+5
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,11 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {
721721

722722
// ParseSecurityComment parses comment for given `security` comment string.
723723
func (operation *Operation) ParseSecurityComment(commentLine string) error {
724+
if len(commentLine) == 0 {
725+
operation.Security = []map[string][]string{}
726+
return nil
727+
}
728+
724729
var (
725730
securityMap = make(map[string][]string)
726731
securitySource = commentLine[strings.Index(commentLine, "@Security")+1:]

‎parser.go

+31
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,9 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
569569

570570
parser.swagger.SecurityDefinitions[value] = scheme
571571

572+
case securityAttr:
573+
parser.swagger.Security = append(parser.swagger.Security, parseSecurity(value))
574+
572575
case "@query.collection.format":
573576
parser.collectionFormatInQuery = TransToValidCollectionFormat(value)
574577

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

774+
func parseSecurity(commentLine string) map[string][]string {
775+
securityMap := make(map[string][]string)
776+
777+
for _, securityOption := range strings.Split(commentLine, "||") {
778+
securityOption = strings.TrimSpace(securityOption)
779+
780+
left, right := strings.Index(securityOption, "["), strings.Index(securityOption, "]")
781+
782+
if !(left == -1 && right == -1) {
783+
scopes := securityOption[left+1 : right]
784+
785+
var options []string
786+
787+
for _, scope := range strings.Split(scopes, ",") {
788+
options = append(options, strings.TrimSpace(scope))
789+
}
790+
791+
securityKey := securityOption[0:left]
792+
securityMap[securityKey] = append(securityMap[securityKey], options...)
793+
} else {
794+
securityKey := strings.TrimSpace(securityOption)
795+
securityMap[securityKey] = []string{}
796+
}
797+
}
798+
799+
return securityMap
800+
}
801+
771802
func initIfEmpty(license *spec.License) *spec.License {
772803
if license == nil {
773804
return new(spec.License)

‎parser_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -2157,6 +2157,21 @@ func TestParseTypeOverrides(t *testing.T) {
21572157
assert.Equal(t, string(expected), string(b))
21582158
}
21592159

2160+
func TestGlobalSecurity(t *testing.T) {
2161+
t.Parallel()
2162+
2163+
searchDir := "testdata/global_security"
2164+
p := New()
2165+
err := p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth)
2166+
assert.NoError(t, err)
2167+
2168+
expected, err := os.ReadFile(filepath.Join(searchDir, "expected.json"))
2169+
assert.NoError(t, err)
2170+
2171+
b, _ := json.MarshalIndent(p.swagger, "", " ")
2172+
assert.Equal(t, string(expected), string(b))
2173+
}
2174+
21602175
func TestParseNested(t *testing.T) {
21612176
t.Parallel()
21622177

‎testdata/global_security/api/api.go

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package api
2+
3+
import (
4+
"net/http"
5+
)
6+
7+
// @Summary default security
8+
// @Success 200
9+
// @Router /testapi/application [get]
10+
func GetApplication(w http.ResponseWriter, r *http.Request) {}
11+
12+
// @Summary no security
13+
// @Security
14+
// @Success 200
15+
// @Router /testapi/nosec [get]
16+
func GetNoSec(w http.ResponseWriter, r *http.Request) {}
17+
18+
// @Summary basic security
19+
// @Security BasicAuth
20+
// @Success 200
21+
// @Router /testapi/basic [get]
22+
func GetBasic(w http.ResponseWriter, r *http.Request) {}
23+
24+
// @Summary oauth2 write
25+
// @Security OAuth2Application[write]
26+
// @Success 200
27+
// @Router /testapi/oauth/write [get]
28+
func GetOAuthWrite(w http.ResponseWriter, r *http.Request) {}
29+
30+
// @Summary oauth2 admin
31+
// @Security OAuth2Application[admin]
32+
// @Success 200
33+
// @Router /testapi/oauth/admin [get]
34+
func GetOAuthAdmin(w http.ResponseWriter, r *http.Request) {}
+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
{
2+
"swagger": "2.0",
3+
"info": {
4+
"title": "Swagger Example API",
5+
"contact": {},
6+
"version": "1.0"
7+
},
8+
"paths": {
9+
"/testapi/application": {
10+
"get": {
11+
"summary": "default security",
12+
"responses": {
13+
"200": {
14+
"description": "OK"
15+
}
16+
}
17+
}
18+
},
19+
"/testapi/basic": {
20+
"get": {
21+
"security": [
22+
{
23+
"BasicAuth": []
24+
}
25+
],
26+
"summary": "basic security",
27+
"responses": {
28+
"200": {
29+
"description": "OK"
30+
}
31+
}
32+
}
33+
},
34+
"/testapi/nosec": {
35+
"get": {
36+
"security": [],
37+
"summary": "no security",
38+
"responses": {
39+
"200": {
40+
"description": "OK"
41+
}
42+
}
43+
}
44+
},
45+
"/testapi/oauth/admin": {
46+
"get": {
47+
"security": [
48+
{
49+
"OAuth2Application": [
50+
"admin"
51+
]
52+
}
53+
],
54+
"summary": "oauth2 admin",
55+
"responses": {
56+
"200": {
57+
"description": "OK"
58+
}
59+
}
60+
}
61+
},
62+
"/testapi/oauth/write": {
63+
"get": {
64+
"security": [
65+
{
66+
"OAuth2Application": [
67+
"write"
68+
]
69+
}
70+
],
71+
"summary": "oauth2 write",
72+
"responses": {
73+
"200": {
74+
"description": "OK"
75+
}
76+
}
77+
}
78+
}
79+
},
80+
"securityDefinitions": {
81+
"APIKeyAuth": {
82+
"type": "apiKey",
83+
"name": "Authorization",
84+
"in": "header"
85+
},
86+
"BasicAuth": {
87+
"type": "basic"
88+
},
89+
"OAuth2Application": {
90+
"type": "oauth2",
91+
"flow": "application",
92+
"tokenUrl": "https://example.com/oauth/token",
93+
"scopes": {
94+
"admin": " Grants read and write access to administrative information",
95+
"write": " Grants write access"
96+
}
97+
}
98+
},
99+
"security": [
100+
{
101+
"APIKeyAuth": [],
102+
"OAuth2Application": []
103+
}
104+
]
105+
}

‎testdata/global_security/main.go

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package global_security
2+
3+
// @title Swagger Example API
4+
// @version 1.0
5+
6+
// @securityDefinitions.apikey APIKeyAuth
7+
// @in header
8+
// @name Authorization
9+
10+
// @securityDefinitions.basic BasicAuth
11+
12+
// @securityDefinitions.oauth2.application OAuth2Application
13+
// @tokenUrl https://example.com/oauth/token
14+
// @scope.write Grants write access
15+
// @scope.admin Grants read and write access to administrative information
16+
17+
// @security APIKeyAuth || OAuth2Application
18+
func main() {}

0 commit comments

Comments
 (0)
Please sign in to comment.