refactor(dbauthz): add authz for system-level functions (#6513)

- Introduces rbac.ResourceSystem
- Grants system.* to system and provisionerd rbac subjects
- Updates dbauthz system queries where applicable
- coderd: Avoid index out of bounds in api.workspaceBuilds
- dbauthz: move GetUsersByIDs out of system, modify RBAC check to ResourceUser
- workspaceapps: Add test case for when owner of app is not found
This commit is contained in:
Cian Johnston
2023-03-10 18:09:28 +00:00
committed by GitHub
parent 1db2b12b8e
commit 144f374f60
17 changed files with 470 additions and 200 deletions

View File

@ -12,6 +12,7 @@ import (
"cdr.dev/slog"
"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/database/dbauthz"
"github.com/coder/coder/codersdk"
)
@ -39,12 +40,14 @@ func Entitlements(
}
}
licenses, err := db.GetUnexpiredLicenses(ctx)
// nolint:gocritic // Getting unexpired licenses is a system function.
licenses, err := db.GetUnexpiredLicenses(dbauthz.AsSystemRestricted(ctx))
if err != nil {
return entitlements, err
}
activeUserCount, err := db.GetActiveUserCount(ctx)
// nolint:gocritic // Getting active user count is a system function.
activeUserCount, err := db.GetActiveUserCount(dbauthz.AsSystemRestricted(ctx))
if err != nil {
return entitlements, xerrors.Errorf("query active user count: %w", err)
}

View File

@ -11,6 +11,7 @@ import (
"github.com/coder/coder/coderd/coderdtest"
"github.com/coder/coder/coderd/provisionerdserver"
"github.com/coder/coder/coderd/rbac"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/enterprise/coderd/coderdenttest"
"github.com/coder/coder/enterprise/coderd/license"
@ -20,6 +21,22 @@ import (
func TestProvisionerDaemonServe(t *testing.T) {
t.Parallel()
t.Run("OK", func(t *testing.T) {
t.Parallel()
client := coderdenttest.New(t, nil)
user := coderdtest.CreateFirstUser(t, client)
coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{
Features: license.Features{
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
srv, err := client.ServeProvisionerDaemon(context.Background(), user.OrganizationID, []codersdk.ProvisionerType{
codersdk.ProvisionerTypeEcho,
}, map[string]string{})
require.NoError(t, err)
srv.DRPCConn().Close()
})
t.Run("NoLicense", func(t *testing.T) {
t.Parallel()
client := coderdenttest.New(t, nil)
@ -42,11 +59,16 @@ func TestProvisionerDaemonServe(t *testing.T) {
codersdk.FeatureExternalProvisionerDaemons: 1,
},
})
srv, err := client.ServeProvisionerDaemon(context.Background(), user.OrganizationID, []codersdk.ProvisionerType{
another, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleOrgAdmin(user.OrganizationID))
_, err := another.ServeProvisionerDaemon(context.Background(), user.OrganizationID, []codersdk.ProvisionerType{
codersdk.ProvisionerTypeEcho,
}, map[string]string{})
require.NoError(t, err)
srv.DRPCConn().Close()
}, map[string]string{
provisionerdserver.TagScope: provisionerdserver.ScopeOrganization,
})
require.Error(t, err)
var apiError *codersdk.Error
require.ErrorAs(t, err, &apiError)
require.Equal(t, http.StatusForbidden, apiError.StatusCode())
})
t.Run("OrganizationNoPerms", func(t *testing.T) {