| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- // Copyright 2019 Yunion
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package db
- import (
- "context"
- "yunion.io/x/log"
- "yunion.io/x/pkg/errors"
- "yunion.io/x/pkg/util/rbacscope"
- "yunion.io/x/onecloud/pkg/cloudcommon/consts"
- "yunion.io/x/onecloud/pkg/cloudcommon/policy"
- "yunion.io/x/onecloud/pkg/httperrors"
- "yunion.io/x/onecloud/pkg/mcclient"
- "yunion.io/x/onecloud/pkg/util/rbacutils"
- )
- func IsObjectRbacAllowed(ctx context.Context, model IModel, userCred mcclient.TokenCredential, action string, extra ...string) error {
- return isObjectRbacAllowed(ctx, model, userCred, action, extra...)
- }
- func isObjectRbacAllowed(ctx context.Context, model IModel, userCred mcclient.TokenCredential, action string, extra ...string) error {
- _, err := isObjectRbacAllowedResult(ctx, model, userCred, action, extra...)
- return err
- }
- func isObjectRbacAllowedResult(ctx context.Context, model IModel, userCred mcclient.TokenCredential, action string, extra ...string) (rbacutils.SPolicyResult, error) {
- manager := model.GetModelManager()
- objOwnerId := model.GetOwnerId()
- var ownerId mcclient.IIdentityProvider
- if userCred != nil {
- ownerId = userCred
- }
- var requireScope rbacscope.TRbacScope
- resScope := manager.ResourceScope()
- switch resScope {
- case rbacscope.ScopeSystem:
- requireScope = rbacscope.ScopeSystem
- case rbacscope.ScopeDomain:
- if ownerId != nil && objOwnerId != nil && (ownerId.GetUserId() == objOwnerId.GetUserId() && action == policy.PolicyActionGet) {
- requireScope = rbacscope.ScopeUser
- } else if ownerId != nil && objOwnerId != nil && (ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() || objOwnerId.GetProjectDomainId() == "" || (model.IsSharable(ownerId) && action == policy.PolicyActionGet)) {
- requireScope = rbacscope.ScopeDomain
- } else {
- requireScope = rbacscope.ScopeSystem
- }
- case rbacscope.ScopeUser:
- if ownerId != nil && objOwnerId != nil && (ownerId.GetUserId() == objOwnerId.GetUserId() || objOwnerId.GetUserId() == "" || (model.IsSharable(ownerId) && action == policy.PolicyActionGet)) {
- requireScope = rbacscope.ScopeUser
- } else if ownerId != nil && objOwnerId != nil && ownerId.GetProjectId() == objOwnerId.GetProjectId() {
- requireScope = rbacscope.ScopeProject
- } else if ownerId != nil && objOwnerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
- requireScope = rbacscope.ScopeDomain
- } else {
- requireScope = rbacscope.ScopeSystem
- }
- default:
- // objOwnerId should not be nil
- if ownerId != nil && objOwnerId != nil && (ownerId.GetProjectId() == objOwnerId.GetProjectId() || objOwnerId.GetProjectId() == "" || (model.IsSharable(ownerId) && action == policy.PolicyActionGet)) {
- requireScope = rbacscope.ScopeProject
- } else if ownerId != nil && objOwnerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
- requireScope = rbacscope.ScopeDomain
- } else {
- requireScope = rbacscope.ScopeSystem
- }
- }
- scope, result := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), manager.KeywordPlural(), action, extra...)
- if result.Result.IsAllow() && !requireScope.HigherThan(scope) {
- err := objectConfirmPolicyTags(ctx, model, result)
- if err != nil {
- return rbacutils.PolicyDeny, errors.Wrap(err, "objectConfirmPolicyTags")
- }
- return result, nil
- }
- return rbacutils.PolicyDeny, httperrors.NewForbiddenError("not enough privilege (require:%s,allow:%s:resource:%s) [tags:%s]", requireScope, scope, resScope, result.String())
- }
- func isJointObjectRbacAllowed(ctx context.Context, item IJointModel, userCred mcclient.TokenCredential, action string, extra ...string) error {
- err1 := isObjectRbacAllowed(ctx, JointMaster(item), userCred, action, extra...)
- err2 := isObjectRbacAllowed(ctx, JointSlave(item), userCred, action, extra...)
- if err1 == nil || err2 == nil {
- return nil
- }
- return err1
- }
- func isClassRbacAllowed(ctx context.Context, manager IModelManager, userCred mcclient.TokenCredential, objOwnerId mcclient.IIdentityProvider, action string, extra ...string) (rbacutils.SPolicyResult, error) {
- var ownerId mcclient.IIdentityProvider
- if userCred != nil {
- ownerId = userCred
- }
- var requireScope rbacscope.TRbacScope
- resScope := manager.ResourceScope()
- switch resScope {
- case rbacscope.ScopeSystem:
- requireScope = rbacscope.ScopeSystem
- case rbacscope.ScopeDomain:
- // objOwnerId should not be nil
- if ownerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
- requireScope = rbacscope.ScopeDomain
- } else {
- requireScope = rbacscope.ScopeSystem
- }
- case rbacscope.ScopeUser:
- if ownerId != nil && ownerId.GetUserId() == objOwnerId.GetUserId() {
- requireScope = rbacscope.ScopeUser
- } else if ownerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
- requireScope = rbacscope.ScopeDomain
- } else {
- requireScope = rbacscope.ScopeSystem
- }
- default:
- // objOwnerId should not be nil
- if ownerId != nil && ownerId.GetProjectId() == objOwnerId.GetProjectId() {
- requireScope = rbacscope.ScopeProject
- } else if ownerId != nil && ownerId.GetProjectDomainId() == objOwnerId.GetProjectDomainId() {
- requireScope = rbacscope.ScopeDomain
- } else {
- requireScope = rbacscope.ScopeSystem
- }
- }
- allowScope, result := policy.PolicyManager.AllowScope(userCred, consts.GetServiceType(), manager.KeywordPlural(), action, extra...)
- if result.Result.IsAllow() && !requireScope.HigherThan(allowScope) {
- err := classConfirmPolicyTags(ctx, manager, objOwnerId, result)
- if err != nil {
- return rbacutils.PolicyDeny, errors.Wrap(err, "classConfirmPolicyTags")
- }
- return result, nil
- }
- return rbacutils.PolicyDeny, httperrors.NewForbiddenError("not enough privilege (require:%s,allow:%s)", requireScope, allowScope)
- }
- type IResource interface {
- KeywordPlural() string
- }
- func IsAllowList(scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- if userCred == nil {
- return rbacutils.PolicyDeny
- }
- return policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionList)
- }
- func IsAdminAllowList(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- return IsAllowList(rbacscope.ScopeSystem, userCred, manager)
- }
- func IsDomainAllowList(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- return IsAllowList(rbacscope.ScopeDomain, userCred, manager)
- }
- func IsProjectAllowList(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- return IsAllowList(rbacscope.ScopeProject, userCred, manager)
- }
- func IsAllowCreate(scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- if userCred == nil {
- return rbacutils.PolicyDeny
- }
- return policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionCreate)
- }
- func IsAdminAllowCreate(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- return IsAllowCreate(rbacscope.ScopeSystem, userCred, manager)
- }
- func IsDomainAllowCreate(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- return IsAllowCreate(rbacscope.ScopeDomain, userCred, manager)
- }
- func IsProjectAllowCreate(userCred mcclient.TokenCredential, manager IResource) rbacutils.SPolicyResult {
- return IsAllowCreate(rbacscope.ScopeProject, userCred, manager)
- }
- func IsAllowClassPerform(scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, manager IResource, action string) rbacutils.SPolicyResult {
- if userCred == nil {
- return rbacutils.PolicyDeny
- }
- return policy.PolicyManager.Allow(scope, userCred, consts.GetServiceType(), manager.KeywordPlural(), policy.PolicyActionPerform, action)
- }
- func IsAdminAllowClassPerform(userCred mcclient.TokenCredential, manager IResource, action string) rbacutils.SPolicyResult {
- return IsAllowClassPerform(rbacscope.ScopeSystem, userCred, manager, action)
- }
- func IsDomainAllowClassPerform(userCred mcclient.TokenCredential, manager IResource, action string) rbacutils.SPolicyResult {
- return IsAllowClassPerform(rbacscope.ScopeDomain, userCred, manager, action)
- }
- func IsProjectAllowClassPerform(userCred mcclient.TokenCredential, manager IResource, action string) rbacutils.SPolicyResult {
- return IsAllowClassPerform(rbacscope.ScopeProject, userCred, manager, action)
- }
- func IsAllowGet(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, obj IModel) bool {
- if userCred == nil {
- return false
- }
- 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)
- return false
- } else {
- return true
- }
- }
- func IsAdminAllowGet(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowGet(ctx, rbacscope.ScopeSystem, userCred, obj)
- }
- func IsDomainAllowGet(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowGet(ctx, rbacscope.ScopeDomain, userCred, obj)
- }
- func IsProjectAllowGet(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowGet(ctx, rbacscope.ScopeProject, userCred, obj)
- }
- func IsAllowGetSpec(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- if userCred == nil {
- return false
- }
- 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)
- return false
- } else {
- return true
- }
- }
- func IsAdminAllowGetSpec(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- return IsAllowGetSpec(ctx, rbacscope.ScopeSystem, userCred, obj, spec)
- }
- func IsDomainAllowGetSpec(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- return IsAllowGetSpec(ctx, rbacscope.ScopeDomain, userCred, obj, spec)
- }
- func IsProjectAllowGetSpec(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- return IsAllowGetSpec(ctx, rbacscope.ScopeProject, userCred, obj, spec)
- }
- func IsAllowPerform(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, obj IModel, action string) bool {
- if userCred == nil {
- return false
- }
- 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)
- return false
- } else {
- return true
- }
- }
- func IsAdminAllowPerform(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, action string) bool {
- return IsAllowPerform(ctx, rbacscope.ScopeSystem, userCred, obj, action)
- }
- func IsDomainAllowPerform(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, action string) bool {
- return IsAllowPerform(ctx, rbacscope.ScopeDomain, userCred, obj, action)
- }
- func IsProjectAllowPerform(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, action string) bool {
- return IsAllowPerform(ctx, rbacscope.ScopeProject, userCred, obj, action)
- }
- func IsAllowUpdate(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, obj IModel) bool {
- if userCred == nil {
- return false
- }
- 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)
- return false
- } else {
- return true
- }
- }
- func IsAdminAllowUpdate(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowUpdate(ctx, rbacscope.ScopeSystem, userCred, obj)
- }
- func IsDomainAllowUpdate(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowUpdate(ctx, rbacscope.ScopeDomain, userCred, obj)
- }
- func IsProjectAllowUpdate(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowUpdate(ctx, rbacscope.ScopeProject, userCred, obj)
- }
- func IsAllowUpdateSpec(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- if userCred == nil {
- return false
- }
- 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)
- return false
- } else {
- return true
- }
- }
- func IsAdminAllowUpdateSpec(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- return IsAllowUpdateSpec(ctx, rbacscope.ScopeSystem, userCred, obj, spec)
- }
- func IsDomainAllowUpdateSpec(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- return IsAllowUpdateSpec(ctx, rbacscope.ScopeDomain, userCred, obj, spec)
- }
- func IsProjectAllowUpdateSpec(ctx context.Context, userCred mcclient.TokenCredential, obj IModel, spec string) bool {
- return IsAllowUpdateSpec(ctx, rbacscope.ScopeProject, userCred, obj, spec)
- }
- func IsAllowDelete(ctx context.Context, scope rbacscope.TRbacScope, userCred mcclient.TokenCredential, obj IModel) bool {
- if userCred == nil {
- return false
- }
- 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)
- return false
- } else {
- return true
- }
- }
- func IsAdminAllowDelete(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowDelete(ctx, rbacscope.ScopeSystem, userCred, obj)
- }
- func IsDomainAllowDelete(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowDelete(ctx, rbacscope.ScopeDomain, userCred, obj)
- }
- func IsProjectAllowDelete(ctx context.Context, userCred mcclient.TokenCredential, obj IModel) bool {
- return IsAllowDelete(ctx, rbacscope.ScopeProject, userCred, obj)
- }
|