user.go 13 KB

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