1
package identityservice
7
"launchpad.net/goose/testservices/hook"
11
// Implement the v2 Key Pair form of identity based on Keystone
13
type KeyPairRequest struct {
15
ApiAccessKeyCredentials struct {
16
AccessKey string `json:"accessKey"`
17
SecretKey string `json:"secretKey"`
18
} `json:"apiAccessKeyCredentials"`
19
TenantName string `json:"tenantName"`
29
func NewKeyPair() *KeyPair {
32
users: make(map[string]UserInfo),
33
tenants: make(map[string]string),
38
func (u *KeyPair) RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider) {
39
service := Service{name, serviceType, serviceProvider.Endpoints()}
43
func (u *KeyPair) AddService(service Service) {
44
u.services = append(u.services, service)
47
func (u *KeyPair) ReturnFailure(w http.ResponseWriter, status int, message string) {
52
Title: http.StatusText(status),
55
if content, err := json.Marshal(e); err != nil {
56
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(internalError)))
57
w.WriteHeader(http.StatusInternalServerError)
58
w.Write(internalError)
60
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(content)))
66
func (u *KeyPair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
67
var req KeyPairRequest
68
// Testing against Canonistack, all responses are application/json, even failures
69
w.Header().Set("Content-Type", "application/json")
70
if r.Header.Get("Content-Type") != "application/json" {
71
u.ReturnFailure(w, http.StatusBadRequest, notJSON)
74
if content, err := ioutil.ReadAll(r.Body); err != nil {
75
w.WriteHeader(http.StatusBadRequest)
78
if err := json.Unmarshal(content, &req); err != nil {
79
u.ReturnFailure(w, http.StatusBadRequest, notJSON)
83
userInfo, errmsg := u.authenticate(req.Auth.ApiAccessKeyCredentials.AccessKey, req.Auth.ApiAccessKeyCredentials.SecretKey)
85
u.ReturnFailure(w, http.StatusUnauthorized, errmsg)
88
res, err := u.generateAccessResponse(userInfo)
90
u.ReturnFailure(w, http.StatusInternalServerError, err.Error())
93
content, err := json.Marshal(res)
95
u.ReturnFailure(w, http.StatusInternalServerError, err.Error())
98
w.WriteHeader(http.StatusOK)
102
func (u *KeyPair) generateAccessResponse(userInfo *UserInfo) (*AccessResponse, error) {
103
res := AccessResponse{}
104
// We pre-populate the response with genuine entries so that it looks sane.
105
if err := json.Unmarshal([]byte(exampleResponse), &res); err != nil {
108
res.Access.ServiceCatalog = u.services
109
res.Access.Token.Id = userInfo.Token
110
res.Access.Token.Tenant.Id = userInfo.TenantId
111
res.Access.User.Id = userInfo.Id
112
if err := u.ProcessControlHook("authorisation", u, &res, userInfo); err != nil {
118
// setupHTTP attaches all the needed handlers to provide the HTTP API.
119
func (u *KeyPair) SetupHTTP(mux *http.ServeMux) {
120
mux.Handle("/tokens", u)