user_test.go 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "net/http"
  6. "os"
  7. "sync"
  8. "testing"
  9. "time"
  10. controller "github.com/gravitl/netmaker/controllers"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/mongoconn"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. type databaseError struct {
  16. Inner *int
  17. Errors int
  18. }
  19. //should be use models.SuccessResponse and models.SuccessfulUserLoginResponse
  20. //rather than creating new type but having trouble decoding that way
  21. type Auth struct {
  22. Username string
  23. AuthToken string
  24. }
  25. type Success struct {
  26. Code int
  27. Message string
  28. Response Auth
  29. }
  30. type AuthorizeTestCase struct {
  31. testname string
  32. name string
  33. password string
  34. code int
  35. tokenExpected bool
  36. errMessage string
  37. }
  38. func TestMain(m *testing.M) {
  39. mongoconn.ConnectDatabase()
  40. var waitgroup sync.WaitGroup
  41. waitgroup.Add(1)
  42. go controller.HandleRESTRequests(&waitgroup)
  43. //wait for http server to start
  44. time.Sleep(time.Second * 1)
  45. os.Exit(m.Run())
  46. }
  47. func TestUsers(t *testing.T) {
  48. // t.Run("check that admin user does not exist", func(t *testing.T) {
  49. // response := checkAdminExists(t)
  50. // assert.Equal(t, false, response)
  51. // })
  52. }
  53. func TestAdminCreation(t *testing.T) {
  54. var admin models.UserAuthParams
  55. var user models.User
  56. admin.UserName = "admin"
  57. admin.Password = "password"
  58. t.Run("AdminCreationSuccess", func(t *testing.T) {
  59. if adminExists(t) {
  60. deleteAdmin(t)
  61. }
  62. response, err := api(t, admin, http.MethodPost, "http://localhost:8081/users/createadmin", "")
  63. assert.Nil(t, err, err)
  64. defer response.Body.Close()
  65. err = json.NewDecoder(response.Body).Decode(&user)
  66. assert.Nil(t, err, err)
  67. assert.Equal(t, admin.UserName, user.UserName)
  68. assert.Equal(t, true, user.IsAdmin)
  69. assert.Equal(t, http.StatusOK, response.StatusCode)
  70. assert.True(t, adminExists(t), "Admin creation failed")
  71. })
  72. t.Run("AdminCreationFailure", func(t *testing.T) {
  73. if !adminExists(t) {
  74. addAdmin(t)
  75. }
  76. response, err := api(t, admin, http.MethodPost, "http://localhost:8081/users/createadmin", "")
  77. assert.Nil(t, err, err)
  78. defer response.Body.Close()
  79. var message models.ErrorResponse
  80. err = json.NewDecoder(response.Body).Decode(&message)
  81. assert.Nil(t, err, err)
  82. assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
  83. assert.Equal(t, http.StatusUnauthorized, message.Code)
  84. assert.Equal(t, "W1R3: Admin already exists! ", message.Message)
  85. })
  86. }
  87. func TestGetUser(t *testing.T) {
  88. //ensure admin exists
  89. if !adminExists(t) {
  90. addAdmin(t)
  91. }
  92. //authenticate
  93. t.Run("GetUserWithValidToken", func(t *testing.T) {
  94. token, err := authenticate(t)
  95. assert.Nil(t, err, err)
  96. response, err := api(t, "", http.MethodGet, "http://localhost:8081/users/admin", token)
  97. assert.Nil(t, err, err)
  98. defer response.Body.Close()
  99. var user models.User
  100. json.NewDecoder(response.Body).Decode(&user)
  101. assert.Equal(t, http.StatusOK, response.StatusCode)
  102. assert.Equal(t, "admin", user.UserName)
  103. assert.Equal(t, true, user.IsAdmin)
  104. })
  105. t.Run("GetUserWithInvalidToken", func(t *testing.T) {
  106. //skip until sort out what should be returned
  107. response, err := api(t, "", http.MethodGet, "http://localhost:8081/users/admin", "secretkey")
  108. assert.Nil(t, err, err)
  109. defer response.Body.Close()
  110. ///not sure what this should be
  111. t.Log(response.Body)
  112. //var something string
  113. //json.NewDecoder(response.Body).Decode(something)
  114. //assert.Equal(t, "Some error message", something)
  115. })
  116. }
  117. func TestUpdateUser(t *testing.T) {
  118. if !adminExists(t) {
  119. addAdmin(t)
  120. }
  121. token, err := authenticate(t)
  122. assert.Nil(t, err, err)
  123. var admin models.UserAuthParams
  124. var user models.User
  125. var message models.ErrorResponse
  126. t.Run("UpdateWrongToken", func(t *testing.T) {
  127. admin.UserName = "admin"
  128. admin.Password = "admin"
  129. response, err := api(t, admin, http.MethodPut, "http://localhost:8081/users/admin", "secretkey")
  130. assert.Nil(t, err, err)
  131. defer response.Body.Close()
  132. err = json.NewDecoder(response.Body).Decode(&message)
  133. assert.Nil(t, err, err)
  134. assert.Equal(t, "W1R3: Error Verifying Auth Token.", message.Message)
  135. assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
  136. })
  137. t.Run("UpdateSuccess", func(t *testing.T) {
  138. admin.UserName = "admin"
  139. admin.Password = "password"
  140. response, err := api(t, admin, http.MethodPut, "http://localhost:8081/users/admin", token)
  141. assert.Nil(t, err, err)
  142. defer response.Body.Close()
  143. err = json.NewDecoder(response.Body).Decode(&user)
  144. assert.Nil(t, err, err)
  145. assert.Equal(t, admin.UserName, user.UserName)
  146. assert.Equal(t, true, user.IsAdmin)
  147. assert.Equal(t, http.StatusOK, response.StatusCode)
  148. })
  149. }
  150. func TestDeleteUser(t *testing.T) {
  151. if !adminExists(t) {
  152. addAdmin(t)
  153. }
  154. token, err := authenticate(t)
  155. assert.Nil(t, err, err)
  156. t.Run("DeleteUser-WongAdmin", func(t *testing.T) {
  157. //skip for now ... shouldn't panic
  158. t.Skip()
  159. function := func() {
  160. _, _ = api(t, "", http.MethodDelete, "http://localhost:8081/users/xxxx", token)
  161. }
  162. assert.Panics(t, function, "")
  163. })
  164. t.Run("DeleteUser-InvalidCredentials", func(t *testing.T) {
  165. response, err := api(t, "", http.MethodDelete, "http://localhost:8081/users/admin", "secretkey")
  166. assert.Nil(t, err, err)
  167. var message models.ErrorResponse
  168. json.NewDecoder(response.Body).Decode(&message)
  169. assert.Equal(t, "W1R3: Error Verifying Auth Token.", message.Message)
  170. assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
  171. })
  172. t.Run("DeleteUser-ValidCredentials", func(t *testing.T) {
  173. response, err := api(t, "", http.MethodDelete, "http://localhost:8081/users/admin", token)
  174. assert.Nil(t, err, err)
  175. var body string
  176. json.NewDecoder(response.Body).Decode(&body)
  177. assert.Equal(t, "admin deleted.", body)
  178. assert.Equal(t, http.StatusOK, response.StatusCode)
  179. })
  180. t.Run("DeletUser-NoAdmin", func(t *testing.T) {
  181. //skip for now ... shouldn't panic
  182. t.Skip()
  183. function := func() {
  184. _, _ = api(t, "", http.MethodDelete, "http://localhost:8081/users/admin", token)
  185. }
  186. assert.Panics(t, function, "")
  187. })
  188. addAdmin(t)
  189. }
  190. func TestAuthenticateUser(t *testing.T) {
  191. cases := []AuthorizeTestCase{
  192. AuthorizeTestCase{
  193. testname: "Invalid User",
  194. name: "invaliduser",
  195. password: "password",
  196. code: http.StatusBadRequest,
  197. tokenExpected: false,
  198. errMessage: "W1R3: User invaliduser not found.",
  199. },
  200. AuthorizeTestCase{
  201. testname: "empty user",
  202. name: "",
  203. password: "password",
  204. code: http.StatusBadRequest,
  205. tokenExpected: false,
  206. errMessage: "W1R3: Username can't be empty",
  207. },
  208. AuthorizeTestCase{
  209. testname: "empty password",
  210. name: "admin",
  211. password: "",
  212. code: http.StatusBadRequest,
  213. tokenExpected: false,
  214. errMessage: "W1R3: Password can't be empty",
  215. },
  216. AuthorizeTestCase{
  217. testname: "Invalid Passord",
  218. name: "admin",
  219. password: "xxxxxxx",
  220. code: http.StatusUnauthorized,
  221. tokenExpected: false,
  222. errMessage: "W1R3: Wrong Password.",
  223. },
  224. AuthorizeTestCase{
  225. testname: "Valid User",
  226. name: "admin",
  227. password: "password",
  228. code: http.StatusOK,
  229. tokenExpected: true,
  230. errMessage: "W1R3: Device Admin Authorized",
  231. },
  232. }
  233. if !adminExists(t) {
  234. addAdmin(t)
  235. }
  236. for _, tc := range cases {
  237. t.Run(tc.testname, func(t *testing.T) {
  238. var admin models.User
  239. admin.UserName = tc.name
  240. admin.Password = tc.password
  241. response, err := api(t, admin, http.MethodPost, "http://localhost:8081/users/authenticate", "secretkey")
  242. assert.Nil(t, err, err)
  243. defer response.Body.Close()
  244. if tc.tokenExpected {
  245. var body Success
  246. err = json.NewDecoder(response.Body).Decode(&body)
  247. assert.Nil(t, err, err)
  248. assert.NotEmpty(t, body.Response.AuthToken, "token not returned")
  249. assert.Equal(t, "W1R3: Device admin Authorized", body.Message)
  250. } else {
  251. var bad models.ErrorResponse
  252. json.NewDecoder(response.Body).Decode(&bad)
  253. assert.Equal(t, tc.errMessage, bad.Message)
  254. }
  255. assert.Equal(t, tc.code, response.StatusCode)
  256. })
  257. }
  258. }
  259. func adminExists(t *testing.T) bool {
  260. response, err := http.Get("http://localhost:8081/users/hasadmin")
  261. assert.Nil(t, err, err)
  262. assert.Equal(t, http.StatusOK, response.StatusCode)
  263. defer response.Body.Close()
  264. var body bool
  265. json.NewDecoder(response.Body).Decode(&body)
  266. return body
  267. }
  268. func api(t *testing.T, data interface{}, method, url, authorization string) (*http.Response, error) {
  269. var request *http.Request
  270. var err error
  271. if data != "" {
  272. payload, err := json.Marshal(data)
  273. assert.Nil(t, err, err)
  274. request, err = http.NewRequest(method, url, bytes.NewBuffer(payload))
  275. assert.Nil(t, err, err)
  276. request.Header.Set("Content-Type", "application/json")
  277. } else {
  278. request, err = http.NewRequest(method, url, nil)
  279. assert.Nil(t, err, err)
  280. }
  281. if authorization != "" {
  282. request.Header.Set("Authorization", "Bearer "+authorization)
  283. }
  284. client := http.Client{}
  285. return client.Do(request)
  286. }
  287. func addAdmin(t *testing.T) {
  288. var admin models.User
  289. admin.UserName = "admin"
  290. admin.Password = "password"
  291. response, err := api(t, admin, http.MethodPost, "http://localhost:8081/users/createadmin", "secretkey")
  292. assert.Nil(t, err, err)
  293. assert.Equal(t, http.StatusOK, response.StatusCode)
  294. }
  295. func authenticate(t *testing.T) (string, error) {
  296. var admin models.User
  297. admin.UserName = "admin"
  298. admin.Password = "password"
  299. response, err := api(t, admin, http.MethodPost, "http://localhost:8081/users/authenticate", "secretkey")
  300. assert.Nil(t, err, err)
  301. var body Success
  302. err = json.NewDecoder(response.Body).Decode(&body)
  303. assert.Nil(t, err, err)
  304. assert.NotEmpty(t, body.Response.AuthToken, "token not returned")
  305. assert.Equal(t, "W1R3: Device admin Authorized", body.Message)
  306. return body.Response.AuthToken, nil
  307. }
  308. func deleteAdmin(t *testing.T) {
  309. if !adminExists(t) {
  310. return
  311. }
  312. token, err := authenticate(t)
  313. assert.Nil(t, err, err)
  314. _, err = api(t, "", http.MethodDelete, "http://localhost:8081/users/admin", token)
  315. assert.Nil(t, err, err)
  316. }