minor fixes

This commit is contained in:
Qiu Jian
2018-11-15 23:41:04 +08:00
parent 475db4c635
commit ca0e3977c7
7 changed files with 191 additions and 38 deletions
+43 -25
View File
@@ -479,14 +479,14 @@ func listItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
retConut := len(retList)
retCount := len(retList)
// apply customizeFilters
retList, err = customizeFilters.DoApply(retList)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
if len(retList) != retConut {
if len(retList) != retCount {
totalCnt = int64(len(retList))
}
paginate := false
@@ -500,7 +500,7 @@ func listItems(manager IModelManager, ctx context.Context, userCred mcclient.Tok
func calculateListResult(data []jsonutils.JSONObject, total, limit, offset int64, paginate bool) *modules.ListResult {
if paginate {
// do offset first
if offset != 0 {
if offset > 0 {
if total > offset {
data = data[offset:]
} else {
@@ -508,11 +508,13 @@ func calculateListResult(data []jsonutils.JSONObject, total, limit, offset int64
}
}
// do limit
if total > limit {
if limit > 0 && total > limit {
data = data[:limit]
}
}
retResult := modules.ListResult{Data: data, Total: int(total), Limit: int(limit), Offset: int(offset)}
return &retResult
}
@@ -957,6 +959,34 @@ func (dispatcher *DBModelDispatcher) BatchCreate(ctx context.Context, query json
return results, nil
}
func managerPerformCheckCreateData(
manager IModelManager,
ctx context.Context,
userCred mcclient.TokenCredential,
action string,
ownerProjId string,
query jsonutils.JSONObject,
data jsonutils.JSONObject,
) (jsonutils.JSONObject, error) {
body, err := data.(*jsonutils.JSONDict).Get(manager.Keyword())
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
bodyDict := body.(*jsonutils.JSONDict)
var isAllow bool
if consts.IsRbacEnabled() {
isAllow = isClassActionRbacAllowed(manager, userCred, ownerProjId, policy.PolicyActionPerform, action)
} else {
isAllow = manager.AllowPerformCheckCreateData(ctx, userCred, query, data)
}
if !isAllow {
return nil, httperrors.NewForbiddenError("not allow to perform %s", action)
}
return manager.ValidateCreateData(ctx, userCred, ownerProjId, query, bodyDict)
}
func (dispatcher *DBModelDispatcher) PerformClassAction(ctx context.Context, action string, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
userCred := fetchUserCredential(ctx)
@@ -969,25 +999,8 @@ func (dispatcher *DBModelDispatcher) PerformClassAction(ctx context.Context, act
defer lockman.ReleaseClass(ctx, dispatcher.modelManager, ownerProjId)
if action == "check-create-data" {
manager := dispatcher.modelManager
body, err := data.(*jsonutils.JSONDict).Get(manager.Keyword())
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
data := body.(*jsonutils.JSONDict)
var isAllow bool
if consts.IsRbacEnabled() {
isAllow = isClassActionRbacAllowed(manager, userCred, ownerProjId, policy.PolicyActionPerform, action)
} else {
isAllow = manager.AllowPerformCheckCreateData(ctx, userCred, query, data)
}
if !isAllow {
return nil, httperrors.NewForbiddenError("not allow to perform %s", action)
}
return manager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
return managerPerformCheckCreateData(dispatcher.modelManager,
ctx, userCred, action, ownerProjId, query, data)
}
managerValue := reflect.ValueOf(dispatcher.modelManager)
@@ -1022,8 +1035,8 @@ func objectPerformAction(dispatcher *DBModelDispatcher, model IModel, modelValue
isGeneral := false
funcName := fmt.Sprintf("Perform%s", utils.Kebab2Camel(action, "-"))
funcValue := modelValue.MethodByName(funcName)
if !funcValue.IsValid() || funcValue.IsNil() {
funcValue = modelValue.MethodByName(generalFuncName)
if !funcValue.IsValid() || funcValue.IsNil() {
@@ -1057,7 +1070,12 @@ func objectPerformAction(dispatcher *DBModelDispatcher, model IModel, modelValue
var isAllow bool
if consts.IsRbacEnabled() {
isAllow = isObjectRbacAllowed(dispatcher.modelManager, model, userCred, policy.PolicyActionPerform, action)
if model == nil {
ownerProjId, _ := fetchOwnerProjectId(ctx, dispatcher.modelManager, userCred, data)
isAllow = isClassActionRbacAllowed(dispatcher.modelManager, userCred, ownerProjId, policy.PolicyActionPerform, action)
} else {
isAllow = isObjectRbacAllowed(dispatcher.modelManager, model, userCred, policy.PolicyActionPerform, action)
}
} else {
allowFuncName := "Allow" + funcName
allowFuncValue := modelValue.MethodByName(allowFuncName)
+14 -5
View File
@@ -89,10 +89,6 @@ func (manager *STaskManager) FilterByName(q *sqlchemy.SQuery, name string) *sqlc
return q
}
func (manager *STaskManager) FilterByOwner(q *sqlchemy.SQuery, owner string) *sqlchemy.SQuery {
return q
}
func (manager *STaskManager) AllowPerformAction(ctx context.Context, userCred mcclient.TokenCredential, action string, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
return true
}
@@ -105,6 +101,19 @@ func (manager *STaskManager) PerformAction(ctx context.Context, userCred mcclien
return resp, nil
}
func (manager *STaskManager) GetOwnerId(userCred mcclient.IIdentityProvider) string {
return userCred.GetProjectId()
}
func (self *STask) GetOwnerProjectId() string {
return self.UserCred.GetProjectId()
}
func (manager *STaskManager) FilterByOwner(q *sqlchemy.SQuery, owner string) *sqlchemy.SQuery {
q = q.Contains("user_cred", owner)
return q
}
func (self *STask) AllowGetDetails(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) bool {
return userCred.IsSystemAdmin() || userCred.GetProjectId() == self.UserCred.GetProjectId()
}
@@ -414,7 +423,7 @@ func execITask(taskValue reflect.Value, task *STask, odata jsonutils.JSONObject,
return
}
log.Debugf("Call %s %s: %s with %s", task.TaskName, stageName, funcValue, params)
log.Debugf("Call %s %s", task.TaskName, stageName)
funcValue.Call(params)
// call save request context
+51 -6
View File
@@ -30,8 +30,37 @@ const (
var (
PolicyManager *SPolicyManager
PolicyFailedRetryInterval = 15 * time.Second
PolicyRefreshInterval = 15 * time.Minute
defaultRules = []rbacutils.SRbacRule{
{
Resource: "tasks",
Action: PolicyActionPerform,
Result: rbacutils.Allow,
},
{
Service: "compute",
Resource: "zones",
Action: PolicyActionList,
Result: rbacutils.Allow,
},
{
Service: "compute",
Resource: "zones",
Action: PolicyActionGet,
Result: rbacutils.Allow,
},
{
Service: "compute",
Resource: "cloudregions",
Action: PolicyActionList,
Result: rbacutils.Allow,
},
{
Service: "compute",
Resource: "cloudregions",
Action: PolicyActionGet,
Result: rbacutils.Allow,
},
}
)
func init() {
@@ -41,7 +70,11 @@ func init() {
type SPolicyManager struct {
policies map[string]rbacutils.SRbacPolicy
adminPolicies map[string]rbacutils.SRbacPolicy
defaultPolicy *rbacutils.SRbacPolicy
lastSync time.Time
failedRetryInterval time.Duration
refreshInterval time.Duration
}
func parseJsonPolicy(obj jsonutils.JSONObject) (string, rbacutils.SRbacPolicy, error) {
@@ -114,8 +147,13 @@ func fetchPolicies() (map[string]rbacutils.SRbacPolicy, map[string]rbacutils.SRb
func (manager *SPolicyManager) start(refreshInterval time.Duration, retryInterval time.Duration) {
log.Infof("PolicyManager start to fetch policies ...")
PolicyRefreshInterval = refreshInterval
PolicyFailedRetryInterval = retryInterval
manager.refreshInterval = refreshInterval
manager.failedRetryInterval = retryInterval
if len(defaultRules) > 0 {
manager.defaultPolicy = &rbacutils.SRbacPolicy{
Rules: rbacutils.CompactRules(defaultRules),
}
}
manager.sync()
}
@@ -124,13 +162,14 @@ func (manager *SPolicyManager) sync() {
policies, adminPolicies, err := fetchPolicies()
if err != nil {
log.Errorf("sync policy fail %s", err)
time.AfterFunc(PolicyFailedRetryInterval, manager.sync)
time.AfterFunc(manager.failedRetryInterval, manager.sync)
return
}
manager.policies = policies
manager.adminPolicies = adminPolicies
manager.lastSync = time.Now()
time.AfterFunc(PolicyRefreshInterval, manager.sync)
time.AfterFunc(manager.refreshInterval, manager.sync)
}
func (manager *SPolicyManager) Allow(isAdmin bool, userCred mcclient.TokenCredential, service string, resource string, action string, extra ...string) rbacutils.TRbacResult {
@@ -152,6 +191,12 @@ func (manager *SPolicyManager) Allow(isAdmin bool, userCred mcclient.TokenCreden
currentPriv = result
}
}
if manager.defaultPolicy != nil {
result := manager.defaultPolicy.Allow(userCredJson, service, resource, action, extra...)
if result.IsHigherPrivilege(currentPriv) {
currentPriv = result
}
}
if consts.IsRbacDebug() {
log.Debugf("[RBAC: %v] %s %s %s %#v permission %s", isAdmin, service, resource, action, extra, currentPriv)
}