Skip to content

Commit 0876d12

Browse files
committed
checkpoint: clean up example_test
1 parent 629d315 commit 0876d12

File tree

4 files changed

+151
-98
lines changed

4 files changed

+151
-98
lines changed

coderd/authz/authz.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ import (
99
var ErrUnauthorized = errors.New("unauthorized")
1010

1111
// TODO: Implement Authorize
12-
func Authorize(subj Subject, res Resource, action rbac.Operation) error {
12+
func Authorize(subj Subject, res Object, action rbac.Operation) error {
1313
// TODO: Expand subject roles into their permissions as appropriate. Apply scopes.
1414

15-
if SiteEnforcer.RolesHavePermission(subj.Roles(), res.ResourceType(), action) {
15+
if res.ObjectType == "" {
16+
return ErrUnauthorized
17+
}
18+
19+
if SiteEnforcer.RolesHavePermission(subj.Roles(), res.ObjectType, action) {
1620
return nil
1721
}
1822

coderd/authz/authz_test.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package authz_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/coder/coder/coderd/authz/rbac"
7+
8+
"github.com/stretchr/testify/require"
9+
10+
"github.com/coder/coder/coderd/authz"
11+
)
12+
13+
func TestAuthorize(t *testing.T) {
14+
t.Parallel()
15+
16+
// testCases := []struct {
17+
// Subject authz.Subject
18+
// Resource authz.Object
19+
// Action rbac.Operation
20+
// ExpectedError string
21+
// }{
22+
// {
23+
// Subject: &authz.SubjectTODO{
24+
// UserID: "user",
25+
// Site: []rbac.Role{authz.SiteMember},
26+
// Org: map[string]rbac.Roles{
27+
// "default": {authz.OrganizationAdmin},
28+
// },
29+
// },
30+
// Resource: &authz.Object{},
31+
// },
32+
// }
33+
34+
// user will become an authn object, and can even be a database.User if it
35+
// fulfills the interface. Until then, use a placeholder.
36+
user := authz.SubjectTODO{
37+
UserID: "alice",
38+
// No site perms
39+
Site: []rbac.Role{authz.SiteMember},
40+
Org: map[string]rbac.Roles{
41+
// Admin of org "default".
42+
"default": {authz.OrganizationAdmin},
43+
},
44+
}
45+
46+
// TODO: Uncomment all assertions when implementation is done.
47+
48+
//nolint:paralleltest
49+
t.Run("ReadAllWorkspaces", func(t *testing.T) {
50+
// To read all workspaces on the site
51+
err := authz.Authorize(user, authz.Object{}, authz.ReadAll)
52+
var _ = err
53+
require.Error(t, err, "this user cannot read all workspaces")
54+
})
55+
56+
// nolint:paralleltest
57+
// t.Run("ReadOrgWorkspaces", func(t *testing.T) {
58+
// To read all workspaces on the org 'default'
59+
// err := authz.Authorize(user, authz.ResourceWorkspace.Org("default"), authz.ActionRead)
60+
// require.NoError(t, err, "this user can read all org workspaces in 'default'")
61+
// })
62+
//
63+
// nolint:paralleltest
64+
// t.Run("ReadMyWorkspace", func(t *testing.T) {
65+
// Note 'database.Workspace' could fulfill the object interface and be passed in directly
66+
// err := authz.Authorize(user, authz.ResourceWorkspace.Org("default").Owner(user.UserID), authz.ActionRead)
67+
// require.NoError(t, err, "this user can their workspace")
68+
//
69+
// err = authz.Authorize(user, authz.ResourceWorkspace.Org("default").Owner(user.UserID).AsID("1234"), authz.ActionRead)
70+
// require.NoError(t, err, "this user can read workspace '1234'")
71+
// })
72+
//
73+
// nolint:paralleltest
74+
// t.Run("CreateNewSiteUser", func(t *testing.T) {
75+
// err := authz.Authorize(user, authz.ResourceUser, authz.ActionCreate)
76+
// var _ = err
77+
// require.Error(t, err, "this user cannot create new users")
78+
// })
79+
}

coderd/authz/example_test.go

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,44 +27,9 @@ func TestExample(t *testing.T) {
2727
},
2828
}
2929

30-
// TODO: Uncomment all assertions when implementation is done.
31-
32-
//nolint:paralleltest
33-
t.Run("ReadAllWorkspaces", func(t *testing.T) {
34-
// To read all workspaces on the site
35-
err := authz.Authorize(user, authz.Object{}, authz.ReadAll)
36-
var _ = err
37-
require.Error(t, err, "this user cannot read all workspaces")
38-
})
39-
40-
// nolint:paralleltest
41-
// t.Run("ReadOrgWorkspaces", func(t *testing.T) {
42-
// To read all workspaces on the org 'default'
43-
// err := authz.Authorize(user, authz.ResourceWorkspace.Org("default"), authz.ActionRead)
44-
// require.NoError(t, err, "this user can read all org workspaces in 'default'")
45-
// })
46-
//
47-
// nolint:paralleltest
48-
// t.Run("ReadMyWorkspace", func(t *testing.T) {
49-
// Note 'database.Workspace' could fulfill the object interface and be passed in directly
50-
// err := authz.Authorize(user, authz.ResourceWorkspace.Org("default").Owner(user.UserID), authz.ActionRead)
51-
// require.NoError(t, err, "this user can their workspace")
52-
//
53-
// err = authz.Authorize(user, authz.ResourceWorkspace.Org("default").Owner(user.UserID).AsID("1234"), authz.ActionRead)
54-
// require.NoError(t, err, "this user can read workspace '1234'")
55-
// })
56-
//
57-
// nolint:paralleltest
58-
// t.Run("CreateNewSiteUser", func(t *testing.T) {
59-
// err := authz.Authorize(user, authz.ResourceUser, authz.ActionCreate)
60-
// var _ = err
61-
// require.Error(t, err, "this user cannot create new users")
62-
// })
63-
}
64-
65-
func must[r any](v r, err error) r {
66-
if err != nil {
67-
panic(err)
68-
}
69-
return v
30+
// To read all workspaces on the site
31+
err := authz.Authorize(user, authz.Object{
32+
ObjectType: authz.Workspaces,
33+
}, authz.ReadAll)
34+
require.EqualError(t, err, authz.ErrUnauthorized.Error(), "this user cannot read all workspaces")
7035
}

coderd/authz/object.go

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,77 @@ package authz
22

33
import "github.com/coder/coder/coderd/authz/rbac"
44

5-
type Resource interface {
6-
ID() string
7-
ResourceType() rbac.Resource
8-
}
9-
10-
type UserResource interface {
11-
Resource
12-
OwnerID() string
13-
}
14-
15-
type OrgResource interface {
16-
Resource
17-
OrgOwnerID() string
18-
}
19-
20-
var _ Resource = (*Object)(nil)
21-
var _ UserResource = (*Object)(nil)
22-
var _ OrgResource = (*Object)(nil)
5+
// type Resource interface {
6+
// ID() string
7+
// ResourceType() rbac.Resource
8+
// }
9+
//
10+
// type UserResource interface {
11+
// Resource
12+
// OwnerID() string
13+
// }
14+
//
15+
// type OrgResource interface {
16+
// Resource
17+
// OrgOwnerID() string
18+
// }
19+
//
20+
// var _ Resource = (*Object)(nil)
21+
// var _ UserResource = (*Object)(nil)
22+
// var _ OrgResource = (*Object)(nil)
2323

2424
// Object is used to create objects for authz checks when you have none in
2525
// hand to run the check on.
2626
// An example is if you want to list all workspaces, you can create a Object
2727
// that represents the set of workspaces you are trying to get access too.
2828
// Do not export this type, as it can be created from a resource type constant.
2929
type Object struct {
30-
id string
31-
owner string
32-
orgOwner string
30+
// ID string
31+
ID string
32+
// Owner string
33+
Owner string
34+
// OrgOwner string
35+
OrgOwner string
3336

34-
// objectType is "workspace", "project", "devurl", etc
35-
objectType rbac.Resource
37+
// ObjectType is "workspace", "project", "devurl", etc
38+
// ObjectType rbac.Resource
39+
ObjectType rbac.Resource
3640
// TODO: SharedUsers?
3741
}
3842

39-
func (z Object) ID() string {
40-
return z.id
41-
}
42-
43-
func (z Object) ResourceType() rbac.Resource {
44-
return z.objectType
45-
}
46-
47-
func (z Object) OwnerID() string {
48-
return z.owner
49-
}
50-
51-
func (z Object) OrgOwnerID() string {
52-
return z.orgOwner
53-
}
54-
43+
// func (z Object) ID() string {
44+
// return z.id
45+
// }
46+
//
47+
// func (z Object) ResourceType() rbac.Resource {
48+
// return z.objectType
49+
// }
50+
//
51+
// func (z Object) OwnerID() string {
52+
// return z.owner
53+
// }
54+
//
55+
// func (z Object) OrgOwnerID() string {
56+
// return z.orgOwner
57+
// }
58+
//
5559
// Org adds an org OwnerID to the resource
56-
//nolint:revive
57-
func (z Object) Org(orgID string) Object {
58-
z.orgOwner = orgID
59-
return z
60-
}
61-
60+
// nolint:revive
61+
// func (z Object) Org(orgID string) Object {
62+
// z.orgOwner = orgID
63+
// return z
64+
// }
65+
//
6266
// Owner adds an OwnerID to the resource
63-
//nolint:revive
64-
func (z Object) Owner(id string) Object {
65-
z.owner = id
66-
return z
67-
}
68-
69-
//nolint:revive
70-
func (z Object) AsID(id string) Object {
71-
z.id = id
72-
return z
73-
}
67+
// nolint:revive
68+
// func (z Object) Owner(id string) Object {
69+
// z.owner = id
70+
// return z
71+
// }
72+
//
73+
// nolint:revive
74+
// func (z Object) AsID(id string) Object {
75+
// z.id = id
76+
// return z
77+
// }
78+
//

0 commit comments

Comments
 (0)