mirror of
https://github.com/coder/coder.git
synced 2026-09-21 20:51:01 +08:00
chore: remove organization_id suffix from org_member roles in database (#13473)
Organization member's table is already scoped to an organization. Rolename should avoid having the org_id appended. Wipes all existing organization role assignments, which should not be used anyway.
This commit is contained in:
@@ -222,7 +222,7 @@ func (r *RootCmd) newCreateAdminUserCommand() *serpent.Command {
|
||||
UserID: newUser.ID,
|
||||
CreatedAt: dbtime.Now(),
|
||||
UpdatedAt: dbtime.Now(),
|
||||
Roles: []string{rbac.RoleOrgAdmin(org.ID)},
|
||||
Roles: []string{rbac.ScopedRoleOrgAdmin(org.ID)},
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert organization member: %w", err)
|
||||
|
||||
@@ -71,7 +71,7 @@ func TestServerCreateAdminUser(t *testing.T) {
|
||||
orgIDs2 := make(map[uuid.UUID]struct{}, len(orgMemberships))
|
||||
for _, membership := range orgMemberships {
|
||||
orgIDs2[membership.OrganizationID] = struct{}{}
|
||||
assert.Equal(t, []string{rbac.RoleOrgAdmin(membership.OrganizationID)}, membership.Roles, "user is not org admin")
|
||||
assert.Equal(t, []string{rbac.ScopedRoleOrgAdmin(membership.OrganizationID)}, membership.Roles, "user is not org admin")
|
||||
}
|
||||
|
||||
require.Equal(t, orgIDs, orgIDs2, "user is not in all orgs")
|
||||
|
||||
Generated
+3
@@ -11458,6 +11458,9 @@ const docTemplate = `{
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Generated
+3
@@ -10341,6 +10341,9 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"organization_id": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -27,7 +27,7 @@ func TestCheckPermissions(t *testing.T) {
|
||||
memberClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID)
|
||||
memberUser, err := memberClient.User(ctx, codersdk.Me)
|
||||
require.NoError(t, err)
|
||||
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID, rbac.RoleOrgAdmin(adminUser.OrganizationID))
|
||||
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID, rbac.ScopedRoleOrgAdmin(adminUser.OrganizationID))
|
||||
orgAdminUser, err := orgAdminClient.User(ctx, codersdk.Me)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ func setupDeps(t *testing.T, store database.Store, ps pubsub.Pubsub) deps {
|
||||
_, err := store.InsertOrganizationMember(context.Background(), database.InsertOrganizationMemberParams{
|
||||
OrganizationID: org.ID,
|
||||
UserID: user.ID,
|
||||
Roles: []string{rbac.RoleOrgMember(org.ID)},
|
||||
Roles: []string{rbac.ScopedRoleOrgMember(org.ID)},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
tv := dbgen.TemplateVersion(t, store, database.TemplateVersion{
|
||||
|
||||
@@ -663,6 +663,7 @@ 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) {
|
||||
return createAnotherUserRetry(t, client, organizationID, 5, roles)
|
||||
}
|
||||
@@ -680,7 +681,7 @@ func AuthzUserSubject(user codersdk.User, orgID uuid.UUID) rbac.Subject {
|
||||
roles = append(roles, r.Name)
|
||||
}
|
||||
// We assume only 1 org exists
|
||||
roles = append(roles, rbac.RoleOrgMember(orgID))
|
||||
roles = append(roles, rbac.ScopedRoleOrgMember(orgID))
|
||||
|
||||
return rbac.Subject{
|
||||
ID: user.ID.String(),
|
||||
@@ -754,6 +755,8 @@ func createAnotherUserRetry(t testing.TB, client *codersdk.Client, organizationI
|
||||
for _, roleName := range roles {
|
||||
roleName := roleName
|
||||
orgID, ok := rbac.IsOrgRole(roleName)
|
||||
roleName, _, err = rbac.RoleSplit(roleName)
|
||||
require.NoError(t, err, "split org role name")
|
||||
if ok {
|
||||
orgRoles[orgID] = append(orgRoles[orgID], roleName)
|
||||
} else {
|
||||
|
||||
@@ -204,13 +204,6 @@ func Group(group database.Group, members []database.User) codersdk.Group {
|
||||
}
|
||||
}
|
||||
|
||||
func SlimRole(role rbac.Role) codersdk.SlimRole {
|
||||
return codersdk.SlimRole{
|
||||
DisplayName: role.DisplayName,
|
||||
Name: role.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func TemplateInsightsParameters(parameterRows []database.GetTemplateParameterInsightsRow) ([]codersdk.TemplateParameterUsage, error) {
|
||||
// Use a stable sort, similarly to how we would sort in the query, note that
|
||||
// we don't sort in the query because order varies depending on the table
|
||||
@@ -525,6 +518,19 @@ func ProvisionerDaemon(dbDaemon database.ProvisionerDaemon) codersdk.Provisioner
|
||||
return result
|
||||
}
|
||||
|
||||
func SlimRole(role rbac.Role) codersdk.SlimRole {
|
||||
roleName, orgIDStr, err := rbac.RoleSplit(role.Name)
|
||||
if err != nil {
|
||||
roleName = role.Name
|
||||
}
|
||||
|
||||
return codersdk.SlimRole{
|
||||
DisplayName: role.DisplayName,
|
||||
Name: roleName,
|
||||
OrganizationID: orgIDStr,
|
||||
}
|
||||
}
|
||||
|
||||
func RBACRole(role rbac.Role) codersdk.Role {
|
||||
roleName, orgIDStr, err := rbac.RoleSplit(role.Name)
|
||||
if err != nil {
|
||||
|
||||
@@ -153,7 +153,7 @@ func TestUpsertCustomRoles(t *testing.T) {
|
||||
UUID: uuid.New(),
|
||||
Valid: true,
|
||||
},
|
||||
subject: merge(canAssignRole, rbac.RoleOrgAdmin(orgID.UUID)),
|
||||
subject: merge(canAssignRole, rbac.ScopedRoleOrgAdmin(orgID.UUID)),
|
||||
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
|
||||
codersdk.ResourceWorkspace: {codersdk.ActionRead},
|
||||
}),
|
||||
@@ -162,7 +162,7 @@ func TestUpsertCustomRoles(t *testing.T) {
|
||||
{
|
||||
name: "user-escalation",
|
||||
// These roles do not grant user perms
|
||||
subject: merge(canAssignRole, rbac.RoleOrgAdmin(orgID.UUID)),
|
||||
subject: merge(canAssignRole, rbac.ScopedRoleOrgAdmin(orgID.UUID)),
|
||||
user: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
|
||||
codersdk.ResourceWorkspace: {codersdk.ActionRead},
|
||||
}),
|
||||
@@ -190,7 +190,7 @@ func TestUpsertCustomRoles(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "read-workspace-in-org",
|
||||
subject: merge(canAssignRole, rbac.RoleOrgAdmin(orgID.UUID)),
|
||||
subject: merge(canAssignRole, rbac.ScopedRoleOrgAdmin(orgID.UUID)),
|
||||
organizationID: orgID,
|
||||
org: codersdk.CreatePermissions(map[codersdk.RBACResource][]codersdk.RBACAction{
|
||||
codersdk.ResourceWorkspace: {codersdk.ActionRead},
|
||||
|
||||
@@ -2472,7 +2472,7 @@ func (q *querier) InsertOrganization(ctx context.Context, arg database.InsertOrg
|
||||
|
||||
func (q *querier) InsertOrganizationMember(ctx context.Context, arg database.InsertOrganizationMemberParams) (database.OrganizationMember, error) {
|
||||
// All roles are added roles. Org member is always implied.
|
||||
addedRoles := append(arg.Roles, rbac.RoleOrgMember(arg.OrganizationID))
|
||||
addedRoles := append(arg.Roles, rbac.ScopedRoleOrgMember(arg.OrganizationID))
|
||||
err := q.canAssignRoles(ctx, &arg.OrganizationID, addedRoles, []string{})
|
||||
if err != nil {
|
||||
return database.OrganizationMember{}, err
|
||||
@@ -2847,8 +2847,22 @@ func (q *querier) UpdateMemberRoles(ctx context.Context, arg database.UpdateMemb
|
||||
return database.OrganizationMember{}, err
|
||||
}
|
||||
|
||||
// The 'rbac' package expects role names to be scoped.
|
||||
// Convert the argument roles for validation.
|
||||
scopedGranted := make([]string, 0, len(arg.GrantedRoles))
|
||||
for _, grantedRole := range arg.GrantedRoles {
|
||||
// This check is a developer safety check. Old code might try to invoke this code path with
|
||||
// organization id suffixes. Catch this and return a nice error so it can be fixed.
|
||||
_, foundOrg, _ := rbac.RoleSplit(grantedRole)
|
||||
if foundOrg != "" {
|
||||
return database.OrganizationMember{}, xerrors.Errorf("attempt to assign a role %q, remove the ':<organization_id> suffix", grantedRole)
|
||||
}
|
||||
|
||||
scopedGranted = append(scopedGranted, rbac.RoleName(grantedRole, arg.OrgID.String()))
|
||||
}
|
||||
|
||||
// The org member role is always implied.
|
||||
impliedTypes := append(arg.GrantedRoles, rbac.RoleOrgMember(arg.OrgID))
|
||||
impliedTypes := append(scopedGranted, rbac.ScopedRoleOrgMember(arg.OrgID))
|
||||
added, removed := rbac.ChangeRoleSet(member.Roles, impliedTypes)
|
||||
err = q.canAssignRoles(ctx, &arg.OrgID, added, removed)
|
||||
if err != nil {
|
||||
|
||||
@@ -636,7 +636,7 @@ func (s *MethodTestSuite) TestOrganization() {
|
||||
check.Args(database.InsertOrganizationMemberParams{
|
||||
OrganizationID: o.ID,
|
||||
UserID: u.ID,
|
||||
Roles: []string{rbac.RoleOrgAdmin(o.ID)},
|
||||
Roles: []string{rbac.ScopedRoleOrgAdmin(o.ID)},
|
||||
}).Asserts(
|
||||
rbac.ResourceAssignRole.InOrg(o.ID), policy.ActionAssign,
|
||||
rbac.ResourceOrganizationMember.InOrg(o.ID).WithID(u.ID), policy.ActionCreate)
|
||||
@@ -664,7 +664,7 @@ func (s *MethodTestSuite) TestOrganization() {
|
||||
mem := dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{
|
||||
OrganizationID: o.ID,
|
||||
UserID: u.ID,
|
||||
Roles: []string{rbac.RoleOrgAdmin(o.ID)},
|
||||
Roles: []string{rbac.ScopedRoleOrgAdmin(o.ID)},
|
||||
})
|
||||
out := mem
|
||||
out.Roles = []string{}
|
||||
|
||||
@@ -1997,7 +1997,9 @@ func (q *FakeQuerier) GetAuthorizationUserRoles(_ context.Context, userID uuid.U
|
||||
|
||||
for _, mem := range q.organizationMembers {
|
||||
if mem.UserID == userID {
|
||||
roles = append(roles, mem.Roles...)
|
||||
for _, orgRole := range mem.Roles {
|
||||
roles = append(roles, orgRole+":"+mem.OrganizationID.String())
|
||||
}
|
||||
roles = append(roles, "organization-member:"+mem.OrganizationID.String())
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+1
-1
@@ -576,7 +576,7 @@ CREATE TABLE organization_members (
|
||||
organization_id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
roles text[] DEFAULT '{organization-member}'::text[] NOT NULL
|
||||
roles text[] DEFAULT '{}'::text[] NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE organizations (
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE ONLY organization_members ALTER COLUMN roles SET DEFAULT '{organization-member}';
|
||||
@@ -0,0 +1,7 @@
|
||||
-- The default was 'organization-member', but we imply that in the
|
||||
-- 'GetAuthorizationUserRoles' query.
|
||||
ALTER TABLE ONLY organization_members ALTER COLUMN roles SET DEFAULT '{}';
|
||||
|
||||
-- No one should be using organization roles yet. If they are, the names in the
|
||||
-- database are now incorrect. Just remove them all.
|
||||
UPDATE organization_members SET roles = '{}';
|
||||
@@ -8432,12 +8432,14 @@ SELECT
|
||||
array_append(users.rbac_roles, 'member'),
|
||||
(
|
||||
SELECT
|
||||
array_agg(org_roles)
|
||||
-- The roles are returned as a flat array, org scoped and site side.
|
||||
-- Concatenating the organization id scopes the organization roles.
|
||||
array_agg(org_roles || ':' || organization_members.organization_id::text)
|
||||
FROM
|
||||
organization_members,
|
||||
-- All org_members get the org-member role for their orgs
|
||||
-- All org_members get the organization-member role for their orgs
|
||||
unnest(
|
||||
array_append(roles, 'organization-member:' || organization_members.organization_id::text)
|
||||
array_append(roles, 'organization-member')
|
||||
) AS org_roles
|
||||
WHERE
|
||||
user_id = users.id
|
||||
|
||||
@@ -227,12 +227,14 @@ SELECT
|
||||
array_append(users.rbac_roles, 'member'),
|
||||
(
|
||||
SELECT
|
||||
array_agg(org_roles)
|
||||
-- The roles are returned as a flat array, org scoped and site side.
|
||||
-- Concatenating the organization id scopes the organization roles.
|
||||
array_agg(org_roles || ':' || organization_members.organization_id::text)
|
||||
FROM
|
||||
organization_members,
|
||||
-- All org_members get the org-member role for their orgs
|
||||
-- All org_members get the organization-member role for their orgs
|
||||
unnest(
|
||||
array_append(roles, 'organization-member:' || organization_members.organization_id::text)
|
||||
array_append(roles, 'organization-member')
|
||||
) AS org_roles
|
||||
WHERE
|
||||
user_id = users.id
|
||||
|
||||
@@ -68,7 +68,7 @@ func TestExtractUserRoles(t *testing.T) {
|
||||
Roles: orgRoles,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return user, append(roles, append(orgRoles, rbac.RoleMember(), rbac.RoleOrgMember(org.ID))...), token
|
||||
return user, append(roles, append(orgRoles, rbac.RoleMember(), rbac.ScopedRoleOrgMember(org.ID))...), token
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -89,7 +89,8 @@ func TestExtractUserRoles(t *testing.T) {
|
||||
|
||||
orgRoles := []string{}
|
||||
if i%2 == 0 {
|
||||
orgRoles = append(orgRoles, rbac.RoleOrgAdmin(organization.ID))
|
||||
orgRoles = append(orgRoles, rbac.RoleOrgAdmin())
|
||||
roles = append(roles, rbac.ScopedRoleOrgAdmin(organization.ID))
|
||||
}
|
||||
_, err = db.InsertOrganizationMember(context.Background(), database.InsertOrganizationMemberParams{
|
||||
OrganizationID: organization.ID,
|
||||
@@ -99,8 +100,7 @@ func TestExtractUserRoles(t *testing.T) {
|
||||
Roles: orgRoles,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
roles = append(roles, orgRoles...)
|
||||
roles = append(roles, rbac.RoleOrgMember(organization.ID))
|
||||
roles = append(roles, rbac.ScopedRoleOrgMember(organization.ID))
|
||||
}
|
||||
return user, roles, token
|
||||
},
|
||||
|
||||
@@ -152,7 +152,7 @@ func TestOrganizationParam(t *testing.T) {
|
||||
_ = dbgen.OrganizationMember(t, db, database.OrganizationMember{
|
||||
OrganizationID: organization.ID,
|
||||
UserID: user.ID,
|
||||
Roles: []string{rbac.RoleOrgMember(organization.ID)},
|
||||
Roles: []string{rbac.ScopedRoleOrgMember(organization.ID)},
|
||||
})
|
||||
_, err := db.UpdateUserRoles(ctx, database.UpdateUserRolesParams{
|
||||
ID: user.ID,
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ func convertOrganizationMember(mem database.OrganizationMember) codersdk.Organiz
|
||||
}
|
||||
|
||||
for _, roleName := range mem.Roles {
|
||||
rbacRole, _ := rbac.RoleByName(roleName)
|
||||
rbacRole, _ := rbac.RoleByName(rbac.RoleName(roleName, mem.OrganizationID.String()))
|
||||
convertedMember.Roles = append(convertedMember.Roles, db2sdk.SlimRole(rbacRole))
|
||||
}
|
||||
return convertedMember
|
||||
|
||||
@@ -94,7 +94,7 @@ func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) {
|
||||
// come back to determining the default role of the person who
|
||||
// creates the org. Until that happens, all users in an organization
|
||||
// should be just regular members.
|
||||
rbac.RoleOrgMember(organization.ID),
|
||||
rbac.ScopedRoleOrgMember(organization.ID),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -168,7 +168,7 @@ func TestFilter(t *testing.T) {
|
||||
Name: "Admin",
|
||||
Actor: Subject{
|
||||
ID: userIDs[0].String(),
|
||||
Roles: RoleNames{RoleOrgMember(orgIDs[0]), "auditor", RoleOwner(), RoleMember()},
|
||||
Roles: RoleNames{ScopedRoleOrgMember(orgIDs[0]), "auditor", RoleOwner(), RoleMember()},
|
||||
},
|
||||
ObjectType: ResourceWorkspace.Type,
|
||||
Action: policy.ActionRead,
|
||||
@@ -177,7 +177,7 @@ func TestFilter(t *testing.T) {
|
||||
Name: "OrgAdmin",
|
||||
Actor: Subject{
|
||||
ID: userIDs[0].String(),
|
||||
Roles: RoleNames{RoleOrgMember(orgIDs[0]), RoleOrgAdmin(orgIDs[0]), RoleMember()},
|
||||
Roles: RoleNames{ScopedRoleOrgMember(orgIDs[0]), ScopedRoleOrgAdmin(orgIDs[0]), RoleMember()},
|
||||
},
|
||||
ObjectType: ResourceWorkspace.Type,
|
||||
Action: policy.ActionRead,
|
||||
@@ -186,7 +186,7 @@ func TestFilter(t *testing.T) {
|
||||
Name: "OrgMember",
|
||||
Actor: Subject{
|
||||
ID: userIDs[0].String(),
|
||||
Roles: RoleNames{RoleOrgMember(orgIDs[0]), RoleOrgMember(orgIDs[1]), RoleMember()},
|
||||
Roles: RoleNames{ScopedRoleOrgMember(orgIDs[0]), ScopedRoleOrgMember(orgIDs[1]), RoleMember()},
|
||||
},
|
||||
ObjectType: ResourceWorkspace.Type,
|
||||
Action: policy.ActionRead,
|
||||
@@ -196,11 +196,11 @@ func TestFilter(t *testing.T) {
|
||||
Actor: Subject{
|
||||
ID: userIDs[0].String(),
|
||||
Roles: RoleNames{
|
||||
RoleOrgMember(orgIDs[0]), RoleOrgAdmin(orgIDs[0]),
|
||||
RoleOrgMember(orgIDs[1]), RoleOrgAdmin(orgIDs[1]),
|
||||
RoleOrgMember(orgIDs[2]), RoleOrgAdmin(orgIDs[2]),
|
||||
RoleOrgMember(orgIDs[4]),
|
||||
RoleOrgMember(orgIDs[5]),
|
||||
ScopedRoleOrgMember(orgIDs[0]), ScopedRoleOrgAdmin(orgIDs[0]),
|
||||
ScopedRoleOrgMember(orgIDs[1]), ScopedRoleOrgAdmin(orgIDs[1]),
|
||||
ScopedRoleOrgMember(orgIDs[2]), ScopedRoleOrgAdmin(orgIDs[2]),
|
||||
ScopedRoleOrgMember(orgIDs[4]),
|
||||
ScopedRoleOrgMember(orgIDs[5]),
|
||||
RoleMember(),
|
||||
},
|
||||
},
|
||||
@@ -221,10 +221,10 @@ func TestFilter(t *testing.T) {
|
||||
Actor: Subject{
|
||||
ID: userIDs[0].String(),
|
||||
Roles: RoleNames{
|
||||
RoleOrgMember(orgIDs[0]),
|
||||
RoleOrgMember(orgIDs[1]),
|
||||
RoleOrgMember(orgIDs[2]),
|
||||
RoleOrgMember(orgIDs[3]),
|
||||
ScopedRoleOrgMember(orgIDs[0]),
|
||||
ScopedRoleOrgMember(orgIDs[1]),
|
||||
ScopedRoleOrgMember(orgIDs[2]),
|
||||
ScopedRoleOrgMember(orgIDs[3]),
|
||||
RoleMember(),
|
||||
},
|
||||
},
|
||||
@@ -235,7 +235,7 @@ func TestFilter(t *testing.T) {
|
||||
Name: "ScopeApplicationConnect",
|
||||
Actor: Subject{
|
||||
ID: userIDs[0].String(),
|
||||
Roles: RoleNames{RoleOrgMember(orgIDs[0]), "auditor", RoleOwner(), RoleMember()},
|
||||
Roles: RoleNames{ScopedRoleOrgMember(orgIDs[0]), "auditor", RoleOwner(), RoleMember()},
|
||||
},
|
||||
ObjectType: ResourceWorkspace.Type,
|
||||
Action: policy.ActionRead,
|
||||
@@ -297,7 +297,7 @@ func TestAuthorizeDomain(t *testing.T) {
|
||||
Groups: []string{allUsersGroup},
|
||||
Roles: Roles{
|
||||
must(RoleByName(RoleMember())),
|
||||
must(RoleByName(RoleOrgMember(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgMember(defOrg))),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ func TestAuthorizeDomain(t *testing.T) {
|
||||
ID: "me",
|
||||
Scope: must(ExpandScope(ScopeAll)),
|
||||
Roles: Roles{
|
||||
must(RoleByName(RoleOrgAdmin(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgAdmin(defOrg))),
|
||||
must(RoleByName(RoleMember())),
|
||||
},
|
||||
}
|
||||
@@ -507,7 +507,7 @@ func TestAuthorizeDomain(t *testing.T) {
|
||||
ID: "me",
|
||||
Scope: must(ExpandScope(ScopeApplicationConnect)),
|
||||
Roles: Roles{
|
||||
must(RoleByName(RoleOrgMember(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgMember(defOrg))),
|
||||
must(RoleByName(RoleMember())),
|
||||
},
|
||||
}
|
||||
@@ -770,7 +770,7 @@ func TestAuthorizeLevels(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
must(RoleByName(RoleOrgAdmin(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgAdmin(defOrg))),
|
||||
{
|
||||
Name: "user-deny-all",
|
||||
// List out deny permissions explicitly
|
||||
@@ -856,7 +856,7 @@ func TestAuthorizeScope(t *testing.T) {
|
||||
ID: "me",
|
||||
Roles: Roles{
|
||||
must(RoleByName(RoleMember())),
|
||||
must(RoleByName(RoleOrgMember(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgMember(defOrg))),
|
||||
},
|
||||
Scope: must(ExpandScope(ScopeApplicationConnect)),
|
||||
}
|
||||
@@ -892,7 +892,7 @@ func TestAuthorizeScope(t *testing.T) {
|
||||
ID: "me",
|
||||
Roles: Roles{
|
||||
must(RoleByName(RoleMember())),
|
||||
must(RoleByName(RoleOrgMember(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgMember(defOrg))),
|
||||
},
|
||||
Scope: Scope{
|
||||
Role: Role{
|
||||
@@ -981,7 +981,7 @@ func TestAuthorizeScope(t *testing.T) {
|
||||
ID: "me",
|
||||
Roles: Roles{
|
||||
must(RoleByName(RoleMember())),
|
||||
must(RoleByName(RoleOrgMember(defOrg))),
|
||||
must(RoleByName(ScopedRoleOrgMember(defOrg))),
|
||||
},
|
||||
Scope: Scope{
|
||||
Role: Role{
|
||||
|
||||
+10
-10
@@ -49,7 +49,7 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
|
||||
Name: "Admin",
|
||||
Actor: rbac.Subject{
|
||||
// Give some extra roles that an admin might have
|
||||
Roles: rbac.RoleNames{rbac.RoleOrgMember(orgs[0]), "auditor", rbac.RoleOwner(), rbac.RoleMember()},
|
||||
Roles: rbac.RoleNames{rbac.ScopedRoleOrgMember(orgs[0]), "auditor", rbac.RoleOwner(), rbac.RoleMember()},
|
||||
ID: user.String(),
|
||||
Scope: rbac.ScopeAll,
|
||||
Groups: noiseGroups,
|
||||
@@ -58,7 +58,7 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
|
||||
{
|
||||
Name: "OrgAdmin",
|
||||
Actor: rbac.Subject{
|
||||
Roles: rbac.RoleNames{rbac.RoleOrgMember(orgs[0]), rbac.RoleOrgAdmin(orgs[0]), rbac.RoleMember()},
|
||||
Roles: rbac.RoleNames{rbac.ScopedRoleOrgMember(orgs[0]), rbac.ScopedRoleOrgAdmin(orgs[0]), rbac.RoleMember()},
|
||||
ID: user.String(),
|
||||
Scope: rbac.ScopeAll,
|
||||
Groups: noiseGroups,
|
||||
@@ -68,7 +68,7 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
|
||||
Name: "OrgMember",
|
||||
Actor: rbac.Subject{
|
||||
// Member of 2 orgs
|
||||
Roles: rbac.RoleNames{rbac.RoleOrgMember(orgs[0]), rbac.RoleOrgMember(orgs[1]), rbac.RoleMember()},
|
||||
Roles: rbac.RoleNames{rbac.ScopedRoleOrgMember(orgs[0]), rbac.ScopedRoleOrgMember(orgs[1]), rbac.RoleMember()},
|
||||
ID: user.String(),
|
||||
Scope: rbac.ScopeAll,
|
||||
Groups: noiseGroups,
|
||||
@@ -79,9 +79,9 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
|
||||
Actor: rbac.Subject{
|
||||
// Admin of many orgs
|
||||
Roles: rbac.RoleNames{
|
||||
rbac.RoleOrgMember(orgs[0]), rbac.RoleOrgAdmin(orgs[0]),
|
||||
rbac.RoleOrgMember(orgs[1]), rbac.RoleOrgAdmin(orgs[1]),
|
||||
rbac.RoleOrgMember(orgs[2]), rbac.RoleOrgAdmin(orgs[2]),
|
||||
rbac.ScopedRoleOrgMember(orgs[0]), rbac.ScopedRoleOrgAdmin(orgs[0]),
|
||||
rbac.ScopedRoleOrgMember(orgs[1]), rbac.ScopedRoleOrgAdmin(orgs[1]),
|
||||
rbac.ScopedRoleOrgMember(orgs[2]), rbac.ScopedRoleOrgAdmin(orgs[2]),
|
||||
rbac.RoleMember(),
|
||||
},
|
||||
ID: user.String(),
|
||||
@@ -94,9 +94,9 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
|
||||
Actor: rbac.Subject{
|
||||
// Admin of many orgs
|
||||
Roles: rbac.RoleNames{
|
||||
rbac.RoleOrgMember(orgs[0]), rbac.RoleOrgAdmin(orgs[0]),
|
||||
rbac.RoleOrgMember(orgs[1]), rbac.RoleOrgAdmin(orgs[1]),
|
||||
rbac.RoleOrgMember(orgs[2]), rbac.RoleOrgAdmin(orgs[2]),
|
||||
rbac.ScopedRoleOrgMember(orgs[0]), rbac.ScopedRoleOrgAdmin(orgs[0]),
|
||||
rbac.ScopedRoleOrgMember(orgs[1]), rbac.ScopedRoleOrgAdmin(orgs[1]),
|
||||
rbac.ScopedRoleOrgMember(orgs[2]), rbac.ScopedRoleOrgAdmin(orgs[2]),
|
||||
rbac.RoleMember(),
|
||||
},
|
||||
ID: user.String(),
|
||||
@@ -108,7 +108,7 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
|
||||
Name: "AdminWithScope",
|
||||
Actor: rbac.Subject{
|
||||
// Give some extra roles that an admin might have
|
||||
Roles: rbac.RoleNames{rbac.RoleOrgMember(orgs[0]), "auditor", rbac.RoleOwner(), rbac.RoleMember()},
|
||||
Roles: rbac.RoleNames{rbac.ScopedRoleOrgMember(orgs[0]), "auditor", rbac.RoleOwner(), rbac.RoleMember()},
|
||||
ID: user.String(),
|
||||
Scope: rbac.ScopeApplicationConnect,
|
||||
Groups: noiseGroups,
|
||||
|
||||
+16
-2
@@ -70,11 +70,25 @@ func RoleMember() string {
|
||||
return RoleName(member, "")
|
||||
}
|
||||
|
||||
func RoleOrgAdmin(organizationID uuid.UUID) string {
|
||||
func RoleOrgAdmin() string {
|
||||
return orgAdmin
|
||||
}
|
||||
|
||||
func RoleOrgMember() string {
|
||||
return orgMember
|
||||
}
|
||||
|
||||
// ScopedRoleOrgAdmin is the org role with the organization ID
|
||||
// Deprecated This was used before organization scope was included as a
|
||||
// field in all user facing APIs. Usage of 'ScopedRoleOrgAdmin()' is preferred.
|
||||
func ScopedRoleOrgAdmin(organizationID uuid.UUID) string {
|
||||
return RoleName(orgAdmin, organizationID.String())
|
||||
}
|
||||
|
||||
func RoleOrgMember(organizationID uuid.UUID) string {
|
||||
// ScopedRoleOrgMember is the org role with the organization ID
|
||||
// Deprecated This was used before organization scope was included as a
|
||||
// field in all user facing APIs. Usage of 'ScopedRoleOrgMember()' is preferred.
|
||||
func ScopedRoleOrgMember(organizationID uuid.UUID) string {
|
||||
return RoleName(orgMember, organizationID.String())
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
// A possible large improvement would be to implement the ast.Value interface directly.
|
||||
func BenchmarkRBACValueAllocation(b *testing.B) {
|
||||
actor := Subject{
|
||||
Roles: RoleNames{RoleOrgMember(uuid.New()), RoleOrgAdmin(uuid.New()), RoleMember()},
|
||||
Roles: RoleNames{ScopedRoleOrgMember(uuid.New()), ScopedRoleOrgAdmin(uuid.New()), RoleMember()},
|
||||
ID: uuid.NewString(),
|
||||
Scope: ScopeAll,
|
||||
Groups: []string{uuid.NewString(), uuid.NewString(), uuid.NewString()},
|
||||
@@ -73,7 +73,7 @@ func TestRegoInputValue(t *testing.T) {
|
||||
// Expand all roles and make sure we have a good copy.
|
||||
// This is because these tests modify the roles, and we don't want to
|
||||
// modify the original roles.
|
||||
roles, err := RoleNames{RoleOrgMember(uuid.New()), RoleOrgAdmin(uuid.New()), RoleMember()}.Expand()
|
||||
roles, err := RoleNames{ScopedRoleOrgMember(uuid.New()), ScopedRoleOrgAdmin(uuid.New()), RoleMember()}.Expand()
|
||||
require.NoError(t, err, "failed to expand roles")
|
||||
for i := range roles {
|
||||
// If all cached values are nil, then the role will not use
|
||||
|
||||
@@ -99,13 +99,13 @@ func TestRolePermissions(t *testing.T) {
|
||||
|
||||
// Subjects to user
|
||||
memberMe := authSubject{Name: "member_me", Actor: rbac.Subject{ID: currentUser.String(), Roles: rbac.RoleNames{rbac.RoleMember()}}}
|
||||
orgMemberMe := authSubject{Name: "org_member_me", Actor: rbac.Subject{ID: currentUser.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleOrgMember(orgID)}}}
|
||||
orgMemberMe := authSubject{Name: "org_member_me", Actor: rbac.Subject{ID: currentUser.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.ScopedRoleOrgMember(orgID)}}}
|
||||
|
||||
owner := authSubject{Name: "owner", Actor: rbac.Subject{ID: adminID.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleOwner()}}}
|
||||
orgAdmin := authSubject{Name: "org_admin", Actor: rbac.Subject{ID: adminID.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleOrgMember(orgID), rbac.RoleOrgAdmin(orgID)}}}
|
||||
orgAdmin := authSubject{Name: "org_admin", Actor: rbac.Subject{ID: adminID.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.ScopedRoleOrgMember(orgID), rbac.ScopedRoleOrgAdmin(orgID)}}}
|
||||
|
||||
otherOrgMember := authSubject{Name: "org_member_other", Actor: rbac.Subject{ID: uuid.NewString(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleOrgMember(otherOrg)}}}
|
||||
otherOrgAdmin := authSubject{Name: "org_admin_other", Actor: rbac.Subject{ID: uuid.NewString(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleOrgMember(otherOrg), rbac.RoleOrgAdmin(otherOrg)}}}
|
||||
otherOrgMember := authSubject{Name: "org_member_other", Actor: rbac.Subject{ID: uuid.NewString(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.ScopedRoleOrgMember(otherOrg)}}}
|
||||
otherOrgAdmin := authSubject{Name: "org_admin_other", Actor: rbac.Subject{ID: uuid.NewString(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.ScopedRoleOrgMember(otherOrg), rbac.ScopedRoleOrgAdmin(otherOrg)}}}
|
||||
|
||||
templateAdmin := authSubject{Name: "template-admin", Actor: rbac.Subject{ID: templateAdminID.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleTemplateAdmin()}}}
|
||||
userAdmin := authSubject{Name: "user-admin", Actor: rbac.Subject{ID: templateAdminID.String(), Roles: rbac.RoleNames{rbac.RoleMember(), rbac.RoleUserAdmin()}}}
|
||||
@@ -636,12 +636,12 @@ func TestIsOrgRole(t *testing.T) {
|
||||
|
||||
// Org roles
|
||||
{
|
||||
RoleName: rbac.RoleOrgAdmin(randomUUID),
|
||||
RoleName: rbac.ScopedRoleOrgAdmin(randomUUID),
|
||||
OrgRole: true,
|
||||
OrgID: randomUUID.String(),
|
||||
},
|
||||
{
|
||||
RoleName: rbac.RoleOrgMember(randomUUID),
|
||||
RoleName: rbac.ScopedRoleOrgMember(randomUUID),
|
||||
OrgRole: true,
|
||||
OrgID: randomUUID.String(),
|
||||
},
|
||||
|
||||
@@ -26,7 +26,7 @@ func TestListRoles(t *testing.T) {
|
||||
// Create owner, member, and org admin
|
||||
owner := coderdtest.CreateFirstUser(t, client)
|
||||
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
|
||||
orgAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleOrgAdmin(owner.OrganizationID))
|
||||
orgAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.ScopedRoleOrgAdmin(owner.OrganizationID))
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
t.Cleanup(cancel)
|
||||
@@ -64,7 +64,7 @@ func TestListRoles(t *testing.T) {
|
||||
return member.ListOrganizationRoles(ctx, owner.OrganizationID)
|
||||
},
|
||||
ExpectedRoles: convertRoles(map[string]bool{
|
||||
rbac.RoleOrgAdmin(owner.OrganizationID): false,
|
||||
rbac.ScopedRoleOrgAdmin(owner.OrganizationID): false,
|
||||
}),
|
||||
},
|
||||
{
|
||||
@@ -93,7 +93,7 @@ func TestListRoles(t *testing.T) {
|
||||
return orgAdmin.ListOrganizationRoles(ctx, owner.OrganizationID)
|
||||
},
|
||||
ExpectedRoles: convertRoles(map[string]bool{
|
||||
rbac.RoleOrgAdmin(owner.OrganizationID): true,
|
||||
rbac.ScopedRoleOrgAdmin(owner.OrganizationID): true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
@@ -122,7 +122,7 @@ func TestListRoles(t *testing.T) {
|
||||
return client.ListOrganizationRoles(ctx, owner.OrganizationID)
|
||||
},
|
||||
ExpectedRoles: convertRoles(map[string]bool{
|
||||
rbac.RoleOrgAdmin(owner.OrganizationID): true,
|
||||
rbac.ScopedRoleOrgAdmin(owner.OrganizationID): true,
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -962,12 +962,12 @@ func TestGrantSiteRoles(t *testing.T) {
|
||||
admin := coderdtest.New(t, nil)
|
||||
first := coderdtest.CreateFirstUser(t, admin)
|
||||
member, _ := coderdtest.CreateAnotherUser(t, admin, first.OrganizationID)
|
||||
orgAdmin, _ := coderdtest.CreateAnotherUser(t, admin, first.OrganizationID, rbac.RoleOrgAdmin(first.OrganizationID))
|
||||
orgAdmin, _ := coderdtest.CreateAnotherUser(t, admin, first.OrganizationID, rbac.ScopedRoleOrgAdmin(first.OrganizationID))
|
||||
randOrg, err := admin.CreateOrganization(ctx, codersdk.CreateOrganizationRequest{
|
||||
Name: "random",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, randOrgUser := coderdtest.CreateAnotherUser(t, admin, randOrg.ID, rbac.RoleOrgAdmin(randOrg.ID))
|
||||
_, randOrgUser := coderdtest.CreateAnotherUser(t, admin, randOrg.ID, rbac.ScopedRoleOrgAdmin(randOrg.ID))
|
||||
userAdmin, _ := coderdtest.CreateAnotherUser(t, admin, first.OrganizationID, rbac.RoleUserAdmin())
|
||||
|
||||
const newUser = "newUser"
|
||||
@@ -986,7 +986,7 @@ func TestGrantSiteRoles(t *testing.T) {
|
||||
Name: "OrgRoleInSite",
|
||||
Client: admin,
|
||||
AssignToUser: codersdk.Me,
|
||||
Roles: []string{rbac.RoleOrgAdmin(first.OrganizationID)},
|
||||
Roles: []string{rbac.RoleOrgAdmin()},
|
||||
Error: true,
|
||||
StatusCode: http.StatusBadRequest,
|
||||
},
|
||||
@@ -1029,7 +1029,7 @@ func TestGrantSiteRoles(t *testing.T) {
|
||||
Client: orgAdmin,
|
||||
OrgID: randOrg.ID,
|
||||
AssignToUser: randOrgUser.ID.String(),
|
||||
Roles: []string{rbac.RoleOrgMember(randOrg.ID)},
|
||||
Roles: []string{rbac.RoleOrgMember()},
|
||||
Error: true,
|
||||
StatusCode: http.StatusNotFound,
|
||||
},
|
||||
@@ -1047,9 +1047,9 @@ func TestGrantSiteRoles(t *testing.T) {
|
||||
Client: orgAdmin,
|
||||
OrgID: first.OrganizationID,
|
||||
AssignToUser: newUser,
|
||||
Roles: []string{rbac.RoleOrgAdmin(first.OrganizationID)},
|
||||
Roles: []string{rbac.RoleOrgAdmin()},
|
||||
ExpectedRoles: []string{
|
||||
rbac.RoleOrgAdmin(first.OrganizationID),
|
||||
rbac.RoleOrgAdmin(),
|
||||
},
|
||||
Error: false,
|
||||
},
|
||||
|
||||
+4
-3
@@ -14,8 +14,9 @@ import (
|
||||
// and it would require extra db calls to fetch this information. The UI does
|
||||
// not need it, so most api calls will use this structure that omits information.
|
||||
type SlimRole struct {
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
DisplayName string `json:"display_name"`
|
||||
OrganizationID string `json:"organization_id,omitempty"`
|
||||
}
|
||||
|
||||
type AssignableRoles struct {
|
||||
@@ -36,7 +37,7 @@ type Permission struct {
|
||||
// Role is a longer form of SlimRole used to edit custom roles.
|
||||
type Role struct {
|
||||
Name string `json:"name" table:"name,default_sort" validate:"username"`
|
||||
OrganizationID string `json:"organization_id" table:"organization_id" format:"uuid"`
|
||||
OrganizationID string `json:"organization_id,omitempty" table:"organization_id" format:"uuid"`
|
||||
DisplayName string `json:"display_name" table:"display_name"`
|
||||
SitePermissions []Permission `json:"site_permissions" table:"site_permissions"`
|
||||
// OrganizationPermissions are specific for the organization in the field 'OrganizationID' above.
|
||||
|
||||
Generated
+2
-1
@@ -68,7 +68,8 @@ curl -X GET http://coder-server:8080/api/v2/audit?limit=0 \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
|
||||
Generated
+5
-2
@@ -1600,7 +1600,8 @@ curl -X PATCH http://coder-server:8080/api/v2/scim/v2/Users/{id} \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1655,7 +1656,8 @@ curl -X GET http://coder-server:8080/api/v2/templates/{template}/acl \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1690,6 +1692,7 @@ Status Code **200**
|
||||
| `» roles` | array | false | | |
|
||||
| `»» display_name` | string | false | | |
|
||||
| `»» name` | string | false | | |
|
||||
| `»» organization_id` | string | false | | |
|
||||
| `» status` | [codersdk.UserStatus](schemas.md#codersdkuserstatus) | false | | |
|
||||
| `» theme_preference` | string | false | | |
|
||||
| `» username` | string | true | | |
|
||||
|
||||
Generated
+2
-1
@@ -289,7 +289,8 @@ curl -X PUT http://coder-server:8080/api/v2/organizations/{organization}/members
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"updated_at": "2019-08-24T14:15:22Z",
|
||||
|
||||
Generated
+19
-11
@@ -966,7 +966,8 @@
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1045,7 +1046,8 @@
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -2972,7 +2974,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -3616,7 +3619,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"updated_at": "2019-08-24T14:15:22Z",
|
||||
@@ -4452,16 +4456,18 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
```json
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| -------------- | ------ | -------- | ------------ | ----------- |
|
||||
| `display_name` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| ----------------- | ------ | -------- | ------------ | ----------- |
|
||||
| `display_name` | string | false | | |
|
||||
| `name` | string | false | | |
|
||||
| `organization_id` | string | false | | |
|
||||
|
||||
## codersdk.SupportConfig
|
||||
|
||||
@@ -5002,7 +5008,8 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -5607,7 +5614,8 @@ If the schedule is empty, the user will be updated to use the default schedule.|
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
|
||||
Generated
+20
-10
@@ -42,7 +42,8 @@ curl -X GET http://coder-server:8080/api/v2/users \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -111,7 +112,8 @@ curl -X POST http://coder-server:8080/api/v2/users \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -381,7 +383,8 @@ curl -X GET http://coder-server:8080/api/v2/users/{user} \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -434,7 +437,8 @@ curl -X DELETE http://coder-server:8080/api/v2/users/{user} \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -497,7 +501,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/appearance \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1148,7 +1153,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/profile \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1201,7 +1207,8 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/roles \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1264,7 +1271,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/roles \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1317,7 +1325,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/activate \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
@@ -1370,7 +1379,8 @@ curl -X PUT http://coder-server:8080/api/v2/users/{user}/status/suspend \
|
||||
"roles": [
|
||||
{
|
||||
"display_name": "string",
|
||||
"name": "string"
|
||||
"name": "string",
|
||||
"organization_id": "string"
|
||||
}
|
||||
],
|
||||
"status": "active",
|
||||
|
||||
@@ -35,7 +35,7 @@ func TestCheckACLPermissions(t *testing.T) {
|
||||
memberClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID)
|
||||
memberUser, err := memberClient.User(ctx, codersdk.Me)
|
||||
require.NoError(t, err)
|
||||
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID, rbac.RoleOrgAdmin(adminUser.OrganizationID))
|
||||
orgAdminClient, _ := coderdtest.CreateAnotherUser(t, adminClient, adminUser.OrganizationID, rbac.ScopedRoleOrgAdmin(adminUser.OrganizationID))
|
||||
orgAdminUser, err := orgAdminClient.User(ctx, codersdk.Me)
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
||||
codersdk.FeatureExternalProvisionerDaemons: 1,
|
||||
},
|
||||
}})
|
||||
another, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleOrgAdmin(user.OrganizationID))
|
||||
another, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.ScopedRoleOrgAdmin(user.OrganizationID))
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
|
||||
@@ -1639,9 +1639,9 @@ func TestTemplateAccess(t *testing.T) {
|
||||
newOrg, err := ownerClient.CreateOrganization(ctx, codersdk.CreateOrganizationRequest{Name: orgName})
|
||||
require.NoError(t, err, "failed to create org")
|
||||
|
||||
adminCli, adminUsr := coderdtest.CreateAnotherUser(t, ownerClient, newOrg.ID, rbac.RoleOrgAdmin(newOrg.ID))
|
||||
groupMemCli, groupMemUsr := coderdtest.CreateAnotherUser(t, ownerClient, newOrg.ID, rbac.RoleOrgMember(newOrg.ID))
|
||||
memberCli, memberUsr := coderdtest.CreateAnotherUser(t, ownerClient, newOrg.ID, rbac.RoleOrgMember(newOrg.ID))
|
||||
adminCli, adminUsr := coderdtest.CreateAnotherUser(t, ownerClient, newOrg.ID, rbac.ScopedRoleOrgAdmin(newOrg.ID))
|
||||
groupMemCli, groupMemUsr := coderdtest.CreateAnotherUser(t, ownerClient, newOrg.ID, rbac.ScopedRoleOrgMember(newOrg.ID))
|
||||
memberCli, memberUsr := coderdtest.CreateAnotherUser(t, ownerClient, newOrg.ID, rbac.ScopedRoleOrgMember(newOrg.ID))
|
||||
|
||||
// Make group
|
||||
group, err := adminCli.CreateGroup(ctx, newOrg.ID, codersdk.CreateGroupRequest{
|
||||
|
||||
Generated
+2
-1
@@ -977,7 +977,7 @@ export interface Response {
|
||||
// From codersdk/roles.go
|
||||
export interface Role {
|
||||
readonly name: string;
|
||||
readonly organization_id: string;
|
||||
readonly organization_id?: string;
|
||||
readonly display_name: string;
|
||||
readonly site_permissions: readonly Permission[];
|
||||
readonly organization_permissions: readonly Permission[];
|
||||
@@ -1030,6 +1030,7 @@ export interface SessionLifetime {
|
||||
export interface SlimRole {
|
||||
readonly name: string;
|
||||
readonly display_name: string;
|
||||
readonly organization_id?: string;
|
||||
}
|
||||
|
||||
// From codersdk/deployment.go
|
||||
|
||||
Reference in New Issue
Block a user