2
0

users.go 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485
  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. // check if user with email exists, then ignore
  198. if !email.IsValid(inviteeEmail) {
  199. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("invalid email "+inviteeEmail), "badrequest"))
  200. return
  201. }
  202. _, err := logic.GetUser(inviteeEmail)
  203. if err == nil {
  204. // user exists already, so ignore
  205. continue
  206. }
  207. invite := models.UserInvite{
  208. Email: inviteeEmail,
  209. PlatformRoleID: inviteReq.PlatformRoleID,
  210. UserGroups: inviteReq.UserGroups,
  211. NetworkRoles: inviteReq.NetworkRoles,
  212. InviteCode: logic.RandomString(8),
  213. }
  214. frontendURL := strings.TrimSuffix(servercfg.GetFrontendURL(), "/")
  215. if frontendURL == "" {
  216. frontendURL = fmt.Sprintf("https://dashboard.%s", servercfg.GetNmBaseDomain())
  217. }
  218. u, err := url.Parse(fmt.Sprintf("%s/invite?email=%s&invite_code=%s",
  219. frontendURL, url.QueryEscape(invite.Email), url.QueryEscape(invite.InviteCode)))
  220. if err != nil {
  221. slog.Error("failed to parse to invite url", "error", err)
  222. return
  223. }
  224. if servercfg.DeployedByOperator() {
  225. u, err = url.Parse(fmt.Sprintf("%s/invite?tenant_id=%s&email=%s&invite_code=%s",
  226. proLogic.GetAccountsUIHost(), url.QueryEscape(servercfg.GetNetmakerTenantID()), url.QueryEscape(invite.Email), url.QueryEscape(invite.InviteCode)))
  227. if err != nil {
  228. slog.Error("failed to parse to invite url", "error", err)
  229. return
  230. }
  231. }
  232. invite.InviteURL = u.String()
  233. err = logic.InsertUserInvite(invite)
  234. if err != nil {
  235. slog.Error("failed to insert invite for user", "email", invite.Email, "error", err)
  236. }
  237. // notify user with magic link
  238. go func(invite models.UserInvite) {
  239. // Set E-Mail body. You can set plain text or html with text/html
  240. e := email.UserInvitedMail{
  241. BodyBuilder: &email.EmailBodyBuilderWithH1HeadlineAndImage{},
  242. InviteURL: invite.InviteURL,
  243. PlatformRoleID: invite.PlatformRoleID,
  244. }
  245. n := email.Notification{
  246. RecipientMail: invite.Email,
  247. }
  248. err = email.GetClient().SendEmail(context.Background(), n, e)
  249. if err != nil {
  250. slog.Error("failed to send email invite", "user", invite.Email, "error", err)
  251. }
  252. }(invite)
  253. }
  254. logic.ReturnSuccessResponse(w, r, "triggered user invites")
  255. }
  256. // swagger:route GET /api/v1/users/invites user listUserInvites
  257. //
  258. // lists all pending invited users.
  259. //
  260. // Schemes: https
  261. //
  262. // Security:
  263. // oauth
  264. //
  265. // Responses:
  266. // 200: ReturnSuccessResponseWithJson
  267. func listUserInvites(w http.ResponseWriter, r *http.Request) {
  268. usersInvites, err := logic.ListUserInvites()
  269. if err != nil {
  270. logger.Log(0, "failed to fetch users: ", err.Error())
  271. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  272. return
  273. }
  274. logic.ReturnSuccessResponseWithJson(w, r, usersInvites, "fetched pending user invites")
  275. }
  276. // swagger:route DELETE /api/v1/users/invite user deleteUserInvite
  277. //
  278. // delete pending invite.
  279. //
  280. // Schemes: https
  281. //
  282. // Security:
  283. // oauth
  284. //
  285. // Responses:
  286. // 200: ReturnSuccessResponse
  287. func deleteUserInvite(w http.ResponseWriter, r *http.Request) {
  288. email := r.URL.Query().Get("invitee_email")
  289. err := logic.DeleteUserInvite(email)
  290. if err != nil {
  291. logger.Log(0, "failed to delete user invite: ", email, err.Error())
  292. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  293. return
  294. }
  295. logic.ReturnSuccessResponse(w, r, "deleted user invite")
  296. }
  297. // swagger:route DELETE /api/v1/users/invites user deleteAllUserInvites
  298. //
  299. // deletes all pending invites.
  300. //
  301. // Schemes: https
  302. //
  303. // Security:
  304. // oauth
  305. //
  306. // Responses:
  307. // 200: ReturnSuccessResponse
  308. func deleteAllUserInvites(w http.ResponseWriter, r *http.Request) {
  309. err := database.DeleteAllRecords(database.USER_INVITES_TABLE_NAME)
  310. if err != nil {
  311. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to delete all pending user invites "+err.Error()), "internal"))
  312. return
  313. }
  314. logic.ReturnSuccessResponse(w, r, "cleared all pending user invites")
  315. }
  316. // swagger:route GET /api/v1/user/groups user listUserGroups
  317. //
  318. // Get all user groups.
  319. //
  320. // Schemes: https
  321. //
  322. // Security:
  323. // oauth
  324. //
  325. // Responses:
  326. // 200: userBodyResponse
  327. func listUserGroups(w http.ResponseWriter, r *http.Request) {
  328. groups, err := proLogic.ListUserGroups()
  329. if err != nil {
  330. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  331. Code: http.StatusInternalServerError,
  332. Message: err.Error(),
  333. })
  334. return
  335. }
  336. logic.ReturnSuccessResponseWithJson(w, r, groups, "successfully fetched user groups")
  337. }
  338. // swagger:route GET /api/v1/user/group user getUserGroup
  339. //
  340. // Get user group.
  341. //
  342. // Schemes: https
  343. //
  344. // Security:
  345. // oauth
  346. //
  347. // Responses:
  348. // 200: userBodyResponse
  349. func getUserGroup(w http.ResponseWriter, r *http.Request) {
  350. gid := r.URL.Query().Get("group_id")
  351. if gid == "" {
  352. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("group id is required"), "badrequest"))
  353. return
  354. }
  355. group, err := proLogic.GetUserGroup(models.UserGroupID(gid))
  356. if err != nil {
  357. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  358. Code: http.StatusInternalServerError,
  359. Message: err.Error(),
  360. })
  361. return
  362. }
  363. logic.ReturnSuccessResponseWithJson(w, r, group, "successfully fetched user group")
  364. }
  365. // swagger:route POST /api/v1/user/group user createUserGroup
  366. //
  367. // Create user groups.
  368. //
  369. // Schemes: https
  370. //
  371. // Security:
  372. // oauth
  373. //
  374. // Responses:
  375. // 200: userBodyResponse
  376. func createUserGroup(w http.ResponseWriter, r *http.Request) {
  377. var userGroupReq models.CreateGroupReq
  378. err := json.NewDecoder(r.Body).Decode(&userGroupReq)
  379. if err != nil {
  380. slog.Error("error decoding request body", "error",
  381. err.Error())
  382. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  383. return
  384. }
  385. err = proLogic.ValidateCreateGroupReq(userGroupReq.Group)
  386. if err != nil {
  387. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  388. return
  389. }
  390. err = proLogic.CreateUserGroup(&userGroupReq.Group)
  391. if err != nil {
  392. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  393. return
  394. }
  395. networks, err := logic.GetNetworks()
  396. if err != nil {
  397. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  398. return
  399. }
  400. for _, network := range networks {
  401. acl := models.Acl{
  402. ID: uuid.New().String(),
  403. Name: fmt.Sprintf("%s group", userGroupReq.Group.Name),
  404. MetaData: "This Policy allows user group to communicate with all gateways",
  405. Default: false,
  406. ServiceType: models.Any,
  407. NetworkID: models.NetworkID(network.NetID),
  408. Proto: models.ALL,
  409. RuleType: models.UserPolicy,
  410. Src: []models.AclPolicyTag{
  411. {
  412. ID: models.UserGroupAclID,
  413. Value: userGroupReq.Group.ID.String(),
  414. },
  415. },
  416. Dst: []models.AclPolicyTag{
  417. {
  418. ID: models.NodeTagID,
  419. Value: fmt.Sprintf("%s.%s", models.NetworkID(network.NetID), models.GwTagName),
  420. }},
  421. AllowedDirection: models.TrafficDirectionUni,
  422. Enabled: true,
  423. CreatedBy: "auto",
  424. CreatedAt: time.Now().UTC(),
  425. }
  426. err = logic.InsertAcl(acl)
  427. if err != nil {
  428. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  429. return
  430. }
  431. }
  432. for _, userID := range userGroupReq.Members {
  433. user, err := logic.GetUser(userID)
  434. if err != nil {
  435. continue
  436. }
  437. if len(user.UserGroups) == 0 {
  438. user.UserGroups = make(map[models.UserGroupID]struct{})
  439. }
  440. user.UserGroups[userGroupReq.Group.ID] = struct{}{}
  441. logic.UpsertUser(*user)
  442. }
  443. logic.ReturnSuccessResponseWithJson(w, r, userGroupReq.Group, "created user group")
  444. }
  445. // swagger:route PUT /api/v1/user/group user updateUserGroup
  446. //
  447. // Update user group.
  448. //
  449. // Schemes: https
  450. //
  451. // Security:
  452. // oauth
  453. //
  454. // Responses:
  455. // 200: userBodyResponse
  456. func updateUserGroup(w http.ResponseWriter, r *http.Request) {
  457. var userGroup models.UserGroup
  458. err := json.NewDecoder(r.Body).Decode(&userGroup)
  459. if err != nil {
  460. slog.Error("error decoding request body", "error",
  461. err.Error())
  462. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  463. return
  464. }
  465. // fetch curr group
  466. currUserG, err := proLogic.GetUserGroup(userGroup.ID)
  467. if err != nil {
  468. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  469. return
  470. }
  471. if currUserG.Default {
  472. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update default user group"), "badrequest"))
  473. return
  474. }
  475. err = proLogic.ValidateUpdateGroupReq(userGroup)
  476. if err != nil {
  477. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  478. return
  479. }
  480. userGroup.ExternalIdentityProviderID = currUserG.ExternalIdentityProviderID
  481. err = proLogic.UpdateUserGroup(userGroup)
  482. if err != nil {
  483. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  484. return
  485. }
  486. // reset configs for service user
  487. go proLogic.UpdatesUserGwAccessOnGrpUpdates(currUserG.NetworkRoles, userGroup.NetworkRoles)
  488. logic.ReturnSuccessResponseWithJson(w, r, userGroup, "updated user group")
  489. }
  490. // swagger:route DELETE /api/v1/user/group user deleteUserGroup
  491. //
  492. // delete user group.
  493. //
  494. // Schemes: https
  495. //
  496. // Security:
  497. // oauth
  498. //
  499. // Responses:
  500. // 200: userBodyResponse
  501. //
  502. // @Summary Delete user group.
  503. // @Router /api/v1/user/group [delete]
  504. // @Tags Users
  505. // @Param group_id query string true "group id required to delete the role"
  506. // @Success 200 {string} string
  507. // @Failure 500 {object} models.ErrorResponse
  508. func deleteUserGroup(w http.ResponseWriter, r *http.Request) {
  509. gid := r.URL.Query().Get("group_id")
  510. if gid == "" {
  511. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("group id is required"), "badrequest"))
  512. return
  513. }
  514. userG, err := proLogic.GetUserGroup(models.UserGroupID(gid))
  515. if err != nil {
  516. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to fetch group details"), "badrequest"))
  517. return
  518. }
  519. if userG.Default {
  520. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot delete default user group"), "badrequest"))
  521. return
  522. }
  523. err = proLogic.DeleteUserGroup(models.UserGroupID(gid))
  524. if err != nil {
  525. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  526. return
  527. }
  528. go proLogic.UpdatesUserGwAccessOnGrpUpdates(userG.NetworkRoles, make(map[models.NetworkID]map[models.UserRoleID]struct{}))
  529. logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user group")
  530. }
  531. // @Summary lists all user roles.
  532. // @Router /api/v1/user/roles [get]
  533. // @Tags Users
  534. // @Param role_id query string true "roleid required to get the role details"
  535. // @Success 200 {object} []models.UserRolePermissionTemplate
  536. // @Failure 500 {object} models.ErrorResponse
  537. func ListRoles(w http.ResponseWriter, r *http.Request) {
  538. platform := r.URL.Query().Get("platform")
  539. var roles []models.UserRolePermissionTemplate
  540. var err error
  541. if platform == "true" {
  542. roles, err = logic.ListPlatformRoles()
  543. } else {
  544. roles, err = proLogic.ListNetworkRoles()
  545. }
  546. if err != nil {
  547. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  548. Code: http.StatusInternalServerError,
  549. Message: err.Error(),
  550. })
  551. return
  552. }
  553. logic.ReturnSuccessResponseWithJson(w, r, roles, "successfully fetched user roles permission templates")
  554. }
  555. // @Summary Get user role permission template.
  556. // @Router /api/v1/user/role [get]
  557. // @Tags Users
  558. // @Param role_id query string true "roleid required to get the role details"
  559. // @Success 200 {object} models.UserRolePermissionTemplate
  560. // @Failure 500 {object} models.ErrorResponse
  561. func getRole(w http.ResponseWriter, r *http.Request) {
  562. rid := r.URL.Query().Get("role_id")
  563. if rid == "" {
  564. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  565. return
  566. }
  567. role, err := logic.GetRole(models.UserRoleID(rid))
  568. if err != nil {
  569. logic.ReturnErrorResponse(w, r, models.ErrorResponse{
  570. Code: http.StatusInternalServerError,
  571. Message: err.Error(),
  572. })
  573. return
  574. }
  575. logic.ReturnSuccessResponseWithJson(w, r, role, "successfully fetched user role permission templates")
  576. }
  577. // @Summary Create user role permission template.
  578. // @Router /api/v1/user/role [post]
  579. // @Tags Users
  580. // @Param body body models.UserRolePermissionTemplate true "user role template"
  581. // @Success 200 {object} models.UserRolePermissionTemplate
  582. // @Failure 500 {object} models.ErrorResponse
  583. func createRole(w http.ResponseWriter, r *http.Request) {
  584. var userRole models.UserRolePermissionTemplate
  585. err := json.NewDecoder(r.Body).Decode(&userRole)
  586. if err != nil {
  587. slog.Error("error decoding request body", "error",
  588. err.Error())
  589. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  590. return
  591. }
  592. err = proLogic.ValidateCreateRoleReq(&userRole)
  593. if err != nil {
  594. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  595. return
  596. }
  597. userRole.Default = false
  598. userRole.GlobalLevelAccess = make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope)
  599. err = proLogic.CreateRole(userRole)
  600. if err != nil {
  601. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  602. return
  603. }
  604. logic.ReturnSuccessResponseWithJson(w, r, userRole, "created user role")
  605. }
  606. // @Summary Update user role permission template.
  607. // @Router /api/v1/user/role [put]
  608. // @Tags Users
  609. // @Param body body models.UserRolePermissionTemplate true "user role template"
  610. // @Success 200 {object} models.UserRolePermissionTemplate
  611. // @Failure 500 {object} models.ErrorResponse
  612. func updateRole(w http.ResponseWriter, r *http.Request) {
  613. var userRole models.UserRolePermissionTemplate
  614. err := json.NewDecoder(r.Body).Decode(&userRole)
  615. if err != nil {
  616. slog.Error("error decoding request body", "error",
  617. err.Error())
  618. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  619. return
  620. }
  621. currRole, err := logic.GetRole(userRole.ID)
  622. if err != nil {
  623. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  624. return
  625. }
  626. err = proLogic.ValidateUpdateRoleReq(&userRole)
  627. if err != nil {
  628. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  629. return
  630. }
  631. userRole.GlobalLevelAccess = make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope)
  632. err = proLogic.UpdateRole(userRole)
  633. if err != nil {
  634. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  635. return
  636. }
  637. // reset configs for service user
  638. go proLogic.UpdatesUserGwAccessOnRoleUpdates(currRole.NetworkLevelAccess, userRole.NetworkLevelAccess, string(userRole.NetworkID))
  639. logic.ReturnSuccessResponseWithJson(w, r, userRole, "updated user role")
  640. }
  641. // @Summary Delete user role permission template.
  642. // @Router /api/v1/user/role [delete]
  643. // @Tags Users
  644. // @Param role_id query string true "roleid required to delete the role"
  645. // @Success 200 {string} string
  646. // @Failure 500 {object} models.ErrorResponse
  647. func deleteRole(w http.ResponseWriter, r *http.Request) {
  648. rid := r.URL.Query().Get("role_id")
  649. if rid == "" {
  650. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  651. return
  652. }
  653. role, err := logic.GetRole(models.UserRoleID(rid))
  654. if err != nil {
  655. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  656. return
  657. }
  658. err = proLogic.DeleteRole(models.UserRoleID(rid), false)
  659. if err != nil {
  660. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  661. return
  662. }
  663. go proLogic.UpdatesUserGwAccessOnRoleUpdates(role.NetworkLevelAccess, make(map[models.RsrcType]map[models.RsrcID]models.RsrcPermissionScope), role.NetworkID.String())
  664. logic.ReturnSuccessResponseWithJson(w, r, nil, "deleted user role")
  665. }
  666. // @Summary Attach user to a remote access gateway
  667. // @Router /api/users/{username}/remote_access_gw/{remote_access_gateway_id} [post]
  668. // @Tags PRO
  669. // @Accept json
  670. // @Produce json
  671. // @Param username path string true "Username"
  672. // @Param remote_access_gateway_id path string true "Remote Access Gateway ID"
  673. // @Success 200 {object} models.ReturnUser
  674. // @Failure 400 {object} models.ErrorResponse
  675. // @Failure 500 {object} models.ErrorResponse
  676. func attachUserToRemoteAccessGw(w http.ResponseWriter, r *http.Request) {
  677. // set header.
  678. w.Header().Set("Content-Type", "application/json")
  679. var params = mux.Vars(r)
  680. username := params["username"]
  681. remoteGwID := params["remote_access_gateway_id"]
  682. if username == "" || remoteGwID == "" {
  683. logic.ReturnErrorResponse(
  684. w,
  685. r,
  686. logic.FormatError(
  687. errors.New("required params `username` and `remote_access_gateway_id`"),
  688. "badrequest",
  689. ),
  690. )
  691. return
  692. }
  693. user, err := logic.GetUser(username)
  694. if err != nil {
  695. slog.Error("failed to fetch user: ", "username", username, "error", err.Error())
  696. logic.ReturnErrorResponse(
  697. w,
  698. r,
  699. logic.FormatError(
  700. fmt.Errorf("failed to fetch user %s, error: %v", username, err),
  701. "badrequest",
  702. ),
  703. )
  704. return
  705. }
  706. if user.PlatformRoleID == models.AdminRole || user.PlatformRoleID == models.SuperAdminRole {
  707. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("superadmins/admins have access to all gateways"), "badrequest"))
  708. return
  709. }
  710. node, err := logic.GetNodeByID(remoteGwID)
  711. if err != nil {
  712. slog.Error("failed to fetch gateway node", "nodeID", remoteGwID, "error", err)
  713. logic.ReturnErrorResponse(
  714. w,
  715. r,
  716. logic.FormatError(
  717. fmt.Errorf("failed to fetch remote access gateway node, error: %v", err),
  718. "badrequest",
  719. ),
  720. )
  721. return
  722. }
  723. if !node.IsIngressGateway {
  724. logic.ReturnErrorResponse(
  725. w,
  726. r,
  727. logic.FormatError(fmt.Errorf("node is not a remote access gateway"), "badrequest"),
  728. )
  729. return
  730. }
  731. if user.RemoteGwIDs == nil {
  732. user.RemoteGwIDs = make(map[string]struct{})
  733. }
  734. user.RemoteGwIDs[node.ID.String()] = struct{}{}
  735. err = logic.UpsertUser(*user)
  736. if err != nil {
  737. slog.Error("failed to update user's gateways", "user", username, "error", err)
  738. logic.ReturnErrorResponse(
  739. w,
  740. r,
  741. logic.FormatError(
  742. fmt.Errorf("failed to fetch remote access gateway node,error: %v", err),
  743. "badrequest",
  744. ),
  745. )
  746. return
  747. }
  748. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  749. }
  750. // @Summary Remove user from a remote access gateway
  751. // @Router /api/users/{username}/remote_access_gw/{remote_access_gateway_id} [delete]
  752. // @Tags PRO
  753. // @Accept json
  754. // @Produce json
  755. // @Param username path string true "Username"
  756. // @Param remote_access_gateway_id path string true "Remote Access Gateway ID"
  757. // @Success 200 {object} models.ReturnUser
  758. // @Failure 400 {object} models.ErrorResponse
  759. // @Failure 500 {object} models.ErrorResponse
  760. func removeUserFromRemoteAccessGW(w http.ResponseWriter, r *http.Request) {
  761. // set header.
  762. w.Header().Set("Content-Type", "application/json")
  763. var params = mux.Vars(r)
  764. username := params["username"]
  765. remoteGwID := params["remote_access_gateway_id"]
  766. if username == "" || remoteGwID == "" {
  767. logic.ReturnErrorResponse(
  768. w,
  769. r,
  770. logic.FormatError(
  771. errors.New("required params `username` and `remote_access_gateway_id`"),
  772. "badrequest",
  773. ),
  774. )
  775. return
  776. }
  777. user, err := logic.GetUser(username)
  778. if err != nil {
  779. logger.Log(0, username, "failed to fetch user: ", err.Error())
  780. logic.ReturnErrorResponse(
  781. w,
  782. r,
  783. logic.FormatError(
  784. fmt.Errorf("failed to fetch user %s, error: %v", username, err),
  785. "badrequest",
  786. ),
  787. )
  788. return
  789. }
  790. delete(user.RemoteGwIDs, remoteGwID)
  791. go func(user models.User, remoteGwID string) {
  792. extclients, err := logic.GetAllExtClients()
  793. if err != nil {
  794. slog.Error("failed to fetch extclients", "error", err)
  795. return
  796. }
  797. for _, extclient := range extclients {
  798. if extclient.OwnerID == user.UserName && remoteGwID == extclient.IngressGatewayID {
  799. err = logic.DeleteExtClientAndCleanup(extclient)
  800. if err != nil {
  801. slog.Error("failed to delete extclient",
  802. "id", extclient.ClientID, "owner", user.UserName, "error", err)
  803. } else {
  804. if err := mq.PublishDeletedClientPeerUpdate(&extclient); err != nil {
  805. slog.Error("error setting ext peers: " + err.Error())
  806. }
  807. }
  808. }
  809. }
  810. if servercfg.IsDNSMode() {
  811. logic.SetDNS()
  812. }
  813. }(*user, remoteGwID)
  814. err = logic.UpsertUser(*user)
  815. if err != nil {
  816. slog.Error("failed to update user gateways", "user", username, "error", err)
  817. logic.ReturnErrorResponse(
  818. w,
  819. r,
  820. logic.FormatError(
  821. errors.New("failed to fetch remote access gaetway node "+err.Error()),
  822. "badrequest",
  823. ),
  824. )
  825. return
  826. }
  827. json.NewEncoder(w).Encode(logic.ToReturnUser(*user))
  828. }
  829. // @Summary Get Users Remote Access Gw Networks.
  830. // @Router /api/users/{username}/remote_access_gw [get]
  831. // @Tags Users
  832. // @Param username path string true "Username to fetch all the gateways with access"
  833. // @Success 200 {object} map[string][]models.UserRemoteGws
  834. // @Failure 500 {object} models.ErrorResponse
  835. func getUserRemoteAccessNetworks(w http.ResponseWriter, r *http.Request) {
  836. // set header.
  837. w.Header().Set("Content-Type", "application/json")
  838. username := r.Header.Get("user")
  839. user, err := logic.GetUser(username)
  840. if err != nil {
  841. logger.Log(0, username, "failed to fetch user: ", err.Error())
  842. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  843. return
  844. }
  845. userGws := make(map[string][]models.UserRemoteGws)
  846. networks := []models.Network{}
  847. networkMap := make(map[string]struct{})
  848. userGwNodes := proLogic.GetUserRAGNodes(*user)
  849. for _, node := range userGwNodes {
  850. network, err := logic.GetNetwork(node.Network)
  851. if err != nil {
  852. slog.Error("failed to get node network", "error", err)
  853. continue
  854. }
  855. if _, ok := networkMap[network.NetID]; ok {
  856. continue
  857. }
  858. networkMap[network.NetID] = struct{}{}
  859. networks = append(networks, network)
  860. }
  861. slog.Debug("returned user gws", "user", username, "gws", userGws)
  862. logic.ReturnSuccessResponseWithJson(w, r, networks, "fetched user accessible networks")
  863. }
  864. // @Summary Get Users Remote Access Gw Networks.
  865. // @Router /api/users/{username}/remote_access_gw [get]
  866. // @Tags Users
  867. // @Param username path string true "Username to fetch all the gateways with access"
  868. // @Success 200 {object} map[string][]models.UserRemoteGws
  869. // @Failure 500 {object} models.ErrorResponse
  870. func getUserRemoteAccessNetworkGateways(w http.ResponseWriter, r *http.Request) {
  871. // set header.
  872. w.Header().Set("Content-Type", "application/json")
  873. var params = mux.Vars(r)
  874. username := r.Header.Get("user")
  875. user, err := logic.GetUser(username)
  876. if err != nil {
  877. logger.Log(0, username, "failed to fetch user: ", err.Error())
  878. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  879. return
  880. }
  881. network := params["network"]
  882. if network == "" {
  883. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params network"), "badrequest"))
  884. return
  885. }
  886. userGws := []models.UserRAGs{}
  887. userGwNodes := proLogic.GetUserRAGNodes(*user)
  888. for _, node := range userGwNodes {
  889. if node.Network != network {
  890. continue
  891. }
  892. host, err := logic.GetHost(node.HostID.String())
  893. if err != nil {
  894. continue
  895. }
  896. userGws = append(userGws, models.UserRAGs{
  897. GwID: node.ID.String(),
  898. GWName: host.Name,
  899. Network: node.Network,
  900. IsInternetGateway: node.IsInternetGateway,
  901. Metadata: node.Metadata,
  902. })
  903. }
  904. slog.Debug("returned user gws", "user", username, "gws", userGws)
  905. logic.ReturnSuccessResponseWithJson(w, r, userGws, "fetched user accessible gateways in network "+network)
  906. }
  907. // @Summary Get Users Remote Access Gw Networks.
  908. // @Router /api/users/{username}/remote_access_gw [get]
  909. // @Tags Users
  910. // @Param username path string true "Username to fetch all the gateways with access"
  911. // @Success 200 {object} map[string][]models.UserRemoteGws
  912. // @Failure 500 {object} models.ErrorResponse
  913. func getRemoteAccessGatewayConf(w http.ResponseWriter, r *http.Request) {
  914. // set header.
  915. w.Header().Set("Content-Type", "application/json")
  916. var params = mux.Vars(r)
  917. username := r.Header.Get("user")
  918. user, err := logic.GetUser(username)
  919. if err != nil {
  920. logger.Log(0, username, "failed to fetch user: ", err.Error())
  921. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  922. return
  923. }
  924. remoteGwID := params["access_point_id"]
  925. if remoteGwID == "" {
  926. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params access_point_id"), "badrequest"))
  927. return
  928. }
  929. var req models.UserRemoteGwsReq
  930. err = json.NewDecoder(r.Body).Decode(&req)
  931. if err != nil {
  932. slog.Error("error decoding request body: ", "error", err)
  933. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  934. return
  935. }
  936. userGwNodes := proLogic.GetUserRAGNodes(*user)
  937. if _, ok := userGwNodes[remoteGwID]; !ok {
  938. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("access denied"), "forbidden"))
  939. return
  940. }
  941. node, err := logic.GetNodeByID(remoteGwID)
  942. if err != nil {
  943. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch gw node %s, error: %v", remoteGwID, err), "badrequest"))
  944. return
  945. }
  946. host, err := logic.GetHost(node.HostID.String())
  947. if err != nil {
  948. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch gw host %s, error: %v", remoteGwID, err), "badrequest"))
  949. return
  950. }
  951. network, err := logic.GetNetwork(node.Network)
  952. if err != nil {
  953. slog.Error("failed to get node network", "error", err)
  954. }
  955. var userConf models.ExtClient
  956. allextClients, err := logic.GetAllExtClients()
  957. if err != nil {
  958. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  959. return
  960. }
  961. for _, extClient := range allextClients {
  962. if extClient.Network != network.NetID || extClient.IngressGatewayID != node.ID.String() {
  963. continue
  964. }
  965. if extClient.RemoteAccessClientID == req.RemoteAccessClientID && extClient.OwnerID == username {
  966. userConf = extClient
  967. userConf.AllowedIPs = logic.GetExtclientAllowedIPs(extClient)
  968. }
  969. }
  970. if userConf.ClientID == "" {
  971. // create a new conf
  972. userConf.OwnerID = user.UserName
  973. userConf.RemoteAccessClientID = req.RemoteAccessClientID
  974. userConf.IngressGatewayID = node.ID.String()
  975. // set extclient dns to ingressdns if extclient dns is not explicitly set
  976. if (userConf.DNS == "") && (node.IngressDNS != "") {
  977. userConf.DNS = node.IngressDNS
  978. }
  979. userConf.Network = node.Network
  980. host, err := logic.GetHost(node.HostID.String())
  981. if err != nil {
  982. logger.Log(0, r.Header.Get("user"),
  983. fmt.Sprintf("failed to get ingress gateway host for node [%s] info: %v", node.ID, err))
  984. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  985. return
  986. }
  987. listenPort := logic.GetPeerListenPort(host)
  988. if host.EndpointIP.To4() == nil {
  989. userConf.IngressGatewayEndpoint = fmt.Sprintf("[%s]:%d", host.EndpointIPv6.String(), listenPort)
  990. } else {
  991. userConf.IngressGatewayEndpoint = fmt.Sprintf("%s:%d", host.EndpointIP.String(), listenPort)
  992. }
  993. userConf.Enabled = true
  994. parentNetwork, err := logic.GetNetwork(node.Network)
  995. if err == nil { // check if parent network default ACL is enabled (yes) or not (no)
  996. userConf.Enabled = parentNetwork.DefaultACL == "yes"
  997. }
  998. userConf.Tags = make(map[models.TagID]struct{})
  999. // userConf.Tags[models.TagID(fmt.Sprintf("%s.%s", userConf.Network,
  1000. // models.RemoteAccessTagName))] = struct{}{}
  1001. if err = logic.CreateExtClient(&userConf); err != nil {
  1002. slog.Error(
  1003. "failed to create extclient",
  1004. "user",
  1005. r.Header.Get("user"),
  1006. "network",
  1007. node.Network,
  1008. "error",
  1009. err,
  1010. )
  1011. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1012. return
  1013. }
  1014. }
  1015. userGw := models.UserRemoteGws{
  1016. GwID: node.ID.String(),
  1017. GWName: host.Name,
  1018. Network: node.Network,
  1019. GwClient: userConf,
  1020. Connected: true,
  1021. IsInternetGateway: node.IsInternetGateway,
  1022. GwPeerPublicKey: host.PublicKey.String(),
  1023. GwListenPort: logic.GetPeerListenPort(host),
  1024. Metadata: node.Metadata,
  1025. AllowedEndpoints: getAllowedRagEndpoints(&node, host),
  1026. NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
  1027. DnsAddress: node.IngressDNS,
  1028. Addresses: utils.NoEmptyStringToCsv(node.Address.String(), node.Address6.String()),
  1029. }
  1030. slog.Debug("returned user gw config", "user", user.UserName, "gws", userGw)
  1031. logic.ReturnSuccessResponseWithJson(w, r, userGw, "fetched user config to gw "+remoteGwID)
  1032. }
  1033. // @Summary Get Users Remote Access Gw.
  1034. // @Router /api/users/{username}/remote_access_gw [get]
  1035. // @Tags Users
  1036. // @Param username path string true "Username to fetch all the gateways with access"
  1037. // @Success 200 {object} map[string][]models.UserRemoteGws
  1038. // @Failure 500 {object} models.ErrorResponse
  1039. func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
  1040. // set header.
  1041. w.Header().Set("Content-Type", "application/json")
  1042. var params = mux.Vars(r)
  1043. username := params["username"]
  1044. if username == "" {
  1045. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("required params username"), "badrequest"))
  1046. return
  1047. }
  1048. user, err := logic.GetUser(username)
  1049. if err != nil {
  1050. logger.Log(0, username, "failed to fetch user: ", err.Error())
  1051. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to fetch user %s, error: %v", username, err), "badrequest"))
  1052. return
  1053. }
  1054. remoteAccessClientID := r.URL.Query().Get("remote_access_clientid")
  1055. var req models.UserRemoteGwsReq
  1056. if remoteAccessClientID == "" {
  1057. err := json.NewDecoder(r.Body).Decode(&req)
  1058. if err != nil {
  1059. slog.Error("error decoding request body: ", "error", err)
  1060. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  1061. return
  1062. }
  1063. }
  1064. reqFromMobile := r.URL.Query().Get("from_mobile") == "true"
  1065. if req.RemoteAccessClientID == "" && remoteAccessClientID == "" {
  1066. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("remote access client id cannot be empty"), "badrequest"))
  1067. return
  1068. }
  1069. if req.RemoteAccessClientID == "" {
  1070. req.RemoteAccessClientID = remoteAccessClientID
  1071. }
  1072. userGws := make(map[string][]models.UserRemoteGws)
  1073. allextClients, err := logic.GetAllExtClients()
  1074. if err != nil {
  1075. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1076. return
  1077. }
  1078. userGwNodes := proLogic.GetUserRAGNodes(*user)
  1079. for _, extClient := range allextClients {
  1080. node, ok := userGwNodes[extClient.IngressGatewayID]
  1081. if !ok {
  1082. continue
  1083. }
  1084. if extClient.RemoteAccessClientID == req.RemoteAccessClientID && extClient.OwnerID == username {
  1085. host, err := logic.GetHost(node.HostID.String())
  1086. if err != nil {
  1087. continue
  1088. }
  1089. network, err := logic.GetNetwork(node.Network)
  1090. if err != nil {
  1091. slog.Error("failed to get node network", "error", err)
  1092. continue
  1093. }
  1094. nodesWithStatus := logic.AddStatusToNodes([]models.Node{node}, false)
  1095. if len(nodesWithStatus) > 0 {
  1096. node = nodesWithStatus[0]
  1097. }
  1098. gws := userGws[node.Network]
  1099. if extClient.DNS == "" {
  1100. extClient.DNS = node.IngressDNS
  1101. }
  1102. extClient.AllowedIPs = logic.GetExtclientAllowedIPs(extClient)
  1103. gws = append(gws, models.UserRemoteGws{
  1104. GwID: node.ID.String(),
  1105. GWName: host.Name,
  1106. Network: node.Network,
  1107. GwClient: extClient,
  1108. Connected: true,
  1109. IsInternetGateway: node.IsInternetGateway,
  1110. GwPeerPublicKey: host.PublicKey.String(),
  1111. GwListenPort: logic.GetPeerListenPort(host),
  1112. Metadata: node.Metadata,
  1113. AllowedEndpoints: getAllowedRagEndpoints(&node, host),
  1114. NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
  1115. Status: node.Status,
  1116. DnsAddress: node.IngressDNS,
  1117. Addresses: utils.NoEmptyStringToCsv(node.Address.String(), node.Address6.String()),
  1118. })
  1119. userGws[node.Network] = gws
  1120. delete(userGwNodes, node.ID.String())
  1121. }
  1122. }
  1123. // add remaining gw nodes to resp
  1124. for gwID := range userGwNodes {
  1125. node, err := logic.GetNodeByID(gwID)
  1126. if err != nil {
  1127. continue
  1128. }
  1129. if !node.IsIngressGateway {
  1130. continue
  1131. }
  1132. if node.PendingDelete {
  1133. continue
  1134. }
  1135. host, err := logic.GetHost(node.HostID.String())
  1136. if err != nil {
  1137. continue
  1138. }
  1139. nodesWithStatus := logic.AddStatusToNodes([]models.Node{node}, false)
  1140. if len(nodesWithStatus) > 0 {
  1141. node = nodesWithStatus[0]
  1142. }
  1143. network, err := logic.GetNetwork(node.Network)
  1144. if err != nil {
  1145. slog.Error("failed to get node network", "error", err)
  1146. }
  1147. gws := userGws[node.Network]
  1148. gws = append(gws, models.UserRemoteGws{
  1149. GwID: node.ID.String(),
  1150. GWName: host.Name,
  1151. Network: node.Network,
  1152. IsInternetGateway: node.IsInternetGateway,
  1153. GwPeerPublicKey: host.PublicKey.String(),
  1154. GwListenPort: logic.GetPeerListenPort(host),
  1155. Metadata: node.Metadata,
  1156. AllowedEndpoints: getAllowedRagEndpoints(&node, host),
  1157. NetworkAddresses: []string{network.AddressRange, network.AddressRange6},
  1158. Status: node.Status,
  1159. DnsAddress: node.IngressDNS,
  1160. Addresses: utils.NoEmptyStringToCsv(node.Address.String(), node.Address6.String()),
  1161. })
  1162. userGws[node.Network] = gws
  1163. }
  1164. if reqFromMobile {
  1165. // send resp in array format
  1166. userGwsArr := []models.UserRemoteGws{}
  1167. for _, userGwI := range userGws {
  1168. userGwsArr = append(userGwsArr, userGwI...)
  1169. }
  1170. logic.ReturnSuccessResponseWithJson(w, r, userGwsArr, "fetched gateways for user"+username)
  1171. return
  1172. }
  1173. slog.Debug("returned user gws", "user", username, "gws", userGws)
  1174. w.WriteHeader(http.StatusOK)
  1175. json.NewEncoder(w).Encode(userGws)
  1176. }
  1177. // @Summary List users attached to an remote access gateway
  1178. // @Router /api/nodes/{network}/{nodeid}/ingress/users [get]
  1179. // @Tags PRO
  1180. // @Accept json
  1181. // @Produce json
  1182. // @Param ingress_id path string true "Ingress Gateway ID"
  1183. // @Success 200 {array} models.IngressGwUsers
  1184. // @Failure 400 {object} models.ErrorResponse
  1185. // @Failure 500 {object} models.ErrorResponse
  1186. func ingressGatewayUsers(w http.ResponseWriter, r *http.Request) {
  1187. w.Header().Set("Content-Type", "application/json")
  1188. var params = mux.Vars(r)
  1189. ingressID := params["ingress_id"]
  1190. node, err := logic.GetNodeByID(ingressID)
  1191. if err != nil {
  1192. slog.Error("failed to get ingress node", "error", err)
  1193. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  1194. return
  1195. }
  1196. gwUsers, err := logic.GetIngressGwUsers(node)
  1197. if err != nil {
  1198. slog.Error(
  1199. "failed to get users on ingress gateway",
  1200. "nodeid",
  1201. ingressID,
  1202. "network",
  1203. node.Network,
  1204. "user",
  1205. r.Header.Get("user"),
  1206. "error",
  1207. err,
  1208. )
  1209. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1210. return
  1211. }
  1212. w.WriteHeader(http.StatusOK)
  1213. json.NewEncoder(w).Encode(gwUsers)
  1214. }
  1215. func getAllowedRagEndpoints(ragNode *models.Node, ragHost *models.Host) []string {
  1216. endpoints := []string{}
  1217. if len(ragHost.EndpointIP) > 0 {
  1218. endpoints = append(endpoints, ragHost.EndpointIP.String())
  1219. }
  1220. if len(ragHost.EndpointIPv6) > 0 {
  1221. endpoints = append(endpoints, ragHost.EndpointIPv6.String())
  1222. }
  1223. if servercfg.IsPro {
  1224. for _, ip := range ragNode.AdditionalRagIps {
  1225. endpoints = append(endpoints, ip.String())
  1226. }
  1227. }
  1228. return endpoints
  1229. }
  1230. // @Summary Get all pending users
  1231. // @Router /api/users_pending [get]
  1232. // @Tags Users
  1233. // @Success 200 {array} models.User
  1234. // @Failure 500 {object} models.ErrorResponse
  1235. func getPendingUsers(w http.ResponseWriter, r *http.Request) {
  1236. // set header.
  1237. w.Header().Set("Content-Type", "application/json")
  1238. users, err := logic.ListPendingReturnUsers()
  1239. if err != nil {
  1240. logger.Log(0, "failed to fetch users: ", err.Error())
  1241. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1242. return
  1243. }
  1244. logic.SortUsers(users[:])
  1245. logger.Log(2, r.Header.Get("user"), "fetched pending users")
  1246. json.NewEncoder(w).Encode(users)
  1247. }
  1248. // @Summary Approve a pending user
  1249. // @Router /api/users_pending/user/{username} [post]
  1250. // @Tags Users
  1251. // @Param username path string true "Username of the pending user to approve"
  1252. // @Success 200 {string} string
  1253. // @Failure 500 {object} models.ErrorResponse
  1254. func approvePendingUser(w http.ResponseWriter, r *http.Request) {
  1255. // set header.
  1256. w.Header().Set("Content-Type", "application/json")
  1257. var params = mux.Vars(r)
  1258. username := params["username"]
  1259. users, err := logic.ListPendingUsers()
  1260. if err != nil {
  1261. logger.Log(0, "failed to fetch users: ", err.Error())
  1262. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1263. return
  1264. }
  1265. for _, user := range users {
  1266. if user.UserName == username {
  1267. var newPass, fetchErr = logic.FetchPassValue("")
  1268. if fetchErr != nil {
  1269. logic.ReturnErrorResponse(w, r, logic.FormatError(fetchErr, "internal"))
  1270. return
  1271. }
  1272. if err = logic.CreateUser(&models.User{
  1273. UserName: user.UserName,
  1274. ExternalIdentityProviderID: user.ExternalIdentityProviderID,
  1275. Password: newPass,
  1276. AuthType: user.AuthType,
  1277. PlatformRoleID: models.ServiceUser,
  1278. }); err != nil {
  1279. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to create user: %s", err), "internal"))
  1280. return
  1281. }
  1282. err = logic.DeletePendingUser(username)
  1283. if err != nil {
  1284. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete pending user: %s", err), "internal"))
  1285. return
  1286. }
  1287. break
  1288. }
  1289. }
  1290. logic.ReturnSuccessResponse(w, r, "approved "+username)
  1291. }
  1292. // @Summary Delete a pending user
  1293. // @Router /api/users_pending/user/{username} [delete]
  1294. // @Tags Users
  1295. // @Param username path string true "Username of the pending user to delete"
  1296. // @Success 200 {string} string
  1297. // @Failure 500 {object} models.ErrorResponse
  1298. func deletePendingUser(w http.ResponseWriter, r *http.Request) {
  1299. // set header.
  1300. w.Header().Set("Content-Type", "application/json")
  1301. var params = mux.Vars(r)
  1302. username := params["username"]
  1303. users, err := logic.ListPendingReturnUsers()
  1304. if err != nil {
  1305. logger.Log(0, "failed to fetch users: ", err.Error())
  1306. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  1307. return
  1308. }
  1309. for _, user := range users {
  1310. if user.UserName == username {
  1311. err = logic.DeletePendingUser(username)
  1312. if err != nil {
  1313. logic.ReturnErrorResponse(w, r, logic.FormatError(fmt.Errorf("failed to delete pending user: %s", err), "internal"))
  1314. return
  1315. }
  1316. break
  1317. }
  1318. }
  1319. logic.ReturnSuccessResponse(w, r, "deleted pending "+username)
  1320. }
  1321. // @Summary Delete all pending users
  1322. // @Router /api/users_pending [delete]
  1323. // @Tags Users
  1324. // @Success 200 {string} string
  1325. // @Failure 500 {object} models.ErrorResponse
  1326. func deleteAllPendingUsers(w http.ResponseWriter, r *http.Request) {
  1327. // set header.
  1328. err := database.DeleteAllRecords(database.PENDING_USERS_TABLE_NAME)
  1329. if err != nil {
  1330. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to delete all pending users "+err.Error()), "internal"))
  1331. return
  1332. }
  1333. logic.ReturnSuccessResponse(w, r, "cleared all pending users")
  1334. }
  1335. // @Summary Sync users and groups from idp.
  1336. // @Router /api/idp/sync [post]
  1337. // @Tags IDP
  1338. // @Success 200 {object} models.SuccessResponse
  1339. func syncIDP(w http.ResponseWriter, r *http.Request) {
  1340. go func() {
  1341. err := proAuth.SyncFromIDP()
  1342. if err != nil {
  1343. logger.Log(0, "failed to sync from idp: ", err.Error())
  1344. } else {
  1345. logger.Log(0, "sync from idp complete")
  1346. }
  1347. }()
  1348. logic.ReturnSuccessResponse(w, r, "starting sync from idp")
  1349. }
  1350. // @Summary Remove idp integration.
  1351. // @Router /api/idp [delete]
  1352. // @Tags IDP
  1353. // @Success 200 {object} models.SuccessResponse
  1354. // @Failure 500 {object} models.ErrorResponse
  1355. func removeIDPIntegration(w http.ResponseWriter, r *http.Request) {
  1356. superAdmin, err := logic.GetSuperAdmin()
  1357. if err != nil {
  1358. logic.ReturnErrorResponse(
  1359. w,
  1360. r,
  1361. logic.FormatError(fmt.Errorf("failed to get superadmin: %v", err), "internal"),
  1362. )
  1363. return
  1364. }
  1365. if superAdmin.AuthType == models.OAuth {
  1366. logic.ReturnErrorResponse(
  1367. w,
  1368. r,
  1369. logic.FormatError(fmt.Errorf("cannot remove idp integration with superadmin oauth user"), "badrequest"),
  1370. )
  1371. return
  1372. }
  1373. settings := logic.GetServerSettings()
  1374. settings.AuthProvider = ""
  1375. settings.OIDCIssuer = ""
  1376. settings.ClientID = ""
  1377. settings.ClientSecret = ""
  1378. settings.SyncEnabled = false
  1379. settings.GoogleAdminEmail = ""
  1380. settings.GoogleSACredsJson = ""
  1381. settings.AzureTenant = ""
  1382. settings.UserFilters = nil
  1383. settings.GroupFilters = nil
  1384. err = logic.UpsertServerSettings(settings)
  1385. if err != nil {
  1386. logic.ReturnErrorResponse(
  1387. w,
  1388. r,
  1389. logic.FormatError(fmt.Errorf("failed to remove idp integration: %v", err), "internal"),
  1390. )
  1391. return
  1392. }
  1393. proAuth.ResetAuthProvider()
  1394. proAuth.ResetIDPSyncHook()
  1395. go func() {
  1396. err := proAuth.SyncFromIDP()
  1397. if err != nil {
  1398. logger.Log(0, "failed to sync from idp: ", err.Error())
  1399. } else {
  1400. logger.Log(0, "sync from idp complete")
  1401. }
  1402. }()
  1403. logic.ReturnSuccessResponse(w, r, "removed idp integration successfully")
  1404. }