Skip to content

Commit fc2fce2

Browse files
committed
fix: assign new oauth users to default org
This is not a final solution, as we eventually want to be able to map to different orgs. This makes it so multi-org does not break oauth/oidc.
1 parent a67362f commit fc2fce2

27 files changed

+209
-37
lines changed

coderd/apidoc/docs.go

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbauthz/dbauthz.go

+6
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,12 @@ func (q *querier) GetDERPMeshKey(ctx context.Context) (string, error) {
10161016
return q.db.GetDERPMeshKey(ctx)
10171017
}
10181018

1019+
func (q *querier) GetDefaultOrganization(ctx context.Context) (database.Organization, error) {
1020+
return fetch(q.log, q.auth, func(ctx context.Context, _ any) (database.Organization, error) {
1021+
return q.db.GetDefaultOrganization(ctx)
1022+
})(ctx, nil)
1023+
}
1024+
10191025
func (q *querier) GetDefaultProxyConfig(ctx context.Context) (database.GetDefaultProxyConfigRow, error) {
10201026
// No authz checks
10211027
return q.db.GetDefaultProxyConfig(ctx)

coderd/database/dbauthz/dbauthz_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,10 @@ func (s *MethodTestSuite) TestOrganization() {
570570
o := dbgen.Organization(s.T(), db, database.Organization{})
571571
check.Args(o.ID).Asserts(o, rbac.ActionRead).Returns(o)
572572
}))
573+
s.Run("GetDefaultOrganization", s.Subtest(func(db database.Store, check *expects) {
574+
o := dbgen.Organization(s.T(), db, database.Organization{})
575+
check.Args().Asserts(o, rbac.ActionRead).Returns(o)
576+
}))
573577
s.Run("GetOrganizationByName", s.Subtest(func(db database.Store, check *expects) {
574578
o := dbgen.Organization(s.T(), db, database.Organization{})
575579
check.Args(o.Name).Asserts(o, rbac.ActionRead).Returns(o)

coderd/database/dbmem/dbmem.go

+13
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,18 @@ func (q *FakeQuerier) GetDERPMeshKey(_ context.Context) (string, error) {
16571657
return q.derpMeshKey, nil
16581658
}
16591659

1660+
func (q *FakeQuerier) GetDefaultOrganization(_ context.Context) (database.Organization, error) {
1661+
q.mutex.RLock()
1662+
defer q.mutex.RUnlock()
1663+
1664+
for _, org := range q.organizations {
1665+
if org.IsDefault {
1666+
return org, nil
1667+
}
1668+
}
1669+
return database.Organization{}, sql.ErrNoRows
1670+
}
1671+
16601672
func (q *FakeQuerier) GetDefaultProxyConfig(_ context.Context) (database.GetDefaultProxyConfigRow, error) {
16611673
return database.GetDefaultProxyConfigRow{
16621674
DisplayName: q.defaultProxyDisplayName,
@@ -5285,6 +5297,7 @@ func (q *FakeQuerier) InsertOrganization(_ context.Context, arg database.InsertO
52855297
Name: arg.Name,
52865298
CreatedAt: arg.CreatedAt,
52875299
UpdatedAt: arg.UpdatedAt,
5300+
IsDefault: len(q.organizations) == 0,
52885301
}
52895302
q.organizations = append(q.organizations, organization)
52905303
return organization, nil

coderd/database/dbmetrics/dbmetrics.go

+7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbmock/dbmock.go

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dump.sql

+4-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
DROP INDEX organizations_single_default_org;
2+
ALTER TABLE organizations DROP COLUMN is_default;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
-- This migration is intended to maintain the existing behavior of single org
2+
-- deployments, while allowing for multi-org deployments. By default, this organization
3+
-- will be used when no organization is specified.
4+
ALTER TABLE organizations ADD COLUMN is_default BOOLEAN NOT NULL DEFAULT FALSE;
5+
6+
-- Only 1 org should ever be set to is_default.
7+
create unique index organizations_single_default_org on organizations (is_default)
8+
where is_default = true;
9+
10+
UPDATE
11+
organizations
12+
SET
13+
is_default = true
14+
WHERE
15+
-- The first organization created will be the default.
16+
id = (SELECT id FROM organizations ORDER BY organizations.created_at ASC LIMIT 1 );

coderd/database/models.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/querier_test.go

+28
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,34 @@ func TestUserChangeLoginType(t *testing.T) {
494494
require.Equal(t, bobExpPass, bob.HashedPassword, "hashed password should not change")
495495
}
496496

497+
func TestDefaultOrg(t *testing.T) {
498+
t.Parallel()
499+
if testing.Short() {
500+
t.SkipNow()
501+
}
502+
503+
sqlDB := testSQLDB(t)
504+
err := migrations.Up(sqlDB)
505+
require.NoError(t, err)
506+
db := database.New(sqlDB)
507+
ctx := context.Background()
508+
509+
// Should start with 0 orgs
510+
all, err := db.GetOrganizations(ctx)
511+
require.NoError(t, err)
512+
require.Len(t, all, 0)
513+
514+
org, err := db.InsertOrganization(ctx, database.InsertOrganizationParams{
515+
ID: uuid.New(),
516+
Name: "default",
517+
Description: "",
518+
CreatedAt: dbtime.Now(),
519+
UpdatedAt: dbtime.Now(),
520+
})
521+
require.NoError(t, err)
522+
require.True(t, org.IsDefault, "first org should always be default")
523+
}
524+
497525
type tvArgs struct {
498526
Status database.ProvisionerJobStatus
499527
// CreateWorkspace is true if we should create a workspace for the template version

coderd/database/queries.sql.go

+37-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/organizations.sql

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
-- name: GetDefaultOrganization :one
2+
SELECT
3+
*
4+
FROM
5+
organizations
6+
WHERE
7+
is_default = true
8+
LIMIT
9+
1;
10+
111
-- name: GetOrganizations :many
212
SELECT
313
*
@@ -39,6 +49,7 @@ WHERE
3949

4050
-- name: InsertOrganization :one
4151
INSERT INTO
42-
organizations (id, "name", description, created_at, updated_at)
52+
organizations (id, "name", description, created_at, updated_at, is_default)
4353
VALUES
44-
($1, $2, $3, $4, $5) RETURNING *;
54+
-- If no organizations exist, and this is the first, make it the default.
55+
($1, $2, $3, $4, $5, (SELECT TRUE FROM organizations LIMIT 1) IS NULL) RETURNING *;

coderd/database/unique_constraint.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/organizations.go

+1
Original file line numberDiff line numberDiff line change
@@ -118,5 +118,6 @@ func convertOrganization(organization database.Organization) codersdk.Organizati
118118
Name: organization.Name,
119119
CreatedAt: organization.CreatedAt,
120120
UpdatedAt: organization.UpdatedAt,
121+
IsDefault: organization.IsDefault,
121122
}
122123
}

coderd/organizations_test.go

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ func TestOrganizationsByUser(t *testing.T) {
2424
require.NoError(t, err)
2525
require.NotNil(t, orgs)
2626
require.Len(t, orgs, 1)
27+
require.True(t, orgs[0].IsDefault, "first org is always default")
28+
29+
// Make an extra org, and it should not be defaulted.
30+
notDefault, err := client.CreateOrganization(ctx, codersdk.CreateOrganizationRequest{
31+
Name: "another",
32+
})
33+
require.NoError(t, err)
34+
require.False(t, notDefault.IsDefault, "only 1 default org allowed")
2735
}
2836

2937
func TestOrganizationByUserAndName(t *testing.T) {

0 commit comments

Comments
 (0)