user_test.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "io/ioutil"
  6. "net/http"
  7. "os"
  8. "sync"
  9. "testing"
  10. "time"
  11. controller "github.com/gravitl/netmaker/controllers"
  12. "github.com/gravitl/netmaker/models"
  13. "github.com/gravitl/netmaker/mongoconn"
  14. "github.com/stretchr/testify/assert"
  15. )
  16. //change this --- there is an existing type
  17. type AuthorizationResponse struct {
  18. Username string
  19. AuthToken string
  20. }
  21. type goodResponse struct {
  22. Code int
  23. Message string
  24. Response AuthorizationResponse
  25. }
  26. type badResponse struct {
  27. Code int
  28. Message string
  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. t.Run("Admin Creation", func(t *testing.T) {
  53. var admin, user models.User
  54. admin.UserName = "admin"
  55. admin.Password = "password"
  56. if !adminExists(t) {
  57. t.Run("AdminCreationValid", func(t *testing.T) {
  58. response, err := api(admin, http.MethodPost, "http://localhost:8081/users/createadmin", "")
  59. if err != nil {
  60. t.Error("error calling createadmin", err)
  61. }
  62. defer response.Body.Close()
  63. json.NewDecoder(response.Body).Decode(&user)
  64. assert.Equal(t, admin.UserName, user.UserName)
  65. assert.Equal(t, true, user.IsAdmin)
  66. assert.Equal(t, http.StatusOK, response.StatusCode)
  67. assert.True(t, adminExists(t), "Admin creation failed")
  68. })
  69. t.Run("AdminCreationInvalid", func(t *testing.T) {
  70. response, err := api(admin, http.MethodPost, "http://localhost:8081/users/createadmin", "")
  71. if err != nil {
  72. t.Error("error calling createadmin", err)
  73. }
  74. defer response.Body.Close()
  75. var message badResponse
  76. json.NewDecoder(response.Body).Decode(&message)
  77. assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
  78. assert.Equal(t, http.StatusUnauthorized, message.Code)
  79. assert.Equal(t, "W1R3: Admin already exists! ", message.Message)
  80. })
  81. } else {
  82. t.Run("AdminCreationInvalid", func(t *testing.T) {
  83. response, err := api(admin, http.MethodPost, "http://localhost:8081/users/createadmin", "")
  84. if err != nil {
  85. t.Error("error calling createadmin", err)
  86. }
  87. defer response.Body.Close()
  88. var message badResponse
  89. json.NewDecoder(response.Body).Decode(&message)
  90. assert.Equal(t, http.StatusUnauthorized, response.StatusCode)
  91. assert.Equal(t, http.StatusUnauthorized, message.Code)
  92. assert.Equal(t, "W1R3: Admin already exists! ", message.Message)
  93. })
  94. //deleteAdmin()
  95. t.Run("Admin Creation - Valid", func(t *testing.T) {
  96. t.Skip()
  97. response, err := api(admin, http.MethodPost, "http://localhost:8081/users/createadmin", "")
  98. if err != nil {
  99. t.Error("error calling createadmin", err)
  100. }
  101. defer response.Body.Close()
  102. json.NewDecoder(response.Body).Decode(&user)
  103. assert.Equal(t, admin.UserName, user.UserName)
  104. assert.Equal(t, true, user.IsAdmin)
  105. assert.Equal(t, http.StatusOK, response.StatusCode)
  106. assert.True(t, adminExists(t), "Admin creation failed")
  107. })
  108. }
  109. })
  110. t.Run("GetUser", func(t *testing.T) {
  111. //ensure admin exists
  112. if !adminExists(t) {
  113. t.Error("admin account does not exist")
  114. return
  115. }
  116. //authenticate
  117. token, err := authenticate()
  118. if err != nil {
  119. t.Error("could not authenticate")
  120. }
  121. response, err := api("", http.MethodGet, "http://localhost:8081/users/admin", token)
  122. if err != nil {
  123. t.Error("could not get user")
  124. }
  125. defer response.Body.Close()
  126. var user models.User
  127. json.NewDecoder(response.Body).Decode(&user)
  128. assert.Equal(t, http.StatusOK, response.StatusCode)
  129. assert.Equal(t, "admin", user.UserName)
  130. assert.Equal(t, true, user.IsAdmin)
  131. })
  132. t.Run("Update User", func(t *testing.T) {
  133. t.Skip()
  134. if !adminExists(t) {
  135. addAdmin(t)
  136. }
  137. //token, err := authenticate()
  138. //if err != nil {
  139. // t.Error("could not authenticate")
  140. //}
  141. var admin, user models.User
  142. admin.UserName = "admin"
  143. admin.Password = "admin"
  144. //payload := map[string]string{"username": "admin", "password": "admin"}
  145. payload, _ := json.Marshal(admin)
  146. request, err := http.NewRequest(http.MethodPut, "http://localhost:8081/users/admin", bytes.NewBuffer(payload))
  147. if err != nil {
  148. t.Error(err)
  149. }
  150. request.Header.Set("Authorization", "Bearer secretkey")
  151. request.Header.Set("Content-Type", "application/json")
  152. client := &http.Client{}
  153. response, err := client.Do(request)
  154. if err != nil {
  155. t.Error("error calling createadmin", err)
  156. }
  157. defer response.Body.Close()
  158. body, _ := ioutil.ReadAll(response.Body)
  159. t.Log(string(body))
  160. _ = json.Unmarshal(body, &user)
  161. assert.Equal(t, admin.UserName, user.UserName)
  162. assert.Equal(t, true, user.IsAdmin)
  163. assert.Equal(t, http.StatusOK, response.StatusCode)
  164. })
  165. t.Run("Authenticate User", func(t *testing.T) {
  166. cases := []AuthorizeTestCase{
  167. AuthorizeTestCase{
  168. testname: "Invalid User",
  169. name: "invaliduser",
  170. password: "password",
  171. code: http.StatusBadRequest,
  172. tokenExpected: false,
  173. errMessage: "W1R3: It's not you it's me.",
  174. },
  175. AuthorizeTestCase{
  176. testname: "empty user",
  177. name: "",
  178. password: "password",
  179. code: http.StatusBadRequest,
  180. tokenExpected: false,
  181. errMessage: "W1R3: Username can't be empty",
  182. },
  183. AuthorizeTestCase{
  184. testname: "empty password",
  185. name: "admin",
  186. password: "",
  187. code: http.StatusBadRequest,
  188. tokenExpected: false,
  189. errMessage: "W1R3: Password can't be empty",
  190. },
  191. AuthorizeTestCase{
  192. testname: "Invalid Passord",
  193. name: "admin",
  194. password: "xxxxxxx",
  195. code: http.StatusBadRequest,
  196. tokenExpected: false,
  197. errMessage: "W1R3: It's not you it's me.",
  198. },
  199. AuthorizeTestCase{
  200. testname: "Valid User",
  201. name: "admin",
  202. password: "password",
  203. code: http.StatusOK,
  204. tokenExpected: true,
  205. errMessage: "W1R3: Device Admin Authorized",
  206. },
  207. }
  208. for _, tc := range cases {
  209. t.Run(tc.testname, func(t *testing.T) {
  210. if !adminExists(t) {
  211. addAdmin(t)
  212. }
  213. var admin models.User
  214. admin.UserName = tc.name
  215. admin.Password = tc.password
  216. response, err := api(admin, http.MethodPost, "http://localhost:8081/users/authenticate", "secretkey")
  217. if err != nil {
  218. t.Error("authenticate api call failed")
  219. }
  220. if tc.tokenExpected {
  221. var body goodResponse
  222. json.NewDecoder(response.Body).Decode(&body)
  223. assert.NotEmpty(t, body.Response.AuthToken, "token not returned")
  224. assert.Equal(t, "W1R3: Device admin Authorized", body.Message)
  225. } else {
  226. var body badResponse
  227. json.NewDecoder(response.Body).Decode(&body)
  228. assert.Equal(t, tc.errMessage, body.Message)
  229. }
  230. assert.Equal(t, tc.code, response.StatusCode)
  231. })
  232. }
  233. })
  234. }
  235. func adminExists(t *testing.T) bool {
  236. response, err := http.Get("http://localhost:8081/users/hasadmin")
  237. if err != nil {
  238. t.Fatal("error calling users/hasadmin", err)
  239. }
  240. assert.Equal(t, http.StatusOK, response.StatusCode)
  241. defer response.Body.Close()
  242. var body bool
  243. json.NewDecoder(response.Body).Decode(&body)
  244. return body
  245. }
  246. func api(data interface{}, method, url, authorization string) (*http.Response, error) {
  247. payload, err := json.Marshal(data)
  248. if err != nil {
  249. return nil, err
  250. }
  251. request, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
  252. if err != nil {
  253. return nil, err
  254. }
  255. request.Header.Set("Content-Type", "application/json")
  256. if authorization != "" {
  257. request.Header.Set("Authorization", "Bearer "+authorization)
  258. }
  259. client := http.Client{}
  260. return client.Do(request)
  261. }
  262. func addAdmin(t *testing.T) {
  263. var admin models.User
  264. admin.UserName = "admin"
  265. admin.Password = "password"
  266. payload, _ := json.Marshal(admin)
  267. request, err := http.NewRequest(http.MethodPost, "http://localhost:8081/users/createadmin",
  268. bytes.NewBuffer(payload))
  269. assert.NotNilf(t, err, "none nil error creating http request")
  270. request.Header.Set("Authorization", "Bearer secretkey")
  271. request.Header.Set("Content-Type", "application/json")
  272. client := &http.Client{}
  273. response, err := client.Do(request)
  274. assert.NotNilf(t, err, "non nil err response from createadmin")
  275. assert.Equal(t, http.StatusOK, response.StatusCode)
  276. }
  277. func authenticate() (string, error) {
  278. var admin models.User
  279. admin.UserName = "admin"
  280. admin.Password = "password"
  281. response, err := api(admin, http.MethodPost, "http://localhost:8081/users/authenticate", "secretkey")
  282. if err != nil {
  283. return "", err
  284. }
  285. var body goodResponse
  286. json.NewDecoder(response.Body).Decode(&body)
  287. token := body.Response.AuthToken
  288. return token, nil
  289. }