| 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" | |
| 14 "golang.org/x/net/context" | 13 "golang.org/x/net/context" |
| 15 | 14 |
| 16 » "github.com/luci/luci-go/server/middleware" | 15 » "github.com/luci/luci-go/server/router" |
| 17 ) | 16 ) |
| 18 | 17 |
| 19 type contextKey int | 18 type contextKey int |
| 20 | 19 |
| 21 // SetSigner injects Signer into the context. | 20 // SetSigner injects Signer into the context. |
| 22 func SetSigner(c context.Context, s Signer) context.Context { | 21 func SetSigner(c context.Context, s Signer) context.Context { |
| 23 return context.WithValue(c, contextKey(0), s) | 22 return context.WithValue(c, contextKey(0), s) |
| 24 } | 23 } |
| 25 | 24 |
| 26 // GetSigner extracts Signer from the context. Returns nil if no Signer is set. | 25 // GetSigner extracts Signer from the context. Returns nil if no Signer is set. |
| 27 func GetSigner(c context.Context) Signer { | 26 func GetSigner(c context.Context) Signer { |
| 28 if s, ok := c.Value(contextKey(0)).(Signer); ok { | 27 if s, ok := c.Value(contextKey(0)).(Signer); ok { |
| 29 return s | 28 return s |
| 30 } | 29 } |
| 31 return nil | 30 return nil |
| 32 } | 31 } |
| 33 | 32 |
| 34 // SignBytes signs the blob with some active private key using Signer installed | 33 // 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. | 34 // 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) { | 35 func SignBytes(c context.Context, blob []byte) (keyName string, signature []byte
, err error) { |
| 37 if s := GetSigner(c); s != nil { | 36 if s := GetSigner(c); s != nil { |
| 38 return s.SignBytes(c, blob) | 37 return s.SignBytes(c, blob) |
| 39 } | 38 } |
| 40 return "", nil, errors.New("signature: no Signer in the context") | 39 return "", nil, errors.New("signature: no Signer in the context") |
| 41 } | 40 } |
| 42 | 41 |
| 43 // InstallHandlers installs a handler that serves public certificates provided | 42 // InstallHandlers installs a handler that serves public certificates provided |
| 44 // by the signer inside the base context. FetchCertificates is hitting this | 43 // by the signer inside the base context. FetchCertificates is hitting this |
| 45 // handler. | 44 // handler. |
| 46 func InstallHandlers(r *httprouter.Router, base middleware.Base) { | 45 func InstallHandlers(r *router.Router, handlers []router.Handler) { |
| 47 » r.GET("/auth/api/v1/server/certificates", base(certsHandler)) | 46 » r.GET("/auth/api/v1/server/certificates", append(handlers, certsHandler)
...) |
| 48 } | 47 } |
| 49 | 48 |
| 50 // certsHandler servers public certificates of the signer in the context. | 49 // 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) { | 50 func certsHandler(c *router.Context) { |
| 52 reply := func(code int, out interface{}) { | 51 reply := func(code int, out interface{}) { |
| 53 » » rw.Header().Set("Content-Type", "application/json") | 52 » » c.Writer.Header().Set("Content-Type", "application/json") |
| 54 » » rw.WriteHeader(code) | 53 » » c.Writer.WriteHeader(code) |
| 55 » » json.NewEncoder(rw).Encode(out) | 54 » » json.NewEncoder(c.Writer).Encode(out) |
| 56 } | 55 } |
| 57 | 56 |
| 58 replyError := func(code int, msg string) { | 57 replyError := func(code int, msg string) { |
| 59 errorReply := struct { | 58 errorReply := struct { |
| 60 Error string `json:"error"` | 59 Error string `json:"error"` |
| 61 }{msg} | 60 }{msg} |
| 62 reply(code, &errorReply) | 61 reply(code, &errorReply) |
| 63 } | 62 } |
| 64 | 63 |
| 65 » s := GetSigner(c) | 64 » s := GetSigner(c.Context) |
| 66 if s == nil { | 65 if s == nil { |
| 67 replyError(http.StatusNotFound, "No Signer instance available") | 66 replyError(http.StatusNotFound, "No Signer instance available") |
| 67 c.Abort() |
| 68 return | 68 return |
| 69 } | 69 } |
| 70 | 70 |
| 71 » certs, err := s.Certificates(c) | 71 » certs, err := s.Certificates(c.Context) |
| 72 if err != nil { | 72 if err != nil { |
| 73 replyError(http.StatusInternalServerError, fmt.Sprintf("Can't fe
tch certificates - %s", err)) | 73 replyError(http.StatusInternalServerError, fmt.Sprintf("Can't fe
tch certificates - %s", err)) |
| 74 » } else { | 74 » » c.Abort() |
| 75 » » reply(http.StatusOK, certs) | 75 » » return |
| 76 } | 76 } |
| 77 |
| 78 reply(http.StatusOK, certs) |
| 77 } | 79 } |
| OLD | NEW |