users.go 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681
  1. package controllers
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "net/http"
  8. "net/url"
  9. "strings"
  10. "time"
  11. "github.com/google/uuid"
  12. "github.com/gorilla/mux"
  13. "github.com/gravitl/netmaker/database"
  14. "github.com/gravitl/netmaker/logger"
  15. "github.com/gravitl/netmaker/logic"
  16. "github.com/gravitl/netmaker/models"
  17. "github.com/gravitl/netmaker/mq"
  18. proAuth "github.com/gravitl/netmaker/pro/auth"
  19. "github.com/gravitl/netmaker/pro/email"
  20. proLogic "github.com/gravitl/netmaker/pro/logic"
  21. "github.com/gravitl/netmaker/servercfg"
  22. "github.com/gravitl/netmaker/utils"
  23. "golang.org/x/exp/slog"
  24. )
  25. func UserHandlers(r *mux.Router) {
  26. r.HandleFunc("/api/oauth/login", proAuth.HandleAuthLogin).Methods(http.MethodGet)
  27. r.HandleFunc("/api/oauth/callback", proAuth.HandleAuthCallback).Methods(http.MethodGet)
  28. r.HandleFunc("/api/oauth/headless", proAuth.HandleHeadlessSSO)
  29. r.HandleFunc("/api/oauth/register/{regKey}", proAuth.RegisterHostSSO).Methods(http.MethodGet)
  30. // User Role Handlers
  31. r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(getRole))).Methods(http.MethodGet)
  32. r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(createRole))).Methods(http.MethodPost)
  33. r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(updateRole))).Methods(http.MethodPut)
  34. r.HandleFunc("/api/v1/users/role", logic.SecurityCheck(true, http.HandlerFunc(deleteRole))).Methods(http.MethodDelete)
  35. // User Group Handlers
  36. r.HandleFunc("/api/v1/users/groups", logic.SecurityCheck(true, http.HandlerFunc(listUserGroups))).Methods(http.MethodGet)
  37. r.HandleFunc("/api/v1/users/group", logic.SecurityCheck(true, http.HandlerFunc(getUserGroup))).Methods(http.MethodGet)
  38. r.HandleFunc("/api/v1/users/group", logic.SecurityCheck(true, http.HandlerFunc(createUserGroup))).Methods(http.MethodPost)
  39. r.HandleFunc("/api/v1/users/group", logic.SecurityCheck(true, http.HandlerFunc(updateUserGroup))).Methods(http.MethodPut)
  40. r.HandleFunc("/api/v1/users/group", logic.SecurityCheck(true, http.HandlerFunc(deleteUserGroup))).Methods(http.MethodDelete)
  41. // User Invite Handlers
  42. r.HandleFunc("/api/v1/users/invite", userInviteVerify).Methods(http.MethodGet)
  43. r.HandleFunc("/api/v1/users/invite-signup", userInviteSignUp).Methods(http.MethodPost)
  44. r.HandleFunc("/api/v1/users/invite", logic.SecurityCheck(true, http.HandlerFunc(inviteUsers))).Methods(http.MethodPost)
  45. r.HandleFunc("/api/v1/users/invites", logic.SecurityCheck(true, http.HandlerFunc(listUserInvites))).Methods(http.MethodGet)
  46. r.HandleFunc("/api/v1/users/invite", logic.SecurityCheck(true, http.HandlerFunc(deleteUserInvite))).Methods(http.MethodDelete)
  47. r.HandleFunc("/api/v1/users/invites", logic.SecurityCheck(true, http.HandlerFunc(deleteAllUserInvites))).Methods(http.MethodDelete)
  48. r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(getPendingUsers))).Methods(http.MethodGet)
  49. r.HandleFunc("/api/users_pending", logic.SecurityCheck(true, http.HandlerFunc(deleteAllPendingUsers))).Methods(http.MethodDelete)
  50. r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(deletePendingUser))).Methods(http.MethodDelete)
  51. r.HandleFunc("/api/users_pending/user/{username}", logic.SecurityCheck(true, http.HandlerFunc(approvePendingUser))).Methods(http.MethodPost)
  52. r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(attachUserToRemoteAccessGw))).Methods(http.MethodPost)
  53. r.HandleFunc("/api/users/{username}/remote_access_gw/{remote_access_gateway_id}", logic.SecurityCheck(true, http.HandlerFunc(removeUserFromRemoteAccessGW))).Methods(http.MethodDelete)
  54. r.HandleFunc("/api/users/{username}/remote_access_gw", logic.SecurityCheck(false, logic.ContinueIfUserMatch(http.HandlerFunc(getUserRemoteAccessGwsV1)))).Methods(http.MethodGet)
  55. r.HandleFunc("/api/users/ingress/{ingress_id}", logic.SecurityCheck(true, http.HandlerFunc(ingressGatewayUsers))).Methods(http.MethodGet)
  56. r.HandleFunc("/api/idp/sync", logic.SecurityCheck(true, http.HandlerFunc(syncIDP))).Methods(http.MethodPost)
  57. r.HandleFunc("/api/idp", logic.SecurityCheck(true, http.HandlerFunc(removeIDPIntegration))).Methods(http.MethodDelete)
  58. }
  59. // swagger:route POST /api/v1/users/invite-signup user userInviteSignUp
  60. //
  61. // user signup via invite.
  62. //
  63. // Schemes: https
  64. //
  65. // Responses:
  66. // 200: ReturnSuccessResponse
  67. func userInviteSignUp(w http.ResponseWriter, r *http.Request) {
  68. email := r.URL.Query().Get("email")
  69. code := r.URL.Query().Get("invite_code")
  70. in, err := logic.GetUserInvite(email)
  71. if err != nil {
  72. logger.Log(0, "failed to fetch users: ", err.Error())
  73. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  74. return
  75. }
  76. if code != in.InviteCode {
  77. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid invite code"), "badrequest"))
  78. return
  79. }
  80. // check if user already exists
  81. _, err = logic.GetUser(email)
  82. if err == nil {
  83. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user already exists"), "badrequest"))
  84. return
  85. }
  86. var user models.User
  87. err = json.NewDecoder(r.Body).Decode(&user)
  88. if err != nil {
  89. logger.Log(0, user.UserName, "error decoding request body: ",
  90. err.Error())
  91. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  92. return
  93. }
  94. if user.UserName != email {
  95. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("username not matching with invite"), "badrequest"))
  96. return
  97. }
  98. if user.Password == "" {
  99. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("password cannot be empty"), "badrequest"))
  100. return
  101. }
  102. user.UserGroups = in.UserGroups
  103. user.PlatformRoleID = models.UserRoleID(in.PlatformRoleID)
  104. if user.PlatformRoleID == "" {
  105. user.PlatformRoleID = models.ServiceUser
  106. }
  107. user.NetworkRoles = in.NetworkRoles
  108. err = logic.CreateUser(&user)
  109. if err != nil {
  110. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  111. return
  112. }
  113. // delete invite
  114. logic.DeleteUserInvite(email)
  115. logic.DeletePendingUser(email)
  116. w.Header().Set("Access-Control-Allow-Origin", "*")
  117. logic.ReturnSuccessResponse(w, r, "created user successfully "+email)
  118. }
  119. // swagger:route GET /api/v1/users/invite user userInviteVerify
  120. //
  121. // verfies user invite.
  122. //
  123. // Schemes: https
  124. //
  125. // Responses:
  126. // 200: ReturnSuccessResponse
  127. func userInviteVerify(w http.ResponseWriter, r *http.Request) {
  128. email := r.URL.Query().Get("email")
  129. code := r.URL.Query().Get("invite_code")
  130. err := logic.ValidateAndApproveUserInvite(email, code)
  131. if err != nil {
  132. logger.Log(0, "failed to fetch users: ", err.Error())
  133. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  134. return
  135. }
  136. logic.ReturnSuccessResponse(w, r, "invite is valid")
  137. }
  138. // swagger:route POST /api/v1/users/invite user inviteUsers
  139. //
  140. // invite users.
  141. //
  142. // Schemes: https
  143. //
  144. // Security:
  145. // oauth
  146. //
  147. // Responses:
  148. // 200: userBodyResponse
  149. func inviteUsers(w http.ResponseWriter, r *http.Request) {
  150. var inviteReq models.InviteUsersReq
  151. err := json.NewDecoder(r.Body).Decode(&inviteReq)
  152. if err != nil {
  153. slog.Error("error decoding request body", "error",
  154. err.Error())
  155. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  156. return
  157. }
  158. callerUserName := r.Header.Get("user")
  159. if r.Header.Get("ismaster") != "yes" {
  160. caller, err := logic.GetUser(callerUserName)
  161. if err != nil {
  162. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "notfound"))
  163. return
  164. }
  165. if inviteReq.PlatformRoleID == models.SuperAdminRole.String() {
  166. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("super admin cannot be invited"), "badrequest"))
  167. return
  168. }
  169. if inviteReq.PlatformRoleID == "" {
  170. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("platform role id cannot be empty"), "badrequest"))
  171. return
  172. }
  173. if (inviteReq.PlatformRoleID == models.AdminRole.String() ||
  174. inviteReq.PlatformRoleID == models.SuperAdminRole.String()) && caller.PlatformRoleID != models.SuperAdminRole {
  175. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("only superadmin can invite admin users"), "forbidden"))
  176. return
  177. }
  178. }
  179. //validate Req
  180. err = proLogic.IsGroupsValid(inviteReq.UserGroups)
  181. if err != nil {
  182. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  183. return
  184. }
  185. err = proLogic.IsNetworkRolesValid(inviteReq.NetworkRoles)
  186. if err != nil {
  187. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  188. return
  189. }
  190. // check platform role
  191. _, err = logic.GetRole(models.UserRoleID(inviteReq.PlatformRoleID))
  192. if err != nil {
  193. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  194. return
  195. }
  196. for _, inviteeEmail := range inviteReq.UserEmails {
  197. inviteeEmail = strings.ToLower(inviteeEmail)
  198. // check if user with email exists, then ignore
  199. if !email.IsValid(inviteeEmail) {
  200. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid email "+inviteeEmail), "badrequest"))
  201. return
  202. }
  203. _, err := logic.GetUser(inviteeEmail)
  204. if err == nil {
  205. // user exists already, so ignore
  206. continue
  207. }
  208. invite := models.UserInvite{
  209. Email: inviteeEmail,
  210. PlatformRoleID: inviteReq.PlatformRoleID,
  211. UserGroups: inviteReq.UserGroups,
  212. NetworkRoles: inviteReq.NetworkRoles,
  213. InviteCode: logic.RandomString(8),
  214. }
  215. frontendURL := strings.TrimSuffix(servercfg.GetFrontendURL(), "/")
  216. if frontendURL == "" {
  217. frontendURL = fmt.Sprintf("https://dashboard.%s", servercfg.GetNmBaseDomain())
  218. }
  219. u, err := url.Parse(fmt.Sprintf("%s/invite?email=%s&invite_code=%s",
  220. frontendURL, url.QueryEscape(invite.Email), url.QueryEscape(invite.InviteCode)))
  221. if err != nil {
  222. slog.Error("failed to parse to invite url", "error", err)
  223. return
  224. }
  225. if servercfg.DeployedByOperator() {
  226. u, err = url.Parse(fmt.Sprintf("%s/invite?tenant_id=%s&email=%s&invite_code=%s",
  227. proLogic.GetAccountsUIHost(), url.QueryEscape(servercfg.GetNetmakerTenantID()), url.QueryEscape(invite.Email), url.QueryEscape(invite.InviteCode)))
  228. if err != nil {
  229. slog.Error("failed to parse to invite url", "error", err)
  230. return
  231. }
  232. }
  233. invite.InviteURL = u.String()
  234. err = logic.InsertUserInvite(invite)
  235. if err != nil {
  236. slog.Error("failed to insert invite for user", "email", invite.Email, "error", err)
  237. }
  238. logic.LogEvent(&models.Event{
  239. Action: models.Create,
  240. Source: models.Subject{
  241. ID: callerUserName,
  242. Name: callerUserName,
  243. Type: models.UserSub,
  244. Info: invite,
  245. },
  246. TriggeredBy: callerUserName,
  247. Target: models.Subject{
  248. ID: inviteeEmail,
  249. Name: inviteeEmail,
  250. Type: models.UserInviteSub,
  251. },
  252. Origin: models.Dashboard,
  253. })
  254. // notify user with magic link
  255. go func(invite models.UserInvite) {
  256. // Set E-Mail body. You can set plain text or html with text/html
  257. e := email.UserInvitedMail{
  258. BodyBuilder: &email.EmailBodyBuilderWithH1HeadlineAndImage{},
  259. InviteURL: invite.InviteURL,
  260. PlatformRoleID: invite.PlatformRoleID,
  261. }
  262. n := email.Notification{
  263. RecipientMail: invite.Email,
  264. }
  265. err = email.GetClient().SendEmail(context.Background(), n, e)
  266. if err != nil {
  267. slog.Error("failed to send email invite", "user", invite.Email, "error", err)
  268. }
  269. }(invite)
  270. }
  271. logic.ReturnSuccessResponse(w, r, "triggered user invites")
  272. }
  273. // swagger:route GET /api/v1/users/invites user listUserInvites
  274. //
  275. // lists all pending invited users.
  276. //
  277. // Schemes: https
  278. //
  279. // Security:
  280. // oauth
  281. //
  282. // Responses:
  283. // 200: ReturnSuccessResponseWithJson
  284. func listUserInvites(w http.ResponseWriter, r *http.Request) {
  285. usersInvites, err := logic.ListUserInvites()
  286. if err != nil {
  287. logger.Log(0, "failed to fetch users: ", err.Error())
  288. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  289. return
  290. }
  291. logic.ReturnSuccessResponseWithJson(w, r, usersInvites, "fetched pending user invites")
  292. }
  293. // swagger:route DELETE /api/v1/users/invite user deleteUserInvite
  294. //
  295. // delete pending invite.
  296. //
  297. // Schemes: https
  298. //
  299. // Security:
  300. // oauth
  301. //
  302. // Responses:
  303. // 200: ReturnSuccessResponse
  304. func deleteUserInvite(w http.ResponseWriter, r *http.Request) {
  305. email := r.URL.Query().Get("invitee_email")
  306. err := logic.DeleteUserInvite(email)
  307. if err != nil {
  308. logger.Log(0, "failed to delete user invite: ", email, err.Error())
  309. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  310. return
  311. }
  312. logic.LogEvent(&models.Event{
  313. Action: models.Delete,
  314. Source: models.Subject{
  315. ID: r.Header.Get("user"),
  316. Name: r.Header.Get("user"),
  317. Type: models.UserSub,
  318. },
  319. TriggeredBy: r.Header.Get("user"),
  320. Target: models.Subject{
  321. ID: email,
  322. Name: email,
  323. Type: models.UserInviteSub,
  324. },
  325. Origin: models.Dashboard,
  326. })
  327. logic.ReturnSuccessResponse(w, r, "deleted user invite")
  328. }
  329. // swagger:route DELETE /api/v1/users/invites user deleteAllUserInvites
  330. //
  331. // deletes all pending invites.
  332. //
  333. // Schemes: https
  334. //
  335. // Security:
  336. // oauth
  337. //
  338. // Responses:
  339. // 200: ReturnSuccessResponse
  340. func deleteAllUserInvites(w http.ResponseWriter, r *http.Request) {
  341. err := database.DeleteAllRecords(database.USER_INVITES_TABLE_NAME)
  342. if err != nil {
  343. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to delete all pending user invites "+err.Error()), "internal"))
  344. return
  345. }
  346. logic.LogEvent(&models.Event{
  347. Action: models.DeleteAll,
  348. Source: models.Subject{
  349. ID: r.Header.Get("user"),
  350. Name: r.Header.Get("user"),
  351. Type: models.UserSub,
  352. },
  353. TriggeredBy: r.Header.Get("user"),
  354. Target: models.Subject{
  355. ID: "All Invites",
  356. Name: "All Invites",
  357. Type: models.UserInviteSub,
  358. },
  359. Origin: models.Dashboard,
  360. })
  361. logic.ReturnSuccessResponse(w, r, "cleared all pending user invites")
  362. }
  363. // swagger:route GET /api/v1/user/groups user listUserGroups
  364. //
  365. // Get all user groups.
  366. //
  367. // Schemes: https
  368. //
  369. // Security:
  370. // oauth
  371. //
  372. // Responses:
  373. // 200: userBodyResponse
  374. func listUserGroups(w http.ResponseWriter, r *http.Request) {
  375. groups, err := proLogic.ListUserGroups()
  376. if err != nil {
  377. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  378. Code: http.StatusInternalServerError,
  379. Message: err.Error(),
  380. })
  381. return
  382. }
  383. logic.ReturnSuccessResponseWithJson(w, r, groups, "successfully fetched user groups")
  384. }
  385. // swagger:route GET /api/v1/user/group user getUserGroup
  386. //
  387. // Get user group.
  388. //
  389. // Schemes: https
  390. //
  391. // Security:
  392. // oauth
  393. //
  394. // Responses:
  395. // 200: userBodyResponse
  396. func getUserGroup(w http.ResponseWriter, r *http.Request) {
  397. gid := r.URL.Query().Get("group_id")
  398. if gid == "" {
  399. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("group id is required"), "badrequest"))
  400. return
  401. }
  402. group, err := proLogic.GetUserGroup(models.UserGroupID(gid))
  403. if err != nil {
  404. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  405. Code: http.StatusInternalServerError,
  406. Message: err.Error(),
  407. })
  408. return
  409. }
  410. logic.ReturnSuccessResponseWithJson(w, r, group, "successfully fetched user group")
  411. }
  412. // swagger:route POST /api/v1/user/group user createUserGroup
  413. //
  414. // Create user groups.
  415. //
  416. // Schemes: https
  417. //
  418. // Security:
  419. // oauth
  420. //
  421. // Responses:
  422. // 200: userBodyResponse
  423. func createUserGroup(w http.ResponseWriter, r *http.Request) {
  424. var userGroupReq models.CreateGroupReq
  425. err := json.NewDecoder(r.Body).Decode(&userGroupReq)
  426. if err != nil {
  427. slog.Error("error decoding request body", "error",
  428. err.Error())
  429. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  430. return
  431. }
  432. err = proLogic.ValidateCreateGroupReq(userGroupReq.Group)
  433. if err != nil {
  434. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  435. return
  436. }
  437. err = proLogic.CreateUserGroup(&userGroupReq.Group)
  438. if err != nil {
  439. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  440. return
  441. }
  442. networks, err := logic.GetNetworks()
  443. if err != nil {
  444. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  445. return
  446. }
  447. for _, network := range networks {
  448. acl := models.Acl{
  449. ID: uuid.New().String(),
  450. Name: fmt.Sprintf("%s group", userGroupReq.Group.Name),
  451. MetaData: "This Policy allows user group to communicate with all gateways",
  452. Default: false,
  453. ServiceType: models.Any,
  454. NetworkID: models.NetworkID(network.NetID),
  455. Proto: models.ALL,
  456. RuleType: models.UserPolicy,
  457. Src: []models.AclPolicyTag{
  458. {
  459. ID: models.UserGroupAclID,
  460. Value: userGroupReq.Group.ID.String(),
  461. },
  462. },
  463. Dst: []models.AclPolicyTag{
  464. {
  465. ID: models.NodeTagID,
  466. Value: fmt.Sprintf("%s.%s", models.NetworkID(network.NetID), models.GwTagName),
  467. }},
  468. AllowedDirection: models.TrafficDirectionUni,
  469. Enabled: true,
  470. CreatedBy: "auto",
  471. CreatedAt: time.Now().UTC(),
  472. }
  473. err = logic.InsertAcl(acl)
  474. if err != nil {
  475. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  476. return
  477. }
  478. }
  479. for _, userID := range userGroupReq.Members {
  480. user, err := logic.GetUser(userID)
  481. if err != nil {
  482. continue
  483. }
  484. if len(user.UserGroups) == 0 {
  485. user.UserGroups = make(map[models.UserGroupID]struct{})
  486. }
  487. user.UserGroups[userGroupReq.Group.ID] = struct{}{}
  488. logic.UpsertUser(*user)
  489. }
  490. logic.LogEvent(&models.Event{
  491. Action: models.Create,
  492. Source: models.Subject{
  493. ID: r.Header.Get("user"),
  494. Name: r.Header.Get("user"),
  495. Type: models.UserSub,
  496. },
  497. TriggeredBy: r.Header.Get("user"),
  498. Target: models.Subject{
  499. ID: userGroupReq.Group.ID.String(),
  500. Name: userGroupReq.Group.Name,
  501. Type: models.UserGroupSub,
  502. },
  503. Origin: models.Dashboard,
  504. })
  505. logic.ReturnSuccessResponseWithJson(w, r, userGroupReq.Group, "created user group")
  506. }
  507. // swagger:route PUT /api/v1/user/group user updateUserGroup
  508. //
  509. // Update user group.
  510. //
  511. // Schemes: https
  512. //
  513. // Security:
  514. // oauth
  515. //
  516. // Responses:
  517. // 200: userBodyResponse
  518. func updateUserGroup(w http.ResponseWriter, r *http.Request) {
  519. var userGroup models.UserGroup
  520. err := json.NewDecoder(r.Body).Decode(&userGroup)
  521. if err != nil {
  522. slog.Error("error decoding request body", "error",
  523. err.Error())
  524. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  525. return
  526. }
  527. // fetch curr group
  528. currUserG, err := proLogic.GetUserGroup(userGroup.ID)
  529. if err != nil {
  530. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  531. return
  532. }
  533. if currUserG.Default {
  534. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update default user group"), "badrequest"))
  535. return
  536. }
  537. err = proLogic.ValidateUpdateGroupReq(userGroup)
  538. if err != nil {
  539. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  540. return
  541. }
  542. userGroup.ExternalIdentityProviderID = currUserG.ExternalIdentityProviderID
  543. err = proLogic.UpdateUserGroup(userGroup)
  544. if err != nil {
  545. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  546. return
  547. }
  548. logic.LogEvent(&models.Event{
  549. Action: models.Update,
  550. Source: models.Subject{
  551. ID: r.Header.Get("user"),
  552. Name: r.Header.Get("user"),
  553. Type: models.UserSub,
  554. },
  555. TriggeredBy: r.Header.Get("user"),
  556. Target: models.Subject{
  557. ID: userGroup.ID.String(),
  558. Name: userGroup.Name,
  559. Type: models.UserGroupSub,
  560. },
  561. Diff: models.Diff{
  562. Old: currUserG,
  563. New: userGroup,
  564. },
  565. Origin: models.Dashboard,
  566. })
  567. // reset configs for service user
  568. go proLogic.UpdatesUserGwAccessOnGrpUpdates(currUserG.NetworkRoles, userGroup.NetworkRoles)
  569. logic.ReturnSuccessResponseWithJson(w, r, userGroup, "updated user group")
  570. }
  571. // swagger:route DELETE /api/v1/user/group user deleteUserGroup
  572. //
  573. // delete user group.
  574. //
  575. // Schemes: https
  576. //
  577. // Security:
  578. // oauth
  579. //
  580. // Responses:
  581. // 200: userBodyResponse
  582. //
  583. // @Summary Delete user group.
  584. // @Router /api/v1/user/group [delete]
  585. // @Tags Users
  586. // @Param group_id query string true "group id required to delete the role"
  587. // @Success 200 {string} string
  588. // @Failure 500 {object} models.ErrorResponse
  589. func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
  590. gid := r.URL.Query().Get("group_id")
  591. if gid == "" {
  592. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("group id is required"), "badrequest"))
  593. return
  594. }
  595. userG, err := proLogic.GetUserGroup(models.UserGroupID(gid))
  596. if err != nil {
  597. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to fetch group details"), "badrequest"))
  598. return
  599. }
  600. if userG.Default {
  601. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot delete default user group"), "badrequest"))
  602. return
  603. }
  604. err = proLogic.DeleteUserGroup(models.UserGroupID(gid))
  605. if err != nil {
  606. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  607. return
  608. }
  609. logic.LogEvent(&models.Event{
  610. Action: models.Delete,
  611. Source: models.Subject{
  612. ID: r.Header.Get("user"),
  613. Name: r.Header.Get("user"),
  614. Type: models.UserSub,
  615. },
  616. TriggeredBy: r.Header.Get("user"),
  617. Target: models.Subject{
  618. ID: userG.ID.String(),
  619. Name: userG.Name,
  620. Type: models.UserGroupSub,
  621. },
  622. Origin: models.Dashboard,
  623. })
  624. go proLogic.UpdatesUserGwAccessOnGrpUpdates(userG.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
  625. logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user group")
  626. }
  627. // @Summary lists all user roles.
  628. // @Router /api/v1/user/roles [get]
  629. // @Tags Users
  630. // @Param role_id query string true "roleid required to get the role details"
  631. // @Success 200 {object} []models.UserRolePermissionTemplate
  632. // @Failure 500 {object} models.ErrorResponse
  633. func ListRoles(w http.ResponseWriter, r *http.Request) {
  634. platform := r.URL.Query().Get("platform")
  635. var roles []models.UserRolePermissionTemplate
  636. var err error
  637. if platform == "true" {
  638. roles, err = logic.ListPlatformRoles()
  639. } else {
  640. roles, err = proLogic.ListNetworkRoles()
  641. }
  642. if err != nil {
  643. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  644. Code: http.StatusInternalServerError,
  645. Message: err.Error(),
  646. })
  647. return
  648. }
  649. logic.ReturnSuccessResponseWithJson(w, r, roles, "successfully fetched user roles permission templates")
  650. }
  651. // @Summary Get user role permission template.
  652. // @Router /api/v1/user/role [get]
  653. // @Tags Users
  654. // @Param role_id query string true "roleid required to get the role details"
  655. // @Success 200 {object} models.UserRolePermissionTemplate
  656. // @Failure 500 {object} models.ErrorResponse
  657. func getRole(w http.ResponseWriter, r *http.Request) {
  658. rid := r.URL.Query().Get("role_id")
  659. if rid == "" {
  660. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  661. return
  662. }
  663. role, err := logic.GetRole(models.UserRoleID(rid))
  664. if err != nil {
  665. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  666. Code: http.StatusInternalServerError,
  667. Message: err.Error(),
  668. })
  669. return
  670. }
  671. logic.ReturnSuccessResponseWithJson(w, r, role, "successfully fetched user role permission templates")
  672. }
  673. // @Summary Create user role permission template.
  674. // @Router /api/v1/user/role [post]
  675. // @Tags Users
  676. // @Param body body models.UserRolePermissionTemplate true "user role template"
  677. // @Success 200 {object} models.UserRolePermissionTemplate
  678. // @Failure 500 {object} models.ErrorResponse
  679. func createRole(w http.ResponseWriter, r *http.Request) {
  680. var userRole models.UserRolePermissionTemplate
  681. err := json.NewDecoder(r.Body).Decode(&userRole)
  682. if err != nil {
  683. slog.Error("error decoding request body", "error",
  684. err.Error())
  685. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  686. return
  687. }
  688. err = proLogic.ValidateCreateRoleReq(&userRole)
  689. if err != nil {
  690. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  691. return
  692. }
  693. userRole.Default = false
  694. userRole.GlobalLevelAccess = make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope)
  695. err = proLogic.CreateRole(userRole)
  696. if err != nil {
  697. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  698. return
  699. }
  700. logic.LogEvent(&models.Event{
  701. Action: models.Create,
  702. Source: models.Subject{
  703. ID: r.Header.Get("user"),
  704. Name: r.Header.Get("user"),
  705. Type: models.UserSub,
  706. },
  707. TriggeredBy: r.Header.Get("user"),
  708. Target: models.Subject{
  709. ID: userRole.ID.String(),
  710. Name: userRole.Name,
  711. Type: models.UserRoleSub,
  712. },
  713. Origin: models.ClientApp,
  714. })
  715. logic.ReturnSuccessResponseWithJson(w, r, userRole, "created user role")
  716. }
  717. // @Summary Update user role permission template.
  718. // @Router /api/v1/user/role [put]
  719. // @Tags Users
  720. // @Param body body models.UserRolePermissionTemplate true "user role template"
  721. // @Success 200 {object} models.UserRolePermissionTemplate
  722. // @Failure 500 {object} models.ErrorResponse
  723. func updateRole(w http.ResponseWriter, r *http.Request) {
  724. var userRole models.UserRolePermissionTemplate
  725. err := json.NewDecoder(r.Body).Decode(&userRole)
  726. if err != nil {
  727. slog.Error("error decoding request body", "error",
  728. err.Error())
  729. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  730. return
  731. }
  732. currRole, err := logic.GetRole(userRole.ID)
  733. if err != nil {
  734. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  735. return
  736. }
  737. err = proLogic.ValidateUpdateRoleReq(&userRole)
  738. if err != nil {
  739. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  740. return
  741. }
  742. userRole.GlobalLevelAccess = make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope)
  743. err = proLogic.UpdateRole(userRole)
  744. if err != nil {
  745. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  746. return
  747. }
  748. logic.LogEvent(&models.Event{
  749. Action: models.Update,
  750. Source: models.Subject{
  751. ID: r.Header.Get("user"),
  752. Name: r.Header.Get("user"),
  753. Type: models.UserSub,
  754. },
  755. TriggeredBy: r.Header.Get("user"),
  756. Target: models.Subject{
  757. ID: userRole.ID.String(),
  758. Name: userRole.Name,
  759. Type: models.UserRoleSub,
  760. },
  761. Diff: models.Diff{
  762. Old: currRole,
  763. New: userRole,
  764. },
  765. Origin: models.Dashboard,
  766. })
  767. // reset configs for service user
  768. go proLogic.UpdatesUserGwAccessOnRoleUpdates(currRole.NetworkLevelAccess, userRole.NetworkLevelAccess, string(userRole.NetworkID))
  769. logic.ReturnSuccessResponseWithJson(w, r, userRole, "updated user role")
  770. }
  771. // @Summary Delete user role permission template.
  772. // @Router /api/v1/user/role [delete]
  773. // @Tags Users
  774. // @Param role_id query string true "roleid required to delete the role"
  775. // @Success 200 {string} string
  776. // @Failure 500 {object} models.ErrorResponse
  777. func deleteRole(w http.ResponseWriter, r *http.Request) {
  778. rid := r.URL.Query().Get("role_id")
  779. if rid == "" {
  780. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  781. return
  782. }
  783. role, err := logic.GetRole(models.UserRoleID(rid))
  784. if err != nil {
  785. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  786. return
  787. }
  788. err = proLogic.DeleteRole(models.UserRoleID(rid), false)
  789. if err != nil {
  790. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  791. return
  792. }
  793. logic.LogEvent(&models.Event{
  794. Action: models.Delete,
  795. Source: models.Subject{
  796. ID: r.Header.Get("user"),
  797. Name: r.Header.Get("user"),
  798. Type: models.UserSub,
  799. },
  800. TriggeredBy: r.Header.Get("user"),
  801. Target: models.Subject{
  802. ID: role.ID.String(),
  803. Name: role.Name,
  804. Type: models.UserRoleSub,
  805. },
  806. Origin: models.Dashboard,
  807. })
  808. go proLogic.UpdatesUserGwAccessOnRoleUpdates(role.NetworkLevelAccess, make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope), role.NetworkID.String())
  809. logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user role")
  810. }
  811. // @Summary Attach user to a remote access gateway
  812. // @Router /api/users/{username}/remote_access_gw/{remote_access_gateway_id} [post]
  813. // @Tags PRO
  814. // @Accept json
  815. // @Produce json
  816. // @Param username path string true "Username"
  817. // @Param remote_access_gateway_id path string true "Remote Access Gateway ID"
  818. // @Success 200 {object} models.ReturnUser
  819. // @Failure 400 {object} models.ErrorResponse
  820. // @Failure 500 {object} models.ErrorResponse
  821. func attachUserToRemoteAccessGw(w http.ResponseWriter, r *http.Request) {
  822. // set header.
  823. w.Header().Set("Content-Type", "application/json")
  824. var params = mux.Vars(r)
  825. username := params["username"]
  826. remoteGwID := params["remote_access_gateway_id"]
  827. if username == "" || remoteGwID == "" {
  828. logic.ReturnErrorResponse(
  829. w,
  830. r,
  831. logic.FormatError(
  832. errors.New("required params `username` and `remote_access_gateway_id`"),
  833. "badrequest",
  834. ),
  835. )
  836. return
  837. }
  838. user, err := logic.GetUser(username)
  839. if err != nil {
  840. slog.Error("failed to fetch user: ", "username", username, "error", err.Error())
  841. logic.ReturnErrorResponse(
  842. w,
  843. r,
  844. logic.FormatError(
  845. fmt.Errorf("failed to fetch user %s, error: %v", username, err),
  846. "badrequest",
  847. ),
  848. )
  849. return
  850. }
  851. if user.PlatformRoleID == models.AdminRole || user.PlatformRoleID == models.SuperAdminRole {
  852. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("superadmins/admins have access to all gateways"), "badrequest"))
  853. return
  854. }
  855. node, err := logic.GetNodeByID(remoteGwID)
  856. if err != nil {
  857. slog.Error("failed to fetch gateway node", "nodeID", remoteGwID, "error", err)
  858. logic.ReturnErrorResponse(
  859. w,
  860. r,
  861. logic.FormatError(
  862. fmt.Errorf("failed to fetch remote access gateway node, error: %v", err),
  863. "badrequest",
  864. ),
  865. )
  866. return
  867. }
  868. if !node.IsIngressGateway {
  869. logic.ReturnErrorResponse(
  870. w,
  871. r,
  872. logic.FormatError(fmt.Errorf("node is not a remote access gateway"), "badrequest"),
  873. )
  874. return
  875. }
  876. if user.RemoteGwIDs == nil {
  877. user.RemoteGwIDs = make(map[string]struct{})
  878. }
  879. user.RemoteGwIDs[node.ID.String()] = struct{}{}
  880. err = logic.UpsertUser(*user)
  881. if err != nil {
  882. slog.Error("failed to update user's gateways", "user", username, "error", err)
  883. logic.ReturnErrorResponse(
  884. w,
  885. r,
  886. logic.FormatError(
  887. fmt.Errorf("failed to fetch remote access gateway node,error: %v", err),
  888. "badrequest",
  889. ),
  890. )
  891. return
  892. }
  893. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  894. }
  895. // @Summary Remove user from a remote access gateway
  896. // @Router /api/users/{username}/remote_access_gw/{remote_access_gateway_id} [delete]
  897. // @Tags PRO
  898. // @Accept json
  899. // @Produce json
  900. // @Param username path string true "Username"
  901. // @Param remote_access_gateway_id path string true "Remote Access Gateway ID"
  902. // @Success 200 {object} models.ReturnUser
  903. // @Failure 400 {object} models.ErrorResponse
  904. // @Failure 500 {object} models.ErrorResponse
  905. func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) {
  906. // set header.
  907. w.Header().Set("Content-Type", "application/json")
  908. var params = mux.Vars(r)
  909. username := params["username"]
  910. remoteGwID := params["remote_access_gateway_id"]
  911. if username == "" || remoteGwID == "" {
  912. logic.ReturnErrorResponse(
  913. w,
  914. r,
  915. logic.FormatError(
  916. errors.New("required params `username` and `remote_access_gateway_id`"),
  917. "badrequest",
  918. ),
  919. )
  920. return
  921. }
  922. user, err := logic.GetUser(username)
  923. if err != nil {
  924. logger.Log(0, username, "failed to fetch user: ", err.Error())
  925. logic.ReturnErrorResponse(
  926. w,
  927. r,
  928. logic.FormatError(
  929. fmt.Errorf("failed to fetch user %s, error: %v", username, err),
  930. "badrequest",
  931. ),
  932. )
  933. return
  934. }
  935. delete(user.RemoteGwIDs, remoteGwID)
  936. go func(user models.User, remoteGwID string) {
  937. extclients, err := logic.GetAllExtClients()
  938. if err != nil {
  939. slog.Error("failed to fetch extclients", "error", err)
  940. return
  941. }
  942. for _, extclient := range extclients {
  943. if extclient.OwnerID == user.UserName && remoteGwID == extclient.IngressGatewayID {
  944. err = logic.DeleteExtClientAndCleanup(extclient)
  945. if err != nil {
  946. slog.Error("failed to delete extclient",
  947. "id", extclient.ClientID, "owner", user.UserName, "error", err)
  948. } else {
  949. if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
  950. slog.Error("error setting ext peers: " + err.Error())
  951. }
  952. }
  953. }
  954. }
  955. if servercfg.IsDNSMode() {
  956. logic.SetDNS()
  957. }
  958. }(*user, remoteGwID)
  959. err = logic.UpsertUser(*user)
  960. if err != nil {
  961. slog.Error("failed to update user gateways", "user", username, "error", err)
  962. logic.ReturnErrorResponse(
  963. w,
  964. r,
  965. logic.FormatError(
  966. errors.New("failed to fetch remote access gaetway node "+err.Error()),
  967. "badrequest",
  968. ),
  969. )
  970. return
  971. }
  972. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  973. }
  974. // @Summary Get Users Remote Access Gw Networks.
  975. // @Router /api/users/{username}/remote_access_gw [get]
  976. // @Tags Users
  977. // @Param username path string true "Username to fetch all the gateways with access"
  978. // @Success 200 {object} map[string][]models.UserRemoteGws
  979. // @Failure 500 {object} models.ErrorResponse
  980. func getUserRemoteAccessNetworks(w http.ResponseWriter, r *http.Request) {
  981. // set header.
  982. w.Header().Set("Content-Type", "application/json")
  983. username := r.Header.Get("user")
  984. user, err := logic.GetUser(username)
  985. if err != nil {
  986. logger.Log(0, username, "failed to fetch user: ", err.Error())
  987. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  988. return
  989. }
  990. userGws := make(map[string][]models.UserRemoteGws)
  991. networks := []models.Network{}
  992. networkMap := make(map[string]struct{})
  993. userGwNodes := proLogic.GetUserRAGNodes(*user)
  994. for _, node := range userGwNodes {
  995. network, err := logic.GetNetwork(node.Network)
  996. if err != nil {
  997. slog.Error("failed to get node network", "error", err)
  998. continue
  999. }
  1000. if _, ok := networkMap[network.NetID]; ok {
  1001. continue
  1002. }
  1003. networkMap[network.NetID] = struct{}{}
  1004. networks = append(networks, network)
  1005. }
  1006. slog.Debug("returned user gws", "user", username, "gws", userGws)
  1007. logic.ReturnSuccessResponseWithJson(w, r, networks, "fetched user accessible networks")
  1008. }
  1009. // @Summary Get Users Remote Access Gw Networks.
  1010. // @Router /api/users/{username}/remote_access_gw [get]
  1011. // @Tags Users
  1012. // @Param username path string true "Username to fetch all the gateways with access"
  1013. // @Success 200 {object} map[string][]models.UserRemoteGws
  1014. // @Failure 500 {object} models.ErrorResponse
  1015. func getUserRemoteAccessNetworkGateways(w http.ResponseWriter, r *http.Request) {
  1016. // set header.
  1017. w.Header().Set("Content-Type", "application/json")
  1018. var params = mux.Vars(r)
  1019. username := r.Header.Get("user")
  1020. user, err := logic.GetUser(username)
  1021. if err != nil {
  1022. logger.Log(0, username, "failed to fetch user: ", err.Error())
  1023. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  1024. return
  1025. }
  1026. network := params["network"]
  1027. if network == "" {
  1028. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params network"), "badrequest"))
  1029. return
  1030. }
  1031. userGws := []models.UserRAGs{}
  1032. userGwNodes := proLogic.GetUserRAGNodes(*user)
  1033. for _, node := range userGwNodes {
  1034. if node.Network != network {
  1035. continue
  1036. }
  1037. host, err := logic.GetHost(node.HostID.String())
  1038. if err != nil {
  1039. continue
  1040. }
  1041. userGws = append(userGws, models.UserRAGs{
  1042. GwID: node.ID.String(),
  1043. GWName: host.Name,
  1044. Network: node.Network,
  1045. IsInternetGateway: node.IsInternetGateway,
  1046. Metadata: node.Metadata,
  1047. })
  1048. }
  1049. slog.Debug("returned user gws", "user", username, "gws", userGws)
  1050. logic.ReturnSuccessResponseWithJson(w, r, userGws, "fetched user accessible gateways in network "+network)
  1051. }
  1052. // @Summary Get Users Remote Access Gw Networks.
  1053. // @Router /api/users/{username}/remote_access_gw [get]
  1054. // @Tags Users
  1055. // @Param username path string true "Username to fetch all the gateways with access"
  1056. // @Success 200 {object} map[string][]models.UserRemoteGws
  1057. // @Failure 500 {object} models.ErrorResponse
  1058. func getRemoteAccessGatewayConf(w http.ResponseWriter, r *http.Request) {
  1059. // set header.
  1060. w.Header().Set("Content-Type", "application/json")
  1061. var params = mux.Vars(r)
  1062. username := r.Header.Get("user")
  1063. user, err := logic.GetUser(username)
  1064. if err != nil {
  1065. logger.Log(0, username, "failed to fetch user: ", err.Error())
  1066. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  1067. return
  1068. }
  1069. remoteGwID := params["access_point_id"]
  1070. if remoteGwID == "" {
  1071. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params access_point_id"), "badrequest"))
  1072. return
  1073. }
  1074. var req models.UserRemoteGwsReq
  1075. err = json.NewDecoder(r.Body).Decode(&req)
  1076. if err != nil {
  1077. slog.Error("error decoding request body: ", "error", err)
  1078. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  1079. return
  1080. }
  1081. userGwNodes := proLogic.GetUserRAGNodes(*user)
  1082. if _, ok := userGwNodes[remoteGwID]; !ok {
  1083. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access denied"), "forbidden"))
  1084. return
  1085. }
  1086. node, err := logic.GetNodeByID(remoteGwID)
  1087. if err != nil {
  1088. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch gw node %s, error: %v", remoteGwID, err), "badrequest"))
  1089. return
  1090. }
  1091. host, err := logic.GetHost(node.HostID.String())
  1092. if err != nil {
  1093. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch gw host %s, error: %v", remoteGwID, err), "badrequest"))
  1094. return
  1095. }
  1096. network, err := logic.GetNetwork(node.Network)
  1097. if err != nil {
  1098. slog.Error("failed to get node network", "error", err)
  1099. }
  1100. var userConf models.ExtClient
  1101. allextClients, err := logic.GetAllExtClients()
  1102. if err != nil {
  1103. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1104. return
  1105. }
  1106. for _, extClient := range allextClients {
  1107. if extClient.Network != network.NetID || extClient.IngressGatewayID != node.ID.String() {
  1108. continue
  1109. }
  1110. if extClient.RemoteAccessClientID == req.RemoteAccessClientID && extClient.OwnerID == username {
  1111. userConf = extClient
  1112. userConf.AllowedIPs = logic.GetExtclientAllowedIPs(extClient)
  1113. }
  1114. }
  1115. if userConf.ClientID == "" {
  1116. // create a new conf
  1117. userConf.OwnerID = user.UserName
  1118. userConf.RemoteAccessClientID = req.RemoteAccessClientID
  1119. userConf.IngressGatewayID = node.ID.String()
  1120. // set extclient dns to ingressdns if extclient dns is not explicitly set
  1121. if (userConf.DNS == "") && (node.IngressDNS != "") {
  1122. userConf.DNS = node.IngressDNS
  1123. }
  1124. userConf.Network = node.Network
  1125. host, err := logic.GetHost(node.HostID.String())
  1126. if err != nil {
  1127. logger.Log(0, r.Header.Get("user"),
  1128. fmt.Sprintf("failed to get ingress gateway host for node [%s] info: %v", node.ID, err))
  1129. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1130. return
  1131. }
  1132. listenPort := logic.GetPeerListenPort(host)
  1133. if host.EndpointIP.To4() == nil {
  1134. userConf.IngressGatewayEndpoint = fmt.Sprintf("[%s]:%d", host.EndpointIPv6.String(), listenPort)
  1135. } else {
  1136. userConf.IngressGatewayEndpoint = fmt.Sprintf("%s:%d", host.EndpointIP.String(), listenPort)
  1137. }
  1138. userConf.Enabled = true
  1139. parentNetwork, err := logic.GetNetwork(node.Network)
  1140. if err == nil { // check if parent network default ACL is enabled (yes) or not (no)
  1141. userConf.Enabled = parentNetwork.DefaultACL == "yes"
  1142. }
  1143. userConf.Tags = make(map[models.TagID]struct{})
  1144. // userConf.Tags[models.TagID(fmt.Sprintf("%s.%s", userConf.Network,
  1145. // models.RemoteAccessTagName))] = struct{}{}
  1146. if err = logic.CreateExtClient(&userConf); err != nil {
  1147. slog.Error(
  1148. "failed to create extclient",
  1149. "user",
  1150. r.Header.Get("user"),
  1151. "network",
  1152. node.Network,
  1153. "error",
  1154. err,
  1155. )
  1156. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1157. return
  1158. }
  1159. }
  1160. userGw := models.UserRemoteGws{
  1161. GwID: node.ID.String(),
  1162. GWName: host.Name,
  1163. Network: node.Network,
  1164. GwClient: userConf,
  1165. Connected: true,
  1166. IsInternetGateway: node.IsInternetGateway,
  1167. GwPeerPublicKey: host.PublicKey.String(),
  1168. GwListenPort: logic.GetPeerListenPort(host),
  1169. Metadata: node.Metadata,
  1170. AllowedEndpoints: getAllowedRagEndpoints(&node, host),
  1171. NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
  1172. DnsAddress: node.IngressDNS,
  1173. Addresses: utils.NoEmptyStringToCsv(node.Address.String(), node.Address6.String()),
  1174. }
  1175. slog.Debug("returned user gw config", "user", user.UserName, "gws", userGw)
  1176. logic.ReturnSuccessResponseWithJson(w, r, userGw, "fetched user config to gw "+remoteGwID)
  1177. }
  1178. // @Summary Get Users Remote Access Gw.
  1179. // @Router /api/users/{username}/remote_access_gw [get]
  1180. // @Tags Users
  1181. // @Param username path string true "Username to fetch all the gateways with access"
  1182. // @Success 200 {object} map[string][]models.UserRemoteGws
  1183. // @Failure 500 {object} models.ErrorResponse
  1184. func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
  1185. // set header.
  1186. w.Header().Set("Content-Type", "application/json")
  1187. var params = mux.Vars(r)
  1188. username := params["username"]
  1189. if username == "" {
  1190. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params username"), "badrequest"))
  1191. return
  1192. }
  1193. user, err := logic.GetUser(username)
  1194. if err != nil {
  1195. logger.Log(0, username, "failed to fetch user: ", err.Error())
  1196. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  1197. return
  1198. }
  1199. remoteAccessClientID := r.URL.Query().Get("remote_access_clientid")
  1200. var req models.UserRemoteGwsReq
  1201. if remoteAccessClientID == "" {
  1202. err := json.NewDecoder(r.Body).Decode(&req)
  1203. if err != nil {
  1204. slog.Error("error decoding request body: ", "error", err)
  1205. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  1206. return
  1207. }
  1208. }
  1209. reqFromMobile := r.URL.Query().Get("from_mobile") == "true"
  1210. if req.RemoteAccessClientID == "" && remoteAccessClientID == "" {
  1211. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("remote access client id cannot be empty"), "badrequest"))
  1212. return
  1213. }
  1214. if req.RemoteAccessClientID == "" {
  1215. req.RemoteAccessClientID = remoteAccessClientID
  1216. }
  1217. userGws := make(map[string][]models.UserRemoteGws)
  1218. allextClients, err := logic.GetAllExtClients()
  1219. if err != nil {
  1220. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1221. return
  1222. }
  1223. userGwNodes := proLogic.GetUserRAGNodes(*user)
  1224. for _, extClient := range allextClients {
  1225. node, ok := userGwNodes[extClient.IngressGatewayID]
  1226. if !ok {
  1227. continue
  1228. }
  1229. if extClient.RemoteAccessClientID == req.RemoteAccessClientID && extClient.OwnerID == username {
  1230. host, err := logic.GetHost(node.HostID.String())
  1231. if err != nil {
  1232. continue
  1233. }
  1234. network, err := logic.GetNetwork(node.Network)
  1235. if err != nil {
  1236. slog.Error("failed to get node network", "error", err)
  1237. continue
  1238. }
  1239. nodesWithStatus := logic.AddStatusToNodes([]models.Node{node}, false)
  1240. if len(nodesWithStatus) > 0 {
  1241. node = nodesWithStatus[0]
  1242. }
  1243. gws := userGws[node.Network]
  1244. if extClient.DNS == "" {
  1245. extClient.DNS = node.IngressDNS
  1246. }
  1247. extClient.IngressGatewayEndpoint = utils.GetExtClientEndpoint(
  1248. host.EndpointIP,
  1249. host.EndpointIPv6,
  1250. logic.GetPeerListenPort(host),
  1251. )
  1252. extClient.AllowedIPs = logic.GetExtclientAllowedIPs(extClient)
  1253. gws = append(gws, models.UserRemoteGws{
  1254. GwID: node.ID.String(),
  1255. GWName: host.Name,
  1256. Network: node.Network,
  1257. GwClient: extClient,
  1258. Connected: true,
  1259. IsInternetGateway: node.IsInternetGateway,
  1260. GwPeerPublicKey: host.PublicKey.String(),
  1261. GwListenPort: logic.GetPeerListenPort(host),
  1262. Metadata: node.Metadata,
  1263. AllowedEndpoints: getAllowedRagEndpoints(&node, host),
  1264. NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
  1265. Status: node.Status,
  1266. DnsAddress: node.IngressDNS,
  1267. Addresses: utils.NoEmptyStringToCsv(node.Address.String(), node.Address6.String()),
  1268. })
  1269. userGws[node.Network] = gws
  1270. delete(userGwNodes, node.ID.String())
  1271. }
  1272. }
  1273. // add remaining gw nodes to resp
  1274. for gwID := range userGwNodes {
  1275. node, err := logic.GetNodeByID(gwID)
  1276. if err != nil {
  1277. continue
  1278. }
  1279. if !node.IsIngressGateway {
  1280. continue
  1281. }
  1282. if node.PendingDelete {
  1283. continue
  1284. }
  1285. host, err := logic.GetHost(node.HostID.String())
  1286. if err != nil {
  1287. continue
  1288. }
  1289. nodesWithStatus := logic.AddStatusToNodes([]models.Node{node}, false)
  1290. if len(nodesWithStatus) > 0 {
  1291. node = nodesWithStatus[0]
  1292. }
  1293. network, err := logic.GetNetwork(node.Network)
  1294. if err != nil {
  1295. slog.Error("failed to get node network", "error", err)
  1296. }
  1297. gws := userGws[node.Network]
  1298. gws = append(gws, models.UserRemoteGws{
  1299. GwID: node.ID.String(),
  1300. GWName: host.Name,
  1301. Network: node.Network,
  1302. IsInternetGateway: node.IsInternetGateway,
  1303. GwPeerPublicKey: host.PublicKey.String(),
  1304. GwListenPort: logic.GetPeerListenPort(host),
  1305. Metadata: node.Metadata,
  1306. AllowedEndpoints: getAllowedRagEndpoints(&node, host),
  1307. NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
  1308. Status: node.Status,
  1309. DnsAddress: node.IngressDNS,
  1310. Addresses: utils.NoEmptyStringToCsv(node.Address.String(), node.Address6.String()),
  1311. })
  1312. userGws[node.Network] = gws
  1313. }
  1314. if reqFromMobile {
  1315. // send resp in array format
  1316. userGwsArr := []models.UserRemoteGws{}
  1317. for _, userGwI := range userGws {
  1318. userGwsArr = append(userGwsArr, userGwI...)
  1319. }
  1320. logic.ReturnSuccessResponseWithJson(w, r, userGwsArr, "fetched gateways for user"+username)
  1321. return
  1322. }
  1323. slog.Debug("returned user gws", "user", username, "gws", userGws)
  1324. w.WriteHeader(http.StatusOK)
  1325. json.NewEncoder(w).Encode(userGws)
  1326. }
  1327. // @Summary List users attached to an remote access gateway
  1328. // @Router /api/nodes/{network}/{nodeid}/ingress/users [get]
  1329. // @Tags PRO
  1330. // @Accept json
  1331. // @Produce json
  1332. // @Param ingress_id path string true "Ingress Gateway ID"
  1333. // @Success 200 {array} models.IngressGwUsers
  1334. // @Failure 400 {object} models.ErrorResponse
  1335. // @Failure 500 {object} models.ErrorResponse
  1336. func ingressGatewayUsers(w http.ResponseWriter, r *http.Request) {
  1337. w.Header().Set("Content-Type", "application/json")
  1338. var params = mux.Vars(r)
  1339. ingressID := params["ingress_id"]
  1340. node, err := logic.GetNodeByID(ingressID)
  1341. if err != nil {
  1342. slog.Error("failed to get ingress node", "error", err)
  1343. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  1344. return
  1345. }
  1346. gwUsers, err := logic.GetIngressGwUsers(node)
  1347. if err != nil {
  1348. slog.Error(
  1349. "failed to get users on ingress gateway",
  1350. "nodeid",
  1351. ingressID,
  1352. "network",
  1353. node.Network,
  1354. "user",
  1355. r.Header.Get("user"),
  1356. "error",
  1357. err,
  1358. )
  1359. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1360. return
  1361. }
  1362. w.WriteHeader(http.StatusOK)
  1363. json.NewEncoder(w).Encode(gwUsers)
  1364. }
  1365. func getAllowedRagEndpoints(ragNode *models.Node, ragHost *models.Host) []string {
  1366. endpoints := []string{}
  1367. if len(ragHost.EndpointIP) > 0 {
  1368. endpoints = append(endpoints, ragHost.EndpointIP.String())
  1369. }
  1370. if len(ragHost.EndpointIPv6) > 0 {
  1371. endpoints = append(endpoints, ragHost.EndpointIPv6.String())
  1372. }
  1373. if servercfg.IsPro {
  1374. for _, ip := range ragNode.AdditionalRagIps {
  1375. endpoints = append(endpoints, ip.String())
  1376. }
  1377. }
  1378. return endpoints
  1379. }
  1380. // @Summary Get all pending users
  1381. // @Router /api/users_pending [get]
  1382. // @Tags Users
  1383. // @Success 200 {array} models.User
  1384. // @Failure 500 {object} models.ErrorResponse
  1385. func getPendingUsers(w http.ResponseWriter, r *http.Request) {
  1386. // set header.
  1387. w.Header().Set("Content-Type", "application/json")
  1388. users, err := logic.ListPendingReturnUsers()
  1389. if err != nil {
  1390. logger.Log(0, "failed to fetch users: ", err.Error())
  1391. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1392. return
  1393. }
  1394. logic.SortUsers(users[:])
  1395. logger.Log(2, r.Header.Get("user"), "fetched pending users")
  1396. json.NewEncoder(w).Encode(users)
  1397. }
  1398. // @Summary Approve a pending user
  1399. // @Router /api/users_pending/user/{username} [post]
  1400. // @Tags Users
  1401. // @Param username path string true "Username of the pending user to approve"
  1402. // @Success 200 {string} string
  1403. // @Failure 500 {object} models.ErrorResponse
  1404. func approvePendingUser(w http.ResponseWriter, r *http.Request) {
  1405. // set header.
  1406. w.Header().Set("Content-Type", "application/json")
  1407. var params = mux.Vars(r)
  1408. username := params["username"]
  1409. users, err := logic.ListPendingUsers()
  1410. if err != nil {
  1411. logger.Log(0, "failed to fetch users: ", err.Error())
  1412. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1413. return
  1414. }
  1415. for _, user := range users {
  1416. if user.UserName == username {
  1417. var newPass, fetchErr = logic.FetchPassValue("")
  1418. if fetchErr != nil {
  1419. logic.ReturnErrorResponse(w, r, logic.FormatError(fetchErr, "internal"))
  1420. return
  1421. }
  1422. if err = logic.CreateUser(&models.User{
  1423. UserName: user.UserName,
  1424. ExternalIdentityProviderID: user.ExternalIdentityProviderID,
  1425. Password: newPass,
  1426. AuthType: user.AuthType,
  1427. PlatformRoleID: models.ServiceUser,
  1428. }); err != nil {
  1429. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to create user: %s", err), "internal"))
  1430. return
  1431. }
  1432. err = logic.DeletePendingUser(username)
  1433. if err != nil {
  1434. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete pending user: %s", err), "internal"))
  1435. return
  1436. }
  1437. break
  1438. }
  1439. }
  1440. logic.LogEvent(&models.Event{
  1441. Action: models.Create,
  1442. Source: models.Subject{
  1443. ID: r.Header.Get("user"),
  1444. Name: r.Header.Get("user"),
  1445. Type: models.UserSub,
  1446. },
  1447. TriggeredBy: r.Header.Get("user"),
  1448. Target: models.Subject{
  1449. ID: username,
  1450. Name: username,
  1451. Type: models.PendingUserSub,
  1452. },
  1453. Origin: models.Dashboard,
  1454. })
  1455. logic.ReturnSuccessResponse(w, r, "approved "+username)
  1456. }
  1457. // @Summary Delete a pending user
  1458. // @Router /api/users_pending/user/{username} [delete]
  1459. // @Tags Users
  1460. // @Param username path string true "Username of the pending user to delete"
  1461. // @Success 200 {string} string
  1462. // @Failure 500 {object} models.ErrorResponse
  1463. func deletePendingUser(w http.ResponseWriter, r *http.Request) {
  1464. // set header.
  1465. w.Header().Set("Content-Type", "application/json")
  1466. var params = mux.Vars(r)
  1467. username := params["username"]
  1468. users, err := logic.ListPendingReturnUsers()
  1469. if err != nil {
  1470. logger.Log(0, "failed to fetch users: ", err.Error())
  1471. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1472. return
  1473. }
  1474. for _, user := range users {
  1475. if user.UserName == username {
  1476. err = logic.DeletePendingUser(username)
  1477. if err != nil {
  1478. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete pending user: %s", err), "internal"))
  1479. return
  1480. }
  1481. break
  1482. }
  1483. }
  1484. logic.LogEvent(&models.Event{
  1485. Action: models.Delete,
  1486. Source: models.Subject{
  1487. ID: r.Header.Get("user"),
  1488. Name: r.Header.Get("user"),
  1489. Type: models.UserSub,
  1490. },
  1491. TriggeredBy: r.Header.Get("user"),
  1492. Target: models.Subject{
  1493. ID: username,
  1494. Name: username,
  1495. Type: models.PendingUserSub,
  1496. },
  1497. Origin: models.Dashboard,
  1498. })
  1499. logic.ReturnSuccessResponse(w, r, "deleted pending "+username)
  1500. }
  1501. // @Summary Delete all pending users
  1502. // @Router /api/users_pending [delete]
  1503. // @Tags Users
  1504. // @Success 200 {string} string
  1505. // @Failure 500 {object} models.ErrorResponse
  1506. func deleteAllPendingUsers(w http.ResponseWriter, r *http.Request) {
  1507. // set header.
  1508. err := database.DeleteAllRecords(database.PENDING_USERS_TABLE_NAME)
  1509. if err != nil {
  1510. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to delete all pending users "+err.Error()), "internal"))
  1511. return
  1512. }
  1513. logic.LogEvent(&models.Event{
  1514. Action: models.DeleteAll,
  1515. Source: models.Subject{
  1516. ID: r.Header.Get("user"),
  1517. Name: r.Header.Get("user"),
  1518. Type: models.UserSub,
  1519. },
  1520. TriggeredBy: r.Header.Get("user"),
  1521. Target: models.Subject{
  1522. ID: r.Header.Get("user"),
  1523. Name: r.Header.Get("user"),
  1524. Type: models.PendingUserSub,
  1525. },
  1526. Origin: models.Dashboard,
  1527. })
  1528. logic.ReturnSuccessResponse(w, r, "cleared all pending users")
  1529. }
  1530. // @Summary Sync users and groups from idp.
  1531. // @Router /api/idp/sync [post]
  1532. // @Tags IDP
  1533. // @Success 200 {object} models.SuccessResponse
  1534. func syncIDP(w http.ResponseWriter, r *http.Request) {
  1535. go func() {
  1536. err := proAuth.SyncFromIDP()
  1537. if err != nil {
  1538. logger.Log(0, "failed to sync from idp: ", err.Error())
  1539. } else {
  1540. logger.Log(0, "sync from idp complete")
  1541. }
  1542. }()
  1543. logic.ReturnSuccessResponse(w, r, "starting sync from idp")
  1544. }
  1545. // @Summary Remove idp integration.
  1546. // @Router /api/idp [delete]
  1547. // @Tags IDP
  1548. // @Success 200 {object} models.SuccessResponse
  1549. // @Failure 500 {object} models.ErrorResponse
  1550. func removeIDPIntegration(w http.ResponseWriter, r *http.Request) {
  1551. superAdmin, err := logic.GetSuperAdmin()
  1552. if err != nil {
  1553. logic.ReturnErrorResponse(
  1554. w,
  1555. r,
  1556. logic.FormatError(fmt.Errorf("failed to get superadmin: %v", err), "internal"),
  1557. )
  1558. return
  1559. }
  1560. if superAdmin.AuthType == models.OAuth {
  1561. logic.ReturnErrorResponse(
  1562. w,
  1563. r,
  1564. logic.FormatError(fmt.Errorf("cannot remove idp integration with superadmin oauth user"), "badrequest"),
  1565. )
  1566. return
  1567. }
  1568. settings := logic.GetServerSettings()
  1569. settings.AuthProvider = ""
  1570. settings.OIDCIssuer = ""
  1571. settings.ClientID = ""
  1572. settings.ClientSecret = ""
  1573. settings.SyncEnabled = false
  1574. settings.GoogleAdminEmail = ""
  1575. settings.GoogleSACredsJson = ""
  1576. settings.AzureTenant = ""
  1577. settings.UserFilters = nil
  1578. settings.GroupFilters = nil
  1579. err = logic.UpsertServerSettings(settings)
  1580. if err != nil {
  1581. logic.ReturnErrorResponse(
  1582. w,
  1583. r,
  1584. logic.FormatError(fmt.Errorf("failed to remove idp integration: %v", err), "internal"),
  1585. )
  1586. return
  1587. }
  1588. proAuth.ResetAuthProvider()
  1589. proAuth.ResetIDPSyncHook()
  1590. go func() {
  1591. err := proAuth.SyncFromIDP()
  1592. if err != nil {
  1593. logger.Log(0, "failed to sync from idp: ", err.Error())
  1594. } else {
  1595. logger.Log(0, "sync from idp complete")
  1596. }
  1597. }()
  1598. logic.ReturnSuccessResponse(w, r, "removed idp integration successfully")
  1599. }