user_test.go 10 KB

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