2
0

user.go 31 KB

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