user.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "reflect"
  9. "github.com/gorilla/mux"
  10. "github.com/gorilla/websocket"
  11. "github.com/gravitl/netmaker/auth"
  12. "github.com/gravitl/netmaker/logger"
  13. "github.com/gravitl/netmaker/logic"
  14. "github.com/gravitl/netmaker/models"
  15. "github.com/gravitl/netmaker/mq"
  16. "github.com/gravitl/netmaker/servercfg"
  17. "golang.org/x/exp/slog"
  18. )
  19. var (
  20. upgrader = websocket.Upgrader{}
  21. )
  22. func userHandlers(r *mux.Router) {
  23. r.HandleFunc("/api/users/adm/hassuperadmin", hasSuperAdmin).Methods(http.MethodGet)
  24. r.HandleFunc("/api/users/adm/createsuperadmin", createSuperAdmin).Methods(http.MethodPost)
  25. r.HandleFunc("/api/users/adm/transfersuperadmin/{username}", logic.SecurityCheck(true, http.HandlerFunc(transferSuperAdmin))).Methods(http.MethodPost)
  26. r.HandleFunc("/api/users/adm/authenticate", authenticateUser).Methods(http.MethodPost)
  27. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUser))).Methods(http.MethodPut)
  28. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceUsers, http.HandlerFunc(createUser)))).Methods(http.MethodPost)
  29. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).Methods(http.MethodDelete)
  30. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).Methods(http.MethodGet)
  31. r.HandleFunc("/api/v1/users", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUserV1)))).Methods(http.MethodGet)
  32. r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).Methods(http.MethodGet)
  33. }
  34. // swagger:route POST /api/users/adm/authenticate authenticate authenticateUser
  35. //
  36. // User 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. if val := request.Header.Get("From-Ui"); val == "true" {
  66. // request came from UI, if normal user block Login
  67. user, err := logic.GetUser(authRequest.UserName)
  68. if err != nil {
  69. logger.Log(0, authRequest.UserName, "user validation failed: ",
  70. err.Error())
  71. logic.ReturnErrorResponse(response, request, logic.FormatError(err, "unauthorized"))
  72. return
  73. }
  74. role, err := logic.GetRole(user.PlatformRoleID)
  75. if err != nil {
  76. logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("access denied to dashboard"), "unauthorized"))
  77. return
  78. }
  79. if role.DenyDashboardAccess {
  80. logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("access denied to dashboard"), "unauthorized"))
  81. return
  82. }
  83. }
  84. user, err := logic.GetUser(authRequest.UserName)
  85. if err != nil {
  86. logic.ReturnErrorResponse(response, request, logic.FormatError(err, "unauthorized"))
  87. return
  88. }
  89. if logic.IsOauthUser(user) == nil {
  90. logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("user is registered via SSO"), "badrequest"))
  91. return
  92. }
  93. username := authRequest.UserName
  94. jwt, err := logic.VerifyAuthRequest(authRequest)
  95. if err != nil {
  96. logger.Log(0, username, "user validation failed: ",
  97. err.Error())
  98. logic.ReturnErrorResponse(response, request, logic.FormatError(err, "badrequest"))
  99. return
  100. }
  101. if jwt == "" {
  102. // very unlikely that err is !nil and no jwt returned, but handle it anyways.
  103. logger.Log(0, username, "jwt token is empty")
  104. logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("no token returned"), "internal"))
  105. return
  106. }
  107. var successResponse = models.SuccessResponse{
  108. Code: http.StatusOK,
  109. Message: "W1R3: Device " + username + " Authorized",
  110. Response: models.SuccessfulUserLoginResponse{
  111. AuthToken: jwt,
  112. UserName: username,
  113. },
  114. }
  115. // Send back the JWT
  116. successJSONResponse, jsonError := json.Marshal(successResponse)
  117. if jsonError != nil {
  118. logger.Log(0, username,
  119. "error marshalling resp: ", jsonError.Error())
  120. logic.ReturnErrorResponse(response, request, errorResponse)
  121. return
  122. }
  123. logger.Log(2, username, "was authenticated")
  124. response.Header().Set("Content-Type", "application/json")
  125. response.Write(successJSONResponse)
  126. go func() {
  127. if servercfg.IsPro && servercfg.GetRacAutoDisable() {
  128. // enable all associeated clients for the user
  129. clients, err := logic.GetAllExtClients()
  130. if err != nil {
  131. slog.Error("error getting clients: ", "error", err)
  132. return
  133. }
  134. for _, client := range clients {
  135. if client.OwnerID == username && !client.Enabled {
  136. slog.Info(fmt.Sprintf("enabling ext client %s for user %s due to RAC autodisabling feature", client.ClientID, client.OwnerID))
  137. if newClient, err := logic.ToggleExtClientConnectivity(&client, true); err != nil {
  138. slog.Error("error enabling ext client in RAC autodisable hook", "error", err)
  139. continue // dont return but try for other clients
  140. } else {
  141. // publish peer update to ingress gateway
  142. if ingressNode, err := logic.GetNodeByID(newClient.IngressGatewayID); err == nil {
  143. if err = mq.PublishPeerUpdate(false); err != nil {
  144. slog.Error("error updating ext clients on", "ingress", ingressNode.ID.String(), "err", err.Error())
  145. }
  146. }
  147. }
  148. }
  149. }
  150. }
  151. }()
  152. }
  153. // swagger:route GET /api/users/adm/hassuperadmin user hasSuperAdmin
  154. //
  155. // Checks whether the server has an admin.
  156. //
  157. // Schemes: https
  158. //
  159. // Security:
  160. // oauth
  161. //
  162. // Responses:
  163. // 200: hasAdmin
  164. func hasSuperAdmin(w http.ResponseWriter, r *http.Request) {
  165. w.Header().Set("Content-Type", "application/json")
  166. hasSuperAdmin, err := logic.HasSuperAdmin()
  167. if err != nil {
  168. logger.Log(0, "failed to check for admin: ", err.Error())
  169. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  170. return
  171. }
  172. json.NewEncoder(w).Encode(hasSuperAdmin)
  173. }
  174. // swagger:route GET /api/users/{username} user getUser
  175. //
  176. // Get an individual user.
  177. //
  178. // Schemes: https
  179. //
  180. // Security:
  181. // oauth
  182. //
  183. // Responses:
  184. // 200: userBodyResponse
  185. func getUser(w http.ResponseWriter, r *http.Request) {
  186. // set header.
  187. w.Header().Set("Content-Type", "application/json")
  188. var params = mux.Vars(r)
  189. usernameFetched := params["username"]
  190. user, err := logic.GetReturnUser(usernameFetched)
  191. if err != nil {
  192. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  193. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  194. return
  195. }
  196. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  197. json.NewEncoder(w).Encode(user)
  198. }
  199. // swagger:route GET /api/v1/users user getUserV1
  200. //
  201. // Get an individual user with role info.
  202. //
  203. // Schemes: https
  204. //
  205. // Security:
  206. // oauth
  207. //
  208. // Responses:
  209. // 200: ReturnUserWithRolesAndGroups
  210. func getUserV1(w http.ResponseWriter, r *http.Request) {
  211. // set header.
  212. w.Header().Set("Content-Type", "application/json")
  213. usernameFetched, _ := url.QueryUnescape(r.URL.Query().Get("username"))
  214. if usernameFetched == "" {
  215. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("username is required"), "badrequest"))
  216. return
  217. }
  218. user, err := logic.GetReturnUser(usernameFetched)
  219. if err != nil {
  220. logger.Log(0, usernameFetched, "failed to fetch user: ", err.Error())
  221. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  222. return
  223. }
  224. userRoleTemplate, err := logic.GetRole(user.PlatformRoleID)
  225. if err != nil {
  226. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  227. return
  228. }
  229. resp := models.ReturnUserWithRolesAndGroups{
  230. ReturnUser: user,
  231. PlatformRole: userRoleTemplate,
  232. }
  233. logger.Log(2, r.Header.Get("user"), "fetched user", usernameFetched)
  234. logic.ReturnSuccessResponseWithJson(w, r, resp, "fetched user with role info")
  235. }
  236. // swagger:route GET /api/users user getUsers
  237. //
  238. // Get all users.
  239. //
  240. // Schemes: https
  241. //
  242. // Security:
  243. // oauth
  244. //
  245. // Responses:
  246. // 200: userBodyResponse
  247. func getUsers(w http.ResponseWriter, r *http.Request) {
  248. // set header.
  249. w.Header().Set("Content-Type", "application/json")
  250. users, err := logic.GetUsers()
  251. if err != nil {
  252. logger.Log(0, "failed to fetch users: ", err.Error())
  253. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  254. return
  255. }
  256. logic.SortUsers(users[:])
  257. logger.Log(2, r.Header.Get("user"), "fetched users")
  258. json.NewEncoder(w).Encode(users)
  259. }
  260. // swagger:route POST /api/users/adm/createsuperadmin user createAdmin
  261. //
  262. // Make a user an admin.
  263. //
  264. // Schemes: https
  265. //
  266. // Security:
  267. // oauth
  268. //
  269. // Responses:
  270. // 200: userBodyResponse
  271. func createSuperAdmin(w http.ResponseWriter, r *http.Request) {
  272. w.Header().Set("Content-Type", "application/json")
  273. var u models.User
  274. err := json.NewDecoder(r.Body).Decode(&u)
  275. if err != nil {
  276. slog.Error("error decoding request body", "error", err.Error())
  277. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  278. return
  279. }
  280. if !servercfg.IsBasicAuthEnabled() {
  281. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"))
  282. return
  283. }
  284. err = logic.CreateSuperAdmin(&u)
  285. if err != nil {
  286. slog.Error("failed to create admin", "error", err.Error())
  287. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  288. return
  289. }
  290. logger.Log(1, u.UserName, "was made a super admin")
  291. json.NewEncoder(w).Encode(logic.ToReturnUser(u))
  292. }
  293. // swagger:route POST /api/users/adm/transfersuperadmin user transferSuperAdmin
  294. //
  295. // Transfers superadmin role to an admin user.
  296. //
  297. // Schemes: https
  298. //
  299. // Security:
  300. // oauth
  301. //
  302. // Responses:
  303. // 200: userBodyResponse
  304. func transferSuperAdmin(w http.ResponseWriter, r *http.Request) {
  305. w.Header().Set("Content-Type", "application/json")
  306. caller, err := logic.GetUser(r.Header.Get("user"))
  307. if err != nil {
  308. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  309. }
  310. if caller.PlatformRoleID != models.SuperAdminRole {
  311. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only superadmin can assign the superadmin role to another user"), "forbidden"))
  312. return
  313. }
  314. var params = mux.Vars(r)
  315. username := params["username"]
  316. u, err := logic.GetUser(username)
  317. if err != nil {
  318. slog.Error("error getting user", "user", u.UserName, "error", err.Error())
  319. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  320. return
  321. }
  322. if u.PlatformRoleID != models.AdminRole {
  323. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only admins can be promoted to superadmin role"), "forbidden"))
  324. return
  325. }
  326. if !servercfg.IsBasicAuthEnabled() {
  327. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"))
  328. return
  329. }
  330. u.PlatformRoleID = models.SuperAdminRole
  331. err = logic.UpsertUser(*u)
  332. if err != nil {
  333. slog.Error("error updating user to superadmin: ", "user", u.UserName, "error", err.Error())
  334. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  335. return
  336. }
  337. caller.PlatformRoleID = models.AdminRole
  338. err = logic.UpsertUser(*caller)
  339. if err != nil {
  340. slog.Error("error demoting user to admin: ", "user", caller.UserName, "error", err.Error())
  341. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  342. return
  343. }
  344. slog.Info("user was made a super admin", "user", u.UserName)
  345. json.NewEncoder(w).Encode(logic.ToReturnUser(*u))
  346. }
  347. // swagger:route POST /api/users/{username} user createUser
  348. //
  349. // Create a user.
  350. //
  351. // Schemes: https
  352. //
  353. // Security:
  354. // oauth
  355. //
  356. // Responses:
  357. // 200: userBodyResponse
  358. func createUser(w http.ResponseWriter, r *http.Request) {
  359. w.Header().Set("Content-Type", "application/json")
  360. caller, err := logic.GetUser(r.Header.Get("user"))
  361. if err != nil {
  362. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  363. return
  364. }
  365. var user models.User
  366. err = json.NewDecoder(r.Body).Decode(&user)
  367. if err != nil {
  368. logger.Log(0, user.UserName, "error decoding request body: ",
  369. err.Error())
  370. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  371. return
  372. }
  373. if user.PlatformRoleID == "" {
  374. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("platform role is missing"), "badrequest"))
  375. return
  376. }
  377. userRole, err := logic.GetRole(user.PlatformRoleID)
  378. if err != nil {
  379. err = errors.New("error fetching role " + user.PlatformRoleID.String() + " " + err.Error())
  380. slog.Error("error creating new user: ", "user", user.UserName, "error", err)
  381. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  382. return
  383. }
  384. if userRole.ID == models.SuperAdminRole {
  385. err = errors.New("additional superadmins cannot be created")
  386. slog.Error("error creating new user: ", "user", user.UserName, "error", err)
  387. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  388. return
  389. }
  390. if caller.PlatformRoleID != models.SuperAdminRole && user.PlatformRoleID == models.AdminRole {
  391. err = errors.New("only superadmin can create admin users")
  392. slog.Error("error creating new user: ", "user", user.UserName, "error", err)
  393. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  394. return
  395. }
  396. if !servercfg.IsPro && user.PlatformRoleID != models.AdminRole {
  397. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("non-admins users can only be created on Pro version"), "forbidden"))
  398. return
  399. }
  400. err = logic.CreateUser(&user)
  401. if err != nil {
  402. slog.Error("error creating new user: ", "user", user.UserName, "error", err.Error())
  403. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  404. return
  405. }
  406. logic.DeleteUserInvite(user.UserName)
  407. logic.DeletePendingUser(user.UserName)
  408. slog.Info("user was created", "username", user.UserName)
  409. json.NewEncoder(w).Encode(logic.ToReturnUser(user))
  410. }
  411. // swagger:route PUT /api/users/{username} user updateUser
  412. //
  413. // Update a user.
  414. //
  415. // Schemes: https
  416. //
  417. // Security:
  418. // oauth
  419. //
  420. // Responses:
  421. // 200: userBodyResponse
  422. func updateUser(w http.ResponseWriter, r *http.Request) {
  423. w.Header().Set("Content-Type", "application/json")
  424. var params = mux.Vars(r)
  425. // start here
  426. var caller *models.User
  427. var err error
  428. var ismaster bool
  429. if r.Header.Get("user") == logic.MasterUser {
  430. ismaster = true
  431. } else {
  432. caller, err = logic.GetUser(r.Header.Get("user"))
  433. if err != nil {
  434. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  435. }
  436. }
  437. username := params["username"]
  438. user, err := logic.GetUser(username)
  439. if err != nil {
  440. logger.Log(0, username,
  441. "failed to update user info: ", err.Error())
  442. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  443. return
  444. }
  445. var userchange models.User
  446. // we decode our body request params
  447. err = json.NewDecoder(r.Body).Decode(&userchange)
  448. if err != nil {
  449. slog.Error("failed to decode body", "error ", err.Error())
  450. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  451. return
  452. }
  453. if user.UserName != userchange.UserName {
  454. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user in param and request body not matching"), "badrequest"))
  455. return
  456. }
  457. selfUpdate := false
  458. if !ismaster && caller.UserName == user.UserName {
  459. selfUpdate = true
  460. }
  461. if !ismaster && !selfUpdate {
  462. if caller.PlatformRoleID == models.AdminRole && user.PlatformRoleID == models.SuperAdminRole {
  463. slog.Error("non-superadmin user", "caller", caller.UserName, "attempted to update superadmin user", username)
  464. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"))
  465. return
  466. }
  467. if caller.PlatformRoleID != models.AdminRole && caller.PlatformRoleID != models.SuperAdminRole {
  468. slog.Error("operation not allowed", "caller", caller.UserName, "attempted to update user", username)
  469. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"))
  470. return
  471. }
  472. if caller.PlatformRoleID == models.AdminRole && user.PlatformRoleID == models.AdminRole {
  473. slog.Error("admin user cannot update another admin", "caller", caller.UserName, "attempted to update admin user", username)
  474. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("admin user cannot update another admin"), "forbidden"))
  475. return
  476. }
  477. if caller.PlatformRoleID == models.AdminRole && userchange.PlatformRoleID == models.AdminRole {
  478. err = errors.New("admin user cannot update role of an another user to admin")
  479. slog.Error("failed to update user", "caller", caller.UserName, "attempted to update user", username, "error", err)
  480. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  481. return
  482. }
  483. }
  484. if !ismaster && selfUpdate {
  485. if user.PlatformRoleID != userchange.PlatformRoleID {
  486. slog.Error("user cannot change his own role", "caller", caller.UserName, "attempted to update user role", username)
  487. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"))
  488. return
  489. }
  490. if servercfg.IsPro {
  491. // user cannot update his own roles and groups
  492. if len(user.NetworkRoles) != len(userchange.NetworkRoles) || !reflect.DeepEqual(user.NetworkRoles, userchange.NetworkRoles) {
  493. err = errors.New("user cannot update self update their network roles")
  494. slog.Error("failed to update user", "caller", caller.UserName, "attempted to update user", username, "error", err)
  495. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  496. return
  497. }
  498. // user cannot update his own roles and groups
  499. if len(user.UserGroups) != len(userchange.UserGroups) || !reflect.DeepEqual(user.UserGroups, userchange.UserGroups) {
  500. err = errors.New("user cannot update self update their groups")
  501. slog.Error("failed to update user", "caller", caller.UserName, "attempted to update user", username, "error", err)
  502. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  503. return
  504. }
  505. }
  506. }
  507. if ismaster {
  508. if user.PlatformRoleID != models.SuperAdminRole && userchange.PlatformRoleID == models.SuperAdminRole {
  509. slog.Error("operation not allowed", "caller", logic.MasterUser, "attempted to update user role to superadmin", username)
  510. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("attempted to update user role to superadmin"), "forbidden"))
  511. return
  512. }
  513. }
  514. if logic.IsOauthUser(user) == nil && userchange.Password != "" {
  515. err := fmt.Errorf("cannot update user's password for an oauth user %s", username)
  516. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  517. return
  518. }
  519. user, err = logic.UpdateUser(&userchange, user)
  520. if err != nil {
  521. logger.Log(0, username,
  522. "failed to update user info: ", err.Error())
  523. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  524. return
  525. }
  526. logger.Log(1, username, "was updated")
  527. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  528. }
  529. // swagger:route DELETE /api/users/{username} user deleteUser
  530. //
  531. // Delete a user.
  532. //
  533. // Schemes: https
  534. //
  535. // Security:
  536. // oauth
  537. //
  538. // Responses:
  539. // 200: userBodyResponse
  540. func deleteUser(w http.ResponseWriter, r *http.Request) {
  541. // Set header
  542. w.Header().Set("Content-Type", "application/json")
  543. // get params
  544. var params = mux.Vars(r)
  545. caller, err := logic.GetUser(r.Header.Get("user"))
  546. if err != nil {
  547. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  548. }
  549. callerUserRole, err := logic.GetRole(caller.PlatformRoleID)
  550. if err != nil {
  551. slog.Error("failed to get role ", "role", callerUserRole.ID, "error", err)
  552. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  553. return
  554. }
  555. username := params["username"]
  556. user, err := logic.GetUser(username)
  557. if err != nil {
  558. logger.Log(0, username,
  559. "failed to update user info: ", err.Error())
  560. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  561. return
  562. }
  563. userRole, err := logic.GetRole(user.PlatformRoleID)
  564. if err != nil {
  565. slog.Error("failed to get role ", "role", userRole.ID, "error", err)
  566. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  567. return
  568. }
  569. if userRole.ID == models.SuperAdminRole {
  570. slog.Error(
  571. "failed to delete user: ", "user", username, "error", "superadmin cannot be deleted")
  572. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("superadmin cannot be deleted"), "internal"))
  573. return
  574. }
  575. if callerUserRole.ID != models.SuperAdminRole {
  576. if callerUserRole.ID == models.AdminRole && userRole.ID == models.AdminRole {
  577. slog.Error(
  578. "failed to delete user: ", "user", username, "error", "admin cannot delete another admin user, including oneself")
  579. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("admin cannot delete another admin user, including oneself"), "internal"))
  580. return
  581. }
  582. }
  583. success, err := logic.DeleteUser(username)
  584. if err != nil {
  585. logger.Log(0, username,
  586. "failed to delete user: ", err.Error())
  587. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  588. return
  589. } else if !success {
  590. err := errors.New("delete unsuccessful")
  591. logger.Log(0, username, err.Error())
  592. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  593. return
  594. }
  595. // check and delete extclient with this ownerID
  596. go func() {
  597. extclients, err := logic.GetAllExtClients()
  598. if err != nil {
  599. slog.Error("failed to get extclients", "error", err)
  600. return
  601. }
  602. for _, extclient := range extclients {
  603. if extclient.OwnerID == user.UserName {
  604. err = logic.DeleteExtClient(extclient.Network, extclient.ClientID)
  605. if err != nil {
  606. slog.Error("failed to delete extclient",
  607. "id", extclient.ClientID, "owner", user.UserName, "error", err)
  608. }
  609. }
  610. }
  611. if servercfg.IsDNSMode() {
  612. logic.SetDNS()
  613. }
  614. }()
  615. logger.Log(1, username, "was deleted")
  616. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  617. }
  618. // Called when vpn client dials in to start the auth flow and first stage is to get register URL itself
  619. func socketHandler(w http.ResponseWriter, r *http.Request) {
  620. // Upgrade our raw HTTP connection to a websocket based one
  621. conn, err := upgrader.Upgrade(w, r, nil)
  622. if err != nil {
  623. logger.Log(0, "error during connection upgrade for node sign-in:", err.Error())
  624. return
  625. }
  626. if conn == nil {
  627. logger.Log(0, "failed to establish web-socket connection during node sign-in")
  628. return
  629. }
  630. // Start handling the session
  631. go auth.SessionHandler(conn)
  632. }