-
Notifications
You must be signed in to change notification settings - Fork 941
chore: ensure default org always exists #12412
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
Changes from all commits
e4b1bb8
b4a4dd4
627c9f8
179828c
db8da5a
b830625
6b086c6
9997f59
3977c71
d35933d
1b8690f
c9af8c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
-- There is no down. If the org is created, just let it be. Deleting an org feels dangerous in a migration. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
-- This ensures a default organization always exists. | ||
INSERT INTO | ||
organizations(id, name, description, created_at, updated_at, is_default) | ||
SELECT | ||
-- Avoid calling it "default" as we are reserving that word as a keyword to fetch | ||
-- the default org regardless of the name. | ||
gen_random_uuid(), | ||
'first-organization', | ||
'Builtin default organization.', | ||
now(), | ||
now(), | ||
true | ||
WHERE | ||
-- Only insert if no organizations exist. | ||
NOT EXISTS (SELECT * FROM organizations); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -171,16 +171,37 @@ func (api *API) postFirstUser(rw http.ResponseWriter, r *http.Request) { | |
} | ||
} | ||
|
||
//nolint:gocritic // needed to create first user | ||
defaultOrg, err := api.Database.GetDefaultOrganization(dbauthz.AsSystemRestricted(ctx)) | ||
if err != nil { | ||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ | ||
Message: "Internal error fetching default organization. If you are encountering this error, you will have to restart the Coder deployment.", | ||
Detail: err.Error(), | ||
}) | ||
return | ||
} | ||
|
||
//nolint:gocritic // ensure everyone group | ||
_, err = api.Database.InsertAllUsersGroup(dbauthz.AsSystemRestricted(ctx), defaultOrg.ID) | ||
// A unique constraint violation just means the group already exists. | ||
// This should not happen, but is ok if it does. | ||
if err != nil && !database.IsUniqueViolation(err) { | ||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ | ||
Message: "Internal error creating all users group.", | ||
Detail: err.Error(), | ||
}) | ||
return | ||
} | ||
|
||
//nolint:gocritic // needed to create first user | ||
user, organizationID, err := api.CreateUser(dbauthz.AsSystemRestricted(ctx), api.Database, CreateUserRequest{ | ||
CreateUserRequest: codersdk.CreateUserRequest{ | ||
Email: createUser.Email, | ||
Username: createUser.Username, | ||
Password: createUser.Password, | ||
// Create an org for the first user. | ||
OrganizationID: uuid.Nil, | ||
Email: createUser.Email, | ||
Username: createUser.Username, | ||
Password: createUser.Password, | ||
OrganizationID: defaultOrg.ID, | ||
Emyrk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
CreateOrganization: true, | ||
CreateOrganization: false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can remove this field, which also allows cleaning up a lot of cruft in userauth.go There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh you are right. I think we can drop the |
||
LoginType: database.LoginTypePassword, | ||
}) | ||
if err != nil { | ||
|
@@ -1033,10 +1054,7 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) { | |
} | ||
|
||
for _, mem := range memberships { | ||
// If we can read the org member, include the roles. | ||
if err == nil { | ||
resp.OrganizationRoles[mem.OrganizationID] = mem.Roles | ||
} | ||
resp.OrganizationRoles[mem.OrganizationID] = mem.Roles | ||
} | ||
|
||
httpapi.Write(ctx, rw, http.StatusOK, resp) | ||
|
@@ -1247,9 +1265,8 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create | |
// TODO: When organizations are allowed to be created, we should | ||
// 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. | ||
orgRoles = append(orgRoles, rbac.RoleOrgMember(req.OrganizationID)) | ||
|
||
// should be just regular members. Membership role is implied, and | ||
// not required to be explicit. | ||
_, err = tx.InsertAllUsersGroup(ctx, organization.ID) | ||
if err != nil { | ||
return xerrors.Errorf("create %q group: %w", database.EveryoneGroup, err) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this also be part of the migration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that too. What I didn't like about the migration was I can't tell if the
INSERT INTO organizations
ran with an insert, or without. So the followup ofINSERT INTO groups
cannot be dependent on if an org did not exist at the start of the migration or not.Putting it in
postFirstUser
ensures that it is a new instance setup, so I know this is safe.Although we do not allow dropping the everyone group, so it should be a safe
INSERT INTO groups ... DO NOTHING
.I can move it to a migration if you feel that is better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just wary of all this side-effect stuff of creating a user.
I also kind of like the symmetry of creating an org and the corresponding everyone group together, since that's presumably what we'll do when we allow creating new organizations, since there is no similar "first user creation" event to tie it to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw this comment after the approval merge, my mistake.
I can make another migration for the everyone group and do nothing on conflict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Up to you