user.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "github.com/gorilla/mux"
  8. "github.com/gorilla/websocket"
  9. "github.com/gravitl/netmaker/auth"
  10. "github.com/gravitl/netmaker/database"
  11. "github.com/gravitl/netmaker/logger"
  12. "github.com/gravitl/netmaker/logic"
  13. "github.com/gravitl/netmaker/models"
  14. "github.com/gravitl/netmaker/mq"
  15. "github.com/gravitl/netmaker/servercfg"
  16. "golang.org/x/exp/slog"
  17. )
  18. var (
  19. upgrader = websocket.Upgrader{}
  20. )
  21. func userHandlers(r *mux.Router) {
  22. r.HandleFunc("/api/users/adm/hassuperadmin", hasSuperAdmin).Methods(http.MethodGet)
  23. r.HandleFunc("/api/users/adm/createsuperadmin", createSuperAdmin).Methods(http.MethodPost)
  24. r.HandleFunc("/api/users/adm/transfersuperadmin/{username}", logic.SecurityCheck(true, http.HandlerFunc(transferSuperAdmin))).
  25. Methods(http.MethodPost)
  26. r.HandleFunc("/api/users/adm/authenticate", authenticateUser).Methods(http.MethodPost)
  27. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(updateUser))).
  28. Methods(http.MethodPut)
  29. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, checkFreeTierLimits(limitChoiceUsers, http.HandlerFunc(createUser)))).
  30. Methods(http.MethodPost)
  31. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(true, http.HandlerFunc(deleteUser))).
  32. Methods(http.MethodDelete)
  33. r.HandleFunc("/api/users/{username}", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUser)))).
  34. Methods(http.MethodGet)
  35. r.HandleFunc("/api/users", logic.SecurityCheck(true, http.HandlerFunc(getUsers))).
  36. Methods(http.MethodGet)
  37. r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(getPendingUsers))).
  38. Methods(http.MethodGet)
  39. r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(deleteAllPendingUsers))).
  40. Methods(http.MethodDelete)
  41. r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(deletePendingUser))).
  42. Methods(http.MethodDelete)
  43. r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(approvePendingUser))).
  44. Methods(http.MethodPost)
  45. }
  46. // @Summary Authenticate a user to retrieve an authorization token
  47. // @Router /api/users/adm/authenticate [post]
  48. // @Tags Auth
  49. // @Accept json
  50. // @Param body body models.UserAuthParams true "Authentication parameters"
  51. // @Success 200 {object} models.SuccessResponse
  52. // @Failure 400 {object} models.ErrorResponse
  53. // @Failure 401 {object} models.ErrorResponse
  54. // @Failure 500 {object} models.ErrorResponse
  55. func authenticateUser(response http.ResponseWriter, request *http.Request) {
  56. // Auth request consists of Mac Address and Password (from node that is authorizing
  57. // in case of Master, auth is ignored and mac is set to "mastermac"
  58. var authRequest models.UserAuthParams
  59. var errorResponse = models.ErrorResponse{
  60. Code: http.StatusInternalServerError, Message: "W1R3: It's not you it's me.",
  61. }
  62. if !servercfg.IsBasicAuthEnabled() {
  63. logic.ReturnErrorResponse(
  64. response,
  65. request,
  66. logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"),
  67. )
  68. return
  69. }
  70. decoder := json.NewDecoder(request.Body)
  71. decoderErr := decoder.Decode(&authRequest)
  72. defer request.Body.Close()
  73. if decoderErr != nil {
  74. logger.Log(0, "error decoding request body: ",
  75. decoderErr.Error())
  76. logic.ReturnErrorResponse(response, request, errorResponse)
  77. return
  78. }
  79. if val := request.Header.Get("From-Ui"); val == "true" {
  80. // request came from UI, if normal user block Login
  81. user, err := logic.GetUser(authRequest.UserName)
  82. if err != nil {
  83. logger.Log(0, authRequest.UserName, "user validation failed: ",
  84. err.Error())
  85. logic.ReturnErrorResponse(response, request, logic.FormatError(err, "unauthorized"))
  86. return
  87. }
  88. if !(user.IsAdmin || user.IsSuperAdmin) {
  89. logic.ReturnErrorResponse(
  90. response,
  91. request,
  92. logic.FormatError(errors.New("only admins can access dashboard"), "unauthorized"),
  93. )
  94. return
  95. }
  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. // @Summary Get all users
  207. // @Router /api/users [get]
  208. // @Tags Users
  209. // @Success 200 {array} models.User
  210. // @Failure 500 {object} models.ErrorResponse
  211. func getUsers(w http.ResponseWriter, r *http.Request) {
  212. // set header.
  213. w.Header().Set("Content-Type", "application/json")
  214. users, err := logic.GetUsers()
  215. if err != nil {
  216. logger.Log(0, "failed to fetch users: ", err.Error())
  217. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  218. return
  219. }
  220. logic.SortUsers(users[:])
  221. logger.Log(2, r.Header.Get("user"), "fetched users")
  222. json.NewEncoder(w).Encode(users)
  223. }
  224. // @Summary Create a super admin
  225. // @Router /api/users/adm/createsuperadmin [post]
  226. // @Tags Users
  227. // @Param body body models.User true "User details"
  228. // @Success 200 {object} models.User
  229. // @Failure 400 {object} models.ErrorResponse
  230. // @Failure 500 {object} models.ErrorResponse
  231. func createSuperAdmin(w http.ResponseWriter, r *http.Request) {
  232. w.Header().Set("Content-Type", "application/json")
  233. var u models.User
  234. err := json.NewDecoder(r.Body).Decode(&u)
  235. if err != nil {
  236. slog.Error("error decoding request body", "error", err.Error())
  237. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  238. return
  239. }
  240. if !servercfg.IsBasicAuthEnabled() {
  241. logic.ReturnErrorResponse(
  242. w,
  243. r,
  244. logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"),
  245. )
  246. return
  247. }
  248. err = logic.CreateSuperAdmin(&u)
  249. if err != nil {
  250. slog.Error("failed to create admin", "error", err.Error())
  251. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  252. return
  253. }
  254. logger.Log(1, u.UserName, "was made a super admin")
  255. json.NewEncoder(w).Encode(logic.ToReturnUser(u))
  256. }
  257. // @Summary Transfer super admin role to another admin user
  258. // @Router /api/users/adm/transfersuperadmin/{username} [post]
  259. // @Tags Users
  260. // @Param username path string true "Username of the user to transfer super admin role"
  261. // @Success 200 {object} models.User
  262. // @Failure 403 {object} models.ErrorResponse
  263. // @Failure 500 {object} models.ErrorResponse
  264. func transferSuperAdmin(w http.ResponseWriter, r *http.Request) {
  265. w.Header().Set("Content-Type", "application/json")
  266. caller, err := logic.GetUser(r.Header.Get("user"))
  267. if err != nil {
  268. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  269. }
  270. if !caller.IsSuperAdmin {
  271. logic.ReturnErrorResponse(
  272. w,
  273. r,
  274. logic.FormatError(
  275. errors.New("only superadmin can assign the superadmin role to another user"),
  276. "forbidden",
  277. ),
  278. )
  279. return
  280. }
  281. var params = mux.Vars(r)
  282. username := params["username"]
  283. u, err := logic.GetUser(username)
  284. if err != nil {
  285. slog.Error("error getting user", "user", u.UserName, "error", err.Error())
  286. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  287. return
  288. }
  289. if !u.IsAdmin {
  290. logic.ReturnErrorResponse(
  291. w,
  292. r,
  293. logic.FormatError(
  294. errors.New("only admins can be promoted to superadmin role"),
  295. "forbidden",
  296. ),
  297. )
  298. return
  299. }
  300. if !servercfg.IsBasicAuthEnabled() {
  301. logic.ReturnErrorResponse(
  302. w,
  303. r,
  304. logic.FormatError(fmt.Errorf("basic auth is disabled"), "badrequest"),
  305. )
  306. return
  307. }
  308. u.IsSuperAdmin = true
  309. u.IsAdmin = false
  310. err = logic.UpsertUser(*u)
  311. if err != nil {
  312. slog.Error("error updating user to superadmin: ", "user", u.UserName, "error", err.Error())
  313. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  314. return
  315. }
  316. caller.IsSuperAdmin = false
  317. caller.IsAdmin = true
  318. err = logic.UpsertUser(*caller)
  319. if err != nil {
  320. slog.Error("error demoting user to admin: ", "user", caller.UserName, "error", err.Error())
  321. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  322. return
  323. }
  324. slog.Info("user was made a super admin", "user", u.UserName)
  325. json.NewEncoder(w).Encode(logic.ToReturnUser(*u))
  326. }
  327. // @Summary Create a user
  328. // @Router /api/users/{username} [post]
  329. // @Tags Users
  330. // @Param username path string true "Username of the user to create"
  331. // @Param body body models.User true "User details"
  332. // @Success 200 {object} models.User
  333. // @Failure 400 {object} models.ErrorResponse
  334. // @Failure 403 {object} models.ErrorResponse
  335. // @Failure 500 {object} models.ErrorResponse
  336. func createUser(w http.ResponseWriter, r *http.Request) {
  337. w.Header().Set("Content-Type", "application/json")
  338. caller, err := logic.GetUser(r.Header.Get("user"))
  339. if err != nil {
  340. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  341. return
  342. }
  343. var user models.User
  344. err = json.NewDecoder(r.Body).Decode(&user)
  345. if err != nil {
  346. logger.Log(0, user.UserName, "error decoding request body: ",
  347. err.Error())
  348. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  349. return
  350. }
  351. if !caller.IsSuperAdmin && user.IsAdmin {
  352. err = errors.New("only superadmin can create admin users")
  353. slog.Error("error creating new user: ", "user", user.UserName, "error", err)
  354. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  355. return
  356. }
  357. if user.IsSuperAdmin {
  358. err = errors.New("additional superadmins cannot be created")
  359. slog.Error("error creating new user: ", "user", user.UserName, "error", err)
  360. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  361. return
  362. }
  363. if !servercfg.IsPro && !user.IsAdmin {
  364. logic.ReturnErrorResponse(
  365. w,
  366. r,
  367. logic.FormatError(
  368. errors.New("non-admins users can only be created on Pro version"),
  369. "forbidden",
  370. ),
  371. )
  372. return
  373. }
  374. err = logic.CreateUser(&user)
  375. if err != nil {
  376. slog.Error("error creating new user: ", "user", user.UserName, "error", err.Error())
  377. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  378. return
  379. }
  380. slog.Info("user was created", "username", user.UserName)
  381. json.NewEncoder(w).Encode(logic.ToReturnUser(user))
  382. }
  383. // @Summary Update a user
  384. // @Router /api/users/{username} [put]
  385. // @Tags Users
  386. // @Param username path string true "Username of the user to update"
  387. // @Param body body models.User true "User details"
  388. // @Success 200 {object} models.User
  389. // @Failure 400 {object} models.ErrorResponse
  390. // @Failure 403 {object} models.ErrorResponse
  391. // @Failure 500 {object} models.ErrorResponse
  392. func updateUser(w http.ResponseWriter, r *http.Request) {
  393. w.Header().Set("Content-Type", "application/json")
  394. var params = mux.Vars(r)
  395. // start here
  396. var caller *models.User
  397. var err error
  398. var ismaster bool
  399. if r.Header.Get("user") == logic.MasterUser {
  400. ismaster = true
  401. } else {
  402. caller, err = logic.GetUser(r.Header.Get("user"))
  403. if err != nil {
  404. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  405. }
  406. }
  407. username := params["username"]
  408. user, err := logic.GetUser(username)
  409. if err != nil {
  410. logger.Log(0, username,
  411. "failed to update user info: ", err.Error())
  412. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  413. return
  414. }
  415. var userchange models.User
  416. // we decode our body request params
  417. err = json.NewDecoder(r.Body).Decode(&userchange)
  418. if err != nil {
  419. slog.Error("failed to decode body", "error ", err.Error())
  420. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  421. return
  422. }
  423. if user.UserName != userchange.UserName {
  424. logic.ReturnErrorResponse(
  425. w,
  426. r,
  427. logic.FormatError(
  428. errors.New("user in param and request body not matching"),
  429. "badrequest",
  430. ),
  431. )
  432. return
  433. }
  434. selfUpdate := false
  435. if !ismaster && caller.UserName == user.UserName {
  436. selfUpdate = true
  437. }
  438. if !ismaster && !selfUpdate {
  439. if caller.IsAdmin && user.IsSuperAdmin {
  440. slog.Error(
  441. "non-superadmin user",
  442. "caller",
  443. caller.UserName,
  444. "attempted to update superadmin user",
  445. username,
  446. )
  447. logic.ReturnErrorResponse(
  448. w,
  449. r,
  450. logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"),
  451. )
  452. return
  453. }
  454. if !caller.IsAdmin && !caller.IsSuperAdmin {
  455. slog.Error(
  456. "operation not allowed",
  457. "caller",
  458. caller.UserName,
  459. "attempted to update user",
  460. username,
  461. )
  462. logic.ReturnErrorResponse(
  463. w,
  464. r,
  465. logic.FormatError(errors.New("cannot update superadmin user"), "forbidden"),
  466. )
  467. return
  468. }
  469. if caller.IsAdmin && user.IsAdmin {
  470. slog.Error(
  471. "admin user cannot update another admin",
  472. "caller",
  473. caller.UserName,
  474. "attempted to update admin user",
  475. username,
  476. )
  477. logic.ReturnErrorResponse(
  478. w,
  479. r,
  480. logic.FormatError(
  481. errors.New("admin user cannot update another admin"),
  482. "forbidden",
  483. ),
  484. )
  485. return
  486. }
  487. if caller.IsAdmin && userchange.IsAdmin {
  488. err = errors.New("admin user cannot update role of an another user to admin")
  489. slog.Error(
  490. "failed to update user",
  491. "caller",
  492. caller.UserName,
  493. "attempted to update user",
  494. username,
  495. "error",
  496. err,
  497. )
  498. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  499. return
  500. }
  501. }
  502. if !ismaster && selfUpdate {
  503. if user.IsAdmin != userchange.IsAdmin || user.IsSuperAdmin != userchange.IsSuperAdmin {
  504. slog.Error(
  505. "user cannot change his own role",
  506. "caller",
  507. caller.UserName,
  508. "attempted to update user role",
  509. username,
  510. )
  511. logic.ReturnErrorResponse(
  512. w,
  513. r,
  514. logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"),
  515. )
  516. return
  517. }
  518. }
  519. if ismaster {
  520. if !user.IsSuperAdmin && userchange.IsSuperAdmin {
  521. slog.Error(
  522. "operation not allowed",
  523. "caller",
  524. logic.MasterUser,
  525. "attempted to update user role to superadmin",
  526. username,
  527. )
  528. logic.ReturnErrorResponse(
  529. w,
  530. r,
  531. logic.FormatError(
  532. errors.New("attempted to update user role to superadmin"),
  533. "forbidden",
  534. ),
  535. )
  536. return
  537. }
  538. }
  539. if auth.IsOauthUser(user) == nil && userchange.Password != "" {
  540. err := fmt.Errorf("cannot update user's password for an oauth user %s", username)
  541. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
  542. return
  543. }
  544. user, err = logic.UpdateUser(&userchange, user)
  545. if err != nil {
  546. logger.Log(0, username,
  547. "failed to update user info: ", err.Error())
  548. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  549. return
  550. }
  551. logger.Log(1, username, "was updated")
  552. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  553. }
  554. // @Summary Delete a user
  555. // @Router /api/users/{username} [delete]
  556. // @Tags Users
  557. // @Param username path string true "Username of the user to delete"
  558. // @Success 200 {string} string
  559. // @Failure 500 {object} models.ErrorResponse
  560. func deleteUser(w http.ResponseWriter, r *http.Request) {
  561. // Set header
  562. w.Header().Set("Content-Type", "application/json")
  563. // get params
  564. var params = mux.Vars(r)
  565. caller, err := logic.GetUser(r.Header.Get("user"))
  566. if err != nil {
  567. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  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. if user.IsSuperAdmin {
  578. slog.Error(
  579. "failed to delete user: ", "user", username, "error", "superadmin cannot be deleted")
  580. logic.ReturnErrorResponse(
  581. w,
  582. r,
  583. logic.FormatError(fmt.Errorf("superadmin cannot be deleted"), "internal"),
  584. )
  585. return
  586. }
  587. if !caller.IsSuperAdmin {
  588. if caller.IsAdmin && user.IsAdmin {
  589. slog.Error(
  590. "failed to delete user: ",
  591. "user",
  592. username,
  593. "error",
  594. "admin cannot delete another admin user, including oneself",
  595. )
  596. logic.ReturnErrorResponse(
  597. w,
  598. r,
  599. logic.FormatError(
  600. fmt.Errorf("admin cannot delete another admin user, including oneself"),
  601. "internal",
  602. ),
  603. )
  604. return
  605. }
  606. }
  607. success, err := logic.DeleteUser(username)
  608. if err != nil {
  609. logger.Log(0, username,
  610. "failed to delete user: ", err.Error())
  611. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  612. return
  613. } else if !success {
  614. err := errors.New("delete unsuccessful")
  615. logger.Log(0, username, err.Error())
  616. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  617. return
  618. }
  619. // check and delete extclient with this ownerID
  620. go func() {
  621. extclients, err := logic.GetAllExtClients()
  622. if err != nil {
  623. slog.Error("failed to get extclients", "error", err)
  624. return
  625. }
  626. for _, extclient := range extclients {
  627. if extclient.OwnerID == user.UserName {
  628. err = logic.DeleteExtClient(extclient.Network, extclient.ClientID)
  629. if err != nil {
  630. slog.Error("failed to delete extclient",
  631. "id", extclient.ClientID, "owner", user.UserName, "error", err)
  632. }
  633. }
  634. }
  635. if servercfg.IsDNSMode() {
  636. logic.SetDNS()
  637. }
  638. }()
  639. logger.Log(1, username, "was deleted")
  640. json.NewEncoder(w).Encode(params["username"] + " deleted.")
  641. }
  642. // Called when vpn client dials in to start the auth flow and first stage is to get register URL itself
  643. func socketHandler(w http.ResponseWriter, r *http.Request) {
  644. // Upgrade our raw HTTP connection to a websocket based one
  645. conn, err := upgrader.Upgrade(w, r, nil)
  646. if err != nil {
  647. logger.Log(0, "error during connection upgrade for node sign-in:", err.Error())
  648. return
  649. }
  650. if conn == nil {
  651. logger.Log(0, "failed to establish web-socket connection during node sign-in")
  652. return
  653. }
  654. // Start handling the session
  655. go auth.SessionHandler(conn)
  656. }
  657. // @Summary Get all pending users
  658. // @Router /api/users_pending [get]
  659. // @Tags Users
  660. // @Success 200 {array} models.User
  661. // @Failure 500 {object} models.ErrorResponse
  662. func getPendingUsers(w http.ResponseWriter, r *http.Request) {
  663. // set header.
  664. w.Header().Set("Content-Type", "application/json")
  665. users, err := logic.ListPendingUsers()
  666. if err != nil {
  667. logger.Log(0, "failed to fetch users: ", err.Error())
  668. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  669. return
  670. }
  671. logic.SortUsers(users[:])
  672. logger.Log(2, r.Header.Get("user"), "fetched pending users")
  673. json.NewEncoder(w).Encode(users)
  674. }
  675. // @Summary Approve a pending user
  676. // @Router /api/users_pending/user/{username} [post]
  677. // @Tags Users
  678. // @Param username path string true "Username of the pending user to approve"
  679. // @Success 200 {string} string
  680. // @Failure 500 {object} models.ErrorResponse
  681. func approvePendingUser(w http.ResponseWriter, r *http.Request) {
  682. // set header.
  683. w.Header().Set("Content-Type", "application/json")
  684. var params = mux.Vars(r)
  685. username := params["username"]
  686. users, err := logic.ListPendingUsers()
  687. if err != nil {
  688. logger.Log(0, "failed to fetch users: ", err.Error())
  689. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  690. return
  691. }
  692. for _, user := range users {
  693. if user.UserName == username {
  694. var newPass, fetchErr = auth.FetchPassValue("")
  695. if fetchErr != nil {
  696. logic.ReturnErrorResponse(w, r, logic.FormatError(fetchErr, "internal"))
  697. return
  698. }
  699. if err = logic.CreateUser(&models.User{
  700. UserName: user.UserName,
  701. Password: newPass,
  702. }); err != nil {
  703. logic.ReturnErrorResponse(
  704. w,
  705. r,
  706. logic.FormatError(fmt.Errorf("failed to create user: %s", err), "internal"),
  707. )
  708. return
  709. }
  710. err = logic.DeletePendingUser(username)
  711. if err != nil {
  712. logic.ReturnErrorResponse(
  713. w,
  714. r,
  715. logic.FormatError(
  716. fmt.Errorf("failed to delete pending user: %s", err),
  717. "internal",
  718. ),
  719. )
  720. return
  721. }
  722. break
  723. }
  724. }
  725. logic.ReturnSuccessResponse(w, r, "approved "+username)
  726. }
  727. // @Summary Delete a pending user
  728. // @Router /api/users_pending/user/{username} [delete]
  729. // @Tags Users
  730. // @Param username path string true "Username of the pending user to delete"
  731. // @Success 200 {string} string
  732. // @Failure 500 {object} models.ErrorResponse
  733. func deletePendingUser(w http.ResponseWriter, r *http.Request) {
  734. // set header.
  735. w.Header().Set("Content-Type", "application/json")
  736. var params = mux.Vars(r)
  737. username := params["username"]
  738. users, err := logic.ListPendingUsers()
  739. if err != nil {
  740. logger.Log(0, "failed to fetch users: ", err.Error())
  741. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  742. return
  743. }
  744. for _, user := range users {
  745. if user.UserName == username {
  746. err = logic.DeletePendingUser(username)
  747. if err != nil {
  748. logic.ReturnErrorResponse(
  749. w,
  750. r,
  751. logic.FormatError(
  752. fmt.Errorf("failed to delete pending user: %s", err),
  753. "internal",
  754. ),
  755. )
  756. return
  757. }
  758. break
  759. }
  760. }
  761. logic.ReturnSuccessResponse(w, r, "deleted pending "+username)
  762. }
  763. // @Summary Delete all pending users
  764. // @Router /api/users_pending [delete]
  765. // @Tags Users
  766. // @Success 200 {string} string
  767. // @Failure 500 {object} models.ErrorResponse
  768. func deleteAllPendingUsers(w http.ResponseWriter, r *http.Request) {
  769. // set header.
  770. w.Header().Set("Content-Type", "application/json")
  771. err := database.DeleteAllRecords(database.PENDING_USERS_TABLE_NAME)
  772. if err != nil {
  773. logic.ReturnErrorResponse(
  774. w,
  775. r,
  776. logic.FormatError(
  777. errors.New("failed to delete all pending users "+err.Error()),
  778. "internal",
  779. ),
  780. )
  781. return
  782. }
  783. logic.ReturnSuccessResponse(w, r, "cleared all pending users")
  784. }