1 package storage
2
3
4
5
6 import (
7 "encoding/base64"
8 "net/http"
9
10 chk "gopkg.in/check.v1"
11 )
12
13 type AuthorizationSuite struct{}
14
15 var _ = chk.Suite(&AuthorizationSuite{})
16
17 func (a *AuthorizationSuite) Test_addAuthorizationHeader(c *chk.C) {
18 cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey)
19 c.Assert(err, chk.IsNil)
20 cli.UseSharedKeyLite = true
21 tableCli := cli.GetTableService()
22
23 headers := map[string]string{
24 "Accept-Charset": "UTF-8",
25 headerContentType: "application/json",
26 headerXmsDate: "Wed, 23 Sep 2015 16:40:05 GMT",
27 headerContentLength: "0",
28 headerXmsVersion: "2015-02-21",
29 "Accept": "application/json;odata=nometadata",
30 }
31 url := "https://golangrocksonazure.table.core.windows.net/tquery()"
32 headers, err = tableCli.client.addAuthorizationHeader("", url, headers, tableCli.auth)
33 c.Assert(err, chk.IsNil)
34
35 c.Assert(headers[headerAuthorization], chk.Equals, "SharedKeyLite golangrocksonazure:NusXSFXAvHqr6EQNXnZZ50CvU1sX0iP/FFDHehnixLc=")
36 }
37
38 func (a *AuthorizationSuite) Test_getSharedKey(c *chk.C) {
39
40 cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey)
41 c.Assert(err, chk.IsNil)
42
43 headers := map[string]string{
44 "Accept-Charset": "UTF-8",
45 headerContentType: "application/json",
46 headerXmsDate: "Wed, 23 Sep 2015 16:40:05 GMT",
47 headerContentLength: "0",
48 headerXmsVersion: "2015-02-21",
49 "Accept": "application/json;odata=nometadata",
50 }
51 url := "https://golangrocksonazure.table.core.windows.net/tquery()"
52
53 key, err := cli.getSharedKey("", url, headers, sharedKeyLiteForTable)
54 c.Assert(err, chk.IsNil)
55 c.Assert(key, chk.Equals, "SharedKeyLite golangrocksonazure:NusXSFXAvHqr6EQNXnZZ50CvU1sX0iP/FFDHehnixLc=")
56 }
57
58 func (a *AuthorizationSuite) Test_buildCanonicalizedResource(c *chk.C) {
59 cli, err := NewBasicClient(dummyStorageAccount, dummyMiniStorageKey)
60 c.Assert(err, chk.IsNil)
61
62 type test struct {
63 url string
64 auth authentication
65 expected string
66 sas bool
67 }
68 tests := []test{
69
70 {"https://golangrocksonazure.blob.core.windows.net/path?a=b&c=d", sharedKey, "/golangrocksonazure/path\na:b\nc:d", false},
71 {"https://golangrocksonazure.blob.core.windows.net/?comp=list", sharedKey, "/golangrocksonazure/\ncomp:list", false},
72 {"https://golangrocksonazure.blob.core.windows.net/cnt/blob", sharedKey, "/golangrocksonazure/cnt/blob", false},
73 {"https://golangrocksonazure.blob.core.windows.net/cnt/bl ob", sharedKey, "/golangrocksonazure/cnt/bl%20ob", false},
74 {"https://golangrocksonazure.blob.core.windows.net/c nt/blob", sharedKey, "/golangrocksonazure/c%20nt/blob", false},
75 {"https://golangrocksonazure.blob.core.windows.net/cnt/blob%3F%23%5B%5D%21$&%27%28%29%2A blob", sharedKey, "/golangrocksonazure/cnt/blob%3F%23%5B%5D%21$&%27%28%29%2A%20blob", false},
76 {"https://golangrocksonazure.blob.core.windows.net/cnt/blob-._~:,@;+=blob", sharedKey, "/golangrocksonazure/cnt/blob-._~:,@;+=blob", false},
77 {"https://golangrocksonazure.blob.core.windows.net/c nt/blob-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=/blob", sharedKey, "/golangrocksonazure/c%20nt/blob-._~:%3F%23%5B%5D@%21$&%27%28%29%2A,;+=/blob", false},
78
79 {"https://golangrocksonazure.table.core.windows.net/mytable", sharedKeyLiteForTable, "/golangrocksonazure/mytable", false},
80 {"https://golangrocksonazure.table.core.windows.net/mytable?comp=acl", sharedKeyLiteForTable, "/golangrocksonazure/mytable?comp=acl", false},
81 {"https://golangrocksonazure.table.core.windows.net/mytable?comp=acl&timeout=10", sharedKeyForTable, "/golangrocksonazure/mytable?comp=acl", false},
82 {"https://golangrocksonazure.table.core.windows.net/mytable(PartitionKey='pkey',RowKey='rowkey%3D')", sharedKeyForTable, "/golangrocksonazure/mytable(PartitionKey='pkey',RowKey='rowkey%3D')", false},
83
84 {"https://golangrocksonazure.blob.core.windows.net/cnt/blob", sharedKey, "/golangrocksonazure/cnt/blob", true},
85 }
86
87 for _, t := range tests {
88 out, err := cli.buildCanonicalizedResource(t.url, t.auth, t.sas)
89 c.Assert(err, chk.IsNil)
90 c.Assert(out, chk.Equals, t.expected)
91 }
92
93 eCli, err := NewEmulatorClient()
94 c.Assert(err, chk.IsNil)
95 eTests := []test{
96 {"http://127.0.0.1:10000/devstoreaccount1/cnt/blob", sharedKey, "/devstoreaccount1/cnt/blob", true},
97 {"http://127.0.0.1:10000/devstoreaccount1/cnt/blob", sharedKey, "/devstoreaccount1/devstoreaccount1/cnt/blob", false},
98 }
99 for _, t := range eTests {
100 out, err := eCli.buildCanonicalizedResource(t.url, t.auth, t.sas)
101 c.Assert(err, chk.IsNil)
102 c.Assert(out, chk.Equals, t.expected)
103 }
104 }
105
106 func (a *AuthorizationSuite) Test_buildCanonicalizedString(c *chk.C) {
107 var tests = []struct {
108 verb string
109 headers map[string]string
110 canonicalizedResource string
111 auth authentication
112 out string
113 }{
114 {
115
116 verb: http.MethodGet,
117 headers: map[string]string{
118 headerXmsDate: "Sun, 11 Oct 2009 21:49:13 GMT",
119 headerXmsVersion: "2009-09-19",
120 },
121 canonicalizedResource: "/myaccount/ mycontainer\ncomp:metadata\nrestype:container\ntimeout:20",
122 auth: sharedKey,
123 out: "GET\n\n\n\n\n\n\n\n\n\n\n\nx-ms-date:Sun, 11 Oct 2009 21:49:13 GMT\nx-ms-version:2009-09-19\n/myaccount/ mycontainer\ncomp:metadata\nrestype:container\ntimeout:20",
124 },
125 {
126
127 verb: http.MethodPut,
128 headers: map[string]string{
129 headerContentType: "text/plain; charset=UTF-8",
130 headerDate: "Sun, 11 Oct 2009 19:52:39 GMT",
131 },
132 canonicalizedResource: "/testaccount1/Tables",
133 auth: sharedKeyForTable,
134 out: "PUT\n\ntext/plain; charset=UTF-8\nSun, 11 Oct 2009 19:52:39 GMT\n/testaccount1/Tables",
135 },
136 {
137
138 verb: http.MethodPut,
139 headers: map[string]string{
140 headerContentType: "text/plain; charset=UTF-8",
141 headerXmsDate: "Sun, 20 Sep 2009 20:36:40 GMT",
142 "x-ms-meta-m1": "v1",
143 "x-ms-meta-m2": "v2",
144 },
145 canonicalizedResource: "/testaccount1/mycontainer/hello.txt",
146 auth: sharedKeyLite,
147 out: "PUT\n\ntext/plain; charset=UTF-8\n\nx-ms-date:Sun, 20 Sep 2009 20:36:40 GMT\nx-ms-meta-m1:v1\nx-ms-meta-m2:v2\n/testaccount1/mycontainer/hello.txt",
148 },
149 {
150
151 verb: "",
152 headers: map[string]string{
153 headerDate: "Sun, 11 Oct 2009 19:52:39 GMT",
154 },
155 canonicalizedResource: "/testaccount1/Tables",
156 auth: sharedKeyLiteForTable,
157 out: "Sun, 11 Oct 2009 19:52:39 GMT\n/testaccount1/Tables",
158 },
159 }
160
161 for _, t := range tests {
162 canonicalizedString, err := buildCanonicalizedString(t.verb, t.headers, t.canonicalizedResource, t.auth)
163 c.Assert(err, chk.IsNil)
164 c.Assert(canonicalizedString, chk.Equals, t.out)
165 }
166 }
167
168 func (a *AuthorizationSuite) Test_buildCanonicalizedHeader(c *chk.C) {
169 type test struct {
170 headers map[string]string
171 expected string
172 }
173 tests := []test{
174 {map[string]string{},
175 ""},
176 {map[string]string{
177 "x-ms-lol": "rofl"},
178 "x-ms-lol:rofl"},
179 {map[string]string{
180 "lol:": "rofl"},
181 ""},
182 {map[string]string{
183 "lol:": "rofl",
184 "x-ms-lol": "rofl"},
185 "x-ms-lol:rofl"},
186 {map[string]string{
187 "x-ms-version": "9999-99-99",
188 "x-ms-blob-type": "BlockBlob"},
189 "x-ms-blob-type:BlockBlob\nx-ms-version:9999-99-99"}}
190
191 for _, i := range tests {
192 c.Assert(buildCanonicalizedHeader(i.headers), chk.Equals, i.expected)
193 }
194 }
195
196 func (a *AuthorizationSuite) Test_createAuthorizationHeader(c *chk.C) {
197 cli, err := NewBasicClient(dummyStorageAccount, base64.StdEncoding.EncodeToString([]byte("bar")))
198 c.Assert(err, chk.IsNil)
199
200 canonicalizedString := `foobarzoo`
201
202 c.Assert(cli.createAuthorizationHeader(canonicalizedString, sharedKey),
203 chk.Equals, `SharedKey golangrocksonazure:h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=`)
204 c.Assert(cli.createAuthorizationHeader(canonicalizedString, sharedKeyLite),
205 chk.Equals, `SharedKeyLite golangrocksonazure:h5U0ATVX6SpbFX1H6GNuxIMeXXCILLoIvhflPtuQZ30=`)
206 }
207
208 func (a *AuthorizationSuite) Test_allSharedKeys(c *chk.C) {
209 cli := getBasicClient(c)
210 rec := cli.appendRecorder(c)
211 defer rec.Stop()
212
213 blobCli := cli.GetBlobService()
214 tableCli := cli.GetTableService()
215
216 cnt1 := blobCli.GetContainerReference(containerName(c, "1"))
217 cnt2 := blobCli.GetContainerReference(containerName(c, "2"))
218
219
220 c.Assert(blobCli.auth, chk.Equals, sharedKey)
221 c.Assert(cnt1.Create(nil), chk.IsNil)
222 c.Assert(cnt1.Delete(nil), chk.IsNil)
223
224
225 c.Assert(tableCli.auth, chk.Equals, sharedKeyForTable)
226 table1 := tableCli.GetTableReference(tableName(c, "1"))
227 c.Assert(table1.tsc.auth, chk.Equals, sharedKeyForTable)
228 c.Assert(table1.Create(30, EmptyPayload, nil), chk.IsNil)
229 c.Assert(table1.Delete(30, nil), chk.IsNil)
230
231
232 cli.UseSharedKeyLite = true
233 blobCli = cli.GetBlobService()
234 tableCli = cli.GetTableService()
235
236
237 c.Assert(blobCli.auth, chk.Equals, sharedKeyLite)
238 c.Assert(cnt2.Create(nil), chk.IsNil)
239 c.Assert(cnt2.Delete(nil), chk.IsNil)
240
241
242 tableCli = cli.GetTableService()
243 c.Assert(tableCli.auth, chk.Equals, sharedKeyLiteForTable)
244 table2 := tableCli.GetTableReference(tableName(c, "2"))
245 c.Assert(table2.tsc.auth, chk.Equals, sharedKeyLiteForTable)
246 c.Assert(table2.Create(30, EmptyPayload, nil), chk.IsNil)
247 c.Assert(table2.Delete(30, nil), chk.IsNil)
248 }
249
View as plain text