...
1
2
3
4
5
6
7
8 package silly
9
10 import (
11 "context"
12 "fmt"
13 "net/http"
14 "strings"
15
16 dcontext "github.com/docker/distribution/context"
17 "github.com/docker/distribution/registry/auth"
18 )
19
20
21
22
23 type accessController struct {
24 realm string
25 service string
26 }
27
28 var _ auth.AccessController = &accessController{}
29
30 func newAccessController(options map[string]interface{}) (auth.AccessController, error) {
31 realm, present := options["realm"]
32 if _, ok := realm.(string); !present || !ok {
33 return nil, fmt.Errorf(`"realm" must be set for silly access controller`)
34 }
35
36 service, present := options["service"]
37 if _, ok := service.(string); !present || !ok {
38 return nil, fmt.Errorf(`"service" must be set for silly access controller`)
39 }
40
41 return &accessController{realm: realm.(string), service: service.(string)}, nil
42 }
43
44
45
46 func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
47 req, err := dcontext.GetRequest(ctx)
48 if err != nil {
49 return nil, err
50 }
51
52 if req.Header.Get("Authorization") == "" {
53 challenge := challenge{
54 realm: ac.realm,
55 service: ac.service,
56 }
57
58 if len(accessRecords) > 0 {
59 var scopes []string
60 for _, access := range accessRecords {
61 scopes = append(scopes, fmt.Sprintf("%s:%s:%s", access.Type, access.Resource.Name, access.Action))
62 }
63 challenge.scope = strings.Join(scopes, " ")
64 }
65
66 return nil, &challenge
67 }
68
69 ctx = auth.WithUser(ctx, auth.UserInfo{Name: "silly"})
70 ctx = dcontext.WithLogger(ctx, dcontext.GetLogger(ctx, auth.UserNameKey, auth.UserKey))
71
72 return ctx, nil
73
74 }
75
76 type challenge struct {
77 realm string
78 service string
79 scope string
80 }
81
82 var _ auth.Challenge = challenge{}
83
84
85 func (ch challenge) SetHeaders(r *http.Request, w http.ResponseWriter) {
86 header := fmt.Sprintf("Bearer realm=%q,service=%q", ch.realm, ch.service)
87
88 if ch.scope != "" {
89 header = fmt.Sprintf("%s,scope=%q", header, ch.scope)
90 }
91
92 w.Header().Set("WWW-Authenticate", header)
93 }
94
95 func (ch challenge) Error() string {
96 return fmt.Sprintf("silly authentication challenge: %#v", ch)
97 }
98
99
100 func init() {
101 auth.Register("silly", auth.InitFunc(newAccessController))
102 }
103
View as plain text