mirror of
https://github.com/coder/coder.git
synced 2025-07-18 14:17:22 +00:00
chore: remove rbac psuedo resources, add custom verbs (#13276)
Removes our pseudo rbac resources like `WorkspaceApplicationConnect` in favor of additional verbs like `ssh`. This is to make more intuitive permissions for building custom roles. The source of truth is now `policy.go`
This commit is contained in:
@ -16,12 +16,12 @@ import (
|
||||
"github.com/open-policy-agent/opa/topdown"
|
||||
|
||||
"cdr.dev/slog"
|
||||
"github.com/coder/coder/v2/coderd/rbac/policy"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/coderd/httpapi/httpapiconstraints"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
"github.com/coder/coder/v2/coderd/rbac/policy"
|
||||
"github.com/coder/coder/v2/coderd/util/slice"
|
||||
"github.com/coder/coder/v2/provisionersdk"
|
||||
)
|
||||
@ -164,14 +164,14 @@ var (
|
||||
DisplayName: "Provisioner Daemon",
|
||||
Site: rbac.Permissions(map[string][]policy.Action{
|
||||
// TODO: Add ProvisionerJob resource type.
|
||||
rbac.ResourceFile.Type: {policy.ActionRead},
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
rbac.ResourceUser.Type: {policy.ActionRead},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceWorkspaceBuild.Type: {policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceUserData.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
rbac.ResourceAPIKey.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceFile.Type: {policy.ActionRead},
|
||||
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
// Unsure why provisionerd needs update and read personal
|
||||
rbac.ResourceUser.Type: {policy.ActionRead, policy.ActionReadPersonal, policy.ActionUpdatePersonal},
|
||||
rbac.ResourceWorkspaceDormant.Type: {policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, policy.ActionWorkspaceStop},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop},
|
||||
rbac.ResourceApiKey.Type: {policy.WildcardSymbol},
|
||||
// When org scoped provisioner credentials are implemented,
|
||||
// this can be reduced to read a specific org.
|
||||
rbac.ResourceOrganization.Type: {policy.ActionRead},
|
||||
@ -192,11 +192,11 @@ var (
|
||||
Name: "autostart",
|
||||
DisplayName: "Autostart Daemon",
|
||||
Site: rbac.Permissions(map[string][]policy.Action{
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
rbac.ResourceWorkspaceBuild.Type: {policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceUser.Type: {policy.ActionRead},
|
||||
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
rbac.ResourceWorkspaceDormant.Type: {policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, policy.ActionWorkspaceStop},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionDelete, policy.ActionRead, policy.ActionUpdate, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop},
|
||||
rbac.ResourceUser.Type: {policy.ActionRead},
|
||||
}),
|
||||
Org: map[string][]rbac.Permission{},
|
||||
User: []rbac.Permission{},
|
||||
@ -214,7 +214,7 @@ var (
|
||||
Name: "hangdetector",
|
||||
DisplayName: "Hang Detector Daemon",
|
||||
Site: rbac.Permissions(map[string][]policy.Action{
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {policy.ActionRead},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionRead, policy.ActionUpdate},
|
||||
}),
|
||||
@ -234,19 +234,17 @@ var (
|
||||
DisplayName: "Coder",
|
||||
Site: rbac.Permissions(map[string][]policy.Action{
|
||||
rbac.ResourceWildcard.Type: {policy.ActionRead},
|
||||
rbac.ResourceAPIKey.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceApiKey.Type: rbac.ResourceApiKey.AvailableActions(),
|
||||
rbac.ResourceGroup.Type: {policy.ActionCreate, policy.ActionUpdate},
|
||||
rbac.ResourceRoleAssignment.Type: {policy.ActionCreate, policy.ActionDelete},
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceAssignRole.Type: rbac.ResourceAssignRole.AvailableActions(),
|
||||
rbac.ResourceSystem.Type: {policy.WildcardSymbol},
|
||||
rbac.ResourceOrganization.Type: {policy.ActionCreate, policy.ActionRead},
|
||||
rbac.ResourceOrganizationMember.Type: {policy.ActionCreate},
|
||||
rbac.ResourceOrgRoleAssignment.Type: {policy.ActionCreate},
|
||||
rbac.ResourceAssignOrgRole.Type: {policy.ActionRead, policy.ActionCreate, policy.ActionDelete},
|
||||
rbac.ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionUpdate},
|
||||
rbac.ResourceUser.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
rbac.ResourceUserData.Type: {policy.ActionCreate, policy.ActionUpdate},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionUpdate},
|
||||
rbac.ResourceWorkspaceBuild.Type: {policy.ActionUpdate},
|
||||
rbac.ResourceWorkspaceExecution.Type: {policy.ActionCreate},
|
||||
rbac.ResourceUser.Type: rbac.ResourceUser.AvailableActions(),
|
||||
rbac.ResourceWorkspaceDormant.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStop},
|
||||
rbac.ResourceWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete, policy.ActionWorkspaceStart, policy.ActionWorkspaceStop, policy.ActionSSH},
|
||||
rbac.ResourceWorkspaceProxy.Type: {policy.ActionCreate, policy.ActionUpdate, policy.ActionDelete},
|
||||
}),
|
||||
Org: map[string][]rbac.Permission{},
|
||||
@ -315,6 +313,20 @@ func insert[
|
||||
authorizer rbac.Authorizer,
|
||||
object rbac.Objecter,
|
||||
insertFunc Insert,
|
||||
) Insert {
|
||||
return insertWithAction(logger, authorizer, object, policy.ActionCreate, insertFunc)
|
||||
}
|
||||
|
||||
func insertWithAction[
|
||||
ObjectType any,
|
||||
ArgumentType any,
|
||||
Insert func(ctx context.Context, arg ArgumentType) (ObjectType, error),
|
||||
](
|
||||
logger slog.Logger,
|
||||
authorizer rbac.Authorizer,
|
||||
object rbac.Objecter,
|
||||
action policy.Action,
|
||||
insertFunc Insert,
|
||||
) Insert {
|
||||
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
|
||||
// Fetch the rbac subject
|
||||
@ -324,7 +336,7 @@ func insert[
|
||||
}
|
||||
|
||||
// Authorize the action
|
||||
err = authorizer.Authorize(ctx, act, policy.ActionCreate, object.RBACObject())
|
||||
err = authorizer.Authorize(ctx, act, action, object.RBACObject())
|
||||
if err != nil {
|
||||
return empty, logNotAuthorizedError(ctx, logger, err)
|
||||
}
|
||||
@ -384,13 +396,14 @@ func update[
|
||||
// The database query function will **ALWAYS** hit the database, even if the
|
||||
// user cannot read the resource. This is because the resource details are
|
||||
// required to run a proper authorization check.
|
||||
func fetch[
|
||||
func fetchWithAction[
|
||||
ArgumentType any,
|
||||
ObjectType rbac.Objecter,
|
||||
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
|
||||
](
|
||||
logger slog.Logger,
|
||||
authorizer rbac.Authorizer,
|
||||
action policy.Action,
|
||||
f DatabaseFunc,
|
||||
) DatabaseFunc {
|
||||
return func(ctx context.Context, arg ArgumentType) (empty ObjectType, err error) {
|
||||
@ -407,7 +420,7 @@ func fetch[
|
||||
}
|
||||
|
||||
// Authorize the action
|
||||
err = authorizer.Authorize(ctx, act, policy.ActionRead, object.RBACObject())
|
||||
err = authorizer.Authorize(ctx, act, action, object.RBACObject())
|
||||
if err != nil {
|
||||
return empty, logNotAuthorizedError(ctx, logger, err)
|
||||
}
|
||||
@ -416,6 +429,18 @@ func fetch[
|
||||
}
|
||||
}
|
||||
|
||||
func fetch[
|
||||
ArgumentType any,
|
||||
ObjectType rbac.Objecter,
|
||||
DatabaseFunc func(ctx context.Context, arg ArgumentType) (ObjectType, error),
|
||||
](
|
||||
logger slog.Logger,
|
||||
authorizer rbac.Authorizer,
|
||||
f DatabaseFunc,
|
||||
) DatabaseFunc {
|
||||
return fetchWithAction(logger, authorizer, policy.ActionRead, f)
|
||||
}
|
||||
|
||||
// fetchAndExec uses fetchAndQuery but only returns the error. The naming comes
|
||||
// from SQL 'exec' functions which only return an error.
|
||||
// See fetchAndQuery for more information.
|
||||
@ -488,6 +513,7 @@ func fetchWithPostFilter[
|
||||
DatabaseFunc func(ctx context.Context, arg ArgumentType) ([]ObjectType, error),
|
||||
](
|
||||
authorizer rbac.Authorizer,
|
||||
action policy.Action,
|
||||
f DatabaseFunc,
|
||||
) DatabaseFunc {
|
||||
return func(ctx context.Context, arg ArgumentType) (empty []ObjectType, err error) {
|
||||
@ -504,7 +530,7 @@ func fetchWithPostFilter[
|
||||
}
|
||||
|
||||
// Authorize the action
|
||||
return rbac.Filter(ctx, authorizer, act, policy.ActionRead, objects)
|
||||
return rbac.Filter(ctx, authorizer, act, action, objects)
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,7 +586,7 @@ func (q *querier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, r
|
||||
return NoActorError
|
||||
}
|
||||
|
||||
roleAssign := rbac.ResourceRoleAssignment
|
||||
roleAssign := rbac.ResourceAssignRole
|
||||
shouldBeOrgRoles := false
|
||||
if orgID != nil {
|
||||
roleAssign = roleAssign.InOrg(*orgID)
|
||||
@ -585,7 +611,7 @@ func (q *querier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, r
|
||||
}
|
||||
|
||||
if len(added) > 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, roleAssign); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionAssign, roleAssign); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -655,6 +681,29 @@ func authorizedTemplateVersionFromJob(ctx context.Context, q *querier, job datab
|
||||
}
|
||||
}
|
||||
|
||||
func (q *querier) authorizeTemplateInsights(ctx context.Context, templateIDs []uuid.UUID) error {
|
||||
// Abort early if can read all template insights, aka admins.
|
||||
// TODO: If we know the org, that would allow org admins to abort early too.
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate); err != nil {
|
||||
for _, templateID := range templateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, template); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(templateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate.All()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *querier) AcquireLock(ctx context.Context, id int64) error {
|
||||
return q.db.AcquireLock(ctx, id)
|
||||
}
|
||||
@ -731,7 +780,7 @@ func (q *querier) DeleteAPIKeyByID(ctx context.Context, id string) error {
|
||||
func (q *querier) DeleteAPIKeysByUserID(ctx context.Context, userID uuid.UUID) error {
|
||||
// TODO: This is not 100% correct because it omits apikey IDs.
|
||||
err := q.authorizeContext(ctx, policy.ActionDelete,
|
||||
rbac.ResourceAPIKey.WithOwner(userID.String()))
|
||||
rbac.ResourceApiKey.WithOwner(userID.String()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -755,7 +804,7 @@ func (q *querier) DeleteAllTailnetTunnels(ctx context.Context, arg database.Dele
|
||||
func (q *querier) DeleteApplicationConnectAPIKeysByUserID(ctx context.Context, userID uuid.UUID) error {
|
||||
// TODO: This is not 100% correct because it omits apikey IDs.
|
||||
err := q.authorizeContext(ctx, policy.ActionDelete,
|
||||
rbac.ResourceAPIKey.WithOwner(userID.String()))
|
||||
rbac.ResourceApiKey.WithOwner(userID.String()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -770,14 +819,14 @@ func (q *querier) DeleteCoordinator(ctx context.Context, id uuid.UUID) error {
|
||||
}
|
||||
|
||||
func (q *querier) DeleteExternalAuthLink(ctx context.Context, arg database.DeleteExternalAuthLinkParams) error {
|
||||
return deleteQ(q.log, q.auth, func(ctx context.Context, arg database.DeleteExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
return fetchAndExec(q.log, q.auth, policy.ActionUpdatePersonal, func(ctx context.Context, arg database.DeleteExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
//nolint:gosimple
|
||||
return q.db.GetExternalAuthLink(ctx, database.GetExternalAuthLinkParams{UserID: arg.UserID, ProviderID: arg.ProviderID})
|
||||
}, q.db.DeleteExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
|
||||
return deleteQ(q.log, q.auth, q.db.GetGitSSHKey, q.db.DeleteGitSSHKey)(ctx, userID)
|
||||
return fetchAndExec(q.log, q.auth, policy.ActionUpdatePersonal, q.db.GetGitSSHKey, q.db.DeleteGitSSHKey)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteGroupByID(ctx context.Context, id uuid.UUID) error {
|
||||
@ -804,7 +853,7 @@ func (q *querier) DeleteLicense(ctx context.Context, id int32) (int32, error) {
|
||||
}
|
||||
|
||||
func (q *querier) DeleteOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceOAuth2ProviderApp); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceOauth2App); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteOAuth2ProviderAppByID(ctx, id)
|
||||
@ -823,14 +872,14 @@ func (q *querier) DeleteOAuth2ProviderAppCodeByID(ctx context.Context, id uuid.U
|
||||
|
||||
func (q *querier) DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx context.Context, arg database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete,
|
||||
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
|
||||
rbac.ResourceOauth2AppCodeToken.WithOwner(arg.UserID.String())); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteOAuth2ProviderAppCodesByAppAndUserID(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteOAuth2ProviderAppSecretByID(ctx context.Context, id uuid.UUID) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceOauth2AppSecret); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteOAuth2ProviderAppSecretByID(ctx, id)
|
||||
@ -838,7 +887,7 @@ func (q *querier) DeleteOAuth2ProviderAppSecretByID(ctx context.Context, id uuid
|
||||
|
||||
func (q *querier) DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx context.Context, arg database.DeleteOAuth2ProviderAppTokensByAppAndUserIDParams) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionDelete,
|
||||
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
|
||||
rbac.ResourceOauth2AppCodeToken.WithOwner(arg.UserID.String())); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteOAuth2ProviderAppTokensByAppAndUserID(ctx, arg)
|
||||
@ -950,15 +999,15 @@ func (q *querier) GetAPIKeyByName(ctx context.Context, arg database.GetAPIKeyByN
|
||||
}
|
||||
|
||||
func (q *querier) GetAPIKeysByLoginType(ctx context.Context, loginType database.LoginType) ([]database.APIKey, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetAPIKeysByLoginType)(ctx, loginType)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetAPIKeysByLoginType)(ctx, loginType)
|
||||
}
|
||||
|
||||
func (q *querier) GetAPIKeysByUserID(ctx context.Context, params database.GetAPIKeysByUserIDParams) ([]database.APIKey, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetAPIKeysByUserID)(ctx, database.GetAPIKeysByUserIDParams{LoginType: params.LoginType, UserID: params.UserID})
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetAPIKeysByUserID)(ctx, database.GetAPIKeysByUserIDParams{LoginType: params.LoginType, UserID: params.UserID})
|
||||
}
|
||||
|
||||
func (q *querier) GetAPIKeysLastUsedAfter(ctx context.Context, lastUsed time.Time) ([]database.APIKey, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetAPIKeysLastUsedAfter)(ctx, lastUsed)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetAPIKeysLastUsedAfter)(ctx, lastUsed)
|
||||
}
|
||||
|
||||
func (q *querier) GetActiveUserCount(ctx context.Context) (int64, error) {
|
||||
@ -1078,11 +1127,11 @@ func (q *querier) GetDeploymentWorkspaceStats(ctx context.Context) (database.Get
|
||||
}
|
||||
|
||||
func (q *querier) GetExternalAuthLink(ctx context.Context, arg database.GetExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
return fetch(q.log, q.auth, q.db.GetExternalAuthLink)(ctx, arg)
|
||||
return fetchWithAction(q.log, q.auth, policy.ActionReadPersonal, q.db.GetExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetExternalAuthLinksByUserID(ctx context.Context, userID uuid.UUID) ([]database.ExternalAuthLink, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetExternalAuthLinksByUserID)(ctx, userID)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionReadPersonal, q.db.GetExternalAuthLinksByUserID)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetFileByHashAndCreator(ctx context.Context, arg database.GetFileByHashAndCreatorParams) (database.File, error) {
|
||||
@ -1125,7 +1174,7 @@ func (q *querier) GetFileTemplates(ctx context.Context, fileID uuid.UUID) ([]dat
|
||||
}
|
||||
|
||||
func (q *querier) GetGitSSHKey(ctx context.Context, userID uuid.UUID) (database.GitSSHKey, error) {
|
||||
return fetch(q.log, q.auth, q.db.GetGitSSHKey)(ctx, userID)
|
||||
return fetchWithAction(q.log, q.auth, policy.ActionReadPersonal, q.db.GetGitSSHKey)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetGroupByID(ctx context.Context, id uuid.UUID) (database.Group, error) {
|
||||
@ -1144,11 +1193,11 @@ func (q *querier) GetGroupMembers(ctx context.Context, id uuid.UUID) ([]database
|
||||
}
|
||||
|
||||
func (q *querier) GetGroupsByOrganizationAndUserID(ctx context.Context, arg database.GetGroupsByOrganizationAndUserIDParams) ([]database.Group, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetGroupsByOrganizationAndUserID)(ctx, arg)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetGroupsByOrganizationAndUserID)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetGroupsByOrganizationID(ctx context.Context, organizationID uuid.UUID) ([]database.Group, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetGroupsByOrganizationID)(ctx, organizationID)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetGroupsByOrganizationID)(ctx, organizationID)
|
||||
}
|
||||
|
||||
func (q *querier) GetHealthSettings(ctx context.Context) (string, error) {
|
||||
@ -1213,7 +1262,7 @@ func (q *querier) GetLicenses(ctx context.Context) ([]database.License, error) {
|
||||
fetch := func(ctx context.Context, _ interface{}) ([]database.License, error) {
|
||||
return q.db.GetLicenses(ctx)
|
||||
}
|
||||
return fetchWithPostFilter(q.auth, fetch)(ctx, nil)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, fetch)(ctx, nil)
|
||||
}
|
||||
|
||||
func (q *querier) GetLogoURL(ctx context.Context) (string, error) {
|
||||
@ -1227,7 +1276,7 @@ func (q *querier) GetNotificationBanners(ctx context.Context) (string, error) {
|
||||
}
|
||||
|
||||
func (q *querier) GetOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderApp, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOAuth2ProviderApp); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOauth2App); err != nil {
|
||||
return database.OAuth2ProviderApp{}, err
|
||||
}
|
||||
return q.db.GetOAuth2ProviderAppByID(ctx, id)
|
||||
@ -1242,7 +1291,7 @@ func (q *querier) GetOAuth2ProviderAppCodeByPrefix(ctx context.Context, secretPr
|
||||
}
|
||||
|
||||
func (q *querier) GetOAuth2ProviderAppSecretByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderAppSecret, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOauth2AppSecret); err != nil {
|
||||
return database.OAuth2ProviderAppSecret{}, err
|
||||
}
|
||||
return q.db.GetOAuth2ProviderAppSecretByID(ctx, id)
|
||||
@ -1253,7 +1302,7 @@ func (q *querier) GetOAuth2ProviderAppSecretByPrefix(ctx context.Context, secret
|
||||
}
|
||||
|
||||
func (q *querier) GetOAuth2ProviderAppSecretsByAppID(ctx context.Context, appID uuid.UUID) ([]database.OAuth2ProviderAppSecret, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOauth2AppSecret); err != nil {
|
||||
return []database.OAuth2ProviderAppSecret{}, err
|
||||
}
|
||||
return q.db.GetOAuth2ProviderAppSecretsByAppID(ctx, appID)
|
||||
@ -1269,14 +1318,14 @@ func (q *querier) GetOAuth2ProviderAppTokenByPrefix(ctx context.Context, hashPre
|
||||
if err != nil {
|
||||
return database.OAuth2ProviderAppToken{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(key.UserID.String())); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOauth2AppCodeToken.WithOwner(key.UserID.String())); err != nil {
|
||||
return database.OAuth2ProviderAppToken{}, err
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (q *querier) GetOAuth2ProviderApps(ctx context.Context) ([]database.OAuth2ProviderApp, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOAuth2ProviderApp); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOauth2App); err != nil {
|
||||
return []database.OAuth2ProviderApp{}, err
|
||||
}
|
||||
return q.db.GetOAuth2ProviderApps(ctx)
|
||||
@ -1285,7 +1334,7 @@ func (q *querier) GetOAuth2ProviderApps(ctx context.Context) ([]database.OAuth2P
|
||||
func (q *querier) GetOAuth2ProviderAppsByUserID(ctx context.Context, userID uuid.UUID) ([]database.GetOAuth2ProviderAppsByUserIDRow, error) {
|
||||
// This authz check is to make sure the caller can read all their own tokens.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead,
|
||||
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(userID.String())); err != nil {
|
||||
rbac.ResourceOauth2AppCodeToken.WithOwner(userID.String())); err != nil {
|
||||
return []database.GetOAuth2ProviderAppsByUserIDRow{}, err
|
||||
}
|
||||
return q.db.GetOAuth2ProviderAppsByUserID(ctx, userID)
|
||||
@ -1309,7 +1358,7 @@ func (q *querier) GetOrganizationByName(ctx context.Context, name string) (datab
|
||||
func (q *querier) GetOrganizationIDsByMemberIDs(ctx context.Context, ids []uuid.UUID) ([]database.GetOrganizationIDsByMemberIDsRow, error) {
|
||||
// TODO: This should be rewritten to return a list of database.OrganizationMember for consistent RBAC objects.
|
||||
// Currently this row returns a list of org ids per user, which is challenging to check against the RBAC system.
|
||||
return fetchWithPostFilter(q.auth, q.db.GetOrganizationIDsByMemberIDs)(ctx, ids)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetOrganizationIDsByMemberIDs)(ctx, ids)
|
||||
}
|
||||
|
||||
func (q *querier) GetOrganizationMemberByUserID(ctx context.Context, arg database.GetOrganizationMemberByUserIDParams) (database.OrganizationMember, error) {
|
||||
@ -1317,18 +1366,18 @@ func (q *querier) GetOrganizationMemberByUserID(ctx context.Context, arg databas
|
||||
}
|
||||
|
||||
func (q *querier) GetOrganizationMembershipsByUserID(ctx context.Context, userID uuid.UUID) ([]database.OrganizationMember, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetOrganizationMembershipsByUserID)(ctx, userID)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetOrganizationMembershipsByUserID)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetOrganizations(ctx context.Context) ([]database.Organization, error) {
|
||||
fetch := func(ctx context.Context, _ interface{}) ([]database.Organization, error) {
|
||||
return q.db.GetOrganizations(ctx)
|
||||
}
|
||||
return fetchWithPostFilter(q.auth, fetch)(ctx, nil)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, fetch)(ctx, nil)
|
||||
}
|
||||
|
||||
func (q *querier) GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]database.Organization, error) {
|
||||
return fetchWithPostFilter(q.auth, q.db.GetOrganizationsByUserID)(ctx, userID)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.GetOrganizationsByUserID)(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]database.ParameterSchema, error) {
|
||||
@ -1370,7 +1419,7 @@ func (q *querier) GetProvisionerDaemons(ctx context.Context) ([]database.Provisi
|
||||
fetch := func(ctx context.Context, _ interface{}) ([]database.ProvisionerDaemon, error) {
|
||||
return q.db.GetProvisionerDaemons(ctx)
|
||||
}
|
||||
return fetchWithPostFilter(q.auth, fetch)(ctx, nil)
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, fetch)(ctx, nil)
|
||||
}
|
||||
|
||||
func (q *querier) GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (database.ProvisionerJob, error) {
|
||||
@ -1496,31 +1545,15 @@ func (q *querier) GetTailnetTunnelPeerIDs(ctx context.Context, srcID uuid.UUID)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateAppInsights(ctx context.Context, arg database.GetTemplateAppInsightsParams) ([]database.GetTemplateAppInsightsRow, error) {
|
||||
// Used by TemplateAppInsights endpoint
|
||||
// For auditors, check read template_insights, and fall back to update template.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateAppInsights(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateAppInsightsByTemplate(ctx context.Context, arg database.GetTemplateAppInsightsByTemplateParams) ([]database.GetTemplateAppInsightsByTemplateRow, error) {
|
||||
// Only used by prometheus metrics, so we don't strictly need to check update template perms.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateAppInsightsByTemplate(ctx, arg)
|
||||
@ -1551,101 +1584,37 @@ func (q *querier) GetTemplateDAUs(ctx context.Context, arg database.GetTemplateD
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateInsights(ctx context.Context, arg database.GetTemplateInsightsParams) (database.GetTemplateInsightsRow, error) {
|
||||
// Used by TemplateInsights endpoint
|
||||
// For auditors, check read template_insights, and fall back to update template.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return database.GetTemplateInsightsRow{}, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
return database.GetTemplateInsightsRow{}, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
return database.GetTemplateInsightsRow{}, err
|
||||
}
|
||||
}
|
||||
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
|
||||
return database.GetTemplateInsightsRow{}, err
|
||||
}
|
||||
return q.db.GetTemplateInsights(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateInsightsByInterval(ctx context.Context, arg database.GetTemplateInsightsByIntervalParams) ([]database.GetTemplateInsightsByIntervalRow, error) {
|
||||
// Used by TemplateInsights endpoint
|
||||
// For auditors, check read template_insights, and fall back to update template.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateInsightsByInterval(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateInsightsByTemplate(ctx context.Context, arg database.GetTemplateInsightsByTemplateParams) ([]database.GetTemplateInsightsByTemplateRow, error) {
|
||||
// Only used by prometheus metrics collector. No need to check update template perms.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateInsightsByTemplate(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateParameterInsights(ctx context.Context, arg database.GetTemplateParameterInsightsParams) ([]database.GetTemplateParameterInsightsRow, error) {
|
||||
// Used by both insights endpoint and prometheus collector.
|
||||
// For auditors, check read template_insights, and fall back to update template.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateParameterInsights(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplateUsageStats(ctx context.Context, arg database.GetTemplateUsageStatsParams) ([]database.TemplateUsageStat, error) {
|
||||
// Used by dbrollup tests, use same safe-guard as other insights endpoints.
|
||||
// For auditors, check read template_insights, and fall back to update template.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := q.authorizeTemplateInsights(ctx, arg.TemplateIDs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateUsageStats(ctx, arg)
|
||||
}
|
||||
@ -1803,19 +1772,19 @@ func (q *querier) GetUnexpiredLicenses(ctx context.Context) ([]database.License,
|
||||
|
||||
func (q *querier) GetUserActivityInsights(ctx context.Context, arg database.GetUserActivityInsightsParams) ([]database.GetUserActivityInsightsRow, error) {
|
||||
// Used by insights endpoints. Need to check both for auditors and for regular users with template acl perms.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate.All()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@ -1840,19 +1809,19 @@ func (q *querier) GetUserCount(ctx context.Context) (int64, error) {
|
||||
|
||||
func (q *querier) GetUserLatencyInsights(ctx context.Context, arg database.GetUserLatencyInsightsParams) ([]database.GetUserLatencyInsightsRow, error) {
|
||||
// Used by insights endpoints. Need to check both for auditors and for regular users with template acl perms.
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceTemplateInsights); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate); err != nil {
|
||||
for _, templateID := range arg.TemplateIDs {
|
||||
template, err := q.db.GetTemplateByID(ctx, templateID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, template); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, template); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(arg.TemplateIDs) == 0 {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceTemplate.All()); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionViewInsights, rbac.ResourceTemplate.All()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@ -1886,7 +1855,11 @@ func (q *querier) GetUserWorkspaceBuildParameters(ctx context.Context, params da
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, u.UserWorkspaceBuildParametersObject()); err != nil {
|
||||
// This permission is a bit strange. Reading workspace build params should be a permission
|
||||
// on the workspace. However, this use case is to autofill a user's last input
|
||||
// to some parameter. So this is kind of a "user setting". For now, this will
|
||||
// be lumped in with user personal data. Subject to change.
|
||||
if err := q.authorizeContext(ctx, policy.ActionReadPersonal, u); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetUserWorkspaceBuildParameters(ctx, params)
|
||||
@ -2143,7 +2116,7 @@ func (q *querier) GetWorkspaceByWorkspaceAppID(ctx context.Context, workspaceApp
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceProxies(ctx context.Context) ([]database.WorkspaceProxy, error) {
|
||||
return fetchWithPostFilter(q.auth, func(ctx context.Context, _ interface{}) ([]database.WorkspaceProxy, error) {
|
||||
return fetchWithPostFilter(q.auth, policy.ActionRead, func(ctx context.Context, _ interface{}) ([]database.WorkspaceProxy, error) {
|
||||
return q.db.GetWorkspaceProxies(ctx)
|
||||
})(ctx, nil)
|
||||
}
|
||||
@ -2277,7 +2250,7 @@ func (q *querier) GetWorkspacesEligibleForTransition(ctx context.Context, now ti
|
||||
|
||||
func (q *querier) InsertAPIKey(ctx context.Context, arg database.InsertAPIKeyParams) (database.APIKey, error) {
|
||||
return insert(q.log, q.auth,
|
||||
rbac.ResourceAPIKey.WithOwner(arg.UserID.String()),
|
||||
rbac.ResourceApiKey.WithOwner(arg.UserID.String()),
|
||||
q.db.InsertAPIKey)(ctx, arg)
|
||||
}
|
||||
|
||||
@ -2312,7 +2285,7 @@ func (q *querier) InsertDeploymentID(ctx context.Context, value string) error {
|
||||
}
|
||||
|
||||
func (q *querier) InsertExternalAuthLink(ctx context.Context, arg database.InsertExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
return insert(q.log, q.auth, rbac.ResourceUserData.WithOwner(arg.UserID.String()).WithID(arg.UserID), q.db.InsertExternalAuthLink)(ctx, arg)
|
||||
return insertWithAction(q.log, q.auth, rbac.ResourceUser.WithID(arg.UserID).WithOwner(arg.UserID.String()), policy.ActionUpdatePersonal, q.db.InsertExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertFile(ctx context.Context, arg database.InsertFileParams) (database.File, error) {
|
||||
@ -2320,7 +2293,7 @@ func (q *querier) InsertFile(ctx context.Context, arg database.InsertFileParams)
|
||||
}
|
||||
|
||||
func (q *querier) InsertGitSSHKey(ctx context.Context, arg database.InsertGitSSHKeyParams) (database.GitSSHKey, error) {
|
||||
return insert(q.log, q.auth, rbac.ResourceUserData.WithOwner(arg.UserID.String()).WithID(arg.UserID), q.db.InsertGitSSHKey)(ctx, arg)
|
||||
return insertWithAction(q.log, q.auth, rbac.ResourceUser.WithOwner(arg.UserID.String()).WithID(arg.UserID), policy.ActionUpdatePersonal, q.db.InsertGitSSHKey)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertGroup(ctx context.Context, arg database.InsertGroupParams) (database.Group, error) {
|
||||
@ -2349,7 +2322,7 @@ func (q *querier) InsertMissingGroups(ctx context.Context, arg database.InsertMi
|
||||
}
|
||||
|
||||
func (q *querier) InsertOAuth2ProviderApp(ctx context.Context, arg database.InsertOAuth2ProviderAppParams) (database.OAuth2ProviderApp, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceOAuth2ProviderApp); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceOauth2App); err != nil {
|
||||
return database.OAuth2ProviderApp{}, err
|
||||
}
|
||||
return q.db.InsertOAuth2ProviderApp(ctx, arg)
|
||||
@ -2357,14 +2330,14 @@ func (q *querier) InsertOAuth2ProviderApp(ctx context.Context, arg database.Inse
|
||||
|
||||
func (q *querier) InsertOAuth2ProviderAppCode(ctx context.Context, arg database.InsertOAuth2ProviderAppCodeParams) (database.OAuth2ProviderAppCode, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate,
|
||||
rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(arg.UserID.String())); err != nil {
|
||||
rbac.ResourceOauth2AppCodeToken.WithOwner(arg.UserID.String())); err != nil {
|
||||
return database.OAuth2ProviderAppCode{}, err
|
||||
}
|
||||
return q.db.InsertOAuth2ProviderAppCode(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertOAuth2ProviderAppSecret(ctx context.Context, arg database.InsertOAuth2ProviderAppSecretParams) (database.OAuth2ProviderAppSecret, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceOauth2AppSecret); err != nil {
|
||||
return database.OAuth2ProviderAppSecret{}, err
|
||||
}
|
||||
return q.db.InsertOAuth2ProviderAppSecret(ctx, arg)
|
||||
@ -2375,7 +2348,7 @@ func (q *querier) InsertOAuth2ProviderAppToken(ctx context.Context, arg database
|
||||
if err != nil {
|
||||
return database.OAuth2ProviderAppToken{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(key.UserID.String())); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceOauth2AppCodeToken.WithOwner(key.UserID.String())); err != nil {
|
||||
return database.OAuth2ProviderAppToken{}, err
|
||||
}
|
||||
return q.db.InsertOAuth2ProviderAppToken(ctx, arg)
|
||||
@ -2561,12 +2534,14 @@ func (q *querier) InsertWorkspaceBuild(ctx context.Context, arg database.InsertW
|
||||
return xerrors.Errorf("get workspace by id: %w", err)
|
||||
}
|
||||
|
||||
var action policy.Action = policy.ActionUpdate
|
||||
var action policy.Action = policy.ActionWorkspaceStart
|
||||
if arg.Transition == database.WorkspaceTransitionDelete {
|
||||
action = policy.ActionDelete
|
||||
} else if arg.Transition == database.WorkspaceTransitionStop {
|
||||
action = policy.ActionWorkspaceStop
|
||||
}
|
||||
|
||||
if err = q.authorizeContext(ctx, action, w.WorkspaceBuildRBAC(arg.Transition)); err != nil {
|
||||
if err = q.authorizeContext(ctx, action, w); err != nil {
|
||||
return xerrors.Errorf("authorize context: %w", err)
|
||||
}
|
||||
|
||||
@ -2719,14 +2694,14 @@ func (q *querier) UpdateExternalAuthLink(ctx context.Context, arg database.Updat
|
||||
fetch := func(ctx context.Context, arg database.UpdateExternalAuthLinkParams) (database.ExternalAuthLink, error) {
|
||||
return q.db.GetExternalAuthLink(ctx, database.GetExternalAuthLinkParams{UserID: arg.UserID, ProviderID: arg.ProviderID})
|
||||
}
|
||||
return updateWithReturn(q.log, q.auth, fetch, q.db.UpdateExternalAuthLink)(ctx, arg)
|
||||
return fetchAndQuery(q.log, q.auth, policy.ActionUpdatePersonal, fetch, q.db.UpdateExternalAuthLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateGitSSHKey(ctx context.Context, arg database.UpdateGitSSHKeyParams) (database.GitSSHKey, error) {
|
||||
fetch := func(ctx context.Context, arg database.UpdateGitSSHKeyParams) (database.GitSSHKey, error) {
|
||||
return q.db.GetGitSSHKey(ctx, arg.UserID)
|
||||
}
|
||||
return updateWithReturn(q.log, q.auth, fetch, q.db.UpdateGitSSHKey)(ctx, arg)
|
||||
return fetchAndQuery(q.log, q.auth, policy.ActionUpdatePersonal, fetch, q.db.UpdateGitSSHKey)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateGroupByID(ctx context.Context, arg database.UpdateGroupByIDParams) (database.Group, error) {
|
||||
@ -2765,14 +2740,14 @@ func (q *querier) UpdateMemberRoles(ctx context.Context, arg database.UpdateMemb
|
||||
}
|
||||
|
||||
func (q *querier) UpdateOAuth2ProviderAppByID(ctx context.Context, arg database.UpdateOAuth2ProviderAppByIDParams) (database.OAuth2ProviderApp, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceOAuth2ProviderApp); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceOauth2App); err != nil {
|
||||
return database.OAuth2ProviderApp{}, err
|
||||
}
|
||||
return q.db.UpdateOAuth2ProviderAppByID(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateOAuth2ProviderAppSecretByID(ctx context.Context, arg database.UpdateOAuth2ProviderAppSecretByIDParams) (database.OAuth2ProviderAppSecret, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceOAuth2ProviderAppSecret); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceOauth2AppSecret); err != nil {
|
||||
return database.OAuth2ProviderAppSecret{}, err
|
||||
}
|
||||
return q.db.UpdateOAuth2ProviderAppSecretByID(ctx, arg)
|
||||
@ -2996,7 +2971,7 @@ func (q *querier) UpdateUserAppearanceSettings(ctx context.Context, arg database
|
||||
if err != nil {
|
||||
return database.User{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, u.UserDataRBACObject()); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdatePersonal, u); err != nil {
|
||||
return database.User{}, err
|
||||
}
|
||||
return q.db.UpdateUserAppearanceSettings(ctx, arg)
|
||||
@ -3012,10 +2987,10 @@ func (q *querier) UpdateUserHashedPassword(ctx context.Context, arg database.Upd
|
||||
return err
|
||||
}
|
||||
|
||||
err = q.authorizeContext(ctx, policy.ActionUpdate, user.UserDataRBACObject())
|
||||
err = q.authorizeContext(ctx, policy.ActionUpdatePersonal, user)
|
||||
if err != nil {
|
||||
// Admins can update passwords for other users.
|
||||
err = q.authorizeContext(ctx, policy.ActionUpdate, user.RBACObject())
|
||||
err = q.authorizeContext(ctx, policy.ActionUpdate, user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -3038,7 +3013,7 @@ func (q *querier) UpdateUserLink(ctx context.Context, arg database.UpdateUserLin
|
||||
LoginType: arg.LoginType,
|
||||
})
|
||||
}
|
||||
return updateWithReturn(q.log, q.auth, fetch, q.db.UpdateUserLink)(ctx, arg)
|
||||
return fetchAndQuery(q.log, q.auth, policy.ActionUpdatePersonal, fetch, q.db.UpdateUserLink)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateUserLinkedID(ctx context.Context, arg database.UpdateUserLinkedIDParams) (database.UserLink, error) {
|
||||
@ -3060,7 +3035,7 @@ func (q *querier) UpdateUserProfile(ctx context.Context, arg database.UpdateUser
|
||||
if err != nil {
|
||||
return database.User{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, u.UserDataRBACObject()); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdatePersonal, u); err != nil {
|
||||
return database.User{}, err
|
||||
}
|
||||
return q.db.UpdateUserProfile(ctx, arg)
|
||||
@ -3071,7 +3046,7 @@ func (q *querier) UpdateUserQuietHoursSchedule(ctx context.Context, arg database
|
||||
if err != nil {
|
||||
return database.User{}, err
|
||||
}
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, u.UserDataRBACObject()); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdatePersonal, u); err != nil {
|
||||
return database.User{}, err
|
||||
}
|
||||
return q.db.UpdateUserQuietHoursSchedule(ctx, arg)
|
||||
@ -3310,7 +3285,7 @@ func (q *querier) UpsertAppSecurityKey(ctx context.Context, data string) error {
|
||||
}
|
||||
|
||||
func (q *querier) UpsertApplicationName(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceDeploymentValues); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceDeploymentConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertApplicationName(ctx, value)
|
||||
@ -3324,7 +3299,7 @@ func (q *querier) UpsertDefaultProxy(ctx context.Context, arg database.UpsertDef
|
||||
}
|
||||
|
||||
func (q *querier) UpsertHealthSettings(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceDeploymentValues); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceDeploymentConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertHealthSettings(ctx, value)
|
||||
@ -3359,14 +3334,14 @@ func (q *querier) UpsertLastUpdateCheck(ctx context.Context, value string) error
|
||||
}
|
||||
|
||||
func (q *querier) UpsertLogoURL(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceDeploymentValues); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceDeploymentConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertLogoURL(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertNotificationBanners(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionCreate, rbac.ResourceDeploymentValues); err != nil {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceDeploymentConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertNotificationBanners(ctx, value)
|
||||
|
@ -218,7 +218,7 @@ func (s *MethodTestSuite) TestAPIKey() {
|
||||
UserID: u.ID,
|
||||
LoginType: database.LoginTypePassword,
|
||||
Scope: database.APIKeyScopeAll,
|
||||
}).Asserts(rbac.ResourceAPIKey.WithOwner(u.ID.String()), policy.ActionCreate)
|
||||
}).Asserts(rbac.ResourceApiKey.WithOwner(u.ID.String()), policy.ActionCreate)
|
||||
}))
|
||||
s.Run("UpdateAPIKeyByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
a, _ := dbgen.APIKey(s.T(), db, database.APIKey{})
|
||||
@ -230,21 +230,23 @@ func (s *MethodTestSuite) TestAPIKey() {
|
||||
a, _ := dbgen.APIKey(s.T(), db, database.APIKey{
|
||||
Scope: database.APIKeyScopeApplicationConnect,
|
||||
})
|
||||
check.Args(a.UserID).Asserts(rbac.ResourceAPIKey.WithOwner(a.UserID.String()), policy.ActionDelete).Returns()
|
||||
check.Args(a.UserID).Asserts(rbac.ResourceApiKey.WithOwner(a.UserID.String()), policy.ActionDelete).Returns()
|
||||
}))
|
||||
s.Run("DeleteExternalAuthLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
a := dbgen.ExternalAuthLink(s.T(), db, database.ExternalAuthLink{})
|
||||
check.Args(database.DeleteExternalAuthLinkParams{
|
||||
ProviderID: a.ProviderID,
|
||||
UserID: a.UserID,
|
||||
}).Asserts(a, policy.ActionDelete).Returns()
|
||||
}).Asserts(rbac.ResourceUserObject(a.UserID), policy.ActionUpdatePersonal).Returns()
|
||||
}))
|
||||
s.Run("GetExternalAuthLinksByUserID", s.Subtest(func(db database.Store, check *expects) {
|
||||
a := dbgen.ExternalAuthLink(s.T(), db, database.ExternalAuthLink{})
|
||||
b := dbgen.ExternalAuthLink(s.T(), db, database.ExternalAuthLink{
|
||||
UserID: a.UserID,
|
||||
})
|
||||
check.Args(a.UserID).Asserts(a, policy.ActionRead, b, policy.ActionRead)
|
||||
check.Args(a.UserID).Asserts(
|
||||
rbac.ResourceUserObject(a.UserID), policy.ActionReadPersonal,
|
||||
rbac.ResourceUserObject(b.UserID), policy.ActionReadPersonal)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -524,10 +526,10 @@ func (s *MethodTestSuite) TestLicense() {
|
||||
Asserts(rbac.ResourceLicense, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("UpsertLogoURL", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts(rbac.ResourceDeploymentValues, policy.ActionCreate)
|
||||
check.Args("value").Asserts(rbac.ResourceDeploymentConfig, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("UpsertNotificationBanners", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts(rbac.ResourceDeploymentValues, policy.ActionCreate)
|
||||
check.Args("value").Asserts(rbac.ResourceDeploymentConfig, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("GetLicenseByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
l, err := db.InsertLicense(context.Background(), database.InsertLicenseParams{
|
||||
@ -634,7 +636,7 @@ func (s *MethodTestSuite) TestOrganization() {
|
||||
UserID: u.ID,
|
||||
Roles: []string{rbac.RoleOrgAdmin(o.ID)},
|
||||
}).Asserts(
|
||||
rbac.ResourceRoleAssignment.InOrg(o.ID), policy.ActionCreate,
|
||||
rbac.ResourceAssignRole.InOrg(o.ID), policy.ActionAssign,
|
||||
rbac.ResourceOrganizationMember.InOrg(o.ID).WithID(u.ID), policy.ActionCreate)
|
||||
}))
|
||||
s.Run("UpdateMemberRoles", s.Subtest(func(db database.Store, check *expects) {
|
||||
@ -654,8 +656,8 @@ func (s *MethodTestSuite) TestOrganization() {
|
||||
OrgID: o.ID,
|
||||
}).Asserts(
|
||||
mem, policy.ActionRead,
|
||||
rbac.ResourceRoleAssignment.InOrg(o.ID), policy.ActionCreate, // org-mem
|
||||
rbac.ResourceRoleAssignment.InOrg(o.ID), policy.ActionDelete, // org-admin
|
||||
rbac.ResourceAssignRole.InOrg(o.ID), policy.ActionAssign, // org-mem
|
||||
rbac.ResourceAssignRole.InOrg(o.ID), policy.ActionDelete, // org-admin
|
||||
).Returns(out)
|
||||
}))
|
||||
}
|
||||
@ -942,31 +944,31 @@ func (s *MethodTestSuite) TestTemplate() {
|
||||
}).Asserts(t1, policy.ActionUpdate).Returns()
|
||||
}))
|
||||
s.Run("GetTemplateInsights", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateInsightsParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetTemplateInsightsParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetUserLatencyInsights", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetUserLatencyInsightsParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetUserLatencyInsightsParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetUserActivityInsights", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetUserActivityInsightsParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead).Errors(sql.ErrNoRows)
|
||||
check.Args(database.GetUserActivityInsightsParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights).Errors(sql.ErrNoRows)
|
||||
}))
|
||||
s.Run("GetTemplateParameterInsights", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateParameterInsightsParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetTemplateParameterInsightsParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetTemplateInsightsByInterval", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateInsightsByIntervalParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetTemplateInsightsByIntervalParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetTemplateInsightsByTemplate", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateInsightsByTemplateParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetTemplateInsightsByTemplateParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetTemplateAppInsights", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateAppInsightsParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetTemplateAppInsightsParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetTemplateAppInsightsByTemplate", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateAppInsightsByTemplateParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead)
|
||||
check.Args(database.GetTemplateAppInsightsByTemplateParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights)
|
||||
}))
|
||||
s.Run("GetTemplateUsageStats", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.GetTemplateUsageStatsParams{}).Asserts(rbac.ResourceTemplateInsights, policy.ActionRead).Errors(sql.ErrNoRows)
|
||||
check.Args(database.GetTemplateUsageStatsParams{}).Asserts(rbac.ResourceTemplate, policy.ActionViewInsights).Errors(sql.ErrNoRows)
|
||||
}))
|
||||
s.Run("UpsertTemplateUsageStats", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Asserts(rbac.ResourceSystem, policy.ActionUpdate)
|
||||
@ -982,7 +984,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
}))
|
||||
s.Run("DeleteAPIKeysByUserID", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(u.ID).Asserts(rbac.ResourceAPIKey.WithOwner(u.ID.String()), policy.ActionDelete).Returns()
|
||||
check.Args(u.ID).Asserts(rbac.ResourceApiKey.WithOwner(u.ID.String()), policy.ActionDelete).Returns()
|
||||
}))
|
||||
s.Run("GetQuotaAllowanceForUser", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
@ -1021,7 +1023,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
check.Args(database.InsertUserParams{
|
||||
ID: uuid.New(),
|
||||
LoginType: database.LoginTypePassword,
|
||||
}).Asserts(rbac.ResourceRoleAssignment, policy.ActionCreate, rbac.ResourceUser, policy.ActionCreate)
|
||||
}).Asserts(rbac.ResourceAssignRole, policy.ActionAssign, rbac.ResourceUser, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertUserLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
@ -1038,13 +1040,13 @@ func (s *MethodTestSuite) TestUser() {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.UpdateUserHashedPasswordParams{
|
||||
ID: u.ID,
|
||||
}).Asserts(u.UserDataRBACObject(), policy.ActionUpdate).Returns()
|
||||
}).Asserts(u, policy.ActionUpdatePersonal).Returns()
|
||||
}))
|
||||
s.Run("UpdateUserQuietHoursSchedule", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.UpdateUserQuietHoursScheduleParams{
|
||||
ID: u.ID,
|
||||
}).Asserts(u.UserDataRBACObject(), policy.ActionUpdate)
|
||||
}).Asserts(u, policy.ActionUpdatePersonal)
|
||||
}))
|
||||
s.Run("UpdateUserLastSeenAt", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
@ -1061,7 +1063,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
Email: u.Email,
|
||||
Username: u.Username,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}).Asserts(u.UserDataRBACObject(), policy.ActionUpdate).Returns(u)
|
||||
}).Asserts(u, policy.ActionUpdatePersonal).Returns(u)
|
||||
}))
|
||||
s.Run("GetUserWorkspaceBuildParameters", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
@ -1070,7 +1072,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
OwnerID: u.ID,
|
||||
TemplateID: uuid.UUID{},
|
||||
},
|
||||
).Asserts(u.UserWorkspaceBuildParametersObject(), policy.ActionRead).Returns(
|
||||
).Asserts(u, policy.ActionReadPersonal).Returns(
|
||||
[]database.GetUserWorkspaceBuildParametersRow{},
|
||||
)
|
||||
}))
|
||||
@ -1080,7 +1082,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
ID: u.ID,
|
||||
ThemePreference: u.ThemePreference,
|
||||
UpdatedAt: u.UpdatedAt,
|
||||
}).Asserts(u.UserDataRBACObject(), policy.ActionUpdate).Returns(u)
|
||||
}).Asserts(u, policy.ActionUpdatePersonal).Returns(u)
|
||||
}))
|
||||
s.Run("UpdateUserStatus", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
@ -1092,38 +1094,38 @@ func (s *MethodTestSuite) TestUser() {
|
||||
}))
|
||||
s.Run("DeleteGitSSHKey", s.Subtest(func(db database.Store, check *expects) {
|
||||
key := dbgen.GitSSHKey(s.T(), db, database.GitSSHKey{})
|
||||
check.Args(key.UserID).Asserts(key, policy.ActionDelete).Returns()
|
||||
check.Args(key.UserID).Asserts(rbac.ResourceUserObject(key.UserID), policy.ActionUpdatePersonal).Returns()
|
||||
}))
|
||||
s.Run("GetGitSSHKey", s.Subtest(func(db database.Store, check *expects) {
|
||||
key := dbgen.GitSSHKey(s.T(), db, database.GitSSHKey{})
|
||||
check.Args(key.UserID).Asserts(key, policy.ActionRead).Returns(key)
|
||||
check.Args(key.UserID).Asserts(rbac.ResourceUserObject(key.UserID), policy.ActionReadPersonal).Returns(key)
|
||||
}))
|
||||
s.Run("InsertGitSSHKey", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.InsertGitSSHKeyParams{
|
||||
UserID: u.ID,
|
||||
}).Asserts(rbac.ResourceUserData.WithID(u.ID).WithOwner(u.ID.String()), policy.ActionCreate)
|
||||
}).Asserts(u, policy.ActionUpdatePersonal)
|
||||
}))
|
||||
s.Run("UpdateGitSSHKey", s.Subtest(func(db database.Store, check *expects) {
|
||||
key := dbgen.GitSSHKey(s.T(), db, database.GitSSHKey{})
|
||||
check.Args(database.UpdateGitSSHKeyParams{
|
||||
UserID: key.UserID,
|
||||
UpdatedAt: key.UpdatedAt,
|
||||
}).Asserts(key, policy.ActionUpdate).Returns(key)
|
||||
}).Asserts(rbac.ResourceUserObject(key.UserID), policy.ActionUpdatePersonal).Returns(key)
|
||||
}))
|
||||
s.Run("GetExternalAuthLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
link := dbgen.ExternalAuthLink(s.T(), db, database.ExternalAuthLink{})
|
||||
check.Args(database.GetExternalAuthLinkParams{
|
||||
ProviderID: link.ProviderID,
|
||||
UserID: link.UserID,
|
||||
}).Asserts(link, policy.ActionRead).Returns(link)
|
||||
}).Asserts(rbac.ResourceUserObject(link.UserID), policy.ActionReadPersonal).Returns(link)
|
||||
}))
|
||||
s.Run("InsertExternalAuthLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.InsertExternalAuthLinkParams{
|
||||
ProviderID: uuid.NewString(),
|
||||
UserID: u.ID,
|
||||
}).Asserts(rbac.ResourceUserData.WithOwner(u.ID.String()).WithID(u.ID), policy.ActionCreate)
|
||||
}).Asserts(u, policy.ActionUpdatePersonal)
|
||||
}))
|
||||
s.Run("UpdateExternalAuthLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
link := dbgen.ExternalAuthLink(s.T(), db, database.ExternalAuthLink{})
|
||||
@ -1134,7 +1136,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
OAuthRefreshToken: link.OAuthRefreshToken,
|
||||
OAuthExpiry: link.OAuthExpiry,
|
||||
UpdatedAt: link.UpdatedAt,
|
||||
}).Asserts(link, policy.ActionUpdate).Returns(link)
|
||||
}).Asserts(rbac.ResourceUserObject(link.UserID), policy.ActionUpdatePersonal).Returns(link)
|
||||
}))
|
||||
s.Run("UpdateUserLink", s.Subtest(func(db database.Store, check *expects) {
|
||||
link := dbgen.UserLink(s.T(), db, database.UserLink{})
|
||||
@ -1145,7 +1147,7 @@ func (s *MethodTestSuite) TestUser() {
|
||||
UserID: link.UserID,
|
||||
LoginType: link.LoginType,
|
||||
DebugContext: json.RawMessage("{}"),
|
||||
}).Asserts(link, policy.ActionUpdate).Returns(link)
|
||||
}).Asserts(rbac.ResourceUserObject(link.UserID), policy.ActionUpdatePersonal).Returns(link)
|
||||
}))
|
||||
s.Run("UpdateUserRoles", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{RBACRoles: []string{rbac.RoleTemplateAdmin()}})
|
||||
@ -1156,8 +1158,8 @@ func (s *MethodTestSuite) TestUser() {
|
||||
ID: u.ID,
|
||||
}).Asserts(
|
||||
u, policy.ActionRead,
|
||||
rbac.ResourceRoleAssignment, policy.ActionCreate,
|
||||
rbac.ResourceRoleAssignment, policy.ActionDelete,
|
||||
rbac.ResourceAssignRole, policy.ActionAssign,
|
||||
rbac.ResourceAssignRole, policy.ActionDelete,
|
||||
).Returns(o)
|
||||
}))
|
||||
s.Run("AllUserIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
@ -1430,7 +1432,18 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
WorkspaceID: w.ID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
Reason: database.BuildReasonInitiator,
|
||||
}).Asserts(w.WorkspaceBuildRBAC(database.WorkspaceTransitionStart), policy.ActionUpdate)
|
||||
}).Asserts(w, policy.ActionWorkspaceStart)
|
||||
}))
|
||||
s.Run("Stop/InsertWorkspaceBuild", s.Subtest(func(db database.Store, check *expects) {
|
||||
t := dbgen.Template(s.T(), db, database.Template{})
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{
|
||||
TemplateID: t.ID,
|
||||
})
|
||||
check.Args(database.InsertWorkspaceBuildParams{
|
||||
WorkspaceID: w.ID,
|
||||
Transition: database.WorkspaceTransitionStop,
|
||||
Reason: database.BuildReasonInitiator,
|
||||
}).Asserts(w, policy.ActionWorkspaceStop)
|
||||
}))
|
||||
s.Run("Start/RequireActiveVersion/VersionMismatch/InsertWorkspaceBuild", s.Subtest(func(db database.Store, check *expects) {
|
||||
t := dbgen.Template(s.T(), db, database.Template{})
|
||||
@ -1452,7 +1465,7 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
Reason: database.BuildReasonInitiator,
|
||||
TemplateVersionID: v.ID,
|
||||
}).Asserts(
|
||||
w.WorkspaceBuildRBAC(database.WorkspaceTransitionStart), policy.ActionUpdate,
|
||||
w, policy.ActionWorkspaceStart,
|
||||
t, policy.ActionUpdate,
|
||||
)
|
||||
}))
|
||||
@ -1480,7 +1493,7 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
Reason: database.BuildReasonInitiator,
|
||||
TemplateVersionID: v.ID,
|
||||
}).Asserts(
|
||||
w.WorkspaceBuildRBAC(database.WorkspaceTransitionStart), policy.ActionUpdate,
|
||||
w, policy.ActionWorkspaceStart,
|
||||
)
|
||||
}))
|
||||
s.Run("Delete/InsertWorkspaceBuild", s.Subtest(func(db database.Store, check *expects) {
|
||||
@ -1489,7 +1502,7 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
WorkspaceID: w.ID,
|
||||
Transition: database.WorkspaceTransitionDelete,
|
||||
Reason: database.BuildReasonInitiator,
|
||||
}).Asserts(w.WorkspaceBuildRBAC(database.WorkspaceTransitionDelete), policy.ActionDelete)
|
||||
}).Asserts(w, policy.ActionDelete)
|
||||
}))
|
||||
s.Run("InsertWorkspaceBuildParameters", s.Subtest(func(db database.Store, check *expects) {
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
@ -2204,13 +2217,13 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
check.Args().Asserts()
|
||||
}))
|
||||
s.Run("UpsertApplicationName", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("").Asserts(rbac.ResourceDeploymentValues, policy.ActionCreate)
|
||||
check.Args("").Asserts(rbac.ResourceDeploymentConfig, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("GetHealthSettings", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts()
|
||||
}))
|
||||
s.Run("UpsertHealthSettings", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("foo").Asserts(rbac.ResourceDeploymentValues, policy.ActionCreate)
|
||||
check.Args("foo").Asserts(rbac.ResourceDeploymentConfig, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("GetDeploymentWorkspaceAgentStats", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(time.Time{}).Asserts()
|
||||
@ -2335,11 +2348,11 @@ func (s *MethodTestSuite) TestOAuth2ProviderApps() {
|
||||
dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{Name: "first"}),
|
||||
dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{Name: "last"}),
|
||||
}
|
||||
check.Args().Asserts(rbac.ResourceOAuth2ProviderApp, policy.ActionRead).Returns(apps)
|
||||
check.Args().Asserts(rbac.ResourceOauth2App, policy.ActionRead).Returns(apps)
|
||||
}))
|
||||
s.Run("GetOAuth2ProviderAppByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
check.Args(app.ID).Asserts(rbac.ResourceOAuth2ProviderApp, policy.ActionRead).Returns(app)
|
||||
check.Args(app.ID).Asserts(rbac.ResourceOauth2App, policy.ActionRead).Returns(app)
|
||||
}))
|
||||
s.Run("GetOAuth2ProviderAppsByUserID", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
@ -2357,7 +2370,7 @@ func (s *MethodTestSuite) TestOAuth2ProviderApps() {
|
||||
APIKeyID: key.ID,
|
||||
})
|
||||
}
|
||||
check.Args(user.ID).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), policy.ActionRead).Returns([]database.GetOAuth2ProviderAppsByUserIDRow{
|
||||
check.Args(user.ID).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionRead).Returns([]database.GetOAuth2ProviderAppsByUserIDRow{
|
||||
{
|
||||
OAuth2ProviderApp: database.OAuth2ProviderApp{
|
||||
ID: app.ID,
|
||||
@ -2370,7 +2383,7 @@ func (s *MethodTestSuite) TestOAuth2ProviderApps() {
|
||||
})
|
||||
}))
|
||||
s.Run("InsertOAuth2ProviderApp", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertOAuth2ProviderAppParams{}).Asserts(rbac.ResourceOAuth2ProviderApp, policy.ActionCreate)
|
||||
check.Args(database.InsertOAuth2ProviderAppParams{}).Asserts(rbac.ResourceOauth2App, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("UpdateOAuth2ProviderAppByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
@ -2381,11 +2394,11 @@ func (s *MethodTestSuite) TestOAuth2ProviderApps() {
|
||||
Name: app.Name,
|
||||
CallbackURL: app.CallbackURL,
|
||||
UpdatedAt: app.UpdatedAt,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderApp, policy.ActionUpdate).Returns(app)
|
||||
}).Asserts(rbac.ResourceOauth2App, policy.ActionUpdate).Returns(app)
|
||||
}))
|
||||
s.Run("DeleteOAuth2ProviderAppByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
check.Args(app.ID).Asserts(rbac.ResourceOAuth2ProviderApp, policy.ActionDelete)
|
||||
check.Args(app.ID).Asserts(rbac.ResourceOauth2App, policy.ActionDelete)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -2405,27 +2418,27 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppSecrets() {
|
||||
_ = dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
|
||||
AppID: app2.ID,
|
||||
})
|
||||
check.Args(app1.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, policy.ActionRead).Returns(secrets)
|
||||
check.Args(app1.ID).Asserts(rbac.ResourceOauth2AppSecret, policy.ActionRead).Returns(secrets)
|
||||
}))
|
||||
s.Run("GetOAuth2ProviderAppSecretByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
|
||||
AppID: app.ID,
|
||||
})
|
||||
check.Args(secret.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, policy.ActionRead).Returns(secret)
|
||||
check.Args(secret.ID).Asserts(rbac.ResourceOauth2AppSecret, policy.ActionRead).Returns(secret)
|
||||
}))
|
||||
s.Run("GetOAuth2ProviderAppSecretByPrefix", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
|
||||
AppID: app.ID,
|
||||
})
|
||||
check.Args(secret.SecretPrefix).Asserts(rbac.ResourceOAuth2ProviderAppSecret, policy.ActionRead).Returns(secret)
|
||||
check.Args(secret.SecretPrefix).Asserts(rbac.ResourceOauth2AppSecret, policy.ActionRead).Returns(secret)
|
||||
}))
|
||||
s.Run("InsertOAuth2ProviderAppSecret", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
check.Args(database.InsertOAuth2ProviderAppSecretParams{
|
||||
AppID: app.ID,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderAppSecret, policy.ActionCreate)
|
||||
}).Asserts(rbac.ResourceOauth2AppSecret, policy.ActionCreate)
|
||||
}))
|
||||
s.Run("UpdateOAuth2ProviderAppSecretByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
@ -2436,14 +2449,14 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppSecrets() {
|
||||
check.Args(database.UpdateOAuth2ProviderAppSecretByIDParams{
|
||||
ID: secret.ID,
|
||||
LastUsedAt: secret.LastUsedAt,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderAppSecret, policy.ActionUpdate).Returns(secret)
|
||||
}).Asserts(rbac.ResourceOauth2AppSecret, policy.ActionUpdate).Returns(secret)
|
||||
}))
|
||||
s.Run("DeleteOAuth2ProviderAppSecretByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
app := dbgen.OAuth2ProviderApp(s.T(), db, database.OAuth2ProviderApp{})
|
||||
secret := dbgen.OAuth2ProviderAppSecret(s.T(), db, database.OAuth2ProviderAppSecret{
|
||||
AppID: app.ID,
|
||||
})
|
||||
check.Args(secret.ID).Asserts(rbac.ResourceOAuth2ProviderAppSecret, policy.ActionDelete)
|
||||
check.Args(secret.ID).Asserts(rbac.ResourceOauth2AppSecret, policy.ActionDelete)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -2472,7 +2485,7 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppCodes() {
|
||||
check.Args(database.InsertOAuth2ProviderAppCodeParams{
|
||||
AppID: app.ID,
|
||||
UserID: user.ID,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), policy.ActionCreate)
|
||||
}).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionCreate)
|
||||
}))
|
||||
s.Run("DeleteOAuth2ProviderAppCodeByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
@ -2495,7 +2508,7 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppCodes() {
|
||||
check.Args(database.DeleteOAuth2ProviderAppCodesByAppAndUserIDParams{
|
||||
AppID: app.ID,
|
||||
UserID: user.ID,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), policy.ActionDelete)
|
||||
}).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionDelete)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -2512,7 +2525,7 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppTokens() {
|
||||
check.Args(database.InsertOAuth2ProviderAppTokenParams{
|
||||
AppSecretID: secret.ID,
|
||||
APIKeyID: key.ID,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), policy.ActionCreate)
|
||||
}).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionCreate)
|
||||
}))
|
||||
s.Run("GetOAuth2ProviderAppTokenByPrefix", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
@ -2527,7 +2540,7 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppTokens() {
|
||||
AppSecretID: secret.ID,
|
||||
APIKeyID: key.ID,
|
||||
})
|
||||
check.Args(token.HashPrefix).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), policy.ActionRead)
|
||||
check.Args(token.HashPrefix).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionRead)
|
||||
}))
|
||||
s.Run("DeleteOAuth2ProviderAppTokensByAppAndUserID", s.Subtest(func(db database.Store, check *expects) {
|
||||
user := dbgen.User(s.T(), db, database.User{})
|
||||
@ -2547,6 +2560,6 @@ func (s *MethodTestSuite) TestOAuth2ProviderAppTokens() {
|
||||
check.Args(database.DeleteOAuth2ProviderAppTokensByAppAndUserIDParams{
|
||||
AppID: app.ID,
|
||||
UserID: user.ID,
|
||||
}).Asserts(rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(user.ID.String()), policy.ActionDelete)
|
||||
}).Asserts(rbac.ResourceOauth2AppCodeToken.WithOwner(user.ID.String()), policy.ActionDelete)
|
||||
}))
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func (s APIKeyScope) ToRBAC() rbac.ScopeName {
|
||||
}
|
||||
|
||||
func (k APIKey) RBACObject() rbac.Object {
|
||||
return rbac.ResourceAPIKey.WithIDString(k.ID).
|
||||
return rbac.ResourceApiKey.WithIDString(k.ID).
|
||||
WithOwner(k.UserID.String())
|
||||
}
|
||||
|
||||
@ -154,51 +154,16 @@ func (w GetWorkspaceByAgentIDRow) RBACObject() rbac.Object {
|
||||
}
|
||||
|
||||
func (w Workspace) RBACObject() rbac.Object {
|
||||
// If a workspace is locked it cannot be accessed.
|
||||
if w.DormantAt.Valid {
|
||||
return w.DormantRBAC()
|
||||
}
|
||||
|
||||
return rbac.ResourceWorkspace.WithID(w.ID).
|
||||
InOrg(w.OrganizationID).
|
||||
WithOwner(w.OwnerID.String())
|
||||
}
|
||||
|
||||
func (w Workspace) ExecutionRBAC() rbac.Object {
|
||||
// If a workspace is locked it cannot be accessed.
|
||||
if w.DormantAt.Valid {
|
||||
return w.DormantRBAC()
|
||||
}
|
||||
|
||||
return rbac.ResourceWorkspaceExecution.
|
||||
WithID(w.ID).
|
||||
InOrg(w.OrganizationID).
|
||||
WithOwner(w.OwnerID.String())
|
||||
}
|
||||
|
||||
func (w Workspace) ApplicationConnectRBAC() rbac.Object {
|
||||
// If a workspace is locked it cannot be accessed.
|
||||
if w.DormantAt.Valid {
|
||||
return w.DormantRBAC()
|
||||
}
|
||||
|
||||
return rbac.ResourceWorkspaceApplicationConnect.
|
||||
WithID(w.ID).
|
||||
InOrg(w.OrganizationID).
|
||||
WithOwner(w.OwnerID.String())
|
||||
}
|
||||
|
||||
func (w Workspace) WorkspaceBuildRBAC(transition WorkspaceTransition) rbac.Object {
|
||||
// If a workspace is dormant it cannot be built.
|
||||
// However we need to allow stopping a workspace by a caller once a workspace
|
||||
// is locked (e.g. for autobuild). Additionally, if a user wants to delete
|
||||
// a locked workspace, they shouldn't have to have it unlocked first.
|
||||
if w.DormantAt.Valid && transition != WorkspaceTransitionStop &&
|
||||
transition != WorkspaceTransitionDelete {
|
||||
return w.DormantRBAC()
|
||||
}
|
||||
|
||||
return rbac.ResourceWorkspaceBuild.
|
||||
WithID(w.ID).
|
||||
InOrg(w.OrganizationID).
|
||||
WithOwner(w.OwnerID.String())
|
||||
}
|
||||
|
||||
func (w Workspace) DormantRBAC() rbac.Object {
|
||||
return rbac.ResourceWorkspaceDormant.
|
||||
WithID(w.ID).
|
||||
@ -246,32 +211,17 @@ func (f File) RBACObject() rbac.Object {
|
||||
}
|
||||
|
||||
// RBACObject returns the RBAC object for the site wide user resource.
|
||||
// If you are trying to get the RBAC object for the UserData, use
|
||||
// u.UserDataRBACObject() instead.
|
||||
func (u User) RBACObject() rbac.Object {
|
||||
return rbac.ResourceUserObject(u.ID)
|
||||
}
|
||||
|
||||
func (u User) UserDataRBACObject() rbac.Object {
|
||||
return rbac.ResourceUserData.WithID(u.ID).WithOwner(u.ID.String())
|
||||
}
|
||||
|
||||
func (u User) UserWorkspaceBuildParametersObject() rbac.Object {
|
||||
return rbac.ResourceUserWorkspaceBuildParameters.WithID(u.ID).WithOwner(u.ID.String())
|
||||
}
|
||||
|
||||
func (u GetUsersRow) RBACObject() rbac.Object {
|
||||
return rbac.ResourceUserObject(u.ID)
|
||||
}
|
||||
|
||||
func (u GitSSHKey) RBACObject() rbac.Object {
|
||||
return rbac.ResourceUserData.WithID(u.UserID).WithOwner(u.UserID.String())
|
||||
}
|
||||
|
||||
func (u ExternalAuthLink) RBACObject() rbac.Object {
|
||||
// I assume UserData is ok?
|
||||
return rbac.ResourceUserData.WithID(u.UserID).WithOwner(u.UserID.String())
|
||||
}
|
||||
func (u GitSSHKey) RBACObject() rbac.Object { return rbac.ResourceUserObject(u.UserID) }
|
||||
func (u ExternalAuthLink) RBACObject() rbac.Object { return rbac.ResourceUserObject(u.UserID) }
|
||||
func (u UserLink) RBACObject() rbac.Object { return rbac.ResourceUserObject(u.UserID) }
|
||||
|
||||
func (u ExternalAuthLink) OAuthToken() *oauth2.Token {
|
||||
return &oauth2.Token{
|
||||
@ -281,25 +231,20 @@ func (u ExternalAuthLink) OAuthToken() *oauth2.Token {
|
||||
}
|
||||
}
|
||||
|
||||
func (u UserLink) RBACObject() rbac.Object {
|
||||
// I assume UserData is ok?
|
||||
return rbac.ResourceUserData.WithOwner(u.UserID.String()).WithID(u.UserID)
|
||||
}
|
||||
|
||||
func (l License) RBACObject() rbac.Object {
|
||||
return rbac.ResourceLicense.WithIDString(strconv.FormatInt(int64(l.ID), 10))
|
||||
}
|
||||
|
||||
func (c OAuth2ProviderAppCode) RBACObject() rbac.Object {
|
||||
return rbac.ResourceOAuth2ProviderAppCodeToken.WithOwner(c.UserID.String())
|
||||
return rbac.ResourceOauth2AppCodeToken.WithOwner(c.UserID.String())
|
||||
}
|
||||
|
||||
func (OAuth2ProviderAppSecret) RBACObject() rbac.Object {
|
||||
return rbac.ResourceOAuth2ProviderAppSecret
|
||||
return rbac.ResourceOauth2AppSecret
|
||||
}
|
||||
|
||||
func (OAuth2ProviderApp) RBACObject() rbac.Object {
|
||||
return rbac.ResourceOAuth2ProviderApp
|
||||
return rbac.ResourceOauth2App
|
||||
}
|
||||
|
||||
func (a GetOAuth2ProviderAppsByUserIDRow) RBACObject() rbac.Object {
|
||||
|
Reference in New Issue
Block a user