security_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // Copyright 2015 CoreOS, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package security
  15. import (
  16. "reflect"
  17. "testing"
  18. "time"
  19. "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/crypto/bcrypt"
  20. "github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
  21. "github.com/coreos/etcd/etcdserver"
  22. "github.com/coreos/etcd/etcdserver/etcdserverpb"
  23. "github.com/coreos/etcd/store"
  24. )
  25. func TestMergeUser(t *testing.T) {
  26. tbl := []struct {
  27. input User
  28. merge User
  29. expect User
  30. iserr bool
  31. }{
  32. {
  33. User{User: "foo"},
  34. User{User: "bar"},
  35. User{},
  36. true,
  37. },
  38. {
  39. User{User: "foo"},
  40. User{User: "foo"},
  41. User{User: "foo", Roles: []string{}},
  42. false,
  43. },
  44. {
  45. User{User: "foo"},
  46. User{User: "foo", Grant: []string{"role1"}},
  47. User{User: "foo", Roles: []string{"role1"}},
  48. false,
  49. },
  50. {
  51. User{User: "foo", Roles: []string{"role1"}},
  52. User{User: "foo", Grant: []string{"role1"}},
  53. User{},
  54. true,
  55. },
  56. {
  57. User{User: "foo", Roles: []string{"role1"}},
  58. User{User: "foo", Revoke: []string{"role2"}},
  59. User{},
  60. true,
  61. },
  62. {
  63. User{User: "foo", Roles: []string{"role1"}},
  64. User{User: "foo", Grant: []string{"role2"}},
  65. User{User: "foo", Roles: []string{"role1", "role2"}},
  66. false,
  67. },
  68. {
  69. User{User: "foo"},
  70. User{User: "foo", Password: "bar"},
  71. User{User: "foo", Roles: []string{}, Password: "$2a$10$aUPOdbOGNawaVSusg3g2wuC3AH6XxIr9/Ms4VgDvzrAVOJPYzZILa"},
  72. false,
  73. },
  74. }
  75. for i, tt := range tbl {
  76. out, err := tt.input.Merge(tt.merge)
  77. if err != nil && !tt.iserr {
  78. t.Fatalf("Got unexpected error on item %d", i)
  79. }
  80. if !tt.iserr {
  81. err := bcrypt.CompareHashAndPassword([]byte(out.Password), []byte(tt.merge.Password))
  82. if err == nil {
  83. tt.expect.Password = out.Password
  84. }
  85. if !reflect.DeepEqual(out, tt.expect) {
  86. t.Errorf("Unequal merge expectation on item %d: got: %#v, expect: %#v", i, out, tt.expect)
  87. }
  88. }
  89. }
  90. }
  91. func TestMergeRole(t *testing.T) {
  92. tbl := []struct {
  93. input Role
  94. merge Role
  95. expect Role
  96. iserr bool
  97. }{
  98. {
  99. Role{Role: "foo"},
  100. Role{Role: "bar"},
  101. Role{},
  102. true,
  103. },
  104. {
  105. Role{Role: "foo"},
  106. Role{Role: "foo", Grant: Permissions{KV: rwPermission{Read: []string{"/foodir"}, Write: []string{"/foodir"}}}},
  107. Role{Role: "foo", Permissions: Permissions{KV: rwPermission{Read: []string{"/foodir"}, Write: []string{"/foodir"}}}},
  108. false,
  109. },
  110. {
  111. Role{Role: "foo", Permissions: Permissions{KV: rwPermission{Read: []string{"/foodir"}, Write: []string{"/foodir"}}}},
  112. Role{Role: "foo", Revoke: Permissions{KV: rwPermission{Read: []string{"/foodir"}, Write: []string{"/foodir"}}}},
  113. Role{Role: "foo", Permissions: Permissions{KV: rwPermission{Read: []string{}, Write: []string{}}}},
  114. false,
  115. },
  116. {
  117. Role{Role: "foo", Permissions: Permissions{KV: rwPermission{Read: []string{"/bardir"}}}},
  118. Role{Role: "foo", Revoke: Permissions{KV: rwPermission{Read: []string{"/foodir"}}}},
  119. Role{},
  120. true,
  121. },
  122. }
  123. for i, tt := range tbl {
  124. out, err := tt.input.Merge(tt.merge)
  125. if err != nil && !tt.iserr {
  126. t.Fatalf("Got unexpected error on item %d", i)
  127. }
  128. if !tt.iserr {
  129. if !reflect.DeepEqual(out, tt.expect) {
  130. t.Errorf("Unequal merge expectation on item %d: got: %#v, expect: %#v", i, out, tt.expect)
  131. }
  132. }
  133. }
  134. }
  135. type testDoer struct {
  136. get etcdserver.Response
  137. }
  138. func (td *testDoer) Do(_ context.Context, req etcdserverpb.Request) (etcdserver.Response, error) {
  139. if req.Method == "GET" {
  140. return td.get, nil
  141. }
  142. return etcdserver.Response{}, nil
  143. }
  144. func TestAllUsers(t *testing.T) {
  145. d := &testDoer{
  146. etcdserver.Response{
  147. Event: &store.Event{
  148. Action: store.Get,
  149. Node: &store.NodeExtern{
  150. Nodes: store.NodeExterns{
  151. &store.NodeExtern{
  152. Key: StorePermsPrefix + "/users/cat",
  153. },
  154. &store.NodeExtern{
  155. Key: StorePermsPrefix + "/users/dog",
  156. },
  157. },
  158. },
  159. },
  160. },
  161. }
  162. expected := []string{"cat", "dog"}
  163. s := NewStore(d, time.Second)
  164. users, err := s.AllUsers()
  165. if err != nil {
  166. t.Error("Unexpected error", err)
  167. }
  168. if !reflect.DeepEqual(users, expected) {
  169. t.Error("AllUsers doesn't match given store. Got", users, "expected", expected)
  170. }
  171. }
  172. func TestGetAndDeleteUser(t *testing.T) {
  173. data := `{"user": "cat", "roles" : ["animal"]}`
  174. d := &testDoer{
  175. etcdserver.Response{
  176. Event: &store.Event{
  177. Action: store.Get,
  178. Node: &store.NodeExtern{
  179. Key: StorePermsPrefix + "/users/cat",
  180. Value: &data,
  181. },
  182. },
  183. },
  184. }
  185. expected := User{User: "cat", Roles: []string{"animal"}}
  186. s := NewStore(d, time.Second)
  187. out, err := s.GetUser("cat")
  188. if err != nil {
  189. t.Error("Unexpected error", err)
  190. }
  191. if !reflect.DeepEqual(out, expected) {
  192. t.Error("GetUser doesn't match given store. Got", out, "expected", expected)
  193. }
  194. err = s.DeleteUser("cat")
  195. if err != nil {
  196. t.Error("Unexpected error", err)
  197. }
  198. }
  199. func TestAllRoles(t *testing.T) {
  200. d := &testDoer{
  201. etcdserver.Response{
  202. Event: &store.Event{
  203. Action: store.Get,
  204. Node: &store.NodeExtern{
  205. Nodes: store.NodeExterns{
  206. &store.NodeExtern{
  207. Key: StorePermsPrefix + "/roles/animal",
  208. },
  209. &store.NodeExtern{
  210. Key: StorePermsPrefix + "/roles/human",
  211. },
  212. },
  213. },
  214. },
  215. },
  216. }
  217. expected := []string{"animal", "human"}
  218. s := NewStore(d, time.Second)
  219. out, err := s.AllRoles()
  220. if err != nil {
  221. t.Error("Unexpected error", err)
  222. }
  223. if !reflect.DeepEqual(out, expected) {
  224. t.Error("AllUsers doesn't match given store. Got", out, "expected", expected)
  225. }
  226. }
  227. func TestGetAndDeleteRole(t *testing.T) {
  228. data := `{"role": "animal"}`
  229. d := &testDoer{
  230. etcdserver.Response{
  231. Event: &store.Event{
  232. Action: store.Get,
  233. Node: &store.NodeExtern{
  234. Key: StorePermsPrefix + "/roles/animal",
  235. Value: &data,
  236. },
  237. },
  238. },
  239. }
  240. expected := Role{Role: "animal"}
  241. s := NewStore(d, time.Second)
  242. out, err := s.GetRole("animal")
  243. if err != nil {
  244. t.Error("Unexpected error", err)
  245. }
  246. if !reflect.DeepEqual(out, expected) {
  247. t.Error("GetRole doesn't match given store. Got", out, "expected", expected)
  248. }
  249. err = s.DeleteRole("animal")
  250. if err != nil {
  251. t.Error("Unexpected error", err)
  252. }
  253. }