Thanks to visit codestin.com
Credit goes to github.com

Skip to content

chore: Rename 'admin' to 'owner' #3498

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 11 commits into from
Aug 15, 2022
22 changes: 22 additions & 0 deletions coderd/database/migrations/000034_remove_admin_role.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
UPDATE
users
SET
-- Replace 'template-admin' and 'user-admin' role with 'admin'
rbac_roles = array_append(
array_remove(
array_remove(rbac_roles, 'template-admin'),
'user-admin'
), 'admin')
WHERE
-- Only on existing admins. If they have either role, make them an admin
ARRAY ['template-admin', 'user-admin'] && rbac_roles;


UPDATE
users
SET
-- Replace 'owner' with 'admin'
rbac_roles = array_replace(rbac_roles, 'owner', 'admin')
WHERE
-- Only on the owner
'owner' = ANY(rbac_roles);
20 changes: 20 additions & 0 deletions coderd/database/migrations/000034_remove_admin_role.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
UPDATE
users
SET
-- Replace the role 'admin' with the role 'owner'
rbac_roles = array_replace(rbac_roles, 'admin', 'owner')
WHERE
-- Update the first user with the role 'admin'. This should be the first
-- user ever, but if that user was demoted from an admin, then choose
-- the next best user.
id = (SELECT id FROM users WHERE 'admin' = ANY(rbac_roles) ORDER BY created_at ASC LIMIT 1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could technically cause the query to fail if no rows are found, I think doing id IN (...) would allow it to match no rows.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting. Let me try it out

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coadler It does not seem to matter.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I thought this would've caused an issue when you compared a non-null field to null. Sounds good then!



UPDATE
users
SET
-- Replace 'admin' role with 'template-admin' and 'user-admin'
rbac_roles = array_cat(array_remove(rbac_roles, 'admin'), ARRAY ['template-admin', 'user-admin'])
WHERE
-- Only on existing admins
'admin' = ANY(rbac_roles);
2 changes: 1 addition & 1 deletion coderd/httpmw/authorize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestExtractUserRoles(t *testing.T) {
{
Name: "Admin",
AddUser: func(db database.Store) (database.User, []string, string) {
roles := []string{rbac.RoleAdmin()}
roles := []string{rbac.RoleOwner()}
user, token := addUser(t, db, roles...)
return user, append(roles, rbac.RoleMember()), token
},
Expand Down
4 changes: 2 additions & 2 deletions coderd/provisionerjobs_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ import (

"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"

"github.com/coder/coder/coderd/database"
"github.com/coder/coder/coderd/database/databasefake"
"github.com/coder/coder/coderd/rbac"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/testutil"
)
Expand Down Expand Up @@ -77,7 +77,7 @@ func TestProvisionerJobLogs_Unit(t *testing.T) {
require.NoError(t, err)
_, err = fDB.InsertUser(ctx, database.InsertUserParams{
ID: userID,
RBACRoles: []string{"admin"},
RBACRoles: []string{rbac.RoleOwner()},
})
require.NoError(t, err)
_, err = fDB.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{
Expand Down
6 changes: 3 additions & 3 deletions coderd/rbac/authz_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func TestFilter(t *testing.T) {
{
Name: "Admin",
SubjectID: userIDs[0].String(),
Roles: []string{RoleOrgMember(orgIDs[0]), "auditor", RoleAdmin(), RoleMember()},
Roles: []string{RoleOrgMember(orgIDs[0]), "auditor", RoleOwner(), RoleMember()},
ObjectType: ResourceWorkspace.Type,
Action: ActionRead,
},
Expand Down Expand Up @@ -292,7 +292,7 @@ func TestAuthorizeDomain(t *testing.T) {
user = subject{
UserID: "me",
Roles: []Role{
must(RoleByName(RoleAdmin())),
must(RoleByName(RoleOwner())),
must(RoleByName(RoleMember())),
},
}
Expand Down Expand Up @@ -499,7 +499,7 @@ func TestAuthorizeLevels(t *testing.T) {
user := subject{
UserID: "me",
Roles: []Role{
must(RoleByName(RoleAdmin())),
must(RoleByName(RoleOwner())),
{
Name: "org-deny:" + defOrg.String(),
Org: map[string][]Permission{
Expand Down
16 changes: 8 additions & 8 deletions coderd/rbac/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

const (
admin string = "admin"
owner string = "owner"
member string = "member"
templateAdmin string = "template-admin"
userAdmin string = "user-admin"
Expand All @@ -24,8 +24,8 @@ const (
// Once we have a database implementation, the "default" roles can be defined on the
// site and orgs, and these functions can be removed.

func RoleAdmin() string {
return roleName(admin, "")
func RoleOwner() string {
return roleName(owner, "")
}

func RoleTemplateAdmin() string {
Expand Down Expand Up @@ -59,10 +59,10 @@ var (
// https://github.com/coder/coder/issues/1194
builtInRoles = map[string]func(orgID string) Role{
// admin grants all actions to all resources.
admin: func(_ string) Role {
owner: func(_ string) Role {
return Role{
Name: admin,
DisplayName: "Admin",
Name: owner,
DisplayName: "Owner",
Site: permissions(map[Object][]Action{
ResourceWildcard: {WildcardSymbol},
}),
Expand Down Expand Up @@ -187,8 +187,8 @@ var (
// The first key is the actor role, the second is the roles they can assign.
// map[actor_role][assign_role]<can_assign>
assignRoles = map[string]map[string]bool{
admin: {
admin: true,
owner: {
owner: true,
auditor: true,
member: true,
orgAdmin: true,
Expand Down
2 changes: 1 addition & 1 deletion coderd/rbac/builtin_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestRoleByName(t *testing.T) {
testCases := []struct {
Role Role
}{
{Role: builtInRoles[admin]("")},
{Role: builtInRoles[owner]("")},
{Role: builtInRoles[member]("")},
{Role: builtInRoles[templateAdmin]("")},
{Role: builtInRoles[userAdmin]("")},
Expand Down
8 changes: 4 additions & 4 deletions coderd/rbac/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func BenchmarkRBACFilter(b *testing.B) {
{
Name: "Admin",
// Give some extra roles that an admin might have
Roles: []string{rbac.RoleOrgMember(orgs[0]), "auditor", rbac.RoleAdmin(), rbac.RoleMember()},
Roles: []string{rbac.RoleOrgMember(orgs[0]), "auditor", rbac.RoleOwner(), rbac.RoleMember()},
UserID: users[0],
},
{
Expand Down Expand Up @@ -119,7 +119,7 @@ func TestRolePermissions(t *testing.T) {
memberMe := authSubject{Name: "member_me", UserID: currentUser.String(), Roles: []string{rbac.RoleMember()}}
orgMemberMe := authSubject{Name: "org_member_me", UserID: currentUser.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOrgMember(orgID)}}

admin := authSubject{Name: "admin", UserID: adminID.String(), Roles: []string{rbac.RoleMember(), rbac.RoleAdmin()}}
admin := authSubject{Name: "admin", UserID: adminID.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOwner()}}
orgAdmin := authSubject{Name: "org_admin", UserID: adminID.String(), Roles: []string{rbac.RoleMember(), rbac.RoleOrgMember(orgID), rbac.RoleOrgAdmin(orgID)}}

otherOrgMember := authSubject{Name: "org_member_other", UserID: uuid.NewString(), Roles: []string{rbac.RoleMember(), rbac.RoleOrgMember(otherOrg)}}
Expand Down Expand Up @@ -358,7 +358,7 @@ func TestIsOrgRole(t *testing.T) {
OrgID string
}{
// Not org roles
{RoleName: rbac.RoleAdmin()},
{RoleName: rbac.RoleOwner()},
{RoleName: rbac.RoleMember()},
{RoleName: "auditor"},

Expand Down Expand Up @@ -413,7 +413,7 @@ func TestListRoles(t *testing.T) {
// Always use constant strings, as if the names change, we need to write
// a SQL migration to change the name on the backend.
require.ElementsMatch(t, []string{
"admin",
"owner",
"member",
"auditor",
"template-admin",
Expand Down
2 changes: 1 addition & 1 deletion coderd/roles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func TestListRoles(t *testing.T) {
require.NoError(t, err, "create org")

const forbidden = "Forbidden"
siteRoles := convertRoles(rbac.RoleAdmin(), "auditor", "template-admin", "user-admin")
siteRoles := convertRoles(rbac.RoleOwner(), "auditor", "template-admin", "user-admin")
orgRoles := convertRoles(rbac.RoleOrgAdmin(admin.OrganizationID))

testCases := []struct {
Expand Down
4 changes: 2 additions & 2 deletions coderd/templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func TestTemplate(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
user := coderdtest.CreateFirstUser(t, client)
member := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleAdmin())
memberWithDeleted := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleAdmin())
member := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleOwner())
memberWithDeleted := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleOwner())
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
Expand Down
2 changes: 1 addition & 1 deletion coderd/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) {
// and add some rbac bypass when calling api functions this way??
// Add the admin role to this first user.
_, err = api.Database.UpdateUserRoles(r.Context(), database.UpdateUserRolesParams{
GrantedRoles: []string{rbac.RoleAdmin()},
GrantedRoles: []string{rbac.RoleOwner()},
ID: user.ID,
})
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions coderd/users_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ func TestSearchUsers(t *testing.T) {
},
{
Name: "OnlyParams",
Query: "status:acTIve sEArch:User-Name role:Admin",
Query: "status:acTIve sEArch:User-Name role:Owner",
Expected: database.GetUsersParams{
Search: "user-name",
Status: []database.UserStatus{database.UserStatusActive},
RbacRole: []string{rbac.RoleAdmin()},
RbacRole: []string{rbac.RoleOwner()},
},
},
{
Expand All @@ -71,11 +71,11 @@ func TestSearchUsers(t *testing.T) {
},
{
Name: "QuotedKey",
Query: `"status":acTIve "sEArch":User-Name "role":Admin`,
Query: `"status":acTIve "sEArch":User-Name "role":Owner`,
Expected: database.GetUsersParams{
Search: "user-name",
Status: []database.UserStatus{database.UserStatusActive},
RbacRole: []string{rbac.RoleAdmin()},
RbacRole: []string{rbac.RoleOwner()},
},
},
{
Expand Down
26 changes: 13 additions & 13 deletions coderd/users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func TestPostUsers(t *testing.T) {
client := coderdtest.New(t, nil)
first := coderdtest.CreateFirstUser(t, client)
notInOrg := coderdtest.CreateAnotherUser(t, client, first.OrganizationID)
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID, rbac.RoleAdmin(), rbac.RoleMember())
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID, rbac.RoleOwner(), rbac.RoleMember())

ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
Expand Down Expand Up @@ -513,7 +513,7 @@ func TestGrantSiteRoles(t *testing.T) {
Name: "UserNotExists",
Client: admin,
AssignToUser: uuid.NewString(),
Roles: []string{rbac.RoleAdmin()},
Roles: []string{rbac.RoleOwner()},
Error: true,
StatusCode: http.StatusBadRequest,
},
Expand All @@ -539,7 +539,7 @@ func TestGrantSiteRoles(t *testing.T) {
Client: admin,
OrgID: first.OrganizationID,
AssignToUser: codersdk.Me,
Roles: []string{rbac.RoleAdmin()},
Roles: []string{rbac.RoleOwner()},
Error: true,
StatusCode: http.StatusBadRequest,
},
Expand Down Expand Up @@ -629,7 +629,7 @@ func TestInitialRoles(t *testing.T) {
roles, err := client.GetUserRoles(ctx, codersdk.Me)
require.NoError(t, err)
require.ElementsMatch(t, roles.Roles, []string{
rbac.RoleAdmin(),
rbac.RoleOwner(),
}, "should be a member and admin")

require.ElementsMatch(t, roles.OrganizationRoles[first.OrganizationID], []string{
Expand Down Expand Up @@ -744,7 +744,7 @@ func TestUsersFilter(t *testing.T) {
for i := 0; i < 15; i++ {
roles := []string{}
if i%2 == 0 {
roles = append(roles, rbac.RoleAdmin())
roles = append(roles, rbac.RoleOwner())
}
if i%3 == 0 {
roles = append(roles, "auditor")
Expand Down Expand Up @@ -823,12 +823,12 @@ func TestUsersFilter(t *testing.T) {
{
Name: "Admins",
Filter: codersdk.UsersRequest{
Role: rbac.RoleAdmin(),
Role: rbac.RoleOwner(),
Status: codersdk.UserStatusSuspended + "," + codersdk.UserStatusActive,
},
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
for _, r := range u.Roles {
if r.Name == rbac.RoleAdmin() {
if r.Name == rbac.RoleOwner() {
return true
}
}
Expand All @@ -838,12 +838,12 @@ func TestUsersFilter(t *testing.T) {
{
Name: "AdminsUppercase",
Filter: codersdk.UsersRequest{
Role: "ADMIN",
Role: "OWNER",
Status: codersdk.UserStatusSuspended + "," + codersdk.UserStatusActive,
},
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
for _, r := range u.Roles {
if r.Name == rbac.RoleAdmin() {
if r.Name == rbac.RoleOwner() {
return true
}
}
Expand All @@ -863,11 +863,11 @@ func TestUsersFilter(t *testing.T) {
{
Name: "SearchQuery",
Filter: codersdk.UsersRequest{
SearchQuery: "i role:admin status:active",
SearchQuery: "i role:owner status:active",
},
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
for _, r := range u.Roles {
if r.Name == rbac.RoleAdmin() {
if r.Name == rbac.RoleOwner() {
return (strings.ContainsAny(u.Username, "iI") || strings.ContainsAny(u.Email, "iI")) &&
u.Status == codersdk.UserStatusActive
}
Expand All @@ -878,11 +878,11 @@ func TestUsersFilter(t *testing.T) {
{
Name: "SearchQueryInsensitive",
Filter: codersdk.UsersRequest{
SearchQuery: "i Role:Admin STATUS:Active",
SearchQuery: "i Role:Owner STATUS:Active",
},
FilterF: func(_ codersdk.UsersRequest, u codersdk.User) bool {
for _, r := range u.Roles {
if r.Name == rbac.RoleAdmin() {
if r.Name == rbac.RoleOwner() {
return (strings.ContainsAny(u.Username, "iI") || strings.ContainsAny(u.Email, "iI")) &&
u.Status == codersdk.UserStatusActive
}
Expand Down
6 changes: 3 additions & 3 deletions coderd/workspaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestAdminViewAllWorkspaces(t *testing.T) {

// This other user is not in the first user's org. Since other is an admin, they can
// still see the "first" user's workspace.
other := coderdtest.CreateAnotherUser(t, client, otherOrg.ID, rbac.RoleAdmin())
other := coderdtest.CreateAnotherUser(t, client, otherOrg.ID, rbac.RoleOwner())
otherWorkspaces, err := other.Workspaces(ctx, codersdk.WorkspaceFilter{})
require.NoError(t, err, "(other) fetch workspaces")

Expand Down Expand Up @@ -137,7 +137,7 @@ func TestPostWorkspacesByOrganization(t *testing.T) {
client := coderdtest.New(t, nil)
first := coderdtest.CreateFirstUser(t, client)

other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID, rbac.RoleMember(), rbac.RoleAdmin())
other := coderdtest.CreateAnotherUser(t, client, first.OrganizationID, rbac.RoleMember(), rbac.RoleOwner())

ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
Expand Down Expand Up @@ -406,7 +406,7 @@ func TestWorkspaceFilter(t *testing.T) {

users := make([]coderUser, 0)
for i := 0; i < 10; i++ {
userClient := coderdtest.CreateAnotherUser(t, client, first.OrganizationID, rbac.RoleAdmin())
userClient := coderdtest.CreateAnotherUser(t, client, first.OrganizationID, rbac.RoleOwner())
user, err := userClient.User(ctx, codersdk.Me)
require.NoError(t, err, "fetch me")

Expand Down
6 changes: 3 additions & 3 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ possible way to use Coder.

Please [install Coder](../install.md) before proceeding with the steps below.

## First time admin user setup
## First time owner user setup

1. Run `coder login <your Access URL>` in a new terminal and follow the
interactive instructions to create your admin user and password.
interactive instructions to create your owner user and password.

> If using `coder server --tunnel`, the Access URL appears in the terminal logs.

Expand Down Expand Up @@ -45,7 +45,7 @@ coder ssh <workspaceName>
```

To access your workspace in the Coder dashboard, navigate to the [configured access URL](../configure.md),
and log in with the admin credentials provided to you by Coder.
and log in with the owner credentials provided to you by Coder.

![Coder Web UI with code-server](./images/code-server.png)

Expand Down
Loading