user.go 15 KB

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