Skip to content

Commit 75e3a12

Browse files
committed
test: Add unit test to verify partial query support
1 parent b3536bc commit 75e3a12

File tree

2 files changed

+51
-3
lines changed

2 files changed

+51
-3
lines changed

coderd/rbac/authz.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ func Filter[O Objecter](ctx context.Context, auth Authorizer, subjID string, sub
3333

3434
// RegoAuthorizer will use a prepared rego query for performing authorize()
3535
type RegoAuthorizer struct {
36-
query rego.PreparedEvalQuery
36+
query rego.PreparedEvalQuery
37+
partial rego.PreparedPartialQuery
3738
}
3839

3940
// Load the policy from policy.rego in this directory.
@@ -49,10 +50,19 @@ func NewAuthorizer() (*RegoAuthorizer, error) {
4950
rego.Module("policy.rego", policy),
5051
).PrepareForEval(ctx)
5152

53+
partial, err := rego.New(
54+
rego.Query("allowed = data.authz.allow"),
55+
rego.Module("policy.rego", policy),
56+
rego.Unknowns([]string{
57+
"input.object.owner",
58+
"input.object.org_owner",
59+
}),
60+
).PrepareForPartial(ctx)
61+
5262
if err != nil {
5363
return nil, xerrors.Errorf("prepare query: %w", err)
5464
}
55-
return &RegoAuthorizer{query: query}, nil
65+
return &RegoAuthorizer{query: query, partial: partial}, nil
5666
}
5767

5868
type authSubject struct {
@@ -107,3 +117,23 @@ func (a RegoAuthorizer) Authorize(ctx context.Context, subjectID string, roles [
107117

108118
return nil
109119
}
120+
121+
// CheckPartial will not authorize the request. This function is to be used for unit testing to verify the rego policy
122+
// can be converted into ONLY queries. This ensures we can convert the queries into SQL WHERE clauses in the future.
123+
// If this function returns an error, then there is a set of inputs that also returns support rules, which cannot
124+
// be converted.
125+
// This function will not be used to actually perform authorization on partial queries.
126+
func (a RegoAuthorizer) CheckPartial(ctx context.Context, subjectID string, roles []Role, action Action, objectType string) (*rego.PartialQueries, interface{}, error) {
127+
input := map[string]interface{}{
128+
"subject": authSubject{
129+
ID: subjectID,
130+
Roles: roles,
131+
},
132+
"object": map[string]string{
133+
"type": objectType,
134+
},
135+
"action": action,
136+
}
137+
result, err := a.partial.Partial(ctx, rego.EvalInput(input))
138+
return result, input, err
139+
}

coderd/rbac/authz_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"encoding/json"
66
"testing"
77

8+
"github.com/coder/coder/testutil"
9+
810
"github.com/google/uuid"
911
"github.com/stretchr/testify/require"
1012
"golang.org/x/xerrors"
@@ -570,7 +572,9 @@ func testAuthorize(t *testing.T, name string, subject subject, sets ...[]authTes
570572
for _, c := range cases {
571573
t.Run(name, func(t *testing.T) {
572574
for _, a := range c.actions {
573-
err := authorizer.Authorize(context.Background(), subject.UserID, subject.Roles, a, c.resource)
575+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
576+
defer cancel()
577+
err := authorizer.Authorize(ctx, subject.UserID, subject.Roles, a, c.resource)
574578
if c.allow {
575579
if err != nil {
576580
var uerr *rbac.UnauthorizedError
@@ -593,6 +597,20 @@ func testAuthorize(t *testing.T, name string, subject subject, sets ...[]authTes
593597
t.Log(string(d))
594598
}
595599
require.Error(t, err, "expected unauthorized")
600+
601+
// Also check the rego policy can form a valid partial query result.
602+
result, input, err := authorizer.CheckPartial(ctx, subject.UserID, subject.Roles, a, c.resource.Type)
603+
require.NoError(t, err, "check partial")
604+
if len(result.Support) > 0 {
605+
d, _ := json.Marshal(input)
606+
t.Logf("input: %s", string(d))
607+
for _, q := range result.Queries {
608+
t.Logf("query: %+v", q.String())
609+
}
610+
for _, s := range result.Support {
611+
t.Logf("support: %+v", s.String())
612+
}
613+
}
596614
}
597615
})
598616
}

0 commit comments

Comments
 (0)