mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
chore: create type for unique role names (#13506)
* chore: create type for unique role names Using `string` was confusing when something should be combined with org context, and when not to. Naming this new name, "RoleIdentifier"
This commit is contained in:
@ -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.RoleIdentifiers(roleNames),
|
||||
Groups: roles.Groups,
|
||||
Scope: rbac.ScopeName(key.Scope),
|
||||
},
|
||||
@ -435,7 +438,7 @@ func randomRBACType() string {
|
||||
func RandomRBACSubject() rbac.Subject {
|
||||
return rbac.Subject{
|
||||
ID: uuid.NewString(),
|
||||
Roles: rbac.RoleNames{rbac.RoleMember()},
|
||||
Roles: rbac.RoleIdentifiers{rbac.RoleMember()},
|
||||
Groups: []string{namesgenerator.GetRandomName(1)},
|
||||
Scope: rbac.ScopeAll,
|
||||
}
|
||||
|
@ -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"
|
||||
@ -663,21 +664,25 @@ func CreateFirstUser(t testing.TB, client *codersdk.Client) codersdk.CreateFirst
|
||||
|
||||
// CreateAnotherUser creates and authenticates a new user.
|
||||
// Roles can include org scoped roles with 'roleName:<organization_id>'
|
||||
func CreateAnotherUser(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, roles ...string) (*codersdk.Client, codersdk.User) {
|
||||
func CreateAnotherUser(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, roles ...rbac.RoleIdentifier) (*codersdk.Client, codersdk.User) {
|
||||
return createAnotherUserRetry(t, client, organizationID, 5, roles)
|
||||
}
|
||||
|
||||
func CreateAnotherUserMutators(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, roles []string, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
|
||||
func CreateAnotherUserMutators(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, roles []rbac.RoleIdentifier, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
|
||||
return createAnotherUserRetry(t, client, organizationID, 5, roles, mutators...)
|
||||
}
|
||||
|
||||
// AuthzUserSubject does not include the user's groups.
|
||||
func AuthzUserSubject(user codersdk.User, orgID uuid.UUID) rbac.Subject {
|
||||
roles := make(rbac.RoleNames, 0, len(user.Roles))
|
||||
roles := make(rbac.RoleIdentifiers, 0, len(user.Roles))
|
||||
// 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.RoleIdentifier{
|
||||
Name: r.Name,
|
||||
OrganizationID: orgID,
|
||||
})
|
||||
}
|
||||
// We assume only 1 org exists
|
||||
roles = append(roles, rbac.ScopedRoleOrgMember(orgID))
|
||||
@ -690,7 +695,7 @@ func AuthzUserSubject(user codersdk.User, orgID uuid.UUID) rbac.Subject {
|
||||
}
|
||||
}
|
||||
|
||||
func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, retries int, roles []string, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
|
||||
func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationID uuid.UUID, retries int, roles []rbac.RoleIdentifier, mutators ...func(r *codersdk.CreateUserRequest)) (*codersdk.Client, codersdk.User) {
|
||||
req := codersdk.CreateUserRequest{
|
||||
Email: namesgenerator.GetRandomName(10) + "@coder.com",
|
||||
Username: RandomUsername(t),
|
||||
@ -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.RoleIdentifier)
|
||||
var siteRoles []rbac.RoleIdentifier
|
||||
|
||||
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.RoleIdentifier{
|
||||
Name: r.Name,
|
||||
OrganizationID: orgID,
|
||||
})
|
||||
}
|
||||
|
||||
user, err = client.UpdateUserRoles(context.Background(), user.ID.String(), codersdk.UpdateRoles{Roles: siteRoles})
|
||||
onlyName := func(role rbac.RoleIdentifier) string {
|
||||
return role.Name
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user