~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/gopkg.in/goose.v1/testservices/identityservice/keypair.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package identityservice
 
2
 
 
3
import (
 
4
        "encoding/json"
 
5
        "fmt"
 
6
        "io/ioutil"
 
7
        "net/http"
 
8
 
 
9
        "gopkg.in/goose.v1/testservices/hook"
 
10
)
 
11
 
 
12
// Implement the v2 Key Pair form of identity based on Keystone
 
13
 
 
14
type KeyPairRequest struct {
 
15
        Auth struct {
 
16
                ApiAccessKeyCredentials struct {
 
17
                        AccessKey string `json:"accessKey"`
 
18
                        SecretKey string `json:"secretKey"`
 
19
                } `json:"apiAccessKeyCredentials"`
 
20
                TenantName string `json:"tenantName"`
 
21
        } `json:"auth"`
 
22
}
 
23
 
 
24
type KeyPair struct {
 
25
        hook.TestService
 
26
        Users
 
27
        services []V2Service
 
28
}
 
29
 
 
30
func NewKeyPair() *KeyPair {
 
31
        return &KeyPair{
 
32
                Users: Users{
 
33
                        users:   make(map[string]UserInfo),
 
34
                        tenants: make(map[string]string),
 
35
                },
 
36
        }
 
37
}
 
38
 
 
39
func (u *KeyPair) RegisterServiceProvider(name, serviceType string, serviceProvider ServiceProvider) {
 
40
        service := V2Service{name, serviceType, serviceProvider.Endpoints()}
 
41
        u.AddService(Service{V2: service})
 
42
}
 
43
 
 
44
func (u *KeyPair) AddService(service Service) {
 
45
        u.services = append(u.services, service.V2)
 
46
}
 
47
 
 
48
func (u *KeyPair) ReturnFailure(w http.ResponseWriter, status int, message string) {
 
49
        e := ErrorWrapper{
 
50
                Error: ErrorResponse{
 
51
                        Message: message,
 
52
                        Code:    status,
 
53
                        Title:   http.StatusText(status),
 
54
                },
 
55
        }
 
56
        if content, err := json.Marshal(e); err != nil {
 
57
                w.Header().Set("Content-Length", fmt.Sprintf("%d", len(internalError)))
 
58
                w.WriteHeader(http.StatusInternalServerError)
 
59
                w.Write(internalError)
 
60
        } else {
 
61
                w.Header().Set("Content-Length", fmt.Sprintf("%d", len(content)))
 
62
                w.WriteHeader(status)
 
63
                w.Write(content)
 
64
        }
 
65
}
 
66
 
 
67
func (u *KeyPair) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 
68
        var req KeyPairRequest
 
69
        // Testing against Canonistack, all responses are application/json, even failures
 
70
        w.Header().Set("Content-Type", "application/json")
 
71
        if r.Header.Get("Content-Type") != "application/json" {
 
72
                u.ReturnFailure(w, http.StatusBadRequest, notJSON)
 
73
                return
 
74
        }
 
75
        if content, err := ioutil.ReadAll(r.Body); err != nil {
 
76
                w.WriteHeader(http.StatusBadRequest)
 
77
                return
 
78
        } else {
 
79
                if err := json.Unmarshal(content, &req); err != nil {
 
80
                        u.ReturnFailure(w, http.StatusBadRequest, notJSON)
 
81
                        return
 
82
                }
 
83
        }
 
84
        userInfo, errmsg := u.authenticate(req.Auth.ApiAccessKeyCredentials.AccessKey, req.Auth.ApiAccessKeyCredentials.SecretKey)
 
85
        if errmsg != "" {
 
86
                u.ReturnFailure(w, http.StatusUnauthorized, errmsg)
 
87
                return
 
88
        }
 
89
        res, err := u.generateAccessResponse(userInfo)
 
90
        if err != nil {
 
91
                u.ReturnFailure(w, http.StatusInternalServerError, err.Error())
 
92
                return
 
93
        }
 
94
        content, err := json.Marshal(res)
 
95
        if err != nil {
 
96
                u.ReturnFailure(w, http.StatusInternalServerError, err.Error())
 
97
                return
 
98
        }
 
99
        w.WriteHeader(http.StatusOK)
 
100
        w.Write(content)
 
101
}
 
102
 
 
103
func (u *KeyPair) generateAccessResponse(userInfo *UserInfo) (*AccessResponse, error) {
 
104
        res := AccessResponse{}
 
105
        // We pre-populate the response with genuine entries so that it looks sane.
 
106
        if err := json.Unmarshal([]byte(exampleResponse), &res); err != nil {
 
107
                return nil, err
 
108
        }
 
109
        res.Access.ServiceCatalog = u.services
 
110
        res.Access.Token.Id = userInfo.Token
 
111
        res.Access.Token.Tenant.Id = userInfo.TenantId
 
112
        res.Access.User.Id = userInfo.Id
 
113
        if err := u.ProcessControlHook("authorisation", u, &res, userInfo); err != nil {
 
114
                return nil, err
 
115
        }
 
116
        return &res, nil
 
117
}
 
118
 
 
119
// setupHTTP attaches all the needed handlers to provide the HTTP API.
 
120
func (u *KeyPair) SetupHTTP(mux *http.ServeMux) {
 
121
        mux.Handle("/tokens", u)
 
122
}