user.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "github.com/gorilla/mux"
  8. "github.com/gravitl/netmaker/auth"
  9. "github.com/gravitl/netmaker/database"
  10. "github.com/gravitl/netmaker/logger"
  11. "github.com/gravitl/netmaker/logic"
  12. "github.com/gravitl/netmaker/models"
  13. )
  14. func userHandlers(r *mux.Router) {
  15. r.HandleFunc("/api/users/adm/hasadmin", hasAdmin).Methods("GET")
  16. r.HandleFunc("/api/users/adm/createadmin", createAdmin).Methods("POST")
  17. r.HandleFunc("/api/users/adm/authenticate", authenticateUser).Methods("POST")
  18. r.HandleFunc("/api/users/{username}", securityCheck(false, continueIfUserMatch(http.HandlerFunc(updateUser)))).Methods("PUT")
  19. r.HandleFunc("/api/users/networks/{username}", securityCheck(true, http.HandlerFunc(updateUserNetworks))).Methods("PUT")
  20. r.HandleFunc("/api/users/{username}/adm", securityCheck(true, http.HandlerFunc(updateUserAdm))).Methods("PUT")
  21. r.HandleFunc("/api/users/{username}", securityCheck(true, http.HandlerFunc(createUser))).Methods("POST")
  22. r.HandleFunc("/api/users/{username}", securityCheck(true, http.HandlerFunc(deleteUser))).Methods("DELETE")
  23. r.HandleFunc("/api/users/{username}", securityCheck(false, continueIfUserMatch(http.HandlerFunc(getUser)))).Methods("GET")
  24. r.HandleFunc("/api/users", securityCheck(true, http.HandlerFunc(getUsers))).Methods("GET")
  25. r.HandleFunc("/api/oauth/login", auth.HandleAuthLogin).Methods("GET")
  26. r.HandleFunc("/api/oauth/callback", auth.HandleAuthCallback).Methods("GET")
  27. }
  28. // swagger:route POST /api/users/adm/authenticate nodes authenticateUser
  29. //
  30. // Node authenticates using its password and retrieves a JWT for authorization.
  31. //
  32. // Schemes: https
  33. //
  34. // Security:
  35. // oauth
  36. //
  37. // Responses:
  38. // 200: successResponse
  39. func authenticateUser(response http.ResponseWriter, request *http.Request) {
  40. // Auth request consists of Mac Address and Password (from node that is authorizing
  41. // in case of Master, auth is ignored and mac is set to "mastermac"
  42. var authRequest models.UserAuthParams
  43. var errorResponse = models.ErrorResponse{
  44. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  45. }
  46. decoder := json.NewDecoder(request.Body)
  47. decoderErr := decoder.Decode(&authRequest)
  48. defer request.Body.Close()
  49. if decoderErr != nil {
  50. logger.Log(0, "error decoding request body: ",
  51. decoderErr.Error())
  52. returnErrorResponse(response, request, errorResponse)
  53. return
  54. }
  55. username := authRequest.UserName
  56. jwt, err := logic.VerifyAuthRequest(authRequest)
  57. if err != nil {
  58. logger.Log(0, username, "user validation failed: ",
  59. err.Error())
  60. returnErrorResponse(response, request, formatError(err, "badrequest"))
  61. return
  62. }
  63. if jwt == "" {
  64. // very unlikely that err is !nil and no jwt returned, but handle it anyways.
  65. logger.Log(0, username, "jwt token is empty")
  66. returnErrorResponse(response, request, formatError(errors.New("no token returned"), "internal"))
  67. return
  68. }
  69. var successResponse = models.SuccessResponse{
  70. Code: http.StatusOK,
  71. Message: "W1R3: Device " + username + " Authorized",
  72. Response: models.SuccessfulUserLoginResponse{
  73. AuthToken: jwt,
  74. UserName: username,
  75. },
  76. }
  77. // Send back the JWT
  78. successJSONResponse, jsonError := json.Marshal(successResponse)
  79. if jsonError != nil {
  80. logger.Log(0, username,
  81. "error marshalling resp: ", err.Error())
  82. returnErrorResponse(response, request, errorResponse)
  83. return
  84. }
  85. logger.Log(2, username, "was authenticated")
  86. response.Header().Set("Content-Type", "application/json")
  87. response.Write(successJSONResponse)
  88. }
  89. // swagger:route GET /api/users/adm/hasadmin nodes hasAdmin
  90. //
  91. // Checks whether the server has an admin.
  92. //
  93. // Schemes: https
  94. //
  95. // Security:
  96. // oauth
  97. //
  98. // Responses:
  99. // 200: successResponse
  100. func hasAdmin(w http.ResponseWriter, r *http.Request) {
  101. w.Header().Set("Content-Type", "application/json")
  102. hasadmin, err := logic.HasAdmin()
  103. if err != nil {
  104. logger.Log(0, "failed to check for admin: ", err.Error())
  105. returnErrorResponse(w, r, formatError(err, "internal"))
  106. return
  107. }
  108. json.NewEncoder(w).Encode(hasadmin)
  109. }
  110. // GetUserInternal - gets an internal user
  111. func GetUserInternal(username string) (models.User, error) {
  112. var user models.User
  113. record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
  114. if err != nil {
  115. return user, err
  116. }
  117. if err = json.Unmarshal([]byte(record), &user); err != nil {
  118. return models.User{}, err
  119. }
  120. return user, err
  121. }
  122. // swagger:route GET /api/users/{username} nodes getUser
  123. //
  124. // Get an individual user.
  125. //
  126. // Schemes: https
  127. //
  128. // Security:
  129. // oauth
  130. //
  131. // Responses:
  132. // 200: userBodyResponse
  133. func getUser(w http.ResponseWriter, r *http.Request) {
  134. // set header.
  135. w.Header().Set("Content-Type", "application/json")
  136. var params = mux.Vars(r)
  137. usernameFetched := params["username"]
  138. user, err := logic.GetUser(usernameFetched)
  139. if err != nil {
  140. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  141. returnErrorResponse(w, r, formatError(err, "internal"))
  142. return
  143. }
  144. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  145. json.NewEncoder(w).Encode(user)
  146. }
  147. // swagger:route GET /api/users nodes getUsers
  148. //
  149. // Get all users.
  150. //
  151. // Schemes: https
  152. //
  153. // Security:
  154. // oauth
  155. //
  156. // Responses:
  157. // 200: userBodyResponse
  158. func getUsers(w http.ResponseWriter, r *http.Request) {
  159. // set header.
  160. w.Header().Set("Content-Type", "application/json")
  161. users, err := logic.GetUsers()
  162. if err != nil {
  163. logger.Log(0, "failed to fetch users: ", err.Error())
  164. returnErrorResponse(w, r, formatError(err, "internal"))
  165. return
  166. }
  167. logger.Log(2, r.Header.Get("user"), "fetched users")
  168. json.NewEncoder(w).Encode(users)
  169. }
  170. // swagger:route POST /api/users/adm/createadmin nodes createAdmin
  171. //
  172. // Make a user an admin.
  173. //
  174. // Schemes: https
  175. //
  176. // Security:
  177. // oauth
  178. //
  179. // Responses:
  180. // 200: userBodyResponse
  181. func createAdmin(w http.ResponseWriter, r *http.Request) {
  182. w.Header().Set("Content-Type", "application/json")
  183. var admin models.User
  184. err := json.NewDecoder(r.Body).Decode(&admin)
  185. if err != nil {
  186. logger.Log(0, admin.UserName, "error decoding request body: ",
  187. err.Error())
  188. returnErrorResponse(w, r, formatError(err, "badrequest"))
  189. return
  190. }
  191. admin, err = logic.CreateAdmin(admin)
  192. if err != nil {
  193. logger.Log(0, admin.UserName, "failed to create admin: ",
  194. err.Error())
  195. returnErrorResponse(w, r, formatError(err, "badrequest"))
  196. return
  197. }
  198. logger.Log(1, admin.UserName, "was made a new admin")
  199. json.NewEncoder(w).Encode(admin)
  200. }
  201. // swagger:route POST /api/users/{username} nodes createUser
  202. //
  203. // Create a user.
  204. //
  205. // Schemes: https
  206. //
  207. // Security:
  208. // oauth
  209. //
  210. // Responses:
  211. // 200: userBodyResponse
  212. func createUser(w http.ResponseWriter, r *http.Request) {
  213. w.Header().Set("Content-Type", "application/json")
  214. var user models.User
  215. err := json.NewDecoder(r.Body).Decode(&user)
  216. if err != nil {
  217. logger.Log(0, user.UserName, "error decoding request body: ",
  218. err.Error())
  219. returnErrorResponse(w, r, formatError(err, "badrequest"))
  220. return
  221. }
  222. user, err = logic.CreateUser(user)
  223. if err != nil {
  224. logger.Log(0, user.UserName, "error creating new user: ",
  225. err.Error())
  226. returnErrorResponse(w, r, formatError(err, "badrequest"))
  227. return
  228. }
  229. logger.Log(1, user.UserName, "was created")
  230. json.NewEncoder(w).Encode(user)
  231. }
  232. // swagger:route PUT /api/users/networks/{username} nodes updateUserNetworks
  233. //
  234. // Updates the networks of the given user.
  235. //
  236. // Schemes: https
  237. //
  238. // Security:
  239. // oauth
  240. //
  241. // Responses:
  242. // 200: userBodyResponse
  243. func updateUserNetworks(w http.ResponseWriter, r *http.Request) {
  244. w.Header().Set("Content-Type", "application/json")
  245. var params = mux.Vars(r)
  246. var user models.User
  247. // start here
  248. username := params["username"]
  249. user, err := GetUserInternal(username)
  250. if err != nil {
  251. logger.Log(0, username,
  252. "failed to update user networks: ", err.Error())
  253. returnErrorResponse(w, r, formatError(err, "internal"))
  254. return
  255. }
  256. var userchange models.User
  257. // we decode our body request params
  258. err = json.NewDecoder(r.Body).Decode(&userchange)
  259. if err != nil {
  260. logger.Log(0, username, "error decoding request body: ",
  261. err.Error())
  262. returnErrorResponse(w, r, formatError(err, "badrequest"))
  263. return
  264. }
  265. err = logic.UpdateUserNetworks(userchange.Networks, userchange.IsAdmin, &user)
  266. if err != nil {
  267. logger.Log(0, username,
  268. "failed to update user networks: ", err.Error())
  269. returnErrorResponse(w, r, formatError(err, "badrequest"))
  270. return
  271. }
  272. logger.Log(1, username, "status was updated")
  273. json.NewEncoder(w).Encode(user)
  274. }
  275. // swagger:route PUT /api/users/{username} nodes updateUser
  276. //
  277. // Update a user.
  278. //
  279. // Schemes: https
  280. //
  281. // Security:
  282. // oauth
  283. //
  284. // Responses:
  285. // 200: userBodyResponse
  286. func updateUser(w http.ResponseWriter, r *http.Request) {
  287. w.Header().Set("Content-Type", "application/json")
  288. var params = mux.Vars(r)
  289. var user models.User
  290. // start here
  291. username := params["username"]
  292. user, err := GetUserInternal(username)
  293. if err != nil {
  294. logger.Log(0, username,
  295. "failed to update user info: ", err.Error())
  296. returnErrorResponse(w, r, formatError(err, "internal"))
  297. return
  298. }
  299. if auth.IsOauthUser(&user) == nil {
  300. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  301. logger.Log(0, err.Error())
  302. returnErrorResponse(w, r, formatError(err, "forbidden"))
  303. return
  304. }
  305. var userchange models.User
  306. // we decode our body request params
  307. err = json.NewDecoder(r.Body).Decode(&userchange)
  308. if err != nil {
  309. logger.Log(0, username, "error decoding request body: ",
  310. err.Error())
  311. returnErrorResponse(w, r, formatError(err, "badrequest"))
  312. return
  313. }
  314. userchange.Networks = nil
  315. user, err = logic.UpdateUser(userchange, user)
  316. if err != nil {
  317. logger.Log(0, username,
  318. "failed to update user info: ", err.Error())
  319. returnErrorResponse(w, r, formatError(err, "badrequest"))
  320. return
  321. }
  322. logger.Log(1, username, "was updated")
  323. json.NewEncoder(w).Encode(user)
  324. }
  325. // swagger:route PUT /api/users/{username}/adm nodes updateUserAdm
  326. //
  327. // Updates the given admin user's info (as long as the user is an admin).
  328. //
  329. // Schemes: https
  330. //
  331. // Security:
  332. // oauth
  333. //
  334. // Responses:
  335. // 200: userBodyResponse
  336. func updateUserAdm(w http.ResponseWriter, r *http.Request) {
  337. w.Header().Set("Content-Type", "application/json")
  338. var params = mux.Vars(r)
  339. var user models.User
  340. // start here
  341. username := params["username"]
  342. user, err := GetUserInternal(username)
  343. if err != nil {
  344. returnErrorResponse(w, r, formatError(err, "internal"))
  345. return
  346. }
  347. if auth.IsOauthUser(&user) != nil {
  348. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  349. logger.Log(0, err.Error())
  350. returnErrorResponse(w, r, formatError(err, "forbidden"))
  351. return
  352. }
  353. var userchange models.User
  354. // we decode our body request params
  355. err = json.NewDecoder(r.Body).Decode(&userchange)
  356. if err != nil {
  357. logger.Log(0, username, "error decoding request body: ",
  358. err.Error())
  359. returnErrorResponse(w, r, formatError(err, "badrequest"))
  360. return
  361. }
  362. if !user.IsAdmin {
  363. logger.Log(0, username, "not an admin user")
  364. returnErrorResponse(w, r, formatError(errors.New("not a admin user"), "badrequest"))
  365. }
  366. user, err = logic.UpdateUser(userchange, user)
  367. if err != nil {
  368. logger.Log(0, username,
  369. "failed to update user (admin) info: ", err.Error())
  370. returnErrorResponse(w, r, formatError(err, "badrequest"))
  371. return
  372. }
  373. logger.Log(1, username, "was updated (admin)")
  374. json.NewEncoder(w).Encode(user)
  375. }
  376. // swagger:route DELETE /api/users/{username} nodes deleteUser
  377. //
  378. // Delete a user.
  379. //
  380. // Schemes: https
  381. //
  382. // Security:
  383. // oauth
  384. //
  385. // Responses:
  386. // 200: userBodyResponse
  387. func deleteUser(w http.ResponseWriter, r *http.Request) {
  388. // Set header
  389. w.Header().Set("Content-Type", "application/json")
  390. // get params
  391. var params = mux.Vars(r)
  392. username := params["username"]
  393. success, err := logic.DeleteUser(username)
  394. if err != nil {
  395. logger.Log(0, username,
  396. "failed to delete user: ", err.Error())
  397. returnErrorResponse(w, r, formatError(err, "internal"))
  398. return
  399. } else if !success {
  400. err := errors.New("delete unsuccessful")
  401. logger.Log(0, username, err.Error())
  402. returnErrorResponse(w, r, formatError(err, "badrequest"))
  403. return
  404. }
  405. logger.Log(1, username, "was deleted")
  406. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  407. }