blob: 6038f96b1b3d85c1d159aa350533f7b11071a52e [file] [log] [blame]
Ash Wilsoncde68122014-08-28 16:15:43 -04001package tokens
2
3import (
4 "fmt"
5 "net/http"
6 "testing"
7
8 "github.com/rackspace/gophercloud"
9 "github.com/rackspace/gophercloud/testhelper"
10)
11
Ash Wilson417d9222014-08-29 07:58:35 -040012// authTokenPost verifies that providing certain AuthOptions and Scope results in an expected JSON structure.
13func authTokenPost(t *testing.T, options gophercloud.AuthOptions, scope *Scope, requestJSON string) {
Ash Wilsoncde68122014-08-28 16:15:43 -040014 setup()
15 defer teardown()
16
17 client := gophercloud.ServiceClient{
18 Endpoint: endpoint(),
Ash Wilson417d9222014-08-29 07:58:35 -040019 Options: options,
Ash Wilson053fcb02014-08-29 08:04:35 -040020 TokenID: "12345abcdef",
Ash Wilsoncde68122014-08-28 16:15:43 -040021 }
22
23 mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
24 testhelper.TestMethod(t, r, "POST")
25 testhelper.TestHeader(t, r, "Content-Type", "application/json")
26 testhelper.TestHeader(t, r, "Accept", "application/json")
Ash Wilson417d9222014-08-29 07:58:35 -040027 testhelper.TestJSONRequest(t, r, requestJSON)
Ash Wilsoncde68122014-08-28 16:15:43 -040028
Ash Wilson4a52e2a2014-08-29 09:28:00 -040029 w.WriteHeader(http.StatusCreated)
Ash Wilsoncde68122014-08-28 16:15:43 -040030 fmt.Fprintf(w, `{}`)
31 })
32
Ash Wilson417d9222014-08-29 07:58:35 -040033 _, err := Create(&client, scope)
Ash Wilsoncde68122014-08-28 16:15:43 -040034 if err != nil {
35 t.Errorf("Create returned an error: %v", err)
36 }
37}
Ash Wilson417d9222014-08-29 07:58:35 -040038
Ash Wilsona8855ff2014-08-29 08:26:29 -040039func authTokenPostErr(t *testing.T, options gophercloud.AuthOptions, scope *Scope, includeToken bool, expectedErr error) {
40 setup()
41 defer teardown()
42
43 client := gophercloud.ServiceClient{
44 Endpoint: endpoint(),
45 Options: options,
46 }
47 if includeToken {
48 client.TokenID = "abcdef123456"
49 }
50
51 _, err := Create(&client, scope)
52 if err == nil {
53 t.Errorf("Create did NOT return an error")
54 }
55 if err != expectedErr {
56 t.Errorf("Create returned an unexpected error: wanted %v, got %v", expectedErr, err)
57 }
58}
59
Ash Wilson417d9222014-08-29 07:58:35 -040060func TestCreateUserIDAndPassword(t *testing.T) {
61 authTokenPost(t, gophercloud.AuthOptions{UserID: "me", Password: "squirrel!"}, nil, `
62 {
63 "auth": {
64 "identity": {
65 "methods": ["password"],
66 "password": {
67 "user": { "id": "me", "password": "squirrel!" }
68 }
69 }
70 }
71 }
72 `)
73}
74
75func TestCreateUsernameDomainIDPassword(t *testing.T) {
76 authTokenPost(t, gophercloud.AuthOptions{Username: "fakey", Password: "notpassword", DomainID: "abc123"}, nil, `
77 {
78 "auth": {
79 "identity": {
80 "methods": ["password"],
81 "password": {
82 "user": {
83 "domain": {
84 "id": "abc123"
85 },
86 "name": "fakey",
87 "password": "notpassword"
88 }
89 }
90 }
91 }
92 }
93 `)
94}
Ash Wilsond8da9e42014-08-29 08:01:06 -040095
96func TestCreateUsernameDomainNamePassword(t *testing.T) {
97 authTokenPost(t, gophercloud.AuthOptions{Username: "frank", Password: "swordfish", DomainName: "spork.net"}, nil, `
98 {
99 "auth": {
100 "identity": {
101 "methods": ["password"],
102 "password": {
103 "user": {
104 "domain": {
105 "name": "spork.net"
106 },
107 "name": "frank",
108 "password": "swordfish"
109 }
110 }
111 }
112 }
113 }
114 `)
115}
Ash Wilson053fcb02014-08-29 08:04:35 -0400116
117func TestCreateTokenID(t *testing.T) {
118 authTokenPost(t, gophercloud.AuthOptions{}, nil, `
119 {
120 "auth": {
121 "identity": {
122 "methods": ["token"],
123 "token": {
124 "id": "12345abcdef"
125 }
126 }
127 }
128 }
129 `)
130}
Ash Wilson1fde6162014-08-29 08:13:06 -0400131
132func TestCreateProjectIDScope(t *testing.T) {
133 options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
134 scope := &Scope{ProjectID: "123456"}
135 authTokenPost(t, options, scope, `
136 {
137 "auth": {
138 "identity": {
139 "methods": ["password"],
140 "password": {
141 "user": {
142 "id": "fenris",
143 "password": "g0t0h311"
144 }
145 }
146 },
147 "scope": {
148 "project": {
149 "id": "123456"
150 }
151 }
152 }
153 }
154 `)
155}
156
157func TestCreateDomainIDScope(t *testing.T) {
158 options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
159 scope := &Scope{DomainID: "1000"}
160 authTokenPost(t, options, scope, `
161 {
162 "auth": {
163 "identity": {
164 "methods": ["password"],
165 "password": {
166 "user": {
167 "id": "fenris",
168 "password": "g0t0h311"
169 }
170 }
171 },
172 "scope": {
173 "domain": {
174 "id": "1000"
175 }
176 }
177 }
178 }
179 `)
180}
181
182func TestCreateProjectNameAndDomainIDScope(t *testing.T) {
183 options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
184 scope := &Scope{ProjectName: "world-domination", DomainID: "1000"}
185 authTokenPost(t, options, scope, `
186 {
187 "auth": {
188 "identity": {
189 "methods": ["password"],
190 "password": {
191 "user": {
192 "id": "fenris",
193 "password": "g0t0h311"
194 }
195 }
196 },
197 "scope": {
198 "project": {
199 "domain": {
200 "id": "1000"
201 },
202 "name": "world-domination"
203 }
204 }
205 }
206 }
207 `)
208}
209
210func TestCreateProjectNameAndDomainNameScope(t *testing.T) {
211 options := gophercloud.AuthOptions{UserID: "fenris", Password: "g0t0h311"}
212 scope := &Scope{ProjectName: "world-domination", DomainName: "evil-plans"}
213 authTokenPost(t, options, scope, `
214 {
215 "auth": {
216 "identity": {
217 "methods": ["password"],
218 "password": {
219 "user": {
220 "id": "fenris",
221 "password": "g0t0h311"
222 }
223 }
224 },
225 "scope": {
226 "project": {
227 "domain": {
228 "name": "evil-plans"
229 },
230 "name": "world-domination"
231 }
232 }
233 }
234 }
235 `)
236}
Ash Wilsona8855ff2014-08-29 08:26:29 -0400237
Ash Wilson4a52e2a2014-08-29 09:28:00 -0400238func TestCreateExtractsTokenFromResponse(t *testing.T) {
239 setup()
240 defer teardown()
241
242 client := gophercloud.ServiceClient{
243 Endpoint: endpoint(),
244 Options: gophercloud.AuthOptions{UserID: "me", Password: "shhh"},
245 }
246
247 mux.HandleFunc("/auth/tokens", func(w http.ResponseWriter, r *http.Request) {
248 w.Header().Add("X-Subject-Token", "aaa111")
249
250 w.WriteHeader(http.StatusCreated)
251 fmt.Fprintf(w, `{}`)
252 })
253
254 result, err := Create(&client, nil)
255 if err != nil {
256 t.Errorf("Create returned an error: %v", err)
257 }
258
259 token, _ := result.TokenID()
260 if token != "aaa111" {
261 t.Errorf("Expected token to be aaa111, but was %s", token)
262 }
263}
264
Ash Wilsona8855ff2014-08-29 08:26:29 -0400265func TestCreateFailureEmptyAuth(t *testing.T) {
266 authTokenPostErr(t, gophercloud.AuthOptions{}, nil, false, ErrMissingPassword)
267}
268
269func TestCreateFailureAPIKey(t *testing.T) {
270 authTokenPostErr(t, gophercloud.AuthOptions{APIKey: "something"}, nil, false, ErrAPIKeyProvided)
271}
272
273func TestCreateFailureTenantID(t *testing.T) {
274 authTokenPostErr(t, gophercloud.AuthOptions{TenantID: "something"}, nil, false, ErrTenantIDProvided)
275}
276
277func TestCreateFailureTenantName(t *testing.T) {
278 authTokenPostErr(t, gophercloud.AuthOptions{TenantName: "something"}, nil, false, ErrTenantNameProvided)
279}
280
281func TestCreateFailureTokenIDUsername(t *testing.T) {
282 authTokenPostErr(t, gophercloud.AuthOptions{Username: "something"}, nil, true, ErrUsernameWithToken)
283}
284
285func TestCreateFailureTokenIDUserID(t *testing.T) {
286 authTokenPostErr(t, gophercloud.AuthOptions{UserID: "something"}, nil, true, ErrUserIDWithToken)
287}
288
289func TestCreateFailureTokenIDDomainID(t *testing.T) {
290 authTokenPostErr(t, gophercloud.AuthOptions{DomainID: "something"}, nil, true, ErrDomainIDWithToken)
291}
292
293func TestCreateFailureTokenIDDomainName(t *testing.T) {
294 authTokenPostErr(t, gophercloud.AuthOptions{DomainName: "something"}, nil, true, ErrDomainNameWithToken)
295}
Ash Wilsonaed3db42014-08-29 08:59:56 -0400296
297func TestCreateFailureMissingUser(t *testing.T) {
298 options := gophercloud.AuthOptions{Password: "supersecure"}
299 authTokenPostErr(t, options, nil, false, ErrUsernameOrUserID)
300}
301
302func TestCreateFailureBothUser(t *testing.T) {
303 options := gophercloud.AuthOptions{
304 Password: "supersecure",
305 Username: "oops",
306 UserID: "redundancy",
307 }
308 authTokenPostErr(t, options, nil, false, ErrUsernameOrUserID)
309}
310
311func TestCreateFailureMissingDomain(t *testing.T) {
312 options := gophercloud.AuthOptions{
313 Password: "supersecure",
314 Username: "notuniqueenough",
315 }
316 authTokenPostErr(t, options, nil, false, ErrDomainIDOrDomainName)
317}
318
319func TestCreateFailureBothDomain(t *testing.T) {
320 options := gophercloud.AuthOptions{
321 Password: "supersecure",
322 Username: "someone",
323 DomainID: "hurf",
324 DomainName: "durf",
325 }
326 authTokenPostErr(t, options, nil, false, ErrDomainIDOrDomainName)
327}
328
329func TestCreateFailureUserIDDomainID(t *testing.T) {
330 options := gophercloud.AuthOptions{
331 UserID: "100",
332 Password: "stuff",
333 DomainID: "oops",
334 }
335 authTokenPostErr(t, options, nil, false, ErrDomainIDWithUserID)
336}
337
338func TestCreateFailureUserIDDomainName(t *testing.T) {
339 options := gophercloud.AuthOptions{
340 UserID: "100",
341 Password: "sssh",
342 DomainName: "oops",
343 }
344 authTokenPostErr(t, options, nil, false, ErrDomainNameWithUserID)
345}
346
347func TestCreateFailureScopeProjectNameAlone(t *testing.T) {
348 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
349 scope := &Scope{ProjectName: "notenough"}
350 authTokenPostErr(t, options, scope, false, ErrScopeDomainIDOrDomainName)
351}
352
353func TestCreateFailureScopeProjectNameAndID(t *testing.T) {
354 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
355 scope := &Scope{ProjectName: "whoops", ProjectID: "toomuch", DomainID: "1234"}
356 authTokenPostErr(t, options, scope, false, ErrScopeProjectIDOrProjectName)
357}
358
359func TestCreateFailureScopeProjectIDAndDomainID(t *testing.T) {
360 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
361 scope := &Scope{ProjectID: "toomuch", DomainID: "notneeded"}
362 authTokenPostErr(t, options, scope, false, ErrScopeProjectIDAlone)
363}
364
365func TestCreateFailureScopeProjectIDAndDomainNAme(t *testing.T) {
366 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
367 scope := &Scope{ProjectID: "toomuch", DomainName: "notneeded"}
368 authTokenPostErr(t, options, scope, false, ErrScopeProjectIDAlone)
369}
370
371func TestCreateFailureScopeDomainIDAndDomainName(t *testing.T) {
372 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
373 scope := &Scope{DomainID: "toomuch", DomainName: "notneeded"}
374 authTokenPostErr(t, options, scope, false, ErrScopeDomainIDOrDomainName)
375}
376
377func TestCreateFailureScopeDomainNameAlone(t *testing.T) {
378 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
379 scope := &Scope{DomainName: "notenough"}
380 authTokenPostErr(t, options, scope, false, ErrScopeDomainName)
381}
382
383func TestCreateFailureEmptyScope(t *testing.T) {
384 options := gophercloud.AuthOptions{UserID: "myself", Password: "swordfish"}
385 scope := &Scope{}
386 authTokenPostErr(t, options, scope, false, ErrScopeEmpty)
387}