Skip to content

Commit edc6bb1

Browse files
committed
(feat) generate OAuth2 Scopes and Descriptions variables
1 parent 2d37852 commit edc6bb1

File tree

7 files changed

+115
-33
lines changed

7 files changed

+115
-33
lines changed

examples/ex_oauth2/oas_security_gen.go

Lines changed: 16 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/ex_oauth2_scopes_and_or/oas_security_gen.go

Lines changed: 17 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gen/_template/security.tmpl

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,45 @@ func findAuthorization(h http.Header, prefix string) (string, bool) {
3434

3535
{{ range $s := $.Securities }}
3636

37+
{{ if gt (len $s.ScopeDescriptions) 0 }}
38+
39+
type ScopeName = string
40+
41+
const (
42+
{{- range $scopeName, $scopeDescription := $s.ScopeDescriptions }}
43+
ScopeName{{ stripNonAlphaNumeric $scopeName }} ScopeName = {{ quote $scopeName }}
44+
{{- end }}
45+
)
46+
47+
{{if $s.Format.IsOAuth2Security}}
48+
var oauth2ScopesDescription{{ $s.Type.Name }} = map[string]string {
49+
{{- range $scopeName, $scopeDescription := $s.ScopeDescriptions }}
50+
ScopeName{{ stripNonAlphaNumeric $scopeName }}: {{ quote $scopeDescription }},
51+
{{- end }}
52+
}
53+
{{- end }}
54+
55+
{{- end }}
56+
3757
{{if $s.Format.IsOAuth2Security}}
3858
var oauth2Scopes{{ $s.Type.Name }} = map[string][]string {
39-
{{- else}}
59+
{{- range $operationName, $scopes := $s.OperationScopes }}
60+
{{ $operationName }}Operation: []string{
61+
{{- range $scopeName := $scopes }}
62+
ScopeName{{ stripNonAlphaNumeric $scopeName }},
63+
{{- end }}
64+
},
65+
{{- end }}
66+
{{- else }}
4067
var operationRoles{{ $s.Type.Name }} = map[string][]string {
41-
{{- end}}
42-
{{- range $operationName, $scopes := $s.Scopes }}
68+
{{- range $operationName, $scopes := $s.OperationScopes }}
4369
{{ $operationName }}Operation: []string{
44-
{{- range $scope := $scopes }}
45-
{{ quote $scope }},
46-
{{- end}}
70+
{{- range $scopeName := $scopes }}
71+
{{ quote $scopeName }},
72+
{{- end }}
4773
},
4874
{{- end }}
75+
{{- end }}
4976
}
5077

5178
func (s *Server) security{{ $s.Type.Name }}(ctx context.Context, operationName OperationName, req *http.Request) (context.Context, bool, error) {

gen/gen_security.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"strings"
66

77
"github.com/go-faster/errors"
8+
"golang.org/x/exp/maps"
89

910
"github.com/ogen-go/ogen/gen/ir"
1011
"github.com/ogen-go/ogen/internal/bitset"
@@ -22,7 +23,7 @@ func (g *Generator) generateSecurityAPIKey(
2223
}
2324
s.Format = ir.APIKeySecurityFormat
2425
s.ParameterName = security.Name
25-
s.Scopes = map[string][]string{
26+
s.OperationScopes = map[string][]string{
2627
operationName: spec.Scopes,
2728
}
2829

@@ -58,10 +59,23 @@ func (g *Generator) generateSecurityOauth2(
5859
) *ir.Security {
5960
s.Format = ir.Oauth2SecurityFormat
6061
s.Kind = ir.HeaderSecurity
61-
s.Scopes = map[string][]string{
62+
s.OperationScopes = map[string][]string{
6263
operationName: spec.Scopes,
6364
}
6465

66+
if spec.Security.Flows.AuthorizationCode != nil {
67+
maps.Copy(s.ScopeDescriptions, spec.Security.Flows.AuthorizationCode.Scopes)
68+
}
69+
if spec.Security.Flows.ClientCredentials != nil {
70+
maps.Copy(s.ScopeDescriptions, spec.Security.Flows.ClientCredentials.Scopes)
71+
}
72+
if spec.Security.Flows.Implicit != nil {
73+
maps.Copy(s.ScopeDescriptions, spec.Security.Flows.Implicit.Scopes)
74+
}
75+
if spec.Security.Flows.Password != nil {
76+
maps.Copy(s.ScopeDescriptions, spec.Security.Flows.Password.Scopes)
77+
}
78+
6579
s.Type.Fields = append(s.Type.Fields,
6680
&ir.Field{
6781
Name: "Token",
@@ -82,7 +96,7 @@ func (g *Generator) generateSecurityHTTP(
8296
) (*ir.Security, error) {
8397
security := spec.Security
8498
s.Kind = ir.HeaderSecurity
85-
s.Scopes = map[string][]string{
99+
s.OperationScopes = map[string][]string{
86100
operationName: spec.Scopes,
87101
}
88102

@@ -119,9 +133,13 @@ func (g *Generator) generateSecurityHTTP(
119133
return s, nil
120134
}
121135

122-
func (g *Generator) generateSecurity(ctx *genctx, operationName string, spec openapi.SecurityScheme) (r *ir.Security, rErr error) {
136+
func (g *Generator) generateSecurity(
137+
ctx *genctx,
138+
operationName string,
139+
spec openapi.SecurityScheme,
140+
) (r *ir.Security, rErr error) {
123141
if sec, ok := g.securities[spec.Name]; ok {
124-
sec.Scopes[operationName] = append(sec.Scopes[operationName], spec.Scopes...)
142+
sec.OperationScopes[operationName] = append(sec.OperationScopes[operationName], spec.Scopes...)
125143
return sec, nil
126144
}
127145
security := spec.Security
@@ -136,14 +154,15 @@ func (g *Generator) generateSecurity(ctx *genctx, operationName string, spec ope
136154
Name: typeName,
137155
}
138156
s := &ir.Security{
139-
Type: t,
140-
Description: security.Description,
157+
Type: t,
158+
Description: security.Description,
159+
ScopeDescriptions: map[string]string{},
141160
}
142161

143162
// Do not create a type for custom security.
144163
if security.XOgenCustomSecurity {
145164
s.Format = ir.CustomSecurityFormat
146-
s.Scopes = map[string][]string{
165+
s.OperationScopes = map[string][]string{
147166
operationName: spec.Scopes,
148167
}
149168
return s, nil

gen/gen_security_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,28 +89,28 @@ func TestGenerateSecurities(t *testing.T) {
8989
{
9090
Kind: ir.HeaderSecurity,
9191
Format: ir.Oauth2SecurityFormat,
92-
Scopes: map[string][]string{
92+
OperationScopes: map[string][]string{
9393
"testOp": {"scope1", "scope2", "scope3"},
9494
},
9595
},
9696
{
9797
Kind: ir.QuerySecurity,
9898
Format: ir.APIKeySecurityFormat,
99-
Scopes: map[string][]string{
99+
OperationScopes: map[string][]string{
100100
"testOp": {"scope4"},
101101
},
102102
},
103103
{
104104
Kind: ir.HeaderSecurity,
105105
Format: ir.BasicHTTPSecurityFormat,
106-
Scopes: map[string][]string{
106+
OperationScopes: map[string][]string{
107107
"testOp": {"scope5"},
108108
},
109109
},
110110
{
111111
Kind: ir.HeaderSecurity,
112112
Format: ir.BearerSecurityFormat,
113-
Scopes: map[string][]string{
113+
OperationScopes: map[string][]string{
114114
"testOp": {"scope6"},
115115
},
116116
},
@@ -130,7 +130,7 @@ func TestGenerateSecurities(t *testing.T) {
130130

131131
require.Equal(t, wantSec.Kind, sec.Kind)
132132
require.Equal(t, wantSec.Format, sec.Format)
133-
require.Contains(t, sec.Scopes, "testOp")
134-
require.Equal(t, wantSec.Scopes["testOp"], sec.Scopes["testOp"])
133+
require.Contains(t, sec.OperationScopes, "testOp")
134+
require.Equal(t, wantSec.OperationScopes["testOp"], sec.OperationScopes["testOp"])
135135
}
136136
}

gen/ir/security.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,13 @@ func (s SecurityFormat) IsCustomSecurity() bool {
9393
}
9494

9595
type Security struct {
96-
Kind SecurityKind
97-
Format SecurityFormat
98-
ParameterName string
99-
Description string
100-
Type *Type
101-
Scopes map[string][]string
96+
Kind SecurityKind
97+
Format SecurityFormat
98+
ParameterName string
99+
Description string
100+
Type *Type
101+
ScopeDescriptions map[string]string
102+
OperationScopes map[string][]string
102103
}
103104

104105
func (s *Security) GoDoc() []string {

gen/templates.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package gen
33
import (
44
"embed"
55
"fmt"
6+
"regexp"
67
"strconv"
78
"strings"
89
"sync"
910
"text/template"
1011

1112
"github.com/go-faster/errors"
13+
"golang.org/x/text/cases"
14+
"golang.org/x/text/language"
1215

1316
"github.com/ogen-go/ogen/gen/ir"
1417
"github.com/ogen-go/ogen/internal/naming"
@@ -208,6 +211,12 @@ func templateFunctions() template.FuncMap {
208211
},
209212
"isObjectParam": isObjectParam,
210213
"paramObjectFields": paramObjectFields,
214+
"stripNonAlphaNumeric": func(s string) string {
215+
// Remove all non-alphabetical characters.
216+
// This is used to generate valid Go identifiers.
217+
reg := regexp.MustCompile("[^a-zA-Z0-9][a-zA-Z]+")
218+
return cases.Title(language.English, cases.NoLower).String(reg.ReplaceAllString(s, ""))
219+
},
211220
}
212221
}
213222

0 commit comments

Comments
 (0)