mirror of
https://github.com/gravitl/netmaker.git
synced 2026-10-12 02:15:06 +00:00
NM-341-v6 (#4107)
* wip(go): wire ctx in extclient apis; * wip(go): wire ctx in extclient apis; * wip(go): remove org id check from global scoped get tenant api; * wip(go): add scope slug to discover response; * wip(go): wire ctx in get users; * wip(go): set tenant id in posture check violations; * wip(go): upsert membership instead of user; * wip(go): pass correct len; * wip(go): optimize (single loop); * wip(go): unify todos; * wip(go): add todo; * wip(go): wire context for network get; * wip(go): wire context; * wip(go): wire context; * wip(go): wire ctx when getting tenant superadmin; * wip(go): add network creator to network admin group; * wip(go): check for user membership on sync; * wip(go): add methods with strict membership check; * wip(go): remove unwanted feature flags; * wip(go): report per-tenant usage during license validation; * wip(go): move email setting from tenant to org; * wip(go): pass org scope to email init; * wip(go): remove old tenant email settings usages; use org settings to get email settings * wip(go): use get email settings from org settings; * wip(go): remove email settings migration; * wip(go): migrate email settings from server to org settings; * wip(go): assign global network admin group membership only for super-admin and admins; * wip(go): assign global network admin group membership only for super-admin and admins; * wip(go): add membership alias to filter; * wip(go): skip clearing local license validation response cache; * wip(go): extend license validation response for multi-tenancy; * wip(go): add functions to get sole tenant and org; * wip(go): use tenant-specific feature flags; * wip(go): add tenant status type; * wip(go): remove old hook comment; * wip(go): expect ctx during license validation; * wip(go): always create default org and tenant for ce; * wip(go): add tenant-specific check for license validation error; * wip(go): cache license validation response in memory; * wip(go): add todo to handle multiple-tenant for integration pull; * wip(go): pass ctx during license validation; * wip(go): add todo for making changes later; run hook separately for each tenant; * wip(go): return specific errors when license validation response not in cache; * wip(go): use retryable.httpclient for calling license validation api; * wip(go): process license validation; * wip(go): license validation function; * wip(go): migration on license validation; * wip(go): org settings not expected; * wip(go): remove expiry from license validation response; * wip(go): add limits and limits enforcement to license validation response; * wip(go): remove expiry usages; * wip(go): add arg to clear cache; * wip(go): add arg to clear cache; * wip(go): skip license validation if cached resp; * wip(go): allow org_id and tenant_id query params; * wip(go): upsert tenant membership on sync; * wip(go): pass ctx to delete network roles; * wip(go): create tenant membership on org owner creation on ce; * wip(go): add tenant orchestrator; * wip(go): use tenant orchestrator; * wip(go): add default settings for tenant; * wip(go): make org owner superadmin on all tenants; * wip(go): simplify SyncOrgAndTenants; * wip(go): retry license validation only 3 times * wip(go): store invalid err; * wip(go): add function to check if limits are to be enforced on a tenant; * wip(go): pass tenant scope if possible when checking for license validation error; * wip(go): remove merge errors; * wip(go): add functions for limit checks; * wip(go): wire host limit check; * wip(go): wire ingress limit check; * wip(go): wire egress limit check; * wip(go): wire client limit check; * wip(go): wire network limit check; * wip(go): wire user limit check; * wip(go): use correct errors; * wip(go): skip telemetry for msps; * wip(go): disable telemetry on msp tenants; * wip(go): err check; * wip(go): uncomment log event; * wip(go): get sso state to get scope for non-headless oauth login; * wip(go): inline delete pending user; * wip(go): allow both org and tenant scope for pending users table; * wip(go): add migration for pending user table during set tenant id and rekey org/tenant id; * wip(go): update queries to use new scope fields in pending users table; * wip(go): allow both org and tenant scope for user invites table; * wip(go): update queries to use new scope fields; * wip(go): add migration for rekey-ing org/tenant id and setting tenant id; * wip(go): inline delete user invite; * wip(go): set scope when creating invite; * wip(go): get user count with membership is ctx is tenant scoped; * wip(go): add methods to upsert and delete org memberships; * wip(go): add global valid tenant and org roles map; * wip(go): add scope query in user invite get by email; * wip(go): add support for upsert and delete of org and tenant membership both; * wip(go): infer scope for user invite apis; * wip(go): wire ctx in get user invite by email; * wip(go): allow no scope headers to be passed in infer scope apis; * wip(go): add validation and checks for org-scoped invite api handlers; * wip(go): wire ctx to is pending user check; * wip(go): infer scope for pending user apis; * wip(go): set default role based on ctx scope; * wip(go): move mfa to tenant membership table; move account status to membership tables; * wip(go): migrate account status and mfa settings; * wip(go): update account status on sync; * wip(go): use update mfa to update mfa setting; * wip(go): set new membership settings on user creation; * wip(go): use membership where required; * wip(go): wire ctx on key unlink refs; * wip(go): use r.Context directly without reinitializing db; * wip(go): wire ctx in acls; * wip(go): add tenant scoped primary key constructor; * wip(go): use tenant scoped primary key for acls, dns, extclients and tags; * wip(go): wire ctx for get groups in network; * wip(go): wire ctx for get groups; * wip(go): scope non-uuid group ids by tenant id; * wip(go): migrate non-uuid group ids to scoped ids; * wip(go): don't expect scope id in invite validation and signup apis; * wip(go): wire ctx for get matching user; allow org scope when querying by external idp id; * wip(go): add mfa to org; * wip(go): scope preauth token; * wip(go): add fallback for older auth tokens; * wip(go): wire ctx for preauth token creation; * wip(go): migrate mfa settings; * wip(go): resolve mfa settings for inherited auth; * wip(go): update mfa for org; * wip(go): infer scope for totp apis; * wip(go): use ctx when passed; * wip(go): infer scope for list user apis; * wip(go): ensure set primary keys don't cause errors during fetch; * wip(go): make primary key for integrations uuid and store provider in separate key; * wip(go): migrate integration ids; * wip(go): use provider instead of id everywhere; * wip(go): remove gorm column; * wip(go): wire ctx for igw egress creation; * wip(go): wire ctx for igw egress update; * wip(go): wire ctx for host registration; * wip(go): wire ctx for host registration; * wip(go): merge errors; * wip(go): merge errors; * wip(go): wire ctx; remove default scope usages; * wip(go): use get with membership; * wip(go): org scope license validation; * wip(go): remove debug log; * wip(go): remove scoping on list roles; * wip(go): ignore invite creation if already exists; * wip(go): add is msp func to check if deployment is msp deployment; * wip(go): ensure username is email for msp users; * wip(go): add email validated check on user table; * wip(go): mark email validated when oauth user; * wip(go): handle gorm error; * wip(go): add tenant id to siem grpc schema; * wip(go): read tenant from scoped ctx; * wip(go): pass scoped ctx to siem grpc client; * wip(go): remove unused publisher; * wip(go): publish all tenant exporter updates on pull; * wip(go): fix wg usage; * wip(go): tenant scope the ctx when getting server info; * wip(go): add tenant id to enrollment key token; * wip(go): make host register tenant scope; * wip(go): add default settings; * wip(go): use correct checks for is msp tenant; * wip(go): add email validation extension; * wip(go): add pages for validation check; * wip(go): use extension for validating user; * wip(go): add invite type; * wip(go): create only one validation invite per user email; * wip(go): add validate email handler; * wip(go): add email builder; * wip(go): add user invite type migration logic; * wip(go): only log email send failures; * wip(go): add tenant id to flows table; * wip(go): add func to check if connected to clickhouse; * wip(go): migrate clickhouse; * wip(go): add tenant id to mdm and edr state; * wip(go): add delete methods for tables; * wip(go): add tenant teardown method; * wip(go): handle tenant deletion; * wip(go): clean up flow logs on tenant deletion; * wip(go): add update org membership role id method; * wip(go): add transfer org ownership api; * wip(go): move audit logs retention period to org settings; * wip(go):get retention period from org settings; * wip(go): remove old audit logs usage; * wip(go): migrate audit logs retention period; * wip(go): unmarshal decodes nums as float64; * wip(go): run flow logs cleanup for all tenants in one go; * wip(go): add audit logs retention period and smtp settings to tenant settings table for non-msp tenants; * wip(go): resolve retention period and smtp settings correctly; * wip(go): handle retention period and smtp settings updates and fetches correctly; * wip(go): overlay retention period and smtp settings on server settings;; * wip(go): upsert overlayed settings; * wip(go): add azure tenant id to org settings; * wip(go): tenant scope list roles; * wip(go): add noop creds; * wip(go): use first instead of find; * wip(go): use correct roles when transfering ownership; * wip(go): delete access tokens only if tenant scoped; * wip(go): make delete user work for both org and tenant scope; * wip(go): delete extclients only if tenant scoped; * wip(go): check if caller is allowed to delete user; * wip(go): infer scope for update user; * wip(go): prevent org-owner elevation; * wip(go): permissions check for update; * wip(go): delete user access tokens only if tenant scope; * wip(go): delete extclients only if tenant scope; * wip(go): move upsert membership in upsert user; * wip(go): set api host when constructing server config; * wip(go): fix static errors; * wip(go): fix test cases; * wip(go): use correct get ns order; * wip(go): use correct get pending host order; * wip(go): use correct get access token order; * wip(go): use correct get event order; * wip(go): return error response on emqx user creation error; * wip(go): store correct value in cache; * wip(go): return better error response; * wip(go): return better error response; * wip(go): use cache when listing egress acls; * wip(go): wire ctx in UserHasNetworkGroupAccess; * wip(go): remove double scope wrapping; * wip(go): add security check for list and get org; * wip(go): ratelimit discover api; * wip(go): expect sole org id in get and create org owner; * wip(go): wrap create org owner in tx; * wip(go): wire ctx correctly; * wip(go): wire ctx for posture check functions; * wip(go): remove resolved todo; * wip(go): wire ctx for posture check function; * wip(go): remove scope from netdesk login api; * wip(go): use orgid correctly; * wip(go): scope user update checks correctly; * wip(go): wire ctx for fetch oauth secret; * wip(go): add tenant_id and org_id query string param to user invite url; * wip(go): get sole org; * wip(go): set query string correctly; * wip(go): wire ctx in update user groups; * wip(go): allow delete oauth non-idp users; * wip(go): delete access tokens post update but check before update;
This commit is contained in:
@@ -264,6 +264,7 @@ func joinHostToNetworks(ctx context.Context, key models.EnrollmentKey, host *sch
|
||||
}
|
||||
|
||||
violations, _ := logic.CheckPostureViolationsForHost(
|
||||
ctx,
|
||||
host,
|
||||
keyTags,
|
||||
schema.NetworkID(network.Name),
|
||||
|
||||
@@ -118,7 +118,7 @@ func getDeviceNetworks(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
// Ownership mismatch must not block the network list; host-scoped state is omitted without a verified host.
|
||||
}
|
||||
networks, err := logic.GetDeviceNetworks(db.WithContext(r.Context()), user, host)
|
||||
networks, err := logic.GetDeviceNetworks(r.Context(), user, host)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
|
||||
@@ -593,7 +593,7 @@ func handleHostRegister(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var joinNetworks []string
|
||||
for _, netI := range enrollmentKey.Networks {
|
||||
violations, _ := logic.CheckPostureViolationsForHost(&newHost, keyTags, schema.NetworkID(netI), true)
|
||||
violations, _ := logic.CheckPostureViolationsForHost(r.Context(), &newHost, keyTags, schema.NetworkID(netI), true)
|
||||
if len(violations) == 0 {
|
||||
joinNetworks = append(joinNetworks, netI)
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ func createExtClient(w http.ResponseWriter, r *http.Request) {
|
||||
if extclient.DeviceID != "" {
|
||||
// check for violations connecting from desktop app
|
||||
staticNode := models.ConvertToStaticNode(extclient)
|
||||
violations, _ := logic.CheckPostureViolations(logic.GetPostureCheckDeviceInfoByNode(&staticNode), schema.NetworkID(extclient.Network))
|
||||
violations, _ := logic.CheckPostureViolations(r.Context(), logic.GetPostureCheckDeviceInfoByNode(&staticNode), schema.NetworkID(extclient.Network))
|
||||
if len(violations) > 0 {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("posture check violations"), logic.Forbidden))
|
||||
return
|
||||
@@ -927,7 +927,7 @@ func updateExtClient(w http.ResponseWriter, r *http.Request) {
|
||||
if newclient.DeviceID != "" && newclient.Enabled {
|
||||
// check for violations connecting from desktop app
|
||||
staticNode := models.ConvertToStaticNode(newclient)
|
||||
violations, _ := logic.CheckPostureViolations(logic.GetPostureCheckDeviceInfoByNode(&staticNode), schema.NetworkID(newclient.Network))
|
||||
violations, _ := logic.CheckPostureViolations(r.Context(), logic.GetPostureCheckDeviceInfoByNode(&staticNode), schema.NetworkID(newclient.Network))
|
||||
if len(violations) > 0 {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("posture check violations"), logic.Forbidden))
|
||||
return
|
||||
|
||||
@@ -647,7 +647,7 @@ func hostUpdateFallback(w http.ResponseWriter, r *http.Request) {
|
||||
)
|
||||
for _, _node := range _nodes {
|
||||
node := logic.ConvertSchemaNodeToModelsNode(&_node)
|
||||
node.PostureChecksViolations, node.PostureCheckViolationSeverityLevel = logic.CheckPostureViolations(logic.GetPostureCheckDeviceInfoByNode(node), schema.NetworkID(node.Network))
|
||||
node.PostureChecksViolations, node.PostureCheckViolationSeverityLevel = logic.CheckPostureViolations(ctx, logic.GetPostureCheckDeviceInfoByNode(node), schema.NetworkID(node.Network))
|
||||
_node.PostureCheckSeverity = node.PostureCheckViolationSeverityLevel
|
||||
_node.PostureCheckLastEvaluationCycleID = uuid.NewString()
|
||||
_node.PostureCheckLastEvaluatedAt = time.Now().UTC()
|
||||
@@ -977,7 +977,7 @@ func addHostToNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
violations, _ := logic.CheckPostureViolationsForHost(host, nil, schema.NetworkID(networkID), true)
|
||||
violations, _ := logic.CheckPostureViolationsForHost(r.Context(), host, nil, schema.NetworkID(networkID), true)
|
||||
if len(violations) > 0 {
|
||||
logic.ReturnErrorResponseWithJson(w, r, violations, logic.FormatError(errors.New("posture check violations"), logic.BadReq))
|
||||
return
|
||||
@@ -1871,7 +1871,7 @@ func approvePendingHost(w http.ResponseWriter, r *http.Request) {
|
||||
keyTags[models.TagID(tagI)] = struct{}{}
|
||||
}
|
||||
|
||||
violations, _ := logic.CheckPostureViolationsForHost(host, keyTags, schema.NetworkID(network.Name), true)
|
||||
violations, _ := logic.CheckPostureViolationsForHost(r.Context(), host, keyTags, schema.NetworkID(network.Name), true)
|
||||
if len(violations) > 0 {
|
||||
err = fmt.Errorf("failed to approve pending host (%s): posture check violations", id)
|
||||
logger.Log(0, err.Error())
|
||||
@@ -1939,7 +1939,7 @@ func addDefaultHostToNetworks(ctx context.Context, host *schema.Host) {
|
||||
continue
|
||||
}
|
||||
|
||||
violations, _ := logic.CheckPostureViolationsForHost(host, make(map[models.TagID]struct{}), schema.NetworkID(network.Name), true)
|
||||
violations, _ := logic.CheckPostureViolationsForHost(ctx, host, make(map[models.TagID]struct{}), schema.NetworkID(network.Name), true)
|
||||
if len(violations) > 0 {
|
||||
logger.Log(2, "skipping network", network.Name, "for default host", host.Name, ": posture check violations")
|
||||
continue
|
||||
|
||||
+13
-3
@@ -45,10 +45,20 @@ func resolveSoleOrg(ctx context.Context, orgID string) (*schema.Organization, er
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if orgID != "sole" && orgID != o.ID && orgID != o.Slug {
|
||||
return nil, errOrgNotFound
|
||||
|
||||
if orgID == "sole" {
|
||||
return o, nil
|
||||
}
|
||||
return o, nil
|
||||
|
||||
if orgID == o.ID {
|
||||
return o, nil
|
||||
}
|
||||
|
||||
if orgID == o.Slug {
|
||||
return o, nil
|
||||
}
|
||||
|
||||
return nil, errOrgNotFound
|
||||
}
|
||||
|
||||
// @Summary Get organization SSO settings
|
||||
|
||||
+44
-26
@@ -324,7 +324,7 @@ func authenticateUser(response http.ResponseWriter, request *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if logic.IsOauthUser(user) == nil {
|
||||
if logic.IsOauthUser(request.Context(), user) == nil {
|
||||
logic.ReturnErrorResponse(response, request, logic.FormatError(errors.New("user is registered via SSO"), "badrequest"))
|
||||
return
|
||||
}
|
||||
@@ -1682,48 +1682,61 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if !ismaster && selfUpdate {
|
||||
if user.PlatformRoleID != userchange.PlatformRoleID {
|
||||
slog.Error("user cannot change his own role", "caller", caller.Username, "attempted to update user role", username)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"))
|
||||
return
|
||||
|
||||
}
|
||||
if scope.Level(r.Context()) == scope.TenantScope {
|
||||
if !ismaster && selfUpdate {
|
||||
if user.PlatformRoleID != userchange.PlatformRoleID {
|
||||
slog.Error("user cannot change his own role", "caller", caller.Username, "attempted to update user role", username)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("user not allowed to self assign role"), "forbidden"))
|
||||
return
|
||||
|
||||
if logic.IsMFAEnforced(r.Context()) && user.IsMFAEnabled && !userchange.IsMFAEnabled {
|
||||
err = errors.New("mfa is enforced, user cannot unset their own mfa")
|
||||
slog.Error("failed to update user", "caller", caller.Username, "attempted to update user", username, "error", err)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if servercfg.IsPro && caller.PlatformRoleID != schema.SuperAdminRole {
|
||||
// users cannot update their own groups; superadmin is exempt
|
||||
if len(user.UserGroups.Data()) != len(userchange.UserGroups.Data()) || !reflect.DeepEqual(user.UserGroups.Data(), userchange.UserGroups.Data()) {
|
||||
err = errors.New("user cannot update self update their groups")
|
||||
if logic.IsMFAEnforced(r.Context()) && user.IsMFAEnabled && !userchange.IsMFAEnabled {
|
||||
err = errors.New("mfa is enforced, user cannot unset their own mfa")
|
||||
slog.Error("failed to update user", "caller", caller.Username, "attempted to update user", username, "error", err)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
|
||||
return
|
||||
}
|
||||
|
||||
if servercfg.IsPro && caller.PlatformRoleID != schema.SuperAdminRole {
|
||||
// users cannot update their own groups; superadmin is exempt
|
||||
if len(user.UserGroups.Data()) != len(userchange.UserGroups.Data()) || !reflect.DeepEqual(user.UserGroups.Data(), userchange.UserGroups.Data()) {
|
||||
err = errors.New("user cannot self update their groups")
|
||||
slog.Error("failed to update user", "caller", caller.Username, "attempted to update user", username, "error", err)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ismaster {
|
||||
if user.PlatformRoleID != schema.SuperAdminRole && userchange.PlatformRoleID == schema.SuperAdminRole {
|
||||
slog.Error("operation not allowed", "caller", logic.MasterUser, "attempted to update user role to superadmin", username)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("attempted to update user role to superadmin"), "forbidden"))
|
||||
|
||||
if ismaster {
|
||||
if user.PlatformRoleID != schema.SuperAdminRole && userchange.PlatformRoleID == schema.SuperAdminRole {
|
||||
slog.Error("operation not allowed", "caller", logic.MasterUser, "attempted to update user role to superadmin", username)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("attempted to update user role to superadmin"), "forbidden"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if user.AuthType == schema.Inherited && userchange.Password != "" {
|
||||
err = fmt.Errorf("cannot update password for user with inherited auth")
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, logic.BadReq))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if logic.IsOauthUser(user) == nil && userchange.Password != "" {
|
||||
err := fmt.Errorf("cannot update user's password for an oauth user %s", username)
|
||||
if logic.IsOauthUser(r.Context(), user) == nil && userchange.Password != "" {
|
||||
err := fmt.Errorf("cannot update password for an oauth user %s", username)
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "forbidden"))
|
||||
return
|
||||
}
|
||||
|
||||
var deleteAccessTokens bool
|
||||
if scope.Level(r.Context()) == scope.TenantScope &&
|
||||
(userchange.PlatformRoleID != user.PlatformRoleID || !logic.CompareMaps(user.UserGroups.Data(), userchange.UserGroups.Data())) {
|
||||
(&schema.UserAccessToken{UserName: user.Username}).DeleteAllUserTokens(r.Context())
|
||||
deleteAccessTokens = true
|
||||
}
|
||||
|
||||
oldUser := *user
|
||||
if ismaster {
|
||||
caller = &schema.User{
|
||||
@@ -1770,6 +1783,11 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
|
||||
if deleteAccessTokens {
|
||||
_ = (&schema.UserAccessToken{UserName: user.Username}).DeleteAllUserTokens(r.Context())
|
||||
}
|
||||
|
||||
logic.LogEvent(r.Context(), &e)
|
||||
ctx := scope.WithContext(db.WithContext(context.Background()), scope.Level(r.Context()), scope.ID(r.Context()))
|
||||
go mq.PublishPeerUpdate(ctx, false)
|
||||
@@ -1916,7 +1934,7 @@ func deleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
break
|
||||
}
|
||||
|
||||
if user.AuthType == schema.OAuth || user.ExternalIdentityProviderID != "" {
|
||||
if logic.IsIDPUser(r.Context(), user) {
|
||||
err = fmt.Errorf("cannot delete idp user %s", username)
|
||||
logger.Log(0, username, "failed to delete user: ", err.Error())
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
|
||||
+14
-4
@@ -60,8 +60,8 @@ func ResolveInheritedAuth(ctx context.Context, user *schema.User) error {
|
||||
}
|
||||
|
||||
// IsOauthUser - returns
|
||||
func IsOauthUser(user *schema.User) error {
|
||||
var currentValue, err = FetchOAuthSecret()
|
||||
func IsOauthUser(ctx context.Context, user *schema.User) error {
|
||||
var currentValue, err = FetchOAuthSecret(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -346,6 +346,16 @@ func ValidateUser(user *schema.User) error {
|
||||
return validationErr
|
||||
}
|
||||
|
||||
func IsIDPUser(ctx context.Context, user *schema.User) bool {
|
||||
if scope.Level(ctx) == scope.TenantScope {
|
||||
if user.AuthType == schema.OAuth && IsSyncEnabled(ctx) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// DeleteUser - deletes a given user
|
||||
func DeleteUser(ctx context.Context, user *schema.User) error {
|
||||
err := user.DeleteMembership(ctx)
|
||||
@@ -383,11 +393,11 @@ func SetOAuthSecret(secret string) error {
|
||||
}
|
||||
|
||||
// FetchOAuthSecret fetches secrets for oauth
|
||||
func FetchOAuthSecret() (string, error) {
|
||||
func FetchOAuthSecret(ctx context.Context) (string, error) {
|
||||
oauthSecret := &schema.Internal{
|
||||
Key: schema.InternalKey_OAuthSecret,
|
||||
}
|
||||
err := oauthSecret.Get(db.WithContext(context.TODO()))
|
||||
err := oauthSecret.Get(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
+2
-2
@@ -232,7 +232,7 @@ func applyDeviceNetworkHostState(ctx context.Context, host *schema.Host, network
|
||||
return
|
||||
}
|
||||
|
||||
violations, _ := CheckPostureViolationsForHost(host, nil, schema.NetworkID(network.Name), true)
|
||||
violations, _ := CheckPostureViolationsForHost(ctx, host, nil, schema.NetworkID(network.Name), true)
|
||||
if len(violations) > 0 {
|
||||
dn.Status = models.DeviceNetworkStatusBlocked
|
||||
return
|
||||
@@ -289,7 +289,7 @@ func JoinDeviceNetwork(ctx context.Context, user *schema.User, host *schema.Host
|
||||
return models.DeviceJoinResult{Status: models.DeviceJoinStatusJoined}, nil
|
||||
}
|
||||
|
||||
violations, _ := CheckPostureViolationsForHost(host, nil, schema.NetworkID(networkID), true)
|
||||
violations, _ := CheckPostureViolationsForHost(ctx, host, nil, schema.NetworkID(networkID), true)
|
||||
if len(violations) > 0 {
|
||||
return empty, errors.New("access blocked: this device doesn't meet security requirements")
|
||||
}
|
||||
|
||||
+3
-4
@@ -40,17 +40,16 @@ var HostLimitExceeded = func(ctx context.Context) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// todo(nm-341): add ctx to func
|
||||
var CheckPostureViolations = func(d models.PostureCheckDeviceInfo, network schema.NetworkID) (v []models.Violation, level schema.Severity) {
|
||||
var CheckPostureViolations = func(ctx context.Context, d models.PostureCheckDeviceInfo, network schema.NetworkID) (v []models.Violation, level schema.Severity) {
|
||||
return []models.Violation{}, schema.SeverityUnknown
|
||||
}
|
||||
|
||||
// todo(nm-341): add ctx to func
|
||||
var CheckPostureViolationsForHost = func(host *schema.Host, tags map[models.TagID]struct{}, network schema.NetworkID, skipAutoUpdate bool) ([]models.Violation, schema.Severity) {
|
||||
var CheckPostureViolationsForHost = func(ctx context.Context, host *schema.Host, tags map[models.TagID]struct{}, network schema.NetworkID, skipAutoUpdate bool) ([]models.Violation, schema.Severity) {
|
||||
if host == nil {
|
||||
return []models.Violation{}, schema.SeverityUnknown
|
||||
}
|
||||
return CheckPostureViolations(models.PostureCheckDeviceInfo{
|
||||
return CheckPostureViolations(ctx, models.PostureCheckDeviceInfo{
|
||||
ClientLocation: host.CountryCode,
|
||||
ClientVersion: host.Version,
|
||||
OS: host.OS,
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
)
|
||||
|
||||
func GetCurrentServerUsage(ctx context.Context) (limits models.Usage) {
|
||||
// todo(nm-341): get usage of all tenants or specific tenant?
|
||||
limits.SetDefaults()
|
||||
hosts, hErr := GetAllHostsWithStatus(ctx, schema.OnlineSt)
|
||||
if hErr == nil {
|
||||
|
||||
+1
-1
@@ -426,7 +426,7 @@ func syncUsers() {
|
||||
for _, user := range users {
|
||||
user := user
|
||||
user.AuthType = schema.BasicAuth
|
||||
if logic.IsOauthUser(&user) == nil {
|
||||
if logic.IsOauthUser(db.WithContext(context.TODO()), &user) == nil {
|
||||
user.AuthType = schema.OAuth
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
type UserExtensions interface {
|
||||
ConfigureAuthType(user *schema.User) error
|
||||
ConfigureAuthType(ctx context.Context, user *schema.User) error
|
||||
ConfigureGlobalAdminGroup(membership *schema.TenantMembership)
|
||||
ConfigureGroups(ctx context.Context, membership *schema.TenantMembership, groups datatypes.JSONType[map[schema.UserGroupID]struct{}])
|
||||
SendEmailValidation(ctx context.Context, user *schema.User) error
|
||||
@@ -16,7 +16,7 @@ type UserExtensions interface {
|
||||
|
||||
type CEUserExtensions struct{}
|
||||
|
||||
func (c *CEUserExtensions) ConfigureAuthType(user *schema.User) error {
|
||||
func (c *CEUserExtensions) ConfigureAuthType(_ context.Context, user *schema.User) error {
|
||||
user.AuthType = schema.BasicAuth
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -153,10 +153,10 @@ func (n *NodeOrchestrator) CreateNode(ctx context.Context, host *schema.Host, ne
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
go func(ctx context.Context) {
|
||||
modelsNode := logic.ConvertSchemaNodeToModelsNode(node)
|
||||
|
||||
modelsNode.PostureChecksViolations, modelsNode.PostureCheckViolationSeverityLevel = logic.CheckPostureViolations(logic.GetPostureCheckDeviceInfoByNode(modelsNode), schema.NetworkID(node.Network.Name))
|
||||
modelsNode.PostureChecksViolations, modelsNode.PostureCheckViolationSeverityLevel = logic.CheckPostureViolations(ctx, logic.GetPostureCheckDeviceInfoByNode(modelsNode), schema.NetworkID(node.Network.Name))
|
||||
node.PostureCheckSeverity = modelsNode.PostureCheckViolationSeverityLevel
|
||||
node.PostureCheckLastEvaluationCycleID = uuid.NewString()
|
||||
node.PostureCheckLastEvaluatedAt = time.Now().UTC()
|
||||
@@ -175,7 +175,7 @@ func (n *NodeOrchestrator) CreateNode(ctx context.Context, host *schema.Host, ne
|
||||
EvaluatedAt: node.PostureCheckLastEvaluatedAt,
|
||||
})
|
||||
}
|
||||
err = node.UpsertViolations(db.WithContext(context.TODO()), _violations)
|
||||
err = node.UpsertViolations(ctx, _violations)
|
||||
if err != nil {
|
||||
logger.Log(1, fmt.Sprintf("failed to upsert node (%s) posture check violations: %v", modelsNode.ID, err))
|
||||
}
|
||||
@@ -204,7 +204,7 @@ func (n *NodeOrchestrator) CreateNode(ctx context.Context, host *schema.Host, ne
|
||||
time.Sleep(time.Second * 30)
|
||||
logic.TriggerCollectMetrics(host.ID.String(), node.ID, "join")
|
||||
}
|
||||
}()
|
||||
}(scope.WithContext(db.WithContext(context.Background()), scope.Level(ctx), scope.ID(ctx)))
|
||||
|
||||
return node, nil
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ func (u *UserOrchestrator) CreateUser(ctx context.Context, user *schema.User, op
|
||||
|
||||
user.Password = string(passwordHash)
|
||||
|
||||
err = u.userExt.ConfigureAuthType(user)
|
||||
err = u.userExt.ConfigureAuthType(ctx, user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ func (p *AzureADProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
if inviteExists {
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(in)
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(r.Context(), in)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
@@ -179,7 +179,7 @@ func (p *AzureADProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
newPass, fetchErr := logic.FetchOAuthSecret()
|
||||
newPass, fetchErr := logic.FetchOAuthSecret(r.Context())
|
||||
if fetchErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -119,7 +119,7 @@ func (p *GitHubProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
if inviteExists {
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(in)
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(r.Context(), in)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
@@ -189,7 +189,7 @@ func (p *GitHubProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
newPass, fetchErr := logic.FetchOAuthSecret()
|
||||
newPass, fetchErr := logic.FetchOAuthSecret(r.Context())
|
||||
if fetchErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -102,7 +102,7 @@ func (p *GoogleProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
if inviteExists {
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(in)
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(r.Context(), in)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
@@ -180,7 +180,7 @@ func (p *GoogleProvider) HandleCallback(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
newPass, fetchErr := logic.FetchOAuthSecret()
|
||||
newPass, fetchErr := logic.FetchOAuthSecret(r.Context())
|
||||
if fetchErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func HandleHeadlessSSOCallback(w http.ResponseWriter, r *http.Request) {
|
||||
handleUserAccountDisabled(w)
|
||||
return
|
||||
}
|
||||
newPass, fetchErr := logic.FetchOAuthSecret()
|
||||
newPass, fetchErr := logic.FetchOAuthSecret(r.Context())
|
||||
if fetchErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -113,7 +113,7 @@ func (p *OIDCProvider) HandleCallback(w http.ResponseWriter, r *http.Request) {
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
if inviteExists {
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(in)
|
||||
user, err := proLogic.PrepareOauthUserFromInvite(r.Context(), in)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
@@ -189,7 +189,7 @@ func (p *OIDCProvider) HandleCallback(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
newPass, fetchErr := logic.FetchOAuthSecret()
|
||||
newPass, fetchErr := logic.FetchOAuthSecret(r.Context())
|
||||
if fetchErr != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/gravitl/netmaker/logger"
|
||||
"github.com/gravitl/netmaker/logic/pro/netcache"
|
||||
"github.com/gravitl/netmaker/schema"
|
||||
"github.com/gravitl/netmaker/scope"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -138,19 +139,25 @@ func returnErrTemplate(uname, message, state string, ncache *netcache.CValue) []
|
||||
// Puts machine key in cache so the callback can retrieve it using the oidc state param
|
||||
// Listens in /oidc/register/:regKey.
|
||||
func RegisterHostSSO(w http.ResponseWriter, r *http.Request) {
|
||||
p, ok := Registry().FromContext(r.Context())
|
||||
if !ok {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("invalid login attempt"))
|
||||
return
|
||||
}
|
||||
vars := mux.Vars(r)
|
||||
|
||||
// machineKeyStr this is not key but state
|
||||
machineKeyStr := vars["regKey"]
|
||||
machineKeyStr := mux.Vars(r)["regKey"]
|
||||
if machineKeyStr == "" {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte("invalid login attempt"))
|
||||
_, _ = w.Write([]byte("invalid login attempt: no key"))
|
||||
return
|
||||
}
|
||||
|
||||
state, err := netcache.Get(machineKeyStr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = w.Write([]byte("invalid login attempt: no state"))
|
||||
return
|
||||
}
|
||||
|
||||
ctx := scope.WithContext(r.Context(), state.Scope, state.ScopeID)
|
||||
p, ok := Registry().FromContext(ctx)
|
||||
if !ok {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
_, _ = w.Write([]byte("invalid login attempt: no auth provider"))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -184,7 +184,7 @@ func syncUsers(ctx context.Context, idpUsers []idp.User, filters []string, remov
|
||||
return err
|
||||
}
|
||||
|
||||
password, err := logic.FetchOAuthSecret()
|
||||
password, err := logic.FetchOAuthSecret(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -364,7 +364,7 @@ func syncGroups(ctx context.Context, idpGroups []idp.Group, filters []string) er
|
||||
}
|
||||
} else {
|
||||
dbGroup.Name = group.Name
|
||||
err = proLogic.UpdateUserGroup(dbGroup)
|
||||
err = proLogic.UpdateUserGroup(ctx, dbGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -327,6 +327,12 @@ func inviteUsers(w http.ResponseWriter, r *http.Request) {
|
||||
slog.Error("failed to parse to invite url", "error", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if scope.Level(r.Context()) == scope.TenantScope {
|
||||
u, err = url.Parse(fmt.Sprintf("%s&tenant_id=%s", u.String(), url.QueryEscape(scope.ID(r.Context()))))
|
||||
} else if scope.Level(r.Context()) == scope.OrgScope {
|
||||
u, err = url.Parse(fmt.Sprintf("%s&org_id=%s", u.String(), url.QueryEscape(scope.ID(r.Context()))))
|
||||
}
|
||||
}
|
||||
invite.InviteURL = u.String()
|
||||
err = invite.Create(r.Context())
|
||||
@@ -605,7 +611,7 @@ func createUserGroup(w http.ResponseWriter, r *http.Request) {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
}
|
||||
err = proLogic.ValidateCreateGroupReq(userGroupReq.Group)
|
||||
err = proLogic.ValidateCreateGroupReq(r.Context(), userGroupReq.Group)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
@@ -683,7 +689,7 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("cannot update default user group"), "badrequest"))
|
||||
return
|
||||
}
|
||||
err = proLogic.ValidateUpdateGroupReq(userGroup)
|
||||
err = proLogic.ValidateUpdateGroupReq(r.Context(), userGroup)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
|
||||
return
|
||||
@@ -691,7 +697,7 @@ func updateUserGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
userGroup.ExternalIdentityProviderID = currUserG.ExternalIdentityProviderID
|
||||
|
||||
err = proLogic.UpdateUserGroup(userGroup)
|
||||
err = proLogic.UpdateUserGroup(r.Context(), userGroup)
|
||||
if err != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
|
||||
return
|
||||
@@ -2124,7 +2130,7 @@ func approvePendingUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var newPass, fetchErr = logic.FetchOAuthSecret()
|
||||
var newPass, fetchErr = logic.FetchOAuthSecret(r.Context())
|
||||
if fetchErr != nil {
|
||||
logic.ReturnErrorResponse(w, r, logic.FormatError(fetchErr, "internal"))
|
||||
return
|
||||
|
||||
+2
-3
@@ -138,10 +138,9 @@ func InitPro() {
|
||||
}
|
||||
}
|
||||
|
||||
defaultOrg := &schema.Organization{}
|
||||
err := defaultOrg.Get(db.WithContext(context.TODO()))
|
||||
org, err := logic.SoleOrganization(db.WithContext(context.TODO()))
|
||||
if err == nil {
|
||||
email.Init(scope.WithContext(db.WithContext(ctx), scope.OrgScope, defaultOrg.ID))
|
||||
email.Init(scope.WithContext(db.WithContext(ctx), scope.OrgScope, org.ID))
|
||||
}
|
||||
go proLogic.EventWatcher()
|
||||
})
|
||||
|
||||
@@ -113,7 +113,7 @@ func RunPostureChecks() error {
|
||||
if noChecks {
|
||||
postureCheckVolationSeverityLevel = schema.SeverityUnknown
|
||||
} else {
|
||||
postureChecksViolations, postureCheckVolationSeverityLevel = GetPostureCheckViolations(pcLi, deviceInfo)
|
||||
postureChecksViolations, postureCheckVolationSeverityLevel = GetPostureCheckViolations(ctx, pcLi, deviceInfo)
|
||||
}
|
||||
if nodeI.IsUserNode {
|
||||
extclient, err := logic.GetExtClient(ctx, nodeI.StaticNode.ClientID, nodeI.StaticNode.Network)
|
||||
@@ -168,16 +168,15 @@ func RunPostureChecks() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func CheckPostureViolations(d models.PostureCheckDeviceInfo, network schema.NetworkID) ([]models.Violation, schema.Severity) {
|
||||
// todo(nm-341): pass tenant scoped context.
|
||||
if !logic.GetFeatureFlags(context.Background()).EnablePostureChecks {
|
||||
func CheckPostureViolations(ctx context.Context, d models.PostureCheckDeviceInfo, network schema.NetworkID) ([]models.Violation, schema.Severity) {
|
||||
if !logic.GetFeatureFlags(ctx).EnablePostureChecks {
|
||||
return []models.Violation{}, schema.SeverityUnknown
|
||||
}
|
||||
pcLi, err := (&schema.PostureCheck{NetworkID: network}).ListByNetwork(db.WithContext(context.TODO()))
|
||||
pcLi, err := (&schema.PostureCheck{NetworkID: network}).ListByNetwork(ctx)
|
||||
if err != nil || len(pcLi) == 0 {
|
||||
return []models.Violation{}, schema.SeverityUnknown
|
||||
}
|
||||
violations, level := GetPostureCheckViolations(pcLi, d)
|
||||
violations, level := GetPostureCheckViolations(ctx, pcLi, d)
|
||||
return violations, level
|
||||
}
|
||||
|
||||
@@ -185,12 +184,13 @@ func CheckPostureViolations(d models.PostureCheckDeviceInfo, network schema.Netw
|
||||
// evaluates network posture checks. Use this for registration and join flows
|
||||
// instead of building PostureCheckDeviceInfo without integration state.
|
||||
func CheckPostureViolationsForHost(
|
||||
ctx context.Context,
|
||||
host *schema.Host,
|
||||
tags map[models.TagID]struct{},
|
||||
network schema.NetworkID,
|
||||
skipAutoUpdate bool,
|
||||
) ([]models.Violation, schema.Severity) {
|
||||
return CheckPostureViolations(GetPostureCheckDeviceInfoForHost(host, tags, skipAutoUpdate, true), network)
|
||||
return CheckPostureViolations(ctx, GetPostureCheckDeviceInfoForHost(host, tags, skipAutoUpdate, true), network)
|
||||
}
|
||||
|
||||
func GetPostureCheckDeviceInfoForHost(
|
||||
@@ -241,9 +241,8 @@ func attachIntegrationStates(ctx context.Context, hostID string, d *models.Postu
|
||||
}
|
||||
}
|
||||
}
|
||||
func GetPostureCheckViolations(checks []schema.PostureCheck, d models.PostureCheckDeviceInfo) ([]models.Violation, schema.Severity) {
|
||||
// todo(nm-341): pass tenant-scoped context.
|
||||
if !logic.GetFeatureFlags(context.Background()).EnablePostureChecks {
|
||||
func GetPostureCheckViolations(ctx context.Context, checks []schema.PostureCheck, d models.PostureCheckDeviceInfo) ([]models.Violation, schema.Severity) {
|
||||
if !logic.GetFeatureFlags(ctx).EnablePostureChecks {
|
||||
return []models.Violation{}, schema.SeverityUnknown
|
||||
}
|
||||
var violations []models.Violation
|
||||
|
||||
+10
-10
@@ -366,7 +366,7 @@ func DeleteNetworkRoles(ctx context.Context, netID string) {
|
||||
for _, userGI := range userGs {
|
||||
if _, ok := userGI.NetworkRoles.Data()[schema.NetworkID(netID)]; ok {
|
||||
delete(userGI.NetworkRoles.Data(), schema.NetworkID(netID))
|
||||
UpdateUserGroup(userGI)
|
||||
_ = UpdateUserGroup(ctx, userGI)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,7 +530,7 @@ func DeleteRole(ctx context.Context, rid schema.UserRoleID, force bool) error {
|
||||
if _, ok := networkRoles[rid]; ok {
|
||||
delete(networkRoles, rid)
|
||||
ug.NetworkRoles.Data()[netID] = networkRoles
|
||||
UpdateUserGroup(ug)
|
||||
_ = UpdateUserGroup(ctx, ug)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -548,13 +548,13 @@ func DeleteRole(ctx context.Context, rid schema.UserRoleID, force bool) error {
|
||||
}).Delete(ctx)
|
||||
}
|
||||
|
||||
func ValidateCreateGroupReq(g schema.UserGroup) error {
|
||||
func ValidateCreateGroupReq(ctx context.Context, g schema.UserGroup) error {
|
||||
|
||||
// check if network roles are valid
|
||||
for _, roleMap := range g.NetworkRoles.Data() {
|
||||
for roleID := range roleMap {
|
||||
role := &schema.UserRole{ID: roleID}
|
||||
err := role.Get(db.WithContext(context.TODO()))
|
||||
err := role.Get(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid network role %s", roleID)
|
||||
}
|
||||
@@ -565,7 +565,7 @@ func ValidateCreateGroupReq(g schema.UserGroup) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func ValidateUpdateGroupReq(new schema.UserGroup) error {
|
||||
func ValidateUpdateGroupReq(ctx context.Context, new schema.UserGroup) error {
|
||||
var newHasAllNetworkRole, newHasSpecNetworkRole bool
|
||||
for networkID := range new.NetworkRoles.Data() {
|
||||
if networkID == schema.AllNetworks {
|
||||
@@ -577,7 +577,7 @@ func ValidateUpdateGroupReq(new schema.UserGroup) error {
|
||||
userRolesMap := new.NetworkRoles.Data()[networkID]
|
||||
for roleID := range userRolesMap {
|
||||
netRole := &schema.UserRole{ID: roleID}
|
||||
err := netRole.Get(db.WithContext(context.TODO()))
|
||||
err := netRole.Get(ctx)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("invalid network role")
|
||||
return err
|
||||
@@ -679,12 +679,12 @@ func GetDefaultGroupAclName(groupName string) string {
|
||||
}
|
||||
|
||||
// UpdateUserGroup - updates new user group
|
||||
func UpdateUserGroup(g schema.UserGroup) error {
|
||||
func UpdateUserGroup(ctx context.Context, g schema.UserGroup) error {
|
||||
// check if the group exists
|
||||
if g.ID == "" {
|
||||
return errors.New("group id cannot be empty")
|
||||
}
|
||||
return g.Update(db.WithContext(context.TODO()))
|
||||
return g.Update(ctx)
|
||||
}
|
||||
|
||||
func DeleteAndCleanUpGroup(group *schema.UserGroup) error {
|
||||
@@ -855,8 +855,8 @@ func IsNetworkRolesValid(networkRoles map[schema.NetworkID]map[schema.UserRoleID
|
||||
}
|
||||
|
||||
// PrepareOauthUserFromInvite - init oauth user before create
|
||||
func PrepareOauthUserFromInvite(in *schema.UserInvite) (schema.User, error) {
|
||||
var newPass, fetchErr = logic.FetchOAuthSecret()
|
||||
func PrepareOauthUserFromInvite(ctx context.Context, in *schema.UserInvite) (schema.User, error) {
|
||||
var newPass, fetchErr = logic.FetchOAuthSecret(ctx)
|
||||
if fetchErr != nil {
|
||||
return schema.User{}, fetchErr
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ import (
|
||||
|
||||
type ProUserExtensions struct{}
|
||||
|
||||
func (p *ProUserExtensions) ConfigureAuthType(user *schema.User) error {
|
||||
func (p *ProUserExtensions) ConfigureAuthType(ctx context.Context, user *schema.User) error {
|
||||
user.AuthType = schema.BasicAuth
|
||||
oauthSecret, err := logic.FetchOAuthSecret()
|
||||
oauthSecret, err := logic.FetchOAuthSecret(ctx)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user