user.go 21 KB

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