2
0

user.go 24 KB

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