user.go 25 KB

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