mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
* feat: Add cachable authorizer to elimate duplicate rbac calls Cache is context bound, so only prevents duplicate rbac calls in the same request context.
106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
package coderdtest_test
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/coderd/coderdtest"
|
|
"github.com/coder/coder/coderd/rbac"
|
|
)
|
|
|
|
func TestAuthorizeAllEndpoints(t *testing.T) {
|
|
t.Parallel()
|
|
client, _, api := coderdtest.NewWithAPI(t, &coderdtest.Options{
|
|
// Required for any subdomain-based proxy tests to pass.
|
|
AppHostname: "*.test.coder.com",
|
|
Authorizer: &coderdtest.RecordingAuthorizer{Wrapped: &coderdtest.FakeAuthorizer{}},
|
|
IncludeProvisionerDaemon: true,
|
|
})
|
|
admin := coderdtest.CreateFirstUser(t, client)
|
|
a := coderdtest.NewAuthTester(context.Background(), t, client, api, admin)
|
|
skipRoute, assertRoute := coderdtest.AGPLRoutes(a)
|
|
a.Test(context.Background(), assertRoute, skipRoute)
|
|
}
|
|
|
|
func TestAuthzRecorder(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("Authorize", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
rec := &coderdtest.RecordingAuthorizer{
|
|
Wrapped: &coderdtest.FakeAuthorizer{},
|
|
}
|
|
sub := coderdtest.RandomRBACSubject()
|
|
pairs := fuzzAuthz(t, sub, rec, 10)
|
|
rec.AssertActor(t, sub, pairs...)
|
|
require.NoError(t, rec.AllAsserted(), "all assertions should have been made")
|
|
})
|
|
|
|
t.Run("Authorize2Subjects", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
rec := &coderdtest.RecordingAuthorizer{
|
|
Wrapped: &coderdtest.FakeAuthorizer{},
|
|
}
|
|
a := coderdtest.RandomRBACSubject()
|
|
aPairs := fuzzAuthz(t, a, rec, 10)
|
|
|
|
b := coderdtest.RandomRBACSubject()
|
|
bPairs := fuzzAuthz(t, b, rec, 10)
|
|
|
|
rec.AssertActor(t, b, bPairs...)
|
|
rec.AssertActor(t, a, aPairs...)
|
|
require.NoError(t, rec.AllAsserted(), "all assertions should have been made")
|
|
})
|
|
|
|
t.Run("Authorize&Prepared", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
rec := &coderdtest.RecordingAuthorizer{
|
|
Wrapped: &coderdtest.FakeAuthorizer{},
|
|
}
|
|
a := coderdtest.RandomRBACSubject()
|
|
aPairs := fuzzAuthz(t, a, rec, 10)
|
|
|
|
b := coderdtest.RandomRBACSubject()
|
|
|
|
act, objTy := coderdtest.RandomRBACAction(), coderdtest.RandomRBACObject().Type
|
|
prep, _ := rec.Prepare(context.Background(), b, act, objTy)
|
|
bPairs := fuzzAuthzPrep(t, prep, 10, act, objTy)
|
|
|
|
rec.AssertActor(t, b, bPairs...)
|
|
rec.AssertActor(t, a, aPairs...)
|
|
require.NoError(t, rec.AllAsserted(), "all assertions should have been made")
|
|
})
|
|
}
|
|
|
|
// fuzzAuthzPrep has same action and object types for all calls.
|
|
func fuzzAuthzPrep(t *testing.T, prep rbac.PreparedAuthorized, n int, action rbac.Action, objectType string) []coderdtest.ActionObjectPair {
|
|
t.Helper()
|
|
pairs := make([]coderdtest.ActionObjectPair, 0, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
obj := coderdtest.RandomRBACObject()
|
|
obj.Type = objectType
|
|
p := coderdtest.ActionObjectPair{Action: action, Object: obj}
|
|
_ = prep.Authorize(context.Background(), p.Object)
|
|
pairs = append(pairs, p)
|
|
}
|
|
return pairs
|
|
}
|
|
|
|
func fuzzAuthz(t *testing.T, sub rbac.Subject, rec rbac.Authorizer, n int) []coderdtest.ActionObjectPair {
|
|
t.Helper()
|
|
pairs := make([]coderdtest.ActionObjectPair, 0, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
p := coderdtest.ActionObjectPair{Action: coderdtest.RandomRBACAction(), Object: coderdtest.RandomRBACObject()}
|
|
_ = rec.Authorize(context.Background(), sub, p.Action, p.Object)
|
|
pairs = append(pairs, p)
|
|
}
|
|
return pairs
|
|
}
|