diff --git a/pkg/apimachinery/identity/context.go b/pkg/apimachinery/identity/context.go index 81a7f81de6c..7600f000e7e 100644 --- a/pkg/apimachinery/identity/context.go +++ b/pkg/apimachinery/identity/context.go @@ -31,6 +31,7 @@ func checkNilRequester(r Requester) bool { } const serviceName = "service" +const serviceNameForProvisioning = "provisioning" // WithServiceIdentity sets an identity representing the service itself in provided org and store it in context. // This is useful for background tasks that has to communicate with unfied storage. It also returns a Requester with @@ -53,6 +54,30 @@ func WithServiceIdentity(ctx context.Context, orgID int64) (context.Context, Req return WithRequester(ctx, r), r } +func WithProvisioningIdentitiy(ctx context.Context, namespace string) (context.Context, Requester, error) { + ns, err := types.ParseNamespace(namespace) + if err != nil { + return nil, nil, err + } + + r := &StaticRequester{ + Type: types.TypeAccessPolicy, + Name: serviceNameForProvisioning, + UserUID: serviceNameForProvisioning, + AuthID: serviceNameForProvisioning, + Login: serviceNameForProvisioning, + OrgRole: RoleAdmin, + IsGrafanaAdmin: true, + Namespace: namespace, + OrgID: ns.OrgID, + Permissions: map[int64]map[string][]string{ + ns.OrgID: serviceIdentityPermissions, + }, + } + + return WithRequester(ctx, r), r, nil +} + // WithServiceIdentityContext sets an identity representing the service itself in context. func WithServiceIdentityContext(ctx context.Context, orgID int64) context.Context { ctx, _ = WithServiceIdentity(ctx, orgID) @@ -79,19 +104,29 @@ var serviceIdentityPermissions = getWildcardPermissions( "folders:read", "folders:write", "folders:create", + "folders:delete", "dashboards:read", "dashboards:write", "dashboards:create", "datasources:query", "datasources:read", + "datasources:delete", "alert.provisioning:write", "alert.provisioning.secrets:read", + "users:read", // accesscontrol.ActionUsersRead, + "org.users:read", // accesscontrol.ActionOrgUsersRead, + "teams:read", // accesscontrol.ActionTeamsRead, ) func IsServiceIdentity(ctx context.Context) bool { - ident, err := GetRequester(ctx) + ident, ok := types.AuthInfoFrom(ctx) + if !ok { + return false + } + t, uid, err := types.ParseTypeID(ident.GetUID()) if err != nil { return false } - return ident.GetUID() == types.NewTypeID(types.TypeAccessPolicy, serviceName) + + return t == types.TypeAccessPolicy && (uid == serviceName || uid == serviceNameForProvisioning) }