user.go 25 KB

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