Skip to content

Commit ef1deb5

Browse files
committed
Merge remote-tracking branch 'origin/authzquerier_layer' into authzquerier_layer
2 parents e152d5f + 85ff5f1 commit ef1deb5

File tree

7 files changed

+119
-24
lines changed

7 files changed

+119
-24
lines changed

coderd/authzquery/template.go

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,32 @@ func (q *AuthzQuerier) GetTemplateVersionParameters(ctx context.Context, templat
155155
}
156156

157157
func (q *AuthzQuerier) GetTemplateVersionsByIDs(ctx context.Context, ids []uuid.UUID) ([]database.TemplateVersion, error) {
158-
// An actor can read template versions if they can read the related template.
159-
// There are multiple template IDs, so we will just check that all templates can be read.
160-
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceTemplate.All()); err != nil {
158+
// TODO: This is so inefficient
159+
versions, err := q.database.GetTemplateVersionsByIDs(ctx, ids)
160+
if err != nil {
161161
return nil, err
162162
}
163-
return q.database.GetTemplateVersionsByIDs(ctx, ids)
163+
checked := make(map[uuid.UUID]bool)
164+
for _, v := range versions {
165+
if _, ok := checked[v.TemplateID.UUID]; ok {
166+
continue
167+
}
168+
169+
obj := v.RBACObjectNoTemplate()
170+
template, err := q.database.GetTemplateByID(ctx, v.TemplateID.UUID)
171+
if err == nil {
172+
obj = v.RBACObject(template)
173+
}
174+
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
175+
return nil, err
176+
}
177+
if err := q.authorizeContext(ctx, rbac.ActionRead, obj); err != nil {
178+
return nil, err
179+
}
180+
checked[v.TemplateID.UUID] = true
181+
}
182+
183+
return versions, nil
164184
}
165185

166186
func (q *AuthzQuerier) GetTemplateVersionsByTemplateID(ctx context.Context, arg database.GetTemplateVersionsByTemplateIDParams) ([]database.TemplateVersion, error) {

coderd/authzquery/user.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,17 @@ func (q *AuthzQuerier) UpdateUserDeletedByID(ctx context.Context, arg database.U
137137
}
138138

139139
func (q *AuthzQuerier) UpdateUserHashedPassword(ctx context.Context, arg database.UpdateUserHashedPasswordParams) error {
140-
fetch := func(ctx context.Context, arg database.UpdateUserHashedPasswordParams) (database.User, error) {
141-
return q.database.GetUserByID(ctx, arg.ID)
140+
user, err := q.database.GetUserByID(ctx, arg.ID)
141+
if err != nil {
142+
return err
143+
}
144+
145+
err = q.authorizeContext(ctx, rbac.ActionUpdate, user.UserDataRBACObject())
146+
if err != nil {
147+
return err
142148
}
143-
return authorizedUpdate(q.authorizer, fetch, q.database.UpdateUserHashedPassword)(ctx, arg)
149+
150+
return q.database.UpdateUserHashedPassword(ctx, arg)
144151
}
145152

146153
func (q *AuthzQuerier) UpdateUserLastSeenAt(ctx context.Context, arg database.UpdateUserLastSeenAtParams) (database.User, error) {

coderd/database/dbgen/generator.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,47 @@ func APIKey(t *testing.T, db database.Store, seed database.APIKey) (key database
6666
return key, fmt.Sprintf("%s-%s", key.ID, secret)
6767
}
6868

69+
func WorkspaceAgent(t *testing.T, db database.Store, orig database.WorkspaceAgent) database.WorkspaceAgent {
70+
workspace, err := db.InsertWorkspaceAgent(context.Background(), database.InsertWorkspaceAgentParams{
71+
ID: takeFirst(orig.ID, uuid.New()),
72+
CreatedAt: takeFirst(orig.CreatedAt, time.Now()),
73+
UpdatedAt: takeFirst(orig.UpdatedAt, time.Now()),
74+
Name: takeFirst(orig.Name, namesgenerator.GetRandomName(1)),
75+
ResourceID: takeFirst(orig.ResourceID, uuid.New()),
76+
AuthToken: takeFirst(orig.AuthToken, uuid.New()),
77+
AuthInstanceID: sql.NullString{
78+
String: takeFirst(orig.AuthInstanceID.String, ""),
79+
Valid: takeFirst(orig.AuthInstanceID.Valid, false),
80+
},
81+
Architecture: takeFirst(orig.Architecture, "amd64"),
82+
EnvironmentVariables: pqtype.NullRawMessage{
83+
RawMessage: takeFirstBytes(orig.EnvironmentVariables.RawMessage, []byte("{}")),
84+
Valid: takeFirst(orig.EnvironmentVariables.Valid, false),
85+
},
86+
OperatingSystem: takeFirst(orig.OperatingSystem, "linux"),
87+
StartupScript: sql.NullString{
88+
String: takeFirst(orig.StartupScript.String, ""),
89+
Valid: takeFirst(orig.StartupScript.Valid, false),
90+
},
91+
Directory: takeFirst(orig.Directory, ""),
92+
InstanceMetadata: pqtype.NullRawMessage{
93+
RawMessage: takeFirstBytes(orig.ResourceMetadata.RawMessage, []byte("{}")),
94+
Valid: takeFirst(orig.ResourceMetadata.Valid, false),
95+
},
96+
ResourceMetadata: pqtype.NullRawMessage{
97+
RawMessage: takeFirstBytes(orig.ResourceMetadata.RawMessage, []byte("{}")),
98+
Valid: takeFirst(orig.ResourceMetadata.Valid, false),
99+
},
100+
ConnectionTimeoutSeconds: takeFirst(orig.ConnectionTimeoutSeconds, 3600),
101+
TroubleshootingURL: takeFirst(orig.TroubleshootingURL, "https://example.com"),
102+
MOTDFile: takeFirst(orig.TroubleshootingURL, ""),
103+
LoginBeforeReady: takeFirst(orig.LoginBeforeReady, false),
104+
StartupScriptTimeoutSeconds: takeFirst(orig.StartupScriptTimeoutSeconds, 3600),
105+
})
106+
require.NoError(t, err, "insert workspace agent")
107+
return workspace
108+
}
109+
69110
func Workspace(t *testing.T, db database.Store, orig database.Workspace) database.Workspace {
70111
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
71112
ID: takeFirst(orig.ID, uuid.New()),

coderd/database/dbgen/generator_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ func TestGenerator(t *testing.T) {
7070
require.Equal(t, exp, must(db.GetWorkspaceByID(context.Background(), exp.ID)))
7171
})
7272

73+
t.Run("WorkspaceAgent", func(t *testing.T) {
74+
t.Parallel()
75+
db := databasefake.New()
76+
exp := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{})
77+
require.Equal(t, exp, must(db.GetWorkspaceAgentByID(context.Background(), exp.ID)))
78+
})
79+
7380
t.Run("Template", func(t *testing.T) {
7481
t.Parallel()
7582
db := databasefake.New()

coderd/httpmw/workspaceagent_test.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package httpmw_test
22

33
import (
4-
"context"
54
"net/http"
65
"net/http/httptest"
76
"testing"
@@ -12,18 +11,18 @@ import (
1211

1312
"github.com/coder/coder/coderd/database"
1413
"github.com/coder/coder/coderd/database/databasefake"
14+
"github.com/coder/coder/coderd/database/dbgen"
1515
"github.com/coder/coder/coderd/httpmw"
1616
"github.com/coder/coder/codersdk"
1717
)
1818

1919
func TestWorkspaceAgent(t *testing.T) {
2020
t.Parallel()
2121

22-
setup := func(db database.Store) (*http.Request, uuid.UUID) {
23-
token := uuid.New()
22+
setup := func(db database.Store, token uuid.UUID) *http.Request {
2423
r := httptest.NewRequest("GET", "/", nil)
2524
r.Header.Set(codersdk.SessionTokenHeader, token.String())
26-
return r, token
25+
return r
2726
}
2827

2928
t.Run("None", func(t *testing.T) {
@@ -34,7 +33,7 @@ func TestWorkspaceAgent(t *testing.T) {
3433
httpmw.ExtractWorkspaceAgent(db),
3534
)
3635
rtr.Get("/", nil)
37-
r, _ := setup(db)
36+
r := setup(db, uuid.New())
3837
rw := httptest.NewRecorder()
3938
rtr.ServeHTTP(rw, r)
4039

@@ -46,6 +45,25 @@ func TestWorkspaceAgent(t *testing.T) {
4645
t.Run("Found", func(t *testing.T) {
4746
t.Parallel()
4847
db := databasefake.New()
48+
49+
var (
50+
user = dbgen.User(t, db, database.User{})
51+
workspace = dbgen.Workspace(t, db, database.Workspace{
52+
OwnerID: user.ID,
53+
})
54+
job = dbgen.ProvisionerJob(t, db, database.ProvisionerJob{})
55+
resource = dbgen.WorkspaceResource(t, db, database.WorkspaceResource{
56+
JobID: job.ID,
57+
})
58+
_ = dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{
59+
WorkspaceID: workspace.ID,
60+
JobID: job.ID,
61+
})
62+
agent = dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{
63+
ResourceID: resource.ID,
64+
})
65+
)
66+
4967
rtr := chi.NewRouter()
5068
rtr.Use(
5169
httpmw.ExtractWorkspaceAgent(db),
@@ -54,13 +72,8 @@ func TestWorkspaceAgent(t *testing.T) {
5472
_ = httpmw.WorkspaceAgent(r)
5573
rw.WriteHeader(http.StatusOK)
5674
})
57-
r, token := setup(db)
58-
_, err := db.InsertWorkspaceAgent(context.Background(), database.InsertWorkspaceAgentParams{
59-
ID: uuid.New(),
60-
AuthToken: token,
61-
})
62-
require.NoError(t, err)
63-
require.NoError(t, err)
75+
r := setup(db, agent.AuthToken)
76+
6477
rw := httptest.NewRecorder()
6578
rtr.ServeHTTP(rw, r)
6679

coderd/workspaceapps.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
jose "gopkg.in/square/go-jose.v2"
2424

2525
"cdr.dev/slog"
26+
"github.com/coder/coder/coderd/authzquery"
2627
"github.com/coder/coder/coderd/database"
2728
"github.com/coder/coder/coderd/httpapi"
2829
"github.com/coder/coder/coderd/httpmw"
@@ -316,7 +317,8 @@ func (api *API) parseWorkspaceApplicationHostname(rw http.ResponseWriter, r *htt
316317
}
317318

318319
func (api *API) handleWorkspaceAppLogout(rw http.ResponseWriter, r *http.Request) {
319-
ctx := r.Context()
320+
// TODO: Limit permissions of this system user. Using scope or new role.
321+
ctx := authzquery.WithAuthorizeSystemContext(r.Context(), rbac.RolesAdminSystem())
320322

321323
// Delete the API key and cookie first before attempting to parse/validate
322324
// the redirect URI.

enterprise/coderd/coderd_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"testing"
77
"time"
88

9+
"github.com/coder/coder/coderd/authzquery"
10+
"github.com/coder/coder/coderd/rbac"
11+
912
"github.com/stretchr/testify/assert"
1013
"github.com/stretchr/testify/require"
1114
"go.uber.org/goleak"
@@ -100,7 +103,8 @@ func TestEntitlements(t *testing.T) {
100103
require.NoError(t, err)
101104
require.False(t, entitlements.HasLicense)
102105
coderdtest.CreateFirstUser(t, client)
103-
_, err = api.Database.InsertLicense(context.Background(), database.InsertLicenseParams{
106+
ctx := authzquery.WithAuthorizeSystemContext(context.Background(), rbac.RolesAdminSystem())
107+
_, err = api.Database.InsertLicense(ctx, database.InsertLicenseParams{
104108
UploadedAt: database.Now(),
105109
Exp: database.Now().AddDate(1, 0, 0),
106110
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -128,7 +132,8 @@ func TestEntitlements(t *testing.T) {
128132
require.False(t, entitlements.HasLicense)
129133
coderdtest.CreateFirstUser(t, client)
130134
// Valid
131-
_, err = api.Database.InsertLicense(context.Background(), database.InsertLicenseParams{
135+
ctx := authzquery.WithAuthorizeSystemContext(context.Background(), rbac.RolesAdminSystem())
136+
_, err = api.Database.InsertLicense(ctx, database.InsertLicenseParams{
132137
UploadedAt: database.Now(),
133138
Exp: database.Now().AddDate(1, 0, 0),
134139
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -139,7 +144,7 @@ func TestEntitlements(t *testing.T) {
139144
})
140145
require.NoError(t, err)
141146
// Expired
142-
_, err = api.Database.InsertLicense(context.Background(), database.InsertLicenseParams{
147+
_, err = api.Database.InsertLicense(ctx, database.InsertLicenseParams{
143148
UploadedAt: database.Now(),
144149
Exp: database.Now().AddDate(-1, 0, 0),
145150
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -148,7 +153,7 @@ func TestEntitlements(t *testing.T) {
148153
})
149154
require.NoError(t, err)
150155
// Invalid
151-
_, err = api.Database.InsertLicense(context.Background(), database.InsertLicenseParams{
156+
_, err = api.Database.InsertLicense(ctx, database.InsertLicenseParams{
152157
UploadedAt: database.Now(),
153158
Exp: database.Now().AddDate(1, 0, 0),
154159
JWT: "invalid",

0 commit comments

Comments
 (0)