| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package signing | 5 package signing |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "errors" | 9 "errors" |
| 10 "fmt" | 10 "fmt" |
| 11 "net/http" | 11 "net/http" |
| 12 | 12 |
| 13 » "github.com/julienschmidt/httprouter" | 13 » "github.com/luci/luci-go/server/router" |
| 14 "golang.org/x/net/context" | 14 "golang.org/x/net/context" |
| 15 | |
| 16 "github.com/luci/luci-go/server/middleware" | |
| 17 ) | 15 ) |
| 18 | 16 |
| 19 type contextKey int | 17 type contextKey int |
| 20 | 18 |
| 21 // SetSigner injects Signer into the context. | 19 // SetSigner injects Signer into the context. |
| 22 func SetSigner(c context.Context, s Signer) context.Context { | 20 func SetSigner(c context.Context, s Signer) context.Context { |
| 23 return context.WithValue(c, contextKey(0), s) | 21 return context.WithValue(c, contextKey(0), s) |
| 24 } | 22 } |
| 25 | 23 |
| 26 // GetSigner extracts Signer from the context. Returns nil if no Signer is set. | 24 // GetSigner extracts Signer from the context. Returns nil if no Signer is set. |
| 27 func GetSigner(c context.Context) Signer { | 25 func GetSigner(c context.Context) Signer { |
| 28 if s, ok := c.Value(contextKey(0)).(Signer); ok { | 26 if s, ok := c.Value(contextKey(0)).(Signer); ok { |
| 29 return s | 27 return s |
| 30 } | 28 } |
| 31 return nil | 29 return nil |
| 32 } | 30 } |
| 33 | 31 |
| 34 // SignBytes signs the blob with some active private key using Signer installed | 32 // SignBytes signs the blob with some active private key using Signer installed |
| 35 // in the context. Returns the signature and name of the key used. | 33 // in the context. Returns the signature and name of the key used. |
| 36 func SignBytes(c context.Context, blob []byte) (keyName string, signature []byte
, err error) { | 34 func SignBytes(c context.Context, blob []byte) (keyName string, signature []byte
, err error) { |
| 37 if s := GetSigner(c); s != nil { | 35 if s := GetSigner(c); s != nil { |
| 38 return s.SignBytes(c, blob) | 36 return s.SignBytes(c, blob) |
| 39 } | 37 } |
| 40 return "", nil, errors.New("signature: no Signer in the context") | 38 return "", nil, errors.New("signature: no Signer in the context") |
| 41 } | 39 } |
| 42 | 40 |
| 43 // InstallHandlers installs a handler that serves public certificates provided | 41 // InstallHandlers installs a handler that serves public certificates provided |
| 44 // by the signer inside the base context. FetchCertificates is hitting this | 42 // by the signer inside the base context. FetchCertificates is hitting this |
| 45 // handler. | 43 // handler. |
| 46 func InstallHandlers(r *httprouter.Router, base middleware.Base) { | 44 func InstallHandlers(r *router.Router, base router.MiddlewareChain) { |
| 47 » r.GET("/auth/api/v1/server/certificates", base(certsHandler)) | 45 » r.GET("/auth/api/v1/server/certificates", base, certsHandler) |
| 48 } | 46 } |
| 49 | 47 |
| 50 // certsHandler servers public certificates of the signer in the context. | 48 // certsHandler servers public certificates of the signer in the context. |
| 51 func certsHandler(c context.Context, rw http.ResponseWriter, r *http.Request, p
httprouter.Params) { | 49 func certsHandler(c *router.Context) { |
| 52 reply := func(code int, out interface{}) { | 50 reply := func(code int, out interface{}) { |
| 53 » » rw.Header().Set("Content-Type", "application/json") | 51 » » c.Writer.Header().Set("Content-Type", "application/json") |
| 54 » » rw.WriteHeader(code) | 52 » » c.Writer.WriteHeader(code) |
| 55 » » json.NewEncoder(rw).Encode(out) | 53 » » json.NewEncoder(c.Writer).Encode(out) |
| 56 } | 54 } |
| 57 | 55 |
| 58 replyError := func(code int, msg string) { | 56 replyError := func(code int, msg string) { |
| 59 errorReply := struct { | 57 errorReply := struct { |
| 60 Error string `json:"error"` | 58 Error string `json:"error"` |
| 61 }{msg} | 59 }{msg} |
| 62 reply(code, &errorReply) | 60 reply(code, &errorReply) |
| 63 } | 61 } |
| 64 | 62 |
| 65 » s := GetSigner(c) | 63 » s := GetSigner(c.Context) |
| 66 if s == nil { | 64 if s == nil { |
| 67 replyError(http.StatusNotFound, "No Signer instance available") | 65 replyError(http.StatusNotFound, "No Signer instance available") |
| 68 return | 66 return |
| 69 } | 67 } |
| 70 | 68 |
| 71 » certs, err := s.Certificates(c) | 69 » certs, err := s.Certificates(c.Context) |
| 72 if err != nil { | 70 if err != nil { |
| 73 replyError(http.StatusInternalServerError, fmt.Sprintf("Can't fe
tch certificates - %s", err)) | 71 replyError(http.StatusInternalServerError, fmt.Sprintf("Can't fe
tch certificates - %s", err)) |
| 74 } else { | 72 } else { |
| 75 reply(http.StatusOK, certs) | 73 reply(http.StatusOK, certs) |
| 76 } | 74 } |
| 77 } | 75 } |
| OLD | NEW |