feat(coderd): add endpoints for editing and deleting organizations (#13287)

This commit is contained in:
Kayla Washburn-Love
2024-05-21 12:46:31 -06:00
committed by GitHub
parent 0a86d6d176
commit 3f1e9c038a
19 changed files with 757 additions and 63 deletions

View File

@ -33,15 +33,18 @@ import (
var validProxyByHostnameRegex = regexp.MustCompile(`^[a-zA-Z0-9._-]+$`)
var errForeignKeyConstraint = &pq.Error{
Code: "23503",
Message: "update or delete on table violates foreign key constraint",
}
var errDuplicateKey = &pq.Error{
Code: "23505",
Message: "duplicate key value violates unique constraint",
}
// A full mapping of error codes from pq v1.10.9 can be found here:
// https://github.com/lib/pq/blob/2a217b94f5ccd3de31aec4152a541b9ff64bed05/error.go#L75
var (
errForeignKeyConstraint = &pq.Error{
Code: "23503", // "foreign_key_violation"
Message: "update or delete on table violates foreign key constraint",
}
errUniqueConstraint = &pq.Error{
Code: "23505", // "unique_violation"
Message: "duplicate key value violates unique constraint",
}
)
// New returns an in-memory fake of the database.
func New() database.Store {
@ -1601,6 +1604,19 @@ func (q *FakeQuerier) DeleteOldWorkspaceAgentStats(_ context.Context) error {
return nil
}
func (q *FakeQuerier) DeleteOrganization(_ context.Context, id uuid.UUID) error {
q.mutex.Lock()
defer q.mutex.Unlock()
for i, org := range q.organizations {
if org.ID == id && !org.IsDefault {
q.organizations = append(q.organizations[:i], q.organizations[i+1:]...)
return nil
}
}
return sql.ErrNoRows
}
func (q *FakeQuerier) DeleteReplicasUpdatedBefore(_ context.Context, before time.Time) error {
q.mutex.Lock()
defer q.mutex.Unlock()
@ -5823,7 +5839,7 @@ func (q *FakeQuerier) InsertDBCryptKey(_ context.Context, arg database.InsertDBC
for _, key := range q.dbcryptKeys {
if key.Number == arg.Number {
return errDuplicateKey
return errUniqueConstraint
}
}
@ -5927,7 +5943,7 @@ func (q *FakeQuerier) InsertGroup(_ context.Context, arg database.InsertGroupPar
for _, group := range q.groups {
if group.OrganizationID == arg.OrganizationID &&
group.Name == arg.Name {
return database.Group{}, errDuplicateKey
return database.Group{}, errUniqueConstraint
}
}
@ -5958,7 +5974,7 @@ func (q *FakeQuerier) InsertGroupMember(_ context.Context, arg database.InsertGr
for _, member := range q.groupMembers {
if member.GroupID == arg.GroupID &&
member.UserID == arg.UserID {
return errDuplicateKey
return errUniqueConstraint
}
}
@ -6042,7 +6058,7 @@ func (q *FakeQuerier) InsertOAuth2ProviderApp(_ context.Context, arg database.In
for _, app := range q.oauth2ProviderApps {
if app.Name == arg.Name {
return database.OAuth2ProviderApp{}, errDuplicateKey
return database.OAuth2ProviderApp{}, errUniqueConstraint
}
}
@ -6423,7 +6439,7 @@ func (q *FakeQuerier) InsertUser(_ context.Context, arg database.InsertUserParam
for _, user := range q.users {
if user.Username == arg.Username && !user.Deleted {
return database.User{}, errDuplicateKey
return database.User{}, errUniqueConstraint
}
}
@ -6836,7 +6852,7 @@ func (q *FakeQuerier) InsertWorkspaceProxy(_ context.Context, arg database.Inser
lastRegionID := int32(0)
for _, p := range q.workspaceProxies {
if !p.Deleted && p.Name == arg.Name {
return database.WorkspaceProxy{}, errDuplicateKey
return database.WorkspaceProxy{}, errUniqueConstraint
}
if p.RegionID > lastRegionID {
lastRegionID = p.RegionID
@ -7230,7 +7246,7 @@ func (q *FakeQuerier) UpdateOAuth2ProviderAppByID(_ context.Context, arg databas
for _, app := range q.oauth2ProviderApps {
if app.Name == arg.Name && app.ID != arg.ID {
return database.OAuth2ProviderApp{}, errDuplicateKey
return database.OAuth2ProviderApp{}, errUniqueConstraint
}
}
@ -7278,6 +7294,33 @@ func (q *FakeQuerier) UpdateOAuth2ProviderAppSecretByID(_ context.Context, arg d
return database.OAuth2ProviderAppSecret{}, sql.ErrNoRows
}
func (q *FakeQuerier) UpdateOrganization(_ context.Context, arg database.UpdateOrganizationParams) (database.Organization, error) {
err := validateDatabaseType(arg)
if err != nil {
return database.Organization{}, err
}
q.mutex.Lock()
defer q.mutex.Unlock()
// Enforce the unique constraint, because the API endpoint relies on the database catching
// non-unique names during updates.
for _, org := range q.organizations {
if org.Name == arg.Name && org.ID != arg.ID {
return database.Organization{}, errUniqueConstraint
}
}
for i, org := range q.organizations {
if org.ID == arg.ID {
org.Name = arg.Name
q.organizations[i] = org
return org, nil
}
}
return database.Organization{}, sql.ErrNoRows
}
func (q *FakeQuerier) UpdateProvisionerDaemonLastSeenAt(_ context.Context, arg database.UpdateProvisionerDaemonLastSeenAtParams) error {
err := validateDatabaseType(arg)
if err != nil {
@ -7875,7 +7918,7 @@ func (q *FakeQuerier) UpdateWorkspace(_ context.Context, arg database.UpdateWork
continue
}
if other.Name == arg.Name {
return database.Workspace{}, errDuplicateKey
return database.Workspace{}, errUniqueConstraint
}
}
@ -8215,7 +8258,7 @@ func (q *FakeQuerier) UpdateWorkspaceProxy(_ context.Context, arg database.Updat
for _, p := range q.workspaceProxies {
if p.Name == arg.Name && p.ID != arg.ID {
return database.WorkspaceProxy{}, errDuplicateKey
return database.WorkspaceProxy{}, errUniqueConstraint
}
}