10000 chore: create type for unique role names by Emyrk · Pull Request #13506 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

chore: create type for unique role names #13506

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jun 11, 2024
Prev Previous commit
Next Next commit
Compiling
  • Loading branch information
Emyrk committed Jun 10, 2024
commit d88c836afd7ddd3e1b967e22af9c96938b4e1b5f
5 changes: 4 additions & 1 deletion coderd/coderdtest/authorize.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,13 @@ func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsse
roles, err := api.Database.GetAuthorizationUserRoles(ctx, key.UserID)
require.NoError(t, err, "fetch user roles")

roleNames, err := roles.RoleNames()
require.NoError(t, err)

return RBACAsserter{
Subject: rbac.Subject{
ID: key.UserID.String(),
Roles: rbac.RoleNames(roles.Roles),
Roles: rbac.RoleNames(roleNames),
Groups: roles.Groups,
Scope: rbac.ScopeName(key.Scope),
},
Expand Down
38 changes: 22 additions & 16 deletions coderd/coderdtest/coderdtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import (
"github.com/coder/coder/v2/coderd/autobuild"
"github.com/coder/coder/v2/coderd/awsidentity"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk"
"github.com/coder/coder/v2/coderd/database/dbauthz"
"github.com/coder/coder/v2/coderd/database/dbrollup"
"github.com/coder/coder/v2/coderd/database/dbtestutil"
Expand Down Expand Up @@ -677,7 +678,11 @@ func AuthzUserSubject(user codersdk.User, orgID uuid.UUID) rbac.Subject {
// Member role is always implied
roles = append(roles, rbac.RoleMember())
for _, r := range user.Roles {
roles = append(roles, r.Name)
orgID, _ := uuid.Parse(r.OrganizationID) // defaults to nil
roles = append(roles, rbac.RoleName{
Name: r.Name,
OrganizationID: orgID,
})
}
// We assume only 1 org exists
roles = append(roles, rbac.ScopedRoleOrgMember(orgID))
Expand Down Expand Up @@ -748,36 +753,37 @@ func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationI

if len(roles) > 0 {
// Find the roles for the org vs the site wide roles
orgRoles := make(map[string][]string)
var siteRoles []string
orgRoles := make(map[uuid.UUID][]rbac.RoleName)
var siteRoles []rbac.RoleName

for _, roleName := range roles {
roleName := roleName
orgID, ok := rbac.IsOrgRole(roleName)
roleName, _, err = rbac.RoleSplit(roleName)
require.NoError(t, err, "split org role name")
ok := roleName.IsOrgRole()
if ok {
roleName, _, err = rbac.RoleSplit(roleName)
require.NoError(t, err, "split rolename")
orgRoles[orgID] = append(orgRoles[orgID], roleName)
orgRoles[roleName.OrganizationID] = append(orgRoles[roleName.OrganizationID], roleName)
} else {
siteRoles = append(siteRoles, roleName)
}
}
// Update the roles
for _, r := range user.Roles {
siteRoles = append(siteRoles, r.Name)
orgID, _ := uuid.Parse(r.OrganizationID)
siteRoles = append(siteRoles, rbac.RoleName{
Name: r.Name,
OrganizationID: orgID,
})
}

onlyName := func(role rbac.RoleName) string {
return role.Name
}

user, err = client.UpdateUserRoles(context.Background(), user.ID.String(), codersdk.UpdateRoles{Roles: siteRoles})
user, err = client.UpdateUserRoles(context.Background(), user.ID.String(), codersdk.UpdateRoles{Roles: db2sdk.List(siteRoles, onlyName)})
require.NoError(t, err, "update site roles")

// Update org roles
for orgID, roles := range orgRoles {
organizationID, err := uuid.Parse(orgID)
require.NoError(t, err, fmt.Sprintf("parse org id %q", orgID))
_, err = client.UpdateOrganizationMemberRoles(context.Background(), organizationID, user.ID.String(),
codersdk.UpdateRoles{Roles: roles})
_, err = client.UpdateOrganizationMemberRoles(context.Background(), orgID, user.ID.String(),
codersdk.UpdateRoles{Roles: db2sdk.List(roles, onlyName)})
require.NoError(t, err, "update org membership roles")
}
}
Expand Down
2 changes: 1 addition & 1 deletion enterprise/coderd/coderd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ func testDBAuthzRole(ctx context.Context) context.Context {
ID: uuid.Nil.String(),
Roles: rbac.Roles([]rbac.Role{
{
Name: "testing",
Name: rbac.RoleName{Name: "testing"},
DisplayName: "Unit Tests",
Site: rbac.Permissions(map[string][]policy.Action{
rbac.ResourceWildcard.Type: {policy.WildcardSymbol},
Expand Down
6 changes: 3 additions & 3 deletions enterprise/coderd/insights_test.go
D7AE
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ func TestTemplateInsightsWithRole(t *testing.T) {

type test struct {
interval codersdk.InsightsReportInterval
role string
role rbac.RoleName
allowed bool
}

tests := []test{
{codersdk.InsightsReportIntervalDay, rbac.RoleTemplateAdmin(), true},
{"", rbac.RoleTemplateAdmin(), true},
{codersdk.InsightsReportIntervalDay, "auditor", true},
{"", "auditor", true},
{codersdk.InsightsReportIntervalDay, rbac.RoleAuditor(), true},
{"", rbac.RoleAuditor(), true},
{codersdk.InsightsReportIntervalDay, rbac.RoleUserAdmin(), false},
{"", rbac.RoleUserAdmin(), false},
{codersdk.InsightsReportIntervalDay, rbac.RoleMember(), false},
Expand Down
7 changes: 4 additions & 3 deletions enterprise/coderd/roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/coderd/license"
Expand Down Expand Up @@ -57,7 +58,7 @@ func TestCustomOrganizationRole(t *testing.T) {
require.NoError(t, err, "upsert role")

// Assign the custom template admin role
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, role.FullName())
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, rbac.RoleName{Name: role.Name, OrganizationID: first.OrganizationID})

// Assert the role exists
// TODO: At present user roles are not returned by the user endpoints.
Expand Down Expand Up @@ -124,7 +125,7 @@ func TestCustomOrganizationRole(t *testing.T) {
require.ErrorContains(t, err, "roles are not enabled")

// Assign the custom template admin role
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, role.FullName())
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, rbac.RoleName{Name: role.Name, OrganizationID: first.OrganizationID})

// Try to create a template version, eg using the custom role
coderdtest.CreateTemplateVersion(t, tmplAdmin, first.OrganizationID, nil)
Expand Down Expand Up @@ -152,7 +153,7 @@ func TestCustomOrganizationRole(t *testing.T) {
require.NoError(t, err, "upsert role")

// Assign the custom template admin role
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, role.FullName())
tmplAdmin, _ := coderdtest.CreateAnotherUser(t, owner, first.OrganizationID, rbac.RoleName{Name: role.Name, OrganizationID: first.OrganizationID})

// Try to create a template version, eg using the custom role
coderdtest.CreateTemplateVersion(t, tmplAdmin, first.OrganizationID, nil)
Expand Down
22 changes: 11 additions & 11 deletions enterprise/coderd/userauth_test.go
< F438 input type="hidden" name="path" value="enterprise/coderd/userauth_test.go" autocomplete="off" data-targets="deferred-diff-lines.inputs" />
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestUserOIDC(t *testing.T) {
cfg.AllowSignups = true
cfg.UserRoleField = "roles"
cfg.UserRoleMapping = map[string][]string{
oidcRoleName: {rbac.RoleTemplateAdmin()},
oidcRoleName: {rbac.RoleTemplateAdmin().String()},
}
},
})
Expand All @@ -79,7 +79,7 @@ func TestUserOIDC(t *testing.T) {
"roles": oidcRoleName,
})
require.Equal(t, http.StatusOK, resp.StatusCode)
runner.AssertRoles(t, "alice", []string{rbac.RoleTemplateAdmin()})
runner.AssertRoles(t, "alice", []string{rbac.RoleTemplateAdmin().String()})
})

// A user has some roles, then on an oauth refresh will lose said
Expand All @@ -92,23 +92,23 @@ func TestUserOIDC(t *testing.T) {

const oidcRoleName = "TemplateAuthor"
runner := setupOIDCTest(t, oidcTestConfig{
Userinfo: jwt.MapClaims{oidcRoleName: []string{rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()}},
Userinfo: jwt.MapClaims{oidcRoleName: []string{rbac.RoleTemplateAdmin().String(), rbac.RoleUserAdmin().String()}},
Config: func(cfg *coderd.OIDCConfig) {
cfg.AllowSignups = true
cfg.UserRoleField = "roles"
cfg.UserRoleMapping = map[string][]string{
oidcRoleName: {rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()},
oidcRoleName: {rbac.RoleTemplateAdmin().String(), rbac.RoleUserAdmin().String()},
}
},
})

// User starts with the owner role
client, resp := runner.Login(t, jwt.MapClaims{
"email": "alice@coder.com",
"roles": []string{"random", oidcRoleName, rbac.RoleOwner()},
"roles": []string{"random", oidcRoleName, rbac.RoleOwner().String()},
})
require.Equal(t, http.StatusOK, resp.StatusCode)
runner.AssertRoles(t, "alice", []string{rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin(), rbac.RoleOwner()})
runner.AssertRoles(t, "alice", []string{rbac.RoleTemplateAdmin().String(), rbac.RoleUserAdmin().String(), rbac.RoleOwner().String()})

// Now refresh the oauth, and check the roles are removed.
// Force a refresh, and assert nothing has changes
Expand All @@ -126,23 +126,23 @@ func TestUserOIDC(t *testing.T) {

const oidcRoleName = "TemplateAuthor"
runner := setupOIDCTest(t, oidcTestConfig{
Userinfo: jwt.MapClaims{oidcRoleName: []string{rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()}},
Userinfo: jwt.MapClaims{oidcRoleName: []string{rbac.RoleTemplateAdmin().String(), rbac.RoleUserAdmin().String()}},
Config: func(cfg *coderd.OIDCConfig) {
cfg.AllowSignups = true
cfg.UserRoleField = "roles"
cfg.UserRoleMapping = map[string][]string{
oidcRoleName: {rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin()},
oidcRoleName: {rbac.RoleTemplateAdmin().String(), rbac.RoleUserAdmin().String()},
}
},
})

// User starts with the owner role
_, resp := runner.Login(t, jwt.MapClaims{
"email": "alice@coder.com",
"roles": []string{"random", oidcRoleName, rbac.RoleOwner()},
"roles": []string{"random", oidcRoleName, rbac.RoleOwner().String()},
})
require.Equal(t, http.StatusOK, resp.StatusCode)
runner.AssertRoles(t, "alice", []string{rbac.RoleTemplateAdmin(), rbac.RoleUserAdmin(), rbac.RoleOwner()})
runner.AssertRoles(t, "alice", []string{rbac.RoleTemplateAdmin().String(), rbac.RoleUserAdmin().String(), rbac.RoleOwner().String()})

// Now login with oauth again, and check the roles are removed.
_, resp = runner.Login(t, jwt.MapClaims{
Expand Down Expand Up @@ -175,7 +175,7 @@ func TestUserOIDC(t *testing.T) {
ctx := testutil.Context(t, testutil.WaitShort)
_, err := runner.AdminClient.UpdateUserRoles(ctx, "alice", codersdk.UpdateRoles{
Roles: []string{
rbac.RoleTemplateAdmin(),
rbac.RoleTemplateAdmin().String(),
},
})
require.Error(t, err)
Expand Down
0