user.go 12 KB

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