users.go 64 KB

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