user.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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. // Node authenticates using its password and retrieves a JWT for authorization.
  29. func authenticateUser(response http.ResponseWriter, request *http.Request) {
  30. // Auth request consists of Mac Address and Password (from node that is authorizing
  31. // in case of Master, auth is ignored and mac is set to "mastermac"
  32. var authRequest models.UserAuthParams
  33. var errorResponse = models.ErrorResponse{
  34. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  35. }
  36. decoder := json.NewDecoder(request.Body)
  37. decoderErr := decoder.Decode(&authRequest)
  38. defer request.Body.Close()
  39. if decoderErr != nil {
  40. logger.Log(0, "error decoding request body: ",
  41. decoderErr.Error())
  42. returnErrorResponse(response, request, errorResponse)
  43. return
  44. }
  45. username := authRequest.UserName
  46. jwt, err := logic.VerifyAuthRequest(authRequest)
  47. if err != nil {
  48. logger.Log(0, username, "user validation failed: ",
  49. err.Error())
  50. returnErrorResponse(response, request, formatError(err, "badrequest"))
  51. return
  52. }
  53. if jwt == "" {
  54. // very unlikely that err is !nil and no jwt returned, but handle it anyways.
  55. logger.Log(0, username, "jwt token is empty")
  56. returnErrorResponse(response, request, formatError(errors.New("no token returned"), "internal"))
  57. return
  58. }
  59. var successResponse = models.SuccessResponse{
  60. Code: http.StatusOK,
  61. Message: "W1R3: Device " + username + " Authorized",
  62. Response: models.SuccessfulUserLoginResponse{
  63. AuthToken: jwt,
  64. UserName: username,
  65. },
  66. }
  67. // Send back the JWT
  68. successJSONResponse, jsonError := json.Marshal(successResponse)
  69. if jsonError != nil {
  70. logger.Log(0, username,
  71. "error marshalling resp: ", err.Error())
  72. returnErrorResponse(response, request, errorResponse)
  73. return
  74. }
  75. logger.Log(2, username, "was authenticated")
  76. response.Header().Set("Content-Type", "application/json")
  77. response.Write(successJSONResponse)
  78. }
  79. func hasAdmin(w http.ResponseWriter, r *http.Request) {
  80. w.Header().Set("Content-Type", "application/json")
  81. hasadmin, err := logic.HasAdmin()
  82. if err != nil {
  83. logger.Log(0, "failed to check for admin: ", err.Error())
  84. returnErrorResponse(w, r, formatError(err, "internal"))
  85. return
  86. }
  87. json.NewEncoder(w).Encode(hasadmin)
  88. }
  89. // GetUserInternal - gets an internal user
  90. func GetUserInternal(username string) (models.User, error) {
  91. var user models.User
  92. record, err := database.FetchRecord(database.USERS_TABLE_NAME, username)
  93. if err != nil {
  94. return user, err
  95. }
  96. if err = json.Unmarshal([]byte(record), &user); err != nil {
  97. return models.User{}, err
  98. }
  99. return user, err
  100. }
  101. // Get an individual user. Nothin fancy here folks.
  102. func getUser(w http.ResponseWriter, r *http.Request) {
  103. // set header.
  104. w.Header().Set("Content-Type", "application/json")
  105. var params = mux.Vars(r)
  106. usernameFetched := params["username"]
  107. user, err := logic.GetUser(usernameFetched)
  108. if err != nil {
  109. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  110. returnErrorResponse(w, r, formatError(err, "internal"))
  111. return
  112. }
  113. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  114. json.NewEncoder(w).Encode(user)
  115. }
  116. // Get all users. Nothin fancy here folks.
  117. func getUsers(w http.ResponseWriter, r *http.Request) {
  118. // set header.
  119. w.Header().Set("Content-Type", "application/json")
  120. users, err := logic.GetUsers()
  121. if err != nil {
  122. logger.Log(0, "failed to fetch users: ", err.Error())
  123. returnErrorResponse(w, r, formatError(err, "internal"))
  124. return
  125. }
  126. logger.Log(2, r.Header.Get("user"), "fetched users")
  127. json.NewEncoder(w).Encode(users)
  128. }
  129. func createAdmin(w http.ResponseWriter, r *http.Request) {
  130. w.Header().Set("Content-Type", "application/json")
  131. var admin models.User
  132. err := json.NewDecoder(r.Body).Decode(&admin)
  133. if err != nil {
  134. logger.Log(0, admin.UserName, "error decoding request body: ",
  135. err.Error())
  136. returnErrorResponse(w, r, formatError(err, "badrequest"))
  137. return
  138. }
  139. admin, err = logic.CreateAdmin(admin)
  140. if err != nil {
  141. logger.Log(0, admin.UserName, "failed to create admin: ",
  142. err.Error())
  143. returnErrorResponse(w, r, formatError(err, "badrequest"))
  144. return
  145. }
  146. logger.Log(1, admin.UserName, "was made a new admin")
  147. json.NewEncoder(w).Encode(admin)
  148. }
  149. func createUser(w http.ResponseWriter, r *http.Request) {
  150. w.Header().Set("Content-Type", "application/json")
  151. var user models.User
  152. err := json.NewDecoder(r.Body).Decode(&user)
  153. if err != nil {
  154. logger.Log(0, user.UserName, "error decoding request body: ",
  155. err.Error())
  156. returnErrorResponse(w, r, formatError(err, "badrequest"))
  157. return
  158. }
  159. user, err = logic.CreateUser(user)
  160. if err != nil {
  161. logger.Log(0, user.UserName, "error creating new user: ",
  162. err.Error())
  163. returnErrorResponse(w, r, formatError(err, "badrequest"))
  164. return
  165. }
  166. logger.Log(1, user.UserName, "was created")
  167. json.NewEncoder(w).Encode(user)
  168. }
  169. func updateUserNetworks(w http.ResponseWriter, r *http.Request) {
  170. w.Header().Set("Content-Type", "application/json")
  171. var params = mux.Vars(r)
  172. var user models.User
  173. // start here
  174. username := params["username"]
  175. user, err := GetUserInternal(username)
  176. if err != nil {
  177. logger.Log(0, username,
  178. "failed to update user networks: ", err.Error())
  179. returnErrorResponse(w, r, formatError(err, "internal"))
  180. return
  181. }
  182. var userchange models.User
  183. // we decode our body request params
  184. err = json.NewDecoder(r.Body).Decode(&userchange)
  185. if err != nil {
  186. logger.Log(0, username, "error decoding request body: ",
  187. err.Error())
  188. returnErrorResponse(w, r, formatError(err, "badrequest"))
  189. return
  190. }
  191. err = logic.UpdateUserNetworks(userchange.Networks, userchange.IsAdmin, &user)
  192. if err != nil {
  193. logger.Log(0, username,
  194. "failed to update user networks: ", err.Error())
  195. returnErrorResponse(w, r, formatError(err, "badrequest"))
  196. return
  197. }
  198. logger.Log(1, username, "status was updated")
  199. json.NewEncoder(w).Encode(user)
  200. }
  201. func updateUser(w http.ResponseWriter, r *http.Request) {
  202. w.Header().Set("Content-Type", "application/json")
  203. var params = mux.Vars(r)
  204. var user models.User
  205. // start here
  206. username := params["username"]
  207. user, err := GetUserInternal(username)
  208. if err != nil {
  209. logger.Log(0, username,
  210. "failed to update user info: ", err.Error())
  211. returnErrorResponse(w, r, formatError(err, "internal"))
  212. return
  213. }
  214. if auth.IsOauthUser(&user) == nil {
  215. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  216. logger.Log(0, err.Error())
  217. returnErrorResponse(w, r, formatError(err, "forbidden"))
  218. return
  219. }
  220. var userchange models.User
  221. // we decode our body request params
  222. err = json.NewDecoder(r.Body).Decode(&userchange)
  223. if err != nil {
  224. logger.Log(0, username, "error decoding request body: ",
  225. err.Error())
  226. returnErrorResponse(w, r, formatError(err, "badrequest"))
  227. return
  228. }
  229. userchange.Networks = nil
  230. user, err = logic.UpdateUser(userchange, user)
  231. if err != nil {
  232. logger.Log(0, username,
  233. "failed to update user info: ", err.Error())
  234. returnErrorResponse(w, r, formatError(err, "badrequest"))
  235. return
  236. }
  237. logger.Log(1, username, "was updated")
  238. json.NewEncoder(w).Encode(user)
  239. }
  240. func updateUserAdm(w http.ResponseWriter, r *http.Request) {
  241. w.Header().Set("Content-Type", "application/json")
  242. var params = mux.Vars(r)
  243. var user models.User
  244. // start here
  245. username := params["username"]
  246. user, err := GetUserInternal(username)
  247. if err != nil {
  248. returnErrorResponse(w, r, formatError(err, "internal"))
  249. return
  250. }
  251. if auth.IsOauthUser(&user) != nil {
  252. err := fmt.Errorf("cannot update user info for oauth user %s", username)
  253. logger.Log(0, err.Error())
  254. returnErrorResponse(w, r, formatError(err, "forbidden"))
  255. return
  256. }
  257. var userchange models.User
  258. // we decode our body request params
  259. err = json.NewDecoder(r.Body).Decode(&userchange)
  260. if err != nil {
  261. logger.Log(0, username, "error decoding request body: ",
  262. err.Error())
  263. returnErrorResponse(w, r, formatError(err, "badrequest"))
  264. return
  265. }
  266. if !user.IsAdmin {
  267. logger.Log(0, username, "not an admin user")
  268. returnErrorResponse(w, r, formatError(errors.New("not a admin user"), "badrequest"))
  269. }
  270. user, err = logic.UpdateUser(userchange, user)
  271. if err != nil {
  272. logger.Log(0, username,
  273. "failed to update user (admin) info: ", err.Error())
  274. returnErrorResponse(w, r, formatError(err, "badrequest"))
  275. return
  276. }
  277. logger.Log(1, username, "was updated (admin)")
  278. json.NewEncoder(w).Encode(user)
  279. }
  280. func deleteUser(w http.ResponseWriter, r *http.Request) {
  281. // Set header
  282. w.Header().Set("Content-Type", "application/json")
  283. // get params
  284. var params = mux.Vars(r)
  285. username := params["username"]
  286. success, err := logic.DeleteUser(username)
  287. if err != nil {
  288. logger.Log(0, username,
  289. "failed to delete user: ", err.Error())
  290. returnErrorResponse(w, r, formatError(err, "internal"))
  291. return
  292. } else if !success {
  293. err := errors.New("delete unsuccessful")
  294. logger.Log(0, username, err.Error())
  295. returnErrorResponse(w, r, formatError(err, "badrequest"))
  296. return
  297. }
  298. logger.Log(1, username, "was deleted")
  299. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  300. }