/
auth_funcs.go
88 lines (80 loc) Β· 2.45 KB
/
auth_funcs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package service
import (
"os"
"path"
"strings"
"goa.design/goa/codegen"
"goa.design/goa/expr"
)
// AuthFuncsFile returns a file that contains a dummy implementation of the
// authorization functions needed to instantiate the service endpoints.
func AuthFuncsFile(genpkg string, root *expr.RootExpr) *codegen.File {
filepath := "auth.go"
if _, err := os.Stat(filepath); !os.IsNotExist(err) {
return nil // file already exists, skip it.
}
var (
sections []*codegen.SectionTemplate
generate bool
scope = codegen.NewNameScope()
)
{
specs := []*codegen.ImportSpec{
{Path: "context"},
{Path: "fmt"},
{Path: "goa.design/goa", Name: "goa"},
{Path: "goa.design/goa/security"},
}
for _, svc := range root.Services {
sd := Services.Get(svc.Name)
specs = append(specs, &codegen.ImportSpec{
Path: path.Join(genpkg, codegen.SnakeCase(sd.VarName)),
Name: scope.Unique(sd.PkgName),
})
}
apiPkg := scope.Unique(strings.ToLower(codegen.Goify(root.API.Name, false)), "api")
header := codegen.Header("", apiPkg, specs)
sections = []*codegen.SectionTemplate{header}
for _, s := range root.Services {
svc := Services.Get(s.Name)
if len(svc.Schemes) > 0 {
generate = true
sections = append(sections, &codegen.SectionTemplate{
Name: "security-authfuncs",
Source: dummyAuthFuncsT,
Data: svc,
})
}
}
}
if len(sections) == 0 || !generate {
return nil
}
return &codegen.File{
Path: filepath,
SectionTemplates: sections,
SkipExist: true,
}
}
// data: Data
const dummyAuthFuncsT = `{{ range .Schemes }}
{{ printf "%sAuth implements the authorization logic for service %q for the %q security scheme." .Type $.Name .SchemeName | comment }}
func (s *{{ $.VarName }}srvc) {{ .Type }}Auth(ctx context.Context, {{ if eq .Type "Basic" }}user, pass{{ else if eq .Type "APIKey" }}key{{ else }}token{{ end }} string, scheme *security.{{ .Type }}Scheme) (context.Context, error) {
//
// TBD: add authorization logic.
//
// In case of authorization failure this function should return
// one of the generated error structs, e.g.:
//
// return ctx, myservice.MakeUnauthorizedError("invalid token")
//
// Alternatively this function may return an instance of
// goa.ServiceError with a Name field value that matches one of
// the design error names, e.g:
//
// return ctx, goa.PermanentError("unauthorized", "invalid token")
//
return ctx, fmt.Errorf("not implemented")
}
{{- end }}
`