mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
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:
@ -115,17 +115,17 @@ func ActorFromContext(ctx context.Context) (rbac.Subject, bool) {
|
||||
return a, ok
|
||||
}
|
||||
|
||||
// AsProvisionerd returns a context with an actor that has permissions required
|
||||
// for provisionerd to function.
|
||||
func AsProvisionerd(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, rbac.Subject{
|
||||
var (
|
||||
subjectProvisionerd = rbac.Subject{
|
||||
ID: uuid.Nil.String(),
|
||||
Roles: rbac.Roles([]rbac.Role{
|
||||
{
|
||||
Name: "provisionerd",
|
||||
DisplayName: "Provisioner Daemon",
|
||||
Site: rbac.Permissions(map[string][]rbac.Action{
|
||||
// TODO: Add ProvisionerJob resource type.
|
||||
rbac.ResourceFile.Type: {rbac.ActionRead},
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {rbac.ActionRead, rbac.ActionUpdate},
|
||||
rbac.ResourceUser.Type: {rbac.ActionRead},
|
||||
rbac.ResourceWorkspace.Type: {rbac.ActionRead, rbac.ActionUpdate, rbac.ActionDelete},
|
||||
@ -135,20 +135,15 @@ func AsProvisionerd(ctx context.Context) context.Context {
|
||||
},
|
||||
}),
|
||||
Scope: rbac.ScopeAll,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// AsAutostart returns a context with an actor that has permissions required
|
||||
// for autostart to function.
|
||||
func AsAutostart(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, rbac.Subject{
|
||||
}
|
||||
subjectAutostart = rbac.Subject{
|
||||
ID: uuid.Nil.String(),
|
||||
Roles: rbac.Roles([]rbac.Role{
|
||||
{
|
||||
Name: "autostart",
|
||||
DisplayName: "Autostart Daemon",
|
||||
Site: rbac.Permissions(map[string][]rbac.Action{
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceTemplate.Type: {rbac.ActionRead, rbac.ActionUpdate},
|
||||
rbac.ResourceWorkspace.Type: {rbac.ActionRead, rbac.ActionUpdate},
|
||||
}),
|
||||
@ -157,14 +152,8 @@ func AsAutostart(ctx context.Context) context.Context {
|
||||
},
|
||||
}),
|
||||
Scope: rbac.ScopeAll,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// AsSystemRestricted returns a context with an actor that has permissions
|
||||
// required for various system operations (login, logout, metrics cache).
|
||||
func AsSystemRestricted(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, rbac.Subject{
|
||||
}
|
||||
subjectSystemRestricted = rbac.Subject{
|
||||
ID: uuid.Nil.String(),
|
||||
Roles: rbac.Roles([]rbac.Role{
|
||||
{
|
||||
@ -175,6 +164,7 @@ func AsSystemRestricted(ctx context.Context) context.Context {
|
||||
rbac.ResourceAPIKey.Type: {rbac.ActionCreate, rbac.ActionUpdate, rbac.ActionDelete},
|
||||
rbac.ResourceGroup.Type: {rbac.ActionCreate, rbac.ActionUpdate},
|
||||
rbac.ResourceRoleAssignment.Type: {rbac.ActionCreate},
|
||||
rbac.ResourceSystem.Type: {rbac.WildcardSymbol},
|
||||
rbac.ResourceOrganization.Type: {rbac.ActionCreate},
|
||||
rbac.ResourceOrganizationMember.Type: {rbac.ActionCreate},
|
||||
rbac.ResourceOrgRoleAssignment.Type: {rbac.ActionCreate},
|
||||
@ -187,8 +177,25 @@ func AsSystemRestricted(ctx context.Context) context.Context {
|
||||
},
|
||||
}),
|
||||
Scope: rbac.ScopeAll,
|
||||
},
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
// AsProvisionerd returns a context with an actor that has permissions required
|
||||
// for provisionerd to function.
|
||||
func AsProvisionerd(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, subjectProvisionerd)
|
||||
}
|
||||
|
||||
// AsAutostart returns a context with an actor that has permissions required
|
||||
// for autostart to function.
|
||||
func AsAutostart(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, subjectAutostart)
|
||||
}
|
||||
|
||||
// AsSystemRestricted returns a context with an actor that has permissions
|
||||
// required for various system operations (login, logout, metrics cache).
|
||||
func AsSystemRestricted(ctx context.Context) context.Context {
|
||||
return context.WithValue(ctx, authContextKey{}, subjectSystemRestricted)
|
||||
}
|
||||
|
||||
var AsRemoveActor = rbac.Subject{
|
||||
|
@ -963,6 +963,18 @@ func (q *querier) GetUserByID(ctx context.Context, id uuid.UUID) (database.User,
|
||||
return fetch(q.log, q.auth, q.db.GetUserByID)(ctx, id)
|
||||
}
|
||||
|
||||
// GetUsersByIDs is only used for usernames on workspace return data.
|
||||
// This function should be replaced by joining this data to the workspace query
|
||||
// itself.
|
||||
func (q *querier) GetUsersByIDs(ctx context.Context, ids []uuid.UUID) ([]database.User, error) {
|
||||
for _, uid := range ids {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceUser.WithID(uid)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return q.db.GetUsersByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
func (q *querier) GetAuthorizedUserCount(ctx context.Context, arg database.GetFilteredUserCountParams, prepared rbac.PreparedAuthorized) (int64, error) {
|
||||
return q.db.GetAuthorizedUserCount(ctx, arg, prepared)
|
||||
}
|
||||
|
@ -282,11 +282,6 @@ func (s *MethodTestSuite) TestProvsionerJob() {
|
||||
check.Args(database.UpdateProvisionerJobWithCancelByIDParams{ID: j.ID}).
|
||||
Asserts(v.RBACObject(tpl), []rbac.Action{rbac.ActionRead, rbac.ActionUpdate}).Returns()
|
||||
}))
|
||||
s.Run("GetProvisionerJobsByIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
a := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
b := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
check.Args([]uuid.UUID{a.ID, b.ID}).Asserts().Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("GetProvisionerLogsByIDBetween", s.Subtest(func(db database.Store, check *expects) {
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{
|
||||
@ -619,22 +614,6 @@ func (s *MethodTestSuite) TestTemplate() {
|
||||
})
|
||||
check.Args(tv.ID).Asserts(t1, rbac.ActionRead).Returns(tv)
|
||||
}))
|
||||
s.Run("GetTemplateVersionsByIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
t1 := dbgen.Template(s.T(), db, database.Template{})
|
||||
t2 := dbgen.Template(s.T(), db, database.Template{})
|
||||
tv1 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: t1.ID, Valid: true},
|
||||
})
|
||||
tv2 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: t2.ID, Valid: true},
|
||||
})
|
||||
tv3 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: t2.ID, Valid: true},
|
||||
})
|
||||
check.Args([]uuid.UUID{tv1.ID, tv2.ID, tv3.ID}).
|
||||
Asserts( /*t1, rbac.ActionRead, t2, rbac.ActionRead*/ ).
|
||||
Returns(slice.New(tv1, tv2, tv3))
|
||||
}))
|
||||
s.Run("GetTemplateVersionsByTemplateID", s.Subtest(func(db database.Store, check *expects) {
|
||||
t1 := dbgen.Template(s.T(), db, database.Template{})
|
||||
a := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
@ -784,6 +763,13 @@ func (s *MethodTestSuite) TestUser() {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(u.ID).Asserts(u, rbac.ActionRead).Returns(u)
|
||||
}))
|
||||
s.Run("GetUsersByIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
a := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now().Add(-time.Hour)})
|
||||
b := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now()})
|
||||
check.Args([]uuid.UUID{a.ID, b.ID}).
|
||||
Asserts(a, rbac.ActionRead, b, rbac.ActionRead).
|
||||
Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("GetAuthorizedUserCount", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(database.GetFilteredUserCountParams{}, emptyPreparedAuthorized{}).Asserts().Returns(int64(1))
|
||||
@ -803,13 +789,6 @@ func (s *MethodTestSuite) TestUser() {
|
||||
b := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now()})
|
||||
check.Args(database.GetUsersParams{}).Asserts(a, rbac.ActionRead, b, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetUsersByIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
a := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now().Add(-time.Hour)})
|
||||
b := dbgen.User(s.T(), db, database.User{CreatedAt: database.Now()})
|
||||
check.Args([]uuid.UUID{a.ID, b.ID}).
|
||||
Asserts( /*a, rbac.ActionRead, b, rbac.ActionRead*/ ).
|
||||
Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("InsertUser", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertUserParams{
|
||||
ID: uuid.New(),
|
||||
@ -977,14 +956,6 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
|
||||
check.Args(agt.AuthInstanceID.String).Asserts(ws, rbac.ActionRead).Returns(agt)
|
||||
}))
|
||||
s.Run("GetWorkspaceAgentsByResourceIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
|
||||
check.Args([]uuid.UUID{res.ID}).Asserts( /*ws, rbac.ActionRead*/ ).
|
||||
Returns([]database.WorkspaceAgent{agt})
|
||||
}))
|
||||
s.Run("UpdateWorkspaceAgentLifecycleStateByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
@ -1026,23 +997,6 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
|
||||
check.Args(agt.ID).Asserts(ws, rbac.ActionRead).Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("GetWorkspaceAppsByAgentIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
aWs := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
aBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: aWs.ID, JobID: uuid.New()})
|
||||
aRes := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: aBuild.JobID})
|
||||
aAgt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: aRes.ID})
|
||||
a := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: aAgt.ID})
|
||||
|
||||
bWs := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
bBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: bWs.ID, JobID: uuid.New()})
|
||||
bRes := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: bBuild.JobID})
|
||||
bAgt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: bRes.ID})
|
||||
b := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: bAgt.ID})
|
||||
|
||||
check.Args([]uuid.UUID{a.AgentID, b.AgentID}).
|
||||
Asserts( /*aWs, rbac.ActionRead, bWs, rbac.ActionRead*/ ).
|
||||
Returns([]database.WorkspaceApp{a, b})
|
||||
}))
|
||||
s.Run("GetWorkspaceBuildByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID})
|
||||
@ -1096,15 +1050,6 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
check.Args(res.ID).Asserts(ws, rbac.ActionRead).Returns(res)
|
||||
}))
|
||||
s.Run("GetWorkspaceResourceMetadataByResourceIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: build.JobID, Type: database.ProvisionerJobTypeWorkspaceBuild})
|
||||
a := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
b := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
check.Args([]uuid.UUID{a.ID, b.ID}).
|
||||
Asserts( /*ws, []rbac.Action{rbac.ActionRead, rbac.ActionRead}*/ )
|
||||
}))
|
||||
s.Run("Build/GetWorkspaceResourcesByJobID", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
@ -1117,18 +1062,6 @@ func (s *MethodTestSuite) TestWorkspace() {
|
||||
job := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: v.JobID, Type: database.ProvisionerJobTypeTemplateVersionImport})
|
||||
check.Args(job.ID).Asserts(v.RBACObject(tpl), []rbac.Action{rbac.ActionRead, rbac.ActionRead}).Returns([]database.WorkspaceResource{})
|
||||
}))
|
||||
s.Run("GetWorkspaceResourcesByJobIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}, JobID: uuid.New()})
|
||||
tJob := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: v.JobID, Type: database.ProvisionerJobTypeTemplateVersionImport})
|
||||
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
wJob := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: build.JobID, Type: database.ProvisionerJobTypeWorkspaceBuild})
|
||||
check.Args([]uuid.UUID{tJob.ID, wJob.ID}).
|
||||
Asserts( /*v.RBACObject(tpl), rbac.ActionRead, ws, rbac.ActionRead*/ ).
|
||||
Returns([]database.WorkspaceResource{})
|
||||
}))
|
||||
s.Run("InsertWorkspace", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
o := dbgen.Organization(s.T(), db, database.Organization{})
|
||||
|
@ -7,53 +7,50 @@ import (
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/rbac"
|
||||
)
|
||||
|
||||
// TODO: All these system functions should have rbac objects created to allow
|
||||
// only system roles to call them. No user roles should ever have the permission
|
||||
// to these objects. Might need a negative permission on the `Owner` role to
|
||||
// prevent owners.
|
||||
|
||||
// GetWorkspaceAppsByAgentIDs
|
||||
// The workspace/job is already fetched.
|
||||
// TODO: This function should be removed/replaced with something with proper auth.
|
||||
func (q *querier) GetWorkspaceAppsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceApp, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceAppsByAgentIDs(ctx, ids)
|
||||
}
|
||||
|
||||
// GetWorkspaceAgentsByResourceIDs
|
||||
// The workspace/job is already fetched.
|
||||
// TODO: This function should be removed/replaced with something with proper auth.
|
||||
func (q *querier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceAgent, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceAgentsByResourceIDs(ctx, ids)
|
||||
}
|
||||
|
||||
// GetWorkspaceResourceMetadataByResourceIDs is only used for build data.
|
||||
// The workspace/job is already fetched.
|
||||
// TODO: This function should be removed/replaced with something with proper auth.
|
||||
func (q *querier) GetWorkspaceResourceMetadataByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceResourceMetadatum, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceResourceMetadataByResourceIDs(ctx, ids)
|
||||
}
|
||||
|
||||
// GetUsersByIDs is only used for usernames on workspace return data.
|
||||
// This function should be replaced by joining this data to the workspace query
|
||||
// itself.
|
||||
// TODO: This function should be removed/replaced with something with proper auth.
|
||||
// A SQL compiled filter is an option.
|
||||
func (q *querier) GetUsersByIDs(ctx context.Context, ids []uuid.UUID) ([]database.User, error) {
|
||||
return q.db.GetUsersByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
// TODO: we need to add a provisioner job resource
|
||||
func (q *querier) GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]database.ProvisionerJob, error) {
|
||||
// TODO: This is missing authorization and is incorrect. This call is used by telemetry, and by 1 http route.
|
||||
// That http handler should find a better way to fetch these jobs with easier rbac authz.
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
return q.db.GetProvisionerJobsByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
// GetTemplateVersionsByIDs is only used for workspace build data.
|
||||
// The workspace is already fetched.
|
||||
// TODO: Find a way to replace this with proper authz.
|
||||
func (q *querier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UUID) ([]database.TemplateVersion, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateVersionsByIDs(ctx, ids)
|
||||
}
|
||||
|
||||
@ -61,18 +58,30 @@ func (q *querier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UUID)
|
||||
// The workspace is already fetched.
|
||||
// TODO: Find a way to replace this with proper authz.
|
||||
func (q *querier) GetWorkspaceResourcesByJobIDs(ctx context.Context, ids []uuid.UUID) ([]database.WorkspaceResource, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceResourcesByJobIDs(ctx, ids)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateUserLinkedID(ctx context.Context, arg database.UpdateUserLinkedIDParams) (database.UserLink, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
return database.UserLink{}, err
|
||||
}
|
||||
return q.db.UpdateUserLinkedID(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserLinkByLinkedID(ctx context.Context, linkedID string) (database.UserLink, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return database.UserLink{}, err
|
||||
}
|
||||
return q.db.GetUserLinkByLinkedID(ctx, linkedID)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserLinkByUserIDLoginType(ctx context.Context, arg database.GetUserLinkByUserIDLoginTypeParams) (database.UserLink, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return database.UserLink{}, err
|
||||
}
|
||||
return q.db.GetUserLinkByUserIDLoginType(ctx, arg)
|
||||
}
|
||||
|
||||
@ -81,96 +90,148 @@ func (q *querier) GetLatestWorkspaceBuilds(ctx context.Context) ([]database.Work
|
||||
// This is because we need to query for all related workspaces to the returned builds.
|
||||
// This is a very inefficient method of fetching the latest workspace builds.
|
||||
// We should just join the rbac properties.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetLatestWorkspaceBuilds(ctx)
|
||||
}
|
||||
|
||||
// GetWorkspaceAgentByAuthToken is used in http middleware to get the workspace agent.
|
||||
// This should only be used by a system user in that middleware.
|
||||
func (q *querier) GetWorkspaceAgentByAuthToken(ctx context.Context, authToken uuid.UUID) (database.WorkspaceAgent, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return database.WorkspaceAgent{}, err
|
||||
}
|
||||
return q.db.GetWorkspaceAgentByAuthToken(ctx, authToken)
|
||||
}
|
||||
|
||||
func (q *querier) GetActiveUserCount(ctx context.Context) (int64, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return q.db.GetActiveUserCount(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetUnexpiredLicenses(ctx context.Context) ([]database.License, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetUnexpiredLicenses(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetAuthorizationUserRoles(ctx context.Context, userID uuid.UUID) (database.GetAuthorizationUserRolesRow, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return database.GetAuthorizationUserRolesRow{}, err
|
||||
}
|
||||
return q.db.GetAuthorizationUserRoles(ctx, userID)
|
||||
}
|
||||
|
||||
func (q *querier) GetDERPMeshKey(ctx context.Context) (string, error) {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return q.db.GetDERPMeshKey(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) InsertDERPMeshKey(ctx context.Context, value string) error {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.InsertDERPMeshKey(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) InsertDeploymentID(ctx context.Context, value string) error {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.InsertDeploymentID(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) InsertReplica(ctx context.Context, arg database.InsertReplicaParams) (database.Replica, error) {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.Replica{}, err
|
||||
}
|
||||
return q.db.InsertReplica(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpdateReplica(ctx context.Context, arg database.UpdateReplicaParams) (database.Replica, error) {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
return database.Replica{}, err
|
||||
}
|
||||
return q.db.UpdateReplica(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteReplicasUpdatedBefore(ctx, updatedAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetReplicasUpdatedAfter(ctx context.Context, updatedAt time.Time) ([]database.Replica, error) {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetReplicasUpdatedAfter(ctx, updatedAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetUserCount(ctx context.Context) (int64, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return q.db.GetUserCount(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetTemplates(ctx context.Context) ([]database.Template, error) {
|
||||
// TODO Implement authz check for system user.
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplates(ctx)
|
||||
}
|
||||
|
||||
// Only used by metrics cache.
|
||||
func (q *querier) GetTemplateAverageBuildTime(ctx context.Context, arg database.GetTemplateAverageBuildTimeParams) (database.GetTemplateAverageBuildTimeRow, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return database.GetTemplateAverageBuildTimeRow{}, err
|
||||
}
|
||||
return q.db.GetTemplateAverageBuildTime(ctx, arg)
|
||||
}
|
||||
|
||||
// Only used by metrics cache.
|
||||
func (q *querier) GetTemplateDAUs(ctx context.Context, templateID uuid.UUID) ([]database.GetTemplateDAUsRow, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetTemplateDAUs(ctx, templateID)
|
||||
}
|
||||
|
||||
// Only used by metrics cache.
|
||||
func (q *querier) GetDeploymentDAUs(ctx context.Context) ([]database.GetDeploymentDAUsRow, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetDeploymentDAUs(ctx)
|
||||
}
|
||||
|
||||
// UpdateWorkspaceBuildCostByID is used by the provisioning system to update the cost of a workspace build.
|
||||
func (q *querier) UpdateWorkspaceBuildCostByID(ctx context.Context, arg database.UpdateWorkspaceBuildCostByIDParams) (database.WorkspaceBuild, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
return database.WorkspaceBuild{}, err
|
||||
}
|
||||
return q.db.UpdateWorkspaceBuildCostByID(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertOrUpdateLastUpdateCheck(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.InsertOrUpdateLastUpdateCheck(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) GetLastUpdateCheck(ctx context.Context) (string, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return q.db.GetLastUpdateCheck(ctx)
|
||||
}
|
||||
|
||||
@ -178,26 +239,44 @@ func (q *querier) GetLastUpdateCheck(ctx context.Context) (string, error) {
|
||||
// telemetry data. Never called by a user.
|
||||
|
||||
func (q *querier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceBuild, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceBuildsCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceAgent, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceAgentsCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceAppsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceApp, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceAppsCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceResource, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceResourcesCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceResourceMetadataCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.WorkspaceResourceMetadatum, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetWorkspaceResourceMetadataCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteOldWorkspaceAgentStats(ctx context.Context) error {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionDelete, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.DeleteOldWorkspaceAgentStats(ctx)
|
||||
}
|
||||
|
||||
@ -210,63 +289,115 @@ func (q *querier) GetDeploymentWorkspaceStats(ctx context.Context) (database.Get
|
||||
}
|
||||
|
||||
func (q *querier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ParameterSchema, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetParameterSchemasCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ProvisionerJob, error) {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
return q.db.GetProvisionerJobsCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
// Provisionerd server functions
|
||||
|
||||
func (q *querier) InsertWorkspaceAgent(ctx context.Context, arg database.InsertWorkspaceAgentParams) (database.WorkspaceAgent, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.WorkspaceAgent{}, err
|
||||
}
|
||||
return q.db.InsertWorkspaceAgent(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertWorkspaceApp(ctx context.Context, arg database.InsertWorkspaceAppParams) (database.WorkspaceApp, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.WorkspaceApp{}, err
|
||||
}
|
||||
return q.db.InsertWorkspaceApp(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertWorkspaceResourceMetadata(ctx context.Context, arg database.InsertWorkspaceResourceMetadataParams) ([]database.WorkspaceResourceMetadatum, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.InsertWorkspaceResourceMetadata(ctx, arg)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) AcquireProvisionerJob(ctx context.Context, arg database.AcquireProvisionerJobParams) (database.ProvisionerJob, error) {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
// return database.ProvisionerJob{}, err
|
||||
// }
|
||||
return q.db.AcquireProvisionerJob(ctx, arg)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, arg database.UpdateProvisionerJobWithCompleteByIDParams) error {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
// return err
|
||||
// }
|
||||
return q.db.UpdateProvisionerJobWithCompleteByID(ctx, arg)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) UpdateProvisionerJobByID(ctx context.Context, arg database.UpdateProvisionerJobByIDParams) error {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
// return err
|
||||
// }
|
||||
return q.db.UpdateProvisionerJobByID(ctx, arg)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) InsertProvisionerJob(ctx context.Context, arg database.InsertProvisionerJobParams) (database.ProvisionerJob, error) {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
// return database.ProvisionerJob{}, err
|
||||
// }
|
||||
return q.db.InsertProvisionerJob(ctx, arg)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) InsertProvisionerJobLogs(ctx context.Context, arg database.InsertProvisionerJobLogsParams) ([]database.ProvisionerJobLog, error) {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
return q.db.InsertProvisionerJobLogs(ctx, arg)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerDaemon resource type
|
||||
func (q *querier) InsertProvisionerDaemon(ctx context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
// return database.ProvisionerDaemon{}, err
|
||||
// }
|
||||
return q.db.InsertProvisionerDaemon(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertTemplateVersionParameter(ctx context.Context, arg database.InsertTemplateVersionParameterParams) (database.TemplateVersionParameter, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.TemplateVersionParameter{}, err
|
||||
}
|
||||
return q.db.InsertTemplateVersionParameter(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertTemplateVersionVariable(ctx context.Context, arg database.InsertTemplateVersionVariableParams) (database.TemplateVersionVariable, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.TemplateVersionVariable{}, err
|
||||
}
|
||||
return q.db.InsertTemplateVersionVariable(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertWorkspaceResource(ctx context.Context, arg database.InsertWorkspaceResourceParams) (database.WorkspaceResource, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.WorkspaceResource{}, err
|
||||
}
|
||||
return q.db.InsertWorkspaceResource(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertParameterSchema(ctx context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.ParameterSchema{}, err
|
||||
}
|
||||
return q.db.InsertParameterSchema(ctx, arg)
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import (
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/database/dbgen"
|
||||
"github.com/coder/coder/coderd/rbac"
|
||||
"github.com/coder/coder/coderd/util/slice"
|
||||
)
|
||||
|
||||
func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
@ -20,51 +22,51 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
UserID: u.ID,
|
||||
LinkedID: l.LinkedID,
|
||||
LoginType: database.LoginTypeGithub,
|
||||
}).Asserts().Returns(l)
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate).Returns(l)
|
||||
}))
|
||||
s.Run("GetUserLinkByLinkedID", s.Subtest(func(db database.Store, check *expects) {
|
||||
l := dbgen.UserLink(s.T(), db, database.UserLink{})
|
||||
check.Args(l.LinkedID).Asserts().Returns(l)
|
||||
check.Args(l.LinkedID).Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(l)
|
||||
}))
|
||||
s.Run("GetUserLinkByUserIDLoginType", s.Subtest(func(db database.Store, check *expects) {
|
||||
l := dbgen.UserLink(s.T(), db, database.UserLink{})
|
||||
check.Args(database.GetUserLinkByUserIDLoginTypeParams{
|
||||
UserID: l.UserID,
|
||||
LoginType: l.LoginType,
|
||||
}).Asserts().Returns(l)
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(l)
|
||||
}))
|
||||
s.Run("GetLatestWorkspaceBuilds", s.Subtest(func(db database.Store, check *expects) {
|
||||
dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{})
|
||||
dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{})
|
||||
check.Args().Asserts()
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceAgentByAuthToken", s.Subtest(func(db database.Store, check *expects) {
|
||||
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{})
|
||||
check.Args(agt.AuthToken).Asserts().Returns(agt)
|
||||
check.Args(agt.AuthToken).Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(agt)
|
||||
}))
|
||||
s.Run("GetActiveUserCount", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts().Returns(int64(0))
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(int64(0))
|
||||
}))
|
||||
s.Run("GetUnexpiredLicenses", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts()
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetAuthorizationUserRoles", s.Subtest(func(db database.Store, check *expects) {
|
||||
u := dbgen.User(s.T(), db, database.User{})
|
||||
check.Args(u.ID).Asserts()
|
||||
check.Args(u.ID).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetDERPMeshKey", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts()
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("InsertDERPMeshKey", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts().Returns()
|
||||
check.Args("value").Asserts(rbac.ResourceSystem, rbac.ActionCreate).Returns()
|
||||
}))
|
||||
s.Run("InsertDeploymentID", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts().Returns()
|
||||
check.Args("value").Asserts(rbac.ResourceSystem, rbac.ActionCreate).Returns()
|
||||
}))
|
||||
s.Run("InsertReplica", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertReplicaParams{
|
||||
ID: uuid.New(),
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("UpdateReplica", s.Subtest(func(db database.Store, check *expects) {
|
||||
replica, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ID: uuid.New()})
|
||||
@ -72,24 +74,24 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
check.Args(database.UpdateReplicaParams{
|
||||
ID: replica.ID,
|
||||
DatabaseLatency: 100,
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("DeleteReplicasUpdatedBefore", s.Subtest(func(db database.Store, check *expects) {
|
||||
_, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ID: uuid.New(), UpdatedAt: time.Now()})
|
||||
require.NoError(s.T(), err)
|
||||
check.Args(time.Now().Add(time.Hour)).Asserts()
|
||||
check.Args(time.Now().Add(time.Hour)).Asserts(rbac.ResourceSystem, rbac.ActionDelete)
|
||||
}))
|
||||
s.Run("GetReplicasUpdatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_, err := db.InsertReplica(context.Background(), database.InsertReplicaParams{ID: uuid.New(), UpdatedAt: time.Now()})
|
||||
require.NoError(s.T(), err)
|
||||
check.Args(time.Now().Add(time.Hour * -1)).Asserts()
|
||||
check.Args(time.Now().Add(time.Hour*-1)).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetUserCount", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts().Returns(int64(0))
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead).Returns(int64(0))
|
||||
}))
|
||||
s.Run("GetTemplates", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.Template(s.T(), db, database.Template{})
|
||||
check.Args().Asserts()
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("UpdateWorkspaceBuildCostByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{})
|
||||
@ -98,115 +100,193 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
check.Args(database.UpdateWorkspaceBuildCostByIDParams{
|
||||
ID: b.ID,
|
||||
DailyCost: 10,
|
||||
}).Asserts().Returns(o)
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionUpdate).Returns(o)
|
||||
}))
|
||||
s.Run("InsertOrUpdateLastUpdateCheck", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts()
|
||||
check.Args("value").Asserts(rbac.ResourceSystem, rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("GetLastUpdateCheck", s.Subtest(func(db database.Store, check *expects) {
|
||||
err := db.InsertOrUpdateLastUpdateCheck(context.Background(), "value")
|
||||
require.NoError(s.T(), err)
|
||||
check.Args().Asserts()
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceBuildsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceAgentsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceAppsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceResourcesCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceResourceMetadataCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.WorkspaceResourceMetadatums(s.T(), db, database.WorkspaceResourceMetadatum{})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("DeleteOldWorkspaceAgentStats", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts()
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionDelete)
|
||||
}))
|
||||
s.Run("GetParameterSchemasCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.ParameterSchema(s.T(), db, database.ParameterSchema{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetProvisionerJobsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: add provisioner job resource type
|
||||
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts()
|
||||
check.Args(time.Now()).Asserts( /*rbac.ResourceSystem, rbac.ActionRead*/ )
|
||||
}))
|
||||
s.Run("GetTemplateVersionsByIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
t1 := dbgen.Template(s.T(), db, database.Template{})
|
||||
t2 := dbgen.Template(s.T(), db, database.Template{})
|
||||
tv1 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: t1.ID, Valid: true},
|
||||
})
|
||||
tv2 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: t2.ID, Valid: true},
|
||||
})
|
||||
tv3 := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
TemplateID: uuid.NullUUID{UUID: t2.ID, Valid: true},
|
||||
})
|
||||
check.Args([]uuid.UUID{tv1.ID, tv2.ID, tv3.ID}).
|
||||
Asserts(rbac.ResourceSystem, rbac.ActionRead).
|
||||
Returns(slice.New(tv1, tv2, tv3))
|
||||
}))
|
||||
s.Run("GetWorkspaceAppsByAgentIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
aWs := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
aBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: aWs.ID, JobID: uuid.New()})
|
||||
aRes := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: aBuild.JobID})
|
||||
aAgt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: aRes.ID})
|
||||
a := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: aAgt.ID})
|
||||
|
||||
bWs := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
bBuild := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: bWs.ID, JobID: uuid.New()})
|
||||
bRes := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: bBuild.JobID})
|
||||
bAgt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: bRes.ID})
|
||||
b := dbgen.WorkspaceApp(s.T(), db, database.WorkspaceApp{AgentID: bAgt.ID})
|
||||
|
||||
check.Args([]uuid.UUID{a.AgentID, b.AgentID}).
|
||||
Asserts(rbac.ResourceSystem, rbac.ActionRead).
|
||||
Returns([]database.WorkspaceApp{a, b})
|
||||
}))
|
||||
s.Run("GetWorkspaceResourcesByJobIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}, JobID: uuid.New()})
|
||||
tJob := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: v.JobID, Type: database.ProvisionerJobTypeTemplateVersionImport})
|
||||
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
wJob := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: build.JobID, Type: database.ProvisionerJobTypeWorkspaceBuild})
|
||||
check.Args([]uuid.UUID{tJob.ID, wJob.ID}).
|
||||
Asserts(rbac.ResourceSystem, rbac.ActionRead).
|
||||
Returns([]database.WorkspaceResource{})
|
||||
}))
|
||||
s.Run("GetWorkspaceResourceMetadataByResourceIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{ID: build.JobID, Type: database.ProvisionerJobTypeWorkspaceBuild})
|
||||
a := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
b := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
check.Args([]uuid.UUID{a.ID, b.ID}).
|
||||
Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetWorkspaceAgentsByResourceIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
ws := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
build := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{WorkspaceID: ws.ID, JobID: uuid.New()})
|
||||
res := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{JobID: build.JobID})
|
||||
agt := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{ResourceID: res.ID})
|
||||
check.Args([]uuid.UUID{res.ID}).
|
||||
Asserts(rbac.ResourceSystem, rbac.ActionRead).
|
||||
Returns([]database.WorkspaceAgent{agt})
|
||||
}))
|
||||
s.Run("GetProvisionerJobsByIDs", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: add a ProvisionerJob resource type
|
||||
a := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
b := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
check.Args([]uuid.UUID{a.ID, b.ID}).
|
||||
Asserts( /*rbac.ResourceSystem, rbac.ActionRead*/ ).
|
||||
Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("InsertWorkspaceAgent", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertWorkspaceAgentParams{
|
||||
ID: uuid.New(),
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertWorkspaceApp", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertWorkspaceAppParams{
|
||||
ID: uuid.New(),
|
||||
Health: database.WorkspaceAppHealthDisabled,
|
||||
SharingLevel: database.AppSharingLevelOwner,
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertWorkspaceResourceMetadata", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertWorkspaceResourceMetadataParams{
|
||||
WorkspaceResourceID: uuid.New(),
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("AcquireProvisionerJob", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: we need to create a ProvisionerJob resource
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{
|
||||
StartedAt: sql.NullTime{Valid: false},
|
||||
})
|
||||
check.Args(database.AcquireProvisionerJobParams{Types: []database.ProvisionerType{j.Provisioner}}).
|
||||
Asserts()
|
||||
Asserts( /*rbac.ResourceSystem, rbac.ActionUpdate*/ )
|
||||
}))
|
||||
s.Run("UpdateProvisionerJobWithCompleteByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: we need to create a ProvisionerJob resource
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
check.Args(database.UpdateProvisionerJobWithCompleteByIDParams{
|
||||
ID: j.ID,
|
||||
}).Asserts()
|
||||
}).Asserts( /*rbac.ResourceSystem, rbac.ActionUpdate*/ )
|
||||
}))
|
||||
s.Run("UpdateProvisionerJobByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: we need to create a ProvisionerJob resource
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
check.Args(database.UpdateProvisionerJobByIDParams{
|
||||
ID: j.ID,
|
||||
UpdatedAt: time.Now(),
|
||||
}).Asserts()
|
||||
}).Asserts( /*rbac.ResourceSystem, rbac.ActionUpdate*/ )
|
||||
}))
|
||||
s.Run("InsertProvisionerJob", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: we need to create a ProvisionerJob resource
|
||||
check.Args(database.InsertProvisionerJobParams{
|
||||
ID: uuid.New(),
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
Type: database.ProvisionerJobTypeWorkspaceBuild,
|
||||
}).Asserts()
|
||||
}).Asserts( /*rbac.ResourceSystem, rbac.ActionCreate*/ )
|
||||
}))
|
||||
s.Run("InsertProvisionerJobLogs", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: we need to create a ProvisionerJob resource
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
check.Args(database.InsertProvisionerJobLogsParams{
|
||||
JobID: j.ID,
|
||||
}).Asserts()
|
||||
}).Asserts( /*rbac.ResourceSystem, rbac.ActionCreate*/ )
|
||||
}))
|
||||
s.Run("InsertProvisionerDaemon", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: we need to create a ProvisionerDaemon resource
|
||||
check.Args(database.InsertProvisionerDaemonParams{
|
||||
ID: uuid.New(),
|
||||
}).Asserts()
|
||||
}).Asserts( /*rbac.ResourceSystem, rbac.ActionCreate*/ )
|
||||
}))
|
||||
s.Run("InsertTemplateVersionParameter", s.Subtest(func(db database.Store, check *expects) {
|
||||
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{})
|
||||
check.Args(database.InsertTemplateVersionParameterParams{
|
||||
TemplateVersionID: v.ID,
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertWorkspaceResource", s.Subtest(func(db database.Store, check *expects) {
|
||||
r := dbgen.WorkspaceResource(s.T(), db, database.WorkspaceResource{})
|
||||
check.Args(database.InsertWorkspaceResourceParams{
|
||||
ID: r.ID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertParameterSchema", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertParameterSchemaParams{
|
||||
@ -214,6 +294,6 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeNone,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
ValidationTypeSystem: database.ParameterTypeSystemNone,
|
||||
}).Asserts()
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
}
|
||||
|
Reference in New Issue
Block a user