Skip to content

Commit a93c2d5

Browse files
committed
Update unit tests to cover the no actor case
1 parent c5e69fa commit a93c2d5

File tree

5 files changed

+56
-8
lines changed

5 files changed

+56
-8
lines changed

coderd/database/dbauthz/dbauthz.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,12 +137,21 @@ func AsSystem(ctx context.Context) context.Context {
137137
)
138138
}
139139

140+
var AsRemoveActor = rbac.Subject{
141+
ID: "remove-actor",
142+
}
143+
140144
// As returns a context with the given actor stored in the context.
141145
// This is used for cases where the actor touching the database is not the
142146
// actor stored in the context.
143147
// When you use this function, be sure to add a //nolint comment
144148
// explaining why it is necessary.
145149
func As(ctx context.Context, actor rbac.Subject) context.Context {
150+
if actor.Equal(AsRemoveActor) {
151+
// AsRemoveActor is a special case that is used to indicate that the actor
152+
// should be removed from the context.
153+
return context.WithValue(ctx, authContextKey{}, nil)
154+
}
146155
return context.WithValue(ctx, authContextKey{}, actor)
147156
}
148157

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,36 @@ import (
1818
"github.com/coder/coder/coderd/rbac"
1919
)
2020

21+
func TestAsNoActor(t *testing.T) {
22+
t.Parallel()
23+
24+
t.Run("AsRemoveActor", func(t *testing.T) {
25+
t.Parallel()
26+
_, ok := dbauthz.ActorFromContext(context.Background())
27+
require.False(t, ok, "no actor should be present")
28+
})
29+
30+
t.Run("AsActor", func(t *testing.T) {
31+
t.Parallel()
32+
ctx := dbauthz.As(context.Background(), coderdtest.RandomRBACSubject())
33+
_, ok := dbauthz.ActorFromContext(ctx)
34+
require.True(t, ok, "actor present")
35+
})
36+
37+
t.Run("DeleteActor", func(t *testing.T) {
38+
t.Parallel()
39+
// First set an actor
40+
ctx := dbauthz.As(context.Background(), coderdtest.RandomRBACSubject())
41+
_, ok := dbauthz.ActorFromContext(ctx)
42+
require.True(t, ok, "actor present")
43+
44+
// Delete the actor
45+
ctx = dbauthz.As(ctx, dbauthz.AsRemoveActor)
46+
_, ok = dbauthz.ActorFromContext(ctx)
47+
require.False(t, ok, "actor should be deleted")
48+
})
49+
}
50+
2151
func TestPing(t *testing.T) {
2252
t.Parallel()
2353

coderd/database/dbauthz/setup_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func (s *MethodTestSuite) Subtest(testCaseF func(db database.Store, check *expec
190190
}
191191

192192
func (s *MethodTestSuite) NoActorErrorTest(callMethod func(ctx context.Context) ([]reflect.Value, error)) {
193-
s.Run("NoActor", func() {
193+
s.Run("AsRemoveActor", func() {
194194
// Call without any actor
195195
_, err := callMethod(context.Background())
196196
s.ErrorIs(err, dbauthz.NoActorError, "method should return NoActorError error when no actor is provided")

coderd/httpmw/authz.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ func AsAuthzSystem(mws ...func(http.Handler) http.Handler) func(http.Handler) ht
1818
return func(next http.Handler) http.Handler {
1919
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
2020
ctx := r.Context()
21-
before, _ := dbauthz.ActorFromContext(r.Context())
21+
before, beforeExists := dbauthz.ActorFromContext(r.Context())
22+
if !beforeExists {
23+
// AsRemoveActor will actually remove the actor from the context.
24+
before = dbauthz.AsRemoveActor
25+
}
2226

2327
r = r.WithContext(dbauthz.AsSystem(ctx))
2428
chain.Handler(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {

coderd/httpmw/authz_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,15 @@ import (
66
"testing"
77

88
"github.com/go-chi/chi/v5"
9+
"github.com/stretchr/testify/assert"
910

10-
"github.com/coder/coder/coderd/httpmw"
11-
11+
"github.com/coder/coder/coderd/coderdtest"
1212
"github.com/coder/coder/coderd/database/dbauthz"
13-
"github.com/coder/coder/coderd/rbac"
14-
"github.com/google/uuid"
15-
"github.com/stretchr/testify/assert"
13+
"github.com/coder/coder/coderd/httpmw"
1614
)
1715

1816
func TestAsAuthzSystem(t *testing.T) {
19-
userActor := rbac.Subject{ID: uuid.NewString()}
17+
userActor := coderdtest.RandomRBACSubject()
2018

2119
base := http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
2220
actor, ok := dbauthz.ActorFromContext(r.Context())
@@ -59,6 +57,13 @@ func TestAsAuthzSystem(t *testing.T) {
5957
r.Use(
6058
// First assert there is no actor context
6159
mwAssertNoUser,
60+
httpmw.AsAuthzSystem(
61+
// Assert the system actor
62+
mwAssertSystem,
63+
mwAssertSystem,
64+
),
65+
mwAssertNoUser,
66+
// ----
6267
// Set to the user actor
6368
mwSetUser,
6469
// Assert the user actor

0 commit comments

Comments
 (0)