diff --git a/cmd/climc/shell/actions.go b/cmd/climc/shell/actions.go index 52c49ad006..6637ebfec4 100644 --- a/cmd/climc/shell/actions.go +++ b/cmd/climc/shell/actions.go @@ -16,6 +16,7 @@ type BaseActionListOptions struct { Descending bool `help:"Descending order"` Action []string `help:"Log action"` Search string `help:"Filter action logs by obj_name, using 'like' syntax."` + Admin bool `help:"admin mode"` } type ActionListOptions struct { diff --git a/pkg/cloudcommon/db/db_dispatcher.go b/pkg/cloudcommon/db/db_dispatcher.go index e24858a1a3..0ce75deef8 100644 --- a/pkg/cloudcommon/db/db_dispatcher.go +++ b/pkg/cloudcommon/db/db_dispatcher.go @@ -753,8 +753,16 @@ func fetchOwnerProjectId(ctx context.Context, manager IModelManager, userCred mc if data != nil { projId = jsonutils.GetAnyString(data, []string{"project", "tenant", "project_id", "tenant_id"}) } + ownerProjId := manager.GetOwnerId(userCred) if len(projId) == 0 { - return manager.GetOwnerId(userCred), nil + return ownerProjId, nil + } + t, _ := TenantCacheManager.FetchTenantByIdOrName(ctx, projId) + if t == nil { + return "", httperrors.NewNotFoundError("Project %s not found", projId) + } + if t.GetId() == ownerProjId { + return ownerProjId, nil } var isAllow bool if consts.IsRbacEnabled() { @@ -769,10 +777,6 @@ func fetchOwnerProjectId(ctx context.Context, manager IModelManager, userCred mc if !isAllow { return "", httperrors.NewForbiddenError("Delegation not allowed") } - t, _ := TenantCacheManager.FetchTenantByIdOrName(ctx, projId) - if t == nil { - return "", httperrors.NewNotFoundError("Project %s not found", projId) - } return t.GetId(), nil } diff --git a/pkg/cloudcommon/db/opslog.go b/pkg/cloudcommon/db/opslog.go index cbc395cf41..6d656e172c 100644 --- a/pkg/cloudcommon/db/opslog.go +++ b/pkg/cloudcommon/db/opslog.go @@ -305,28 +305,24 @@ func (manager *SOpsLogManager) LogDetachEvent(ctx context.Context, m1, m2 IModel } func (manager *SOpsLogManager) ListItemFilter(ctx context.Context, q *sqlchemy.SQuery, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (*sqlchemy.SQuery, error) { - queryDict, ok := query.(*jsonutils.JSONDict) - if !ok { - return nil, fmt.Errorf("invalid query string") - } - objTypes := jsonutils.GetQueryStringArray(queryDict, "obj_type") + objTypes := jsonutils.GetQueryStringArray(query, "obj_type") if objTypes != nil && len(objTypes) > 0 { - queryDict.RemoveIgnoreCase("obj_type") q = q.Filter(sqlchemy.In(q.Field("obj_type"), objTypes)) } - objIds := jsonutils.GetQueryStringArray(queryDict, "obj_id") + objIds := jsonutils.GetQueryStringArray(query, "obj_id") if objIds != nil && len(objIds) > 0 { - queryDict.RemoveIgnoreCase("obj_id") q = q.Filter(sqlchemy.OR(sqlchemy.In(q.Field("obj_id"), objIds), sqlchemy.In(q.Field("obj_name"), objIds))) } - action := jsonutils.GetQueryStringArray(queryDict, "action") + action := jsonutils.GetQueryStringArray(query, "action") if action != nil && len(action) > 0 { - queryDict.RemoveIgnoreCase("action") q = q.Filter(sqlchemy.In(q.Field("action"), action)) } - if !IsAdminAllowList(userCred, manager) { - q = q.Filter(sqlchemy.OR(sqlchemy.AND(sqlchemy.IsNotNull(q.Field("owner_tenant_id")), sqlchemy.Equals(q.Field("owner_tenant_id"), userCred.GetProjectId())), sqlchemy.Equals(q.Field("tenant_id"), userCred.GetProjectId()))) - } + //if !IsAdminAllowList(userCred, manager) { + // q = q.Filter(sqlchemy.OR( + // sqlchemy.Equals(q.Field("owner_tenant_id"), manager.GetOwnerId(userCred)), + // sqlchemy.Equals(q.Field("tenant_id"), manager.GetOwnerId(userCred)), + // )) + //} since, _ := query.GetTime("since") if !since.IsZero() { q = q.GT("ops_time", since) @@ -335,6 +331,7 @@ func (manager *SOpsLogManager) ListItemFilter(ctx context.Context, q *sqlchemy.S if !until.IsZero() { q = q.LE("ops_time", until) } + log.Debugf("%s", q.String()) return q, nil } @@ -385,8 +382,22 @@ func (self *SOpsLogManager) FilterByName(q *sqlchemy.SQuery, name string) *sqlch func (self *SOpsLogManager) FilterByOwner(q *sqlchemy.SQuery, owner string) *sqlchemy.SQuery { if len(owner) > 0 { - return q.Equals("owner_project_id", owner) - } else { - return q + q = q.Filter(sqlchemy.OR( + sqlchemy.Equals(q.Field("owner_tenant_id"), owner), + sqlchemy.Equals(q.Field("tenant_id"), owner), + )) } + return q +} + +func (manager *SOpsLogManager) GetOwnerId(userCred mcclient.IIdentityProvider) string { + return userCred.GetProjectId() +} + +func (self *SOpsLog) GetOwnerProjectId() string { + return self.OwnerProjectId +} + +func (self *SOpsLog) IsSharable() bool { + return false } diff --git a/pkg/cloudcommon/policy/defaults.go b/pkg/cloudcommon/policy/defaults.go index 89720ddb8c..d6eaa528a9 100644 --- a/pkg/cloudcommon/policy/defaults.go +++ b/pkg/cloudcommon/policy/defaults.go @@ -137,5 +137,17 @@ var ( Action: PolicyActionGet, Result: rbacutils.OwnerAllow, }, + { + Service: "log", + Resource: "actions", + Action: PolicyActionList, + Result: rbacutils.OwnerAllow, + }, + { + Service: "log", + Resource: "actions", + Action: PolicyActionGet, + Result: rbacutils.OwnerAllow, + }, } ) diff --git a/pkg/cloudcommon/policy/policy.go b/pkg/cloudcommon/policy/policy.go index d6f2ad2e97..a9df96880f 100644 --- a/pkg/cloudcommon/policy/policy.go +++ b/pkg/cloudcommon/policy/policy.go @@ -246,7 +246,7 @@ func (manager *SPolicyManager) allowWithoutCache(isAdmin bool, userCred mcclient } } if consts.IsRbacDebug() { - log.Debugf("[RBAC: %v] %s %s %s %#v permission %s", isAdmin, service, resource, action, extra, currentPriv) + log.Debugf("[RBAC: %v] %s %s %s %#v permission %s userCred: %s", isAdmin, service, resource, action, extra, currentPriv, userCredJson) } return unifyRbacResult(isAdmin, currentPriv) }