mirror of https://github.com/coder/coder.git
chore: Compile rego once to save CPU cycles in testing (#4169)
Compiling rego isn't very fast, so this should speed up tests in CI!
This commit is contained in:
parent
1e1967e0db
commit
8738755ffc
|
@ -109,13 +109,7 @@ func New(options *Options) *API {
|
|||
options.MetricsCacheRefreshInterval = time.Hour
|
||||
}
|
||||
if options.Authorizer == nil {
|
||||
var err error
|
||||
options.Authorizer, err = rbac.NewAuthorizer()
|
||||
if err != nil {
|
||||
// This should never happen, as the unit tests would fail if the
|
||||
// default built in authorizer failed.
|
||||
panic(xerrors.Errorf("rego authorize panic: %w", err))
|
||||
}
|
||||
options.Authorizer = rbac.NewAuthorizer()
|
||||
}
|
||||
if options.PrometheusRegistry == nil {
|
||||
options.PrometheusRegistry = prometheus.NewRegistry()
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/open-policy-agent/opa/rego"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
@ -66,32 +67,37 @@ type RegoAuthorizer struct {
|
|||
|
||||
var _ Authorizer = (*RegoAuthorizer)(nil)
|
||||
|
||||
// Load the policy from policy.rego in this directory.
|
||||
//
|
||||
//go:embed policy.rego
|
||||
var policy string
|
||||
var (
|
||||
// Load the policy from policy.rego in this directory.
|
||||
//
|
||||
//go:embed policy.rego
|
||||
policy string
|
||||
queryOnce sync.Once
|
||||
query rego.PreparedEvalQuery
|
||||
)
|
||||
|
||||
const (
|
||||
rolesOkCheck = "role_ok"
|
||||
scopeOkCheck = "scope_ok"
|
||||
)
|
||||
|
||||
func NewAuthorizer() (*RegoAuthorizer, error) {
|
||||
ctx := context.Background()
|
||||
query, err := rego.New(
|
||||
// Bind the results to 2 variables for easy checking later.
|
||||
rego.Query(
|
||||
fmt.Sprintf("%s := data.authz.role_allow "+
|
||||
"%s := data.authz.scope_allow",
|
||||
rolesOkCheck, scopeOkCheck),
|
||||
),
|
||||
rego.Module("policy.rego", policy),
|
||||
).PrepareForEval(ctx)
|
||||
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("prepare query: %w", err)
|
||||
}
|
||||
return &RegoAuthorizer{query: query}, nil
|
||||
func NewAuthorizer() *RegoAuthorizer {
|
||||
queryOnce.Do(func() {
|
||||
var err error
|
||||
query, err = rego.New(
|
||||
// Bind the results to 2 variables for easy checking later.
|
||||
rego.Query(
|
||||
fmt.Sprintf("%s := data.authz.role_allow "+
|
||||
"%s := data.authz.scope_allow",
|
||||
rolesOkCheck, scopeOkCheck),
|
||||
),
|
||||
rego.Module("policy.rego", policy),
|
||||
).PrepareForEval(context.Background())
|
||||
if err != nil {
|
||||
panic(xerrors.Errorf("compile rego: %w", err))
|
||||
}
|
||||
})
|
||||
return &RegoAuthorizer{query: query}
|
||||
}
|
||||
|
||||
type authSubject struct {
|
||||
|
|
|
@ -40,10 +40,8 @@ func (w fakeObject) RBACObject() Object {
|
|||
|
||||
func TestFilterError(t *testing.T) {
|
||||
t.Parallel()
|
||||
auth, err := NewAuthorizer()
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = Filter(context.Background(), auth, uuid.NewString(), []string{}, ScopeAll, ActionRead, []Object{ResourceUser, ResourceWorkspace})
|
||||
auth := NewAuthorizer()
|
||||
_, err := Filter(context.Background(), auth, uuid.NewString(), []string{}, ScopeAll, ActionRead, []Object{ResourceUser, ResourceWorkspace})
|
||||
require.ErrorContains(t, err, "object types must be uniform")
|
||||
}
|
||||
|
||||
|
@ -160,8 +158,7 @@ func TestFilter(t *testing.T) {
|
|||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
|
||||
defer cancel()
|
||||
auth, err := NewAuthorizer()
|
||||
require.NoError(t, err, "new auth")
|
||||
auth := NewAuthorizer()
|
||||
|
||||
scope := ScopeAll
|
||||
if tc.Scope != "" {
|
||||
|
@ -742,8 +739,7 @@ type authTestCase struct {
|
|||
|
||||
func testAuthorize(t *testing.T, name string, subject subject, sets ...[]authTestCase) {
|
||||
t.Helper()
|
||||
authorizer, err := NewAuthorizer()
|
||||
require.NoError(t, err)
|
||||
authorizer := NewAuthorizer()
|
||||
for _, cases := range sets {
|
||||
for i, c := range cases {
|
||||
c := c
|
||||
|
|
|
@ -82,10 +82,7 @@ func BenchmarkRBACFilter(b *testing.B) {
|
|||
},
|
||||
}
|
||||
|
||||
authorizer, err := rbac.NewAuthorizer()
|
||||
if err != nil {
|
||||
require.NoError(b, err)
|
||||
}
|
||||
authorizer := rbac.NewAuthorizer()
|
||||
for _, c := range benchCases {
|
||||
b.Run(c.Name, func(b *testing.B) {
|
||||
objects := benchmarkSetup(orgs, users, b.N)
|
||||
|
@ -119,8 +116,7 @@ type authSubject struct {
|
|||
func TestRolePermissions(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
auth, err := rbac.NewAuthorizer()
|
||||
require.NoError(t, err, "new rego authorizer")
|
||||
auth := rbac.NewAuthorizer()
|
||||
|
||||
// currentUser is anything that references "me", "mine", or "my".
|
||||
currentUser := uuid.New()
|
||||
|
|
Loading…
Reference in New Issue