blob: 69b8bccda23c749fe99f84e30ea6f54f9b0f999b [file] [log] [blame]
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -07001package gophercloud
2
3import (
Samuel A. Falvo II978fed82013-06-25 17:59:19 -07004 "encoding/json"
Samuel A. Falvo II839428e2013-06-25 18:02:24 -07005 "io/ioutil"
6 "net/http"
7 "strings"
8 "testing"
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -07009)
10
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -070011type testTransport struct {
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070012 called int
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -070013 response string
14}
15
16func (t *testTransport) RoundTrip(req *http.Request) (rsp *http.Response, err error) {
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070017 t.called++
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -070018
19 headers := make(http.Header)
20 headers.Add("Content-Type", "application/xml; charset=UTF-8")
21
22 body := ioutil.NopCloser(strings.NewReader(t.response))
23
24 rsp = &http.Response{
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070025 Status: "200 OK",
26 StatusCode: 200,
27 Proto: "HTTP/1.1",
28 ProtoMajor: 1,
29 ProtoMinor: 1,
30 Header: headers,
31 Body: body,
32 ContentLength: -1,
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -070033 TransferEncoding: nil,
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070034 Close: true,
35 Trailer: nil,
36 Request: req,
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -070037 }
38 return
39}
40
Samuel A. Falvo II978fed82013-06-25 17:59:19 -070041type tenantIdCheckTransport struct {
42 expectTenantId bool
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070043 tenantIdFound bool
Samuel A. Falvo II978fed82013-06-25 17:59:19 -070044}
45
46func (t *tenantIdCheckTransport) RoundTrip(req *http.Request) (rsp *http.Response, err error) {
47 var authContainer *AuthContainer
48
49 headers := make(http.Header)
50 headers.Add("Content-Type", "application/xml; charset=UTF-8")
51
52 body := ioutil.NopCloser(strings.NewReader("t.response"))
53
54 rsp = &http.Response{
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070055 Status: "200 OK",
56 StatusCode: 200,
57 Proto: "HTTP/1.1",
58 ProtoMajor: 1,
59 ProtoMinor: 1,
60 Header: headers,
61 Body: body,
62 ContentLength: -1,
Samuel A. Falvo II978fed82013-06-25 17:59:19 -070063 TransferEncoding: nil,
Samuel A. Falvo II839428e2013-06-25 18:02:24 -070064 Close: true,
65 Trailer: nil,
66 Request: req,
Samuel A. Falvo II978fed82013-06-25 17:59:19 -070067 }
68
69 bytes, err := ioutil.ReadAll(req.Body)
70 if err != nil {
71 return nil, err
72 }
73 err = json.Unmarshal(bytes, &authContainer)
74 if err != nil {
75 return nil, err
76 }
77 t.tenantIdFound = (authContainer.Auth.TenantId != "")
78
79 if t.tenantIdFound != t.expectTenantId {
80 rsp.Status = "500 Internal Server Error"
81 rsp.StatusCode = 500
82 }
83 return
84}
85
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -070086func TestAuthProvider(t *testing.T) {
87 c := TestContext()
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -070088 tt := &testTransport{}
89 c.UseCustomClient(&http.Client{
90 Transport: tt,
91 })
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -070092
93 _, err := c.Authenticate("", AuthOptions{})
94 if err == nil {
95 t.Error("Expected error for empty provider string")
96 return
97 }
98 _, err = c.Authenticate("unknown-provider", AuthOptions{Username: "u", Password: "p"})
99 if err == nil {
100 t.Error("Expected error for unknown service provider")
101 return
102 }
103
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -0700104 err = c.RegisterProvider("provider", &Provider{AuthEndpoint: "/"})
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -0700105 if err != nil {
106 t.Error(err)
107 return
108 }
109 _, err = c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
110 if err != nil {
111 t.Error(err)
112 return
113 }
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -0700114 if tt.called != 1 {
115 t.Error("Expected transport to be called once.")
116 return
117 }
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -0700118}
119
Samuel A. Falvo II978fed82013-06-25 17:59:19 -0700120func TestTenantIdEncoding(t *testing.T) {
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -0700121 c := TestContext()
Samuel A. Falvo II978fed82013-06-25 17:59:19 -0700122 tt := &tenantIdCheckTransport{}
123 c.UseCustomClient(&http.Client{
124 Transport: tt,
125 })
Samuel A. Falvo II5d0d74c2013-06-25 17:23:18 -0700126 c.RegisterProvider("provider", &Provider{AuthEndpoint: "/"})
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -0700127
Samuel A. Falvo II978fed82013-06-25 17:59:19 -0700128 tt.expectTenantId = false
129 _, err := c.Authenticate("provider", AuthOptions{
130 Username: "u",
131 Password: "p",
132 })
133 if err != nil {
134 t.Error(err)
135 return
136 }
137 if tt.tenantIdFound {
138 t.Error("Tenant ID should not have been encoded")
139 return
140 }
141
142 tt.expectTenantId = true
143 _, err = c.Authenticate("provider", AuthOptions{
144 Username: "u",
145 Password: "p",
146 TenantId: "t",
147 })
148 if err != nil {
149 t.Error(err)
150 return
151 }
152 if !tt.tenantIdFound {
153 t.Error("Tenant ID should have been encoded")
154 return
155 }
156}
157
158func TestUserNameAndPassword(t *testing.T) {
159 c := TestContext()
160 c.UseCustomClient(&http.Client{Transport: &testTransport{}})
161 c.RegisterProvider("provider", &Provider{AuthEndpoint: "http://localhost/"})
162
163 credentials := []AuthOptions{
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -0700164 AuthOptions{},
165 AuthOptions{Username: "u"},
166 AuthOptions{Password: "p"},
167 }
Samuel A. Falvo II978fed82013-06-25 17:59:19 -0700168 for i, auth := range credentials {
Samuel A. Falvo IIfd78c302013-06-25 16:35:32 -0700169 _, err := c.Authenticate("provider", auth)
170 if err == nil {
171 t.Error("Expected error from missing credentials (%d)", i)
172 return
173 }
174 }
175
176 _, err := c.Authenticate("provider", AuthOptions{Username: "u", Password: "p"})
177 if err != nil {
178 t.Error(err)
179 return
180 }
181}