fix: validate policy violation when assign users for oidc IDP

This commit is contained in:
Qiu Jian
2024-01-27 15:14:00 +08:00
parent 9442b445d0
commit 78123d0335
15 changed files with 43 additions and 36 deletions
+3
View File
@@ -27,6 +27,9 @@ import (
)
func objectConfirmPolicyTags(ctx context.Context, model IModel, result rbacutils.SPolicyResult) error {
if result.Result.IsDeny() {
return errors.Wrap(httperrors.ErrForbidden, "no permission")
}
model.GetModelManager().ResourceScope()
if _, ok := model.(IStandaloneModel); !ok {
// a plain resource
+9 -9
View File
@@ -156,7 +156,7 @@ func IsAllowList(scope rbacscope.TRbacScope, userCred mcclient.TokenCredential,
if userCred == nil {
return rbacutils.PolicyDeny
}
return userCred.IsAllow(scope, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionList)
return policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionList)
}
func IsAdminAllowList(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
@@ -175,7 +175,7 @@ func IsAllowCreate(scope rbacscope.TRbacScope, userCred mcclient.TokenCredential
if userCred == nil {
return rbacutils.PolicyDeny
}
return userCred.IsAllow(scope, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionCreate)
return policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionCreate)
}
func IsAdminAllowCreate(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
@@ -194,7 +194,7 @@ func IsAllowClassPerform(scope rbacscope.TRbacScope, userCred mcclient.TokenCred
if userCred == nil {
return rbacutils.PolicyDeny
}
return userCred.IsAllow(scope, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionPerform, action)
return policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionPerform, action)
}
func IsAdminAllowClassPerform(userCred mcclient.TokenCredential, manager IResource, action string) rbacutils.SPolicyResult {
@@ -213,7 +213,7 @@ func IsAllowGet(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclie
if userCred == nil {
return false
}
result := userCred.IsAllow(scope, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionGet)
result := policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionGet)
err := objectConfirmPolicyTags(ctx, obj, result)
if err != nil {
log.Errorf("IsAllowGet %s", err)
@@ -239,7 +239,7 @@ func IsAllowGetSpec(ctx context.Context, scope rbacscope.TRbacScope, userCred mc
if userCred == nil {
return false
}
result := userCred.IsAllow(scope, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionGet, spec)
result := policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionGet, spec)
err := objectConfirmPolicyTags(ctx, obj, result)
if err != nil {
log.Errorf("IsAllowGetSpec %s", err)
@@ -265,7 +265,7 @@ func IsAllowPerform(ctx context.Context, scope rbacscope.TRbacScope, userCred mc
if userCred == nil {
return false
}
result := userCred.IsAllow(scope, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionPerform, action)
result := policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionPerform, action)
err := objectConfirmPolicyTags(ctx, obj, result)
if err != nil {
log.Errorf("IsAllowPerform %s", err)
@@ -291,7 +291,7 @@ func IsAllowUpdate(ctx context.Context, scope rbacscope.TRbacScope, userCred mcc
if userCred == nil {
return false
}
result := userCred.IsAllow(scope, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionUpdate)
result := policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionUpdate)
err := objectConfirmPolicyTags(ctx, obj, result)
if err != nil {
log.Errorf("IsAllowUpdate %s", err)
@@ -317,7 +317,7 @@ func IsAllowUpdateSpec(ctx context.Context, scope rbacscope.TRbacScope, userCred
if userCred == nil {
return false
}
result := userCred.IsAllow(scope, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionUpdate, spec)
result := policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionUpdate, spec)
err := objectConfirmPolicyTags(ctx, obj, result)
if err != nil {
log.Errorf("IsAllowUpdateSpec %s", err)
@@ -343,7 +343,7 @@ func IsAllowDelete(ctx context.Context, scope rbacscope.TRbacScope, userCred mcc
if userCred == nil {
return false
}
result := userCred.IsAllow(scope, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionDelete)
result := policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), obj.KeywordPlural(), policy.PolicyActionDelete)
err := objectConfirmPolicyTags(ctx, obj, result)
if err != nil {
log.Errorf("IsAllowDelete %s", err)
+1
View File
@@ -691,6 +691,7 @@ func SharableModelCustomizeCreate(model ISharableBaseModel, ctx context.Context,
if managedModel, ok := model.(IManagedResourceBase); ok {
isManaged = managedModel.IsManaged()
}
// log.Debugf("isManaged: %v IsAdminAllowPerform %v ownerId.GetProjectDomainId %s userCred.GetProjectDomainId %s", isManaged, IsAdminAllowPerform(ctx, userCred, model, "public"), ownerId.GetProjectDomainId(), userCred.GetProjectDomainId())
if !isManaged && IsAdminAllowPerform(ctx, userCred, model, "public") && ownerId.GetProjectDomainId() == userCred.GetProjectDomainId() {
model.SetShare(rbacscope.ScopeSystem)
data.(*jsonutils.JSONDict).Set("public_scope", jsonutils.NewString(string(rbacscope.ScopeSystem)))
+2 -3
View File
@@ -22,7 +22,6 @@ import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type SPolicyTokenCredential struct {
@@ -34,13 +33,13 @@ func (self *SPolicyTokenCredential) HasSystemAdminPrivilege() bool {
return PolicyManager.IsScopeCapable(self.TokenCredential, rbacscope.ScopeSystem)
}
func (self *SPolicyTokenCredential) IsAllow(targetScope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
/*func (self *SPolicyTokenCredential) IsAllow(targetScope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
allowScope, result := PolicyManager.AllowScope(self.TokenCredential, service, resource, action, extra...)
if result.Result == rbacutils.Allow && !targetScope.HigherThan(allowScope) {
return result
}
return rbacutils.PolicyDeny
}
}*/
func init() {
gotypes.RegisterSerializableTransformer(mcclient.TokenCredentialType, func(input gotypes.ISerializable) gotypes.ISerializable {
+2 -2
View File
@@ -41,7 +41,7 @@ func AddSshKeysHandler(prefix string, app *appsrv.Application) {
func adminSshKeysHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) {
publicOnly := false
userCred := auth.FetchUserCredential(ctx, policy.FilterPolicyCredential)
if !userCred.IsAllow(rbacscope.ScopeDomain, consts.GetServiceType(), "sshkeypairs", policy.PolicyActionGet).Result.IsAllow() {
if !policy.PolicyManager.Allow(rbacscope.ScopeDomain, userCred, consts.GetServiceType(), "sshkeypairs", policy.PolicyActionGet).Result.IsAllow() {
publicOnly = true
}
params, query, _ := appsrv.FetchEnv(ctx, w, r)
@@ -83,7 +83,7 @@ func sendSshKey(ctx context.Context, w http.ResponseWriter, userCred mcclient.To
var privKey, pubKey string
if isAdmin {
if userCred.IsAllow(rbacscope.ScopeSystem, consts.GetServiceType(), "sshkeypairs", policy.PolicyActionGet).Result.IsAllow() {
if policy.PolicyManager.Allow(rbacscope.ScopeSystem, userCred, consts.GetServiceType(), "sshkeypairs", policy.PolicyActionGet).Result.IsAllow() {
privKey, pubKey, _ = GetSshAdminKeypair(ctx)
} else {
httperrors.ForbiddenError(ctx, w, "not allow to access admin key")
+7
View File
@@ -48,5 +48,12 @@ func ValidateConfig(conf api.SIdpAttributeOptions, userCred mcclient.TokenCreden
}
conf.DefaultRoleId = obj.GetId()
}
if len(conf.DefaultProjectId) > 0 && len(conf.DefaultRoleId) > 0 {
// validate policy
err := models.ValidateJoinProjectRoles(userCred, conf.DefaultProjectId, []string{conf.DefaultRoleId})
if err != nil {
return conf, errors.Wrap(err, "ValidateJoinProjectRoles")
}
}
return conf, nil
}
+6 -2
View File
@@ -626,11 +626,15 @@ func validateAssignPolicies(userCred mcclient.TokenCredential, projectId string,
}
func validateJoinProject(userCred mcclient.TokenCredential, project *SProject, roleIds []string) error {
_, assignPolicies, err := RolePolicyManager.GetMatchPolicyGroup2(false, roleIds, project.Id, "", time.Time{}, false)
return ValidateJoinProjectRoles(userCred, project.Id, roleIds)
}
func ValidateJoinProjectRoles(userCred mcclient.TokenCredential, projectId string, roleIds []string) error {
_, assignPolicies, err := RolePolicyManager.GetMatchPolicyGroup2(false, roleIds, projectId, "", time.Time{}, false)
if err != nil {
return errors.Wrap(err, "RolePolicyManager.GetMatchPolicyGroup2")
}
return validateAssignPolicies(userCred, project.Id, assignPolicies)
return validateAssignPolicies(userCred, projectId, assignPolicies)
}
// 将用户或组加入项目
+2 -1
View File
@@ -263,7 +263,8 @@ func verifyCommon(ctx context.Context, w http.ResponseWriter, tokenStr string) (
if adminToken == nil || len(tokenStr) == 0 {
return nil, httperrors.NewForbiddenError("missing auth token")
}
if adminToken.IsAllow(rbacscope.ScopeSystem, api.SERVICE_TYPE, "tokens", "perform", "auth").Result.IsDeny() {
result := policy.PolicyManager.Allow(rbacscope.ScopeSystem, adminToken, api.SERVICE_TYPE, "tokens", "perform", "auth")
if result.Result.IsDeny() {
return nil, httperrors.NewForbiddenError("%s not allow to auth", adminToken.GetUserName())
}
token, err := TokenStrDecode(ctx, tokenStr)
+2 -2
View File
@@ -55,7 +55,7 @@ func invalidateToken(ctx context.Context, tokenStr string) error {
if err != nil {
return httperrors.NewInvalidCredentialError(errors.Wrapf(err, "invalid token").Error())
}
if adminToken.GetUserId() != token.UserId && adminToken.IsAllow(rbacscope.ScopeSystem, api.SERVICE_TYPE, "tokens", "delete").Result.IsDeny() {
if adminToken.GetUserId() != token.UserId && policy.PolicyManager.Allow(rbacscope.ScopeSystem, adminToken, api.SERVICE_TYPE, "tokens", "delete").Result.IsDeny() {
return httperrors.NewForbiddenError("%s not allow to delete token", adminToken.GetUserName())
}
err = models.TokenCacheManager.Invalidate(ctx, adminToken, tokenStr)
@@ -91,7 +91,7 @@ func fetchInvalidTokens(ctx context.Context) ([]string, error) {
if adminToken == nil {
return nil, httperrors.NewForbiddenError("missing auth token")
}
if adminToken.IsAllow(rbacscope.ScopeSystem, api.SERVICE_TYPE, "tokens", "list", "invalid").Result.IsDeny() {
if policy.PolicyManager.Allow(rbacscope.ScopeSystem, adminToken, api.SERVICE_TYPE, "tokens", "list", "invalid").Result.IsDeny() {
return nil, httperrors.NewForbiddenError("%s not allow to list invalid tokens", adminToken.GetUserName())
}
tokens, err := models.TokenCacheManager.FetchInvalidTokens()
+1 -1
View File
@@ -68,7 +68,7 @@ func doCheckPolicies(ctx context.Context, input mcclient.SCheckPoliciesInput) (*
if adminToken == nil {
return nil, httperrors.NewForbiddenError("missing auth token")
}
if adminToken.IsAllow(rbacscope.ScopeSystem, api.SERVICE_TYPE, "tokens", "perform", "check_policies").Result.IsDeny() {
if policy.PolicyManager.Allow(rbacscope.ScopeSystem, adminToken, api.SERVICE_TYPE, "tokens", "perform", "check_policies").Result.IsDeny() {
return nil, httperrors.NewForbiddenError("%s not allow to check policies", adminToken.GetUserName())
}
names, group, err := models.RolePolicyManager.GetMatchPolicyGroupByInput(input.UserId, input.ProjectId, time.Now(), false)
+1 -3
View File
@@ -20,8 +20,6 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type ExternalService struct {
@@ -94,7 +92,7 @@ type TokenCredential interface {
// IsAdmin() bool
HasSystemAdminPrivilege() bool
IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult
// IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult
GetRegions() []string
+2 -4
View File
@@ -21,10 +21,8 @@ import (
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/util/rbacscope"
api "yunion.io/x/onecloud/pkg/apis/identity"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type KeystoneEndpointV2 struct {
@@ -213,7 +211,7 @@ func (this *TokenCredentialV2) HasSystemAdminPrivilege() bool {
return this.IsAdmin() && this.GetTenantName() == "system"
}
func (this *TokenCredentialV2) IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
/*func (this *TokenCredentialV2) IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
if this.isAllow(scope, service, resource, action, extra...) {
return rbacutils.PolicyAllow
} else {
@@ -227,7 +225,7 @@ func (this *TokenCredentialV2) isAllow(scope rbacscope.TRbacScope, service strin
} else {
return true
}
}
}*/
func (this *TokenCredentialV2) Len() int {
return this.ServiceCatalog.Len()
+2 -4
View File
@@ -22,12 +22,10 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/rbacscope"
"yunion.io/x/pkg/utils"
api "yunion.io/x/onecloud/pkg/apis/identity"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
const REGION_ZONE_SEP = '-'
@@ -242,7 +240,7 @@ func (this *TokenCredentialV3) HasSystemAdminPrivilege() bool {
return this.IsAdmin() && this.GetTenantName() == "system"
}
func (this *TokenCredentialV3) IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
/*func (this *TokenCredentialV3) IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
if this.isAllow(scope, service, resource, action, extra...) {
return rbacutils.PolicyAllow
} else {
@@ -256,7 +254,7 @@ func (this *TokenCredentialV3) isAllow(scope rbacscope.TRbacScope, service strin
} else {
return true
}
}
}*/
func (this *TokenCredentialV3) GetRegions() []string {
return this.Token.Catalog.getRegions()
+2 -4
View File
@@ -22,10 +22,8 @@ import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/gotypes"
"yunion.io/x/pkg/util/rbacscope"
api "yunion.io/x/onecloud/pkg/apis/identity"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
type SSimpleToken struct {
@@ -133,7 +131,7 @@ func (self *SSimpleToken) HasSystemAdminPrivilege() bool {
return self.IsAdmin() && self.Project == "system"
}
func (this *SSimpleToken) IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
/*func (this *SSimpleToken) IsAllow(scope rbacscope.TRbacScope, service string, resource string, action string, extra ...string) rbacutils.SPolicyResult {
if this.isAllow(scope, service, resource, action, extra...) {
return rbacutils.PolicyAllow
} else {
@@ -147,7 +145,7 @@ func (this *SSimpleToken) isAllow(scope rbacscope.TRbacScope, service string, re
} else {
return true
}
}
}*/
func (self *SSimpleToken) GetRegions() []string {
return nil
+1 -1
View File
@@ -152,7 +152,7 @@ func getNamespaceInContext(userCred mcclient.TokenCredential, query jsonutils.JS
func getNamespace(userCred mcclient.TokenCredential, resource string, query jsonutils.JSONObject, data *jsonutils.JSONDict) (string, string, error) {
var namespace, namespace_id string
if userCred.IsAllow(rbacscope.ScopeSystem, consts.GetServiceType(), resource, policy.PolicyActionList).Result.IsAllow() {
if policy.PolicyManager.Allow(rbacscope.ScopeSystem, userCred, consts.GetServiceType(), resource, policy.PolicyActionList).Result.IsAllow() {
if name, nameId, e := getNamespaceInContext(userCred, query, data); e != nil {
return "", "", e
} else {