forked from openshift/origin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
token.go
86 lines (70 loc) · 2.45 KB
/
token.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
package server
import (
"encoding/json"
"net/http"
context "github.com/docker/distribution/context"
"k8s.io/kubernetes/pkg/client/restclient"
"github.com/openshift/origin/pkg/client"
)
type tokenHandler struct {
ctx context.Context
anonymousConfig restclient.Config
}
// NewTokenHandler returns a handler that implements the docker token protocol
func NewTokenHandler(ctx context.Context, client RegistryClient) http.Handler {
return &tokenHandler{
ctx: ctx,
anonymousConfig: client.SafeClientConfig(),
}
}
// bearer token issued to token requests that present no credentials
// recognized by the openshift auth provider as identifying the anonymous user
const anonymousToken = "anonymous"
func (t *tokenHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
ctx := context.WithRequest(t.ctx, req)
// If no authorization is provided, return a token the auth provider will treat as an anonymous user
if len(req.Header.Get("Authorization")) == 0 {
context.GetRequestLogger(ctx).Debugf("anonymous token request")
t.writeToken(anonymousToken, w, req)
return
}
// use the password as the token
_, token, ok := req.BasicAuth()
if !ok {
context.GetRequestLogger(ctx).Debugf("no basic auth credentials provided")
t.writeUnauthorized(w, req)
return
}
// TODO: if this doesn't validate as an API token, attempt to obtain an API token using the given username/password
copied := t.anonymousConfig
copied.BearerToken = token
osClient, err := client.New(&copied)
if err != nil {
context.GetRequestLogger(ctx).Errorf("error building client: %v", err)
t.writeError(w, req)
return
}
if _, err := osClient.Users().Get("~"); err != nil {
context.GetRequestLogger(ctx).Debugf("invalid token: %v", err)
t.writeUnauthorized(w, req)
return
}
t.writeToken(token, w, req)
}
func (t *tokenHandler) writeError(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
json.NewEncoder(w).Encode(map[string]interface{}{"error": "invalid_request"})
}
func (t *tokenHandler) writeToken(token string, w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
json.NewEncoder(w).Encode(map[string]interface{}{
"token": token,
"access_token": token,
})
}
func (t *tokenHandler) writeUnauthorized(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(401)
}