chore: include organization name when fetching templates (#13751)

* chore: include organization name when fetching templates
* chore: rename template_with_user to template_with_names
This commit is contained in:
Steven Masley
2024-07-02 09:08:30 -05:00
committed by GitHub
parent b87c12ba92
commit 128674918b
25 changed files with 177 additions and 84 deletions
+20 -10
View File
@@ -515,7 +515,7 @@ func (q *FakeQuerier) getLatestWorkspaceBuildByWorkspaceIDNoLock(_ context.Conte
func (q *FakeQuerier) getTemplateByIDNoLock(_ context.Context, id uuid.UUID) (database.Template, error) {
for _, template := range q.templates {
if template.ID == id {
return q.templateWithUserNoLock(template), nil
return q.templateWithNameNoLock(template), nil
}
}
return database.Template{}, sql.ErrNoRows
@@ -524,12 +524,12 @@ func (q *FakeQuerier) getTemplateByIDNoLock(_ context.Context, id uuid.UUID) (da
func (q *FakeQuerier) templatesWithUserNoLock(tpl []database.TemplateTable) []database.Template {
cpy := make([]database.Template, 0, len(tpl))
for _, t := range tpl {
cpy = append(cpy, q.templateWithUserNoLock(t))
cpy = append(cpy, q.templateWithNameNoLock(t))
}
return cpy
}
func (q *FakeQuerier) templateWithUserNoLock(tpl database.TemplateTable) database.Template {
func (q *FakeQuerier) templateWithNameNoLock(tpl database.TemplateTable) database.Template {
var user database.User
for _, _user := range q.users {
if _user.ID == tpl.CreatedBy {
@@ -537,13 +537,23 @@ func (q *FakeQuerier) templateWithUserNoLock(tpl database.TemplateTable) databas
break
}
}
var withUser database.Template
var org database.Organization
for _, _org := range q.organizations {
if _org.ID == tpl.OrganizationID {
org = _org
break
}
}
var withNames database.Template
// This is a cheeky way to copy the fields over without explicitly listing them all.
d, _ := json.Marshal(tpl)
_ = json.Unmarshal(d, &withUser)
withUser.CreatedByUsername = user.Username
withUser.CreatedByAvatarURL = user.AvatarURL
return withUser
_ = json.Unmarshal(d, &withNames)
withNames.CreatedByUsername = user.Username
withNames.CreatedByAvatarURL = user.AvatarURL
withNames.OrganizationName = org.Name
return withNames
}
func (q *FakeQuerier) templateVersionWithUserNoLock(tpl database.TemplateVersionTable) database.TemplateVersion {
@@ -3675,7 +3685,7 @@ func (q *FakeQuerier) GetTemplateByOrganizationAndName(_ context.Context, arg da
if template.Deleted != arg.Deleted {
continue
}
return q.templateWithUserNoLock(template), nil
return q.templateWithNameNoLock(template), nil
}
return database.Template{}, sql.ErrNoRows
}
@@ -9323,7 +9333,7 @@ func (q *FakeQuerier) GetAuthorizedTemplates(ctx context.Context, arg database.G
var templates []database.Template
for _, templateTable := range q.templates {
template := q.templateWithUserNoLock(templateTable)
template := q.templateWithNameNoLock(templateTable)
if prepared != nil && prepared.Authorize(ctx, template.RBACObject()) != nil {
continue
}
+7 -5
View File
@@ -1055,7 +1055,7 @@ COMMENT ON COLUMN templates.autostart_block_days_of_week IS 'A bitmap of days of
COMMENT ON COLUMN templates.deprecated IS 'If set to a non empty string, the template will no longer be able to be used. The message will be displayed to the user.';
CREATE VIEW template_with_users AS
CREATE VIEW template_with_names AS
SELECT templates.id,
templates.created_at,
templates.updated_at,
@@ -1085,11 +1085,13 @@ CREATE VIEW template_with_users AS
templates.activity_bump,
templates.max_port_sharing_level,
COALESCE(visible_users.avatar_url, ''::text) AS created_by_avatar_url,
COALESCE(visible_users.username, ''::text) AS created_by_username
FROM (templates
LEFT JOIN visible_users ON ((templates.created_by = visible_users.id)));
COALESCE(visible_users.username, ''::text) AS created_by_username,
COALESCE(organizations.name, ''::text) AS organization_name
FROM ((templates
LEFT JOIN visible_users ON ((templates.created_by = visible_users.id)))
LEFT JOIN organizations ON ((templates.organization_id = organizations.id)));
COMMENT ON VIEW template_with_users IS 'Joins in the username + avatar url of the created by user.';
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
CREATE TABLE user_links (
user_id uuid NOT NULL,
+1 -1
View File
@@ -32,7 +32,7 @@ func TestViewSubsetTemplate(t *testing.T) {
tableFields := allFields(table)
joinedFields := allFields(joined)
if !assert.Subset(t, fieldNames(joinedFields), fieldNames(tableFields), "table is not subset") {
t.Log("Some fields were added to the Template Table without updating the 'template_with_users' view.")
t.Log("Some fields were added to the Template Table without updating the 'template_with_names' view.")
t.Log("See migration 000138_join_users.up.sql to create the view.")
}
}
@@ -0,0 +1,16 @@
DROP VIEW template_with_names;
CREATE VIEW
template_with_users
AS
SELECT
templates.*,
coalesce(visible_users.avatar_url, '') AS created_by_avatar_url,
coalesce(visible_users.username, '') AS created_by_username
FROM
templates
LEFT JOIN
visible_users
ON
templates.created_by = visible_users.id;
COMMENT ON VIEW template_with_users IS 'Joins in the username + avatar url of the created by user.';
@@ -0,0 +1,24 @@
-- Update the template_with_users view by recreating it.
DROP VIEW template_with_users;
-- Renaming template_with_users -> template_with_names
CREATE VIEW
template_with_names
AS
SELECT
templates.*,
coalesce(visible_users.avatar_url, '') AS created_by_avatar_url,
coalesce(visible_users.username, '') AS created_by_username,
coalesce(organizations.name, '') AS organization_name
FROM
templates
LEFT JOIN
visible_users
ON
templates.created_by = visible_users.id
LEFT JOIN
organizations
ON templates.organization_id = organizations.id
;
COMMENT ON VIEW template_with_names IS 'Joins in the display name information such as username, avatar, and organization name.';
+1
View File
@@ -116,6 +116,7 @@ func (q *sqlQuerier) GetAuthorizedTemplates(ctx context.Context, arg GetTemplate
&i.MaxPortSharingLevel,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.OrganizationName,
); err != nil {
return nil, err
}
+2 -1
View File
@@ -2243,7 +2243,7 @@ type TailnetTunnel struct {
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
// Joins in the username + avatar url of the created by user.
// Joins in the display name information such as username, avatar, and organization name.
type Template struct {
ID uuid.UUID `db:"id" json:"id"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
@@ -2275,6 +2275,7 @@ type Template struct {
MaxPortSharingLevel AppSharingLevel `db:"max_port_sharing_level" json:"max_port_sharing_level"`
CreatedByAvatarURL string `db:"created_by_avatar_url" json:"created_by_avatar_url"`
CreatedByUsername string `db:"created_by_username" json:"created_by_username"`
OrganizationName string `db:"organization_name" json:"organization_name"`
}
type TemplateTable struct {
+11 -7
View File
@@ -7178,9 +7178,9 @@ func (q *sqlQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg GetTem
const getTemplateByID = `-- name: GetTemplateByID :one
SELECT
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username, organization_name
FROM
template_with_users
template_with_names
WHERE
id = $1
LIMIT
@@ -7221,15 +7221,16 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
&i.MaxPortSharingLevel,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.OrganizationName,
)
return i, err
}
const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
SELECT
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username, organization_name
FROM
template_with_users AS templates
template_with_names AS templates
WHERE
organization_id = $1
AND deleted = $2
@@ -7278,12 +7279,13 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
&i.MaxPortSharingLevel,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.OrganizationName,
)
return i, err
}
const getTemplates = `-- name: GetTemplates :many
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username FROM template_with_users AS templates
SELECT id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username, organization_name FROM template_with_names AS templates
ORDER BY (name, id) ASC
`
@@ -7327,6 +7329,7 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
&i.MaxPortSharingLevel,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.OrganizationName,
); err != nil {
return nil, err
}
@@ -7343,9 +7346,9 @@ func (q *sqlQuerier) GetTemplates(ctx context.Context) ([]Template, error) {
const getTemplatesWithFilter = `-- name: GetTemplatesWithFilter :many
SELECT
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username
id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, default_ttl, created_by, icon, user_acl, group_acl, display_name, allow_user_cancel_workspace_jobs, allow_user_autostart, allow_user_autostop, failure_ttl, time_til_dormant, time_til_dormant_autodelete, autostop_requirement_days_of_week, autostop_requirement_weeks, autostart_block_days_of_week, require_active_version, deprecated, activity_bump, max_port_sharing_level, created_by_avatar_url, created_by_username, organization_name
FROM
template_with_users AS templates
template_with_names AS templates
WHERE
-- Optionally include deleted templates
templates.deleted = $1
@@ -7437,6 +7440,7 @@ func (q *sqlQuerier) GetTemplatesWithFilter(ctx context.Context, arg GetTemplate
&i.MaxPortSharingLevel,
&i.CreatedByAvatarURL,
&i.CreatedByUsername,
&i.OrganizationName,
); err != nil {
return nil, err
}
+4 -4
View File
@@ -2,7 +2,7 @@
SELECT
*
FROM
template_with_users
template_with_names
WHERE
id = $1
LIMIT
@@ -12,7 +12,7 @@ LIMIT
SELECT
*
FROM
template_with_users AS templates
template_with_names AS templates
WHERE
-- Optionally include deleted templates
templates.deleted = @deleted
@@ -54,7 +54,7 @@ ORDER BY (name, id) ASC
SELECT
*
FROM
template_with_users AS templates
template_with_names AS templates
WHERE
organization_id = @organization_id
AND deleted = @deleted
@@ -63,7 +63,7 @@ LIMIT
1;
-- name: GetTemplates :many
SELECT * FROM template_with_users AS templates
SELECT * FROM template_with_names AS templates
ORDER BY (name, id) ASC
;
+3 -3
View File
@@ -55,10 +55,10 @@ sql:
- column: "templates.group_acl"
go_type:
type: "TemplateACL"
- column: "template_with_users.user_acl"
- column: "template_with_names.user_acl"
go_type:
type: "TemplateACL"
- column: "template_with_users.group_acl"
- column: "template_with_names.group_acl"
go_type:
type: "TemplateACL"
- column: "template_usage_stats.app_usage_mins"
@@ -72,7 +72,7 @@ sql:
type: "[]byte"
rename:
template: TemplateTable
template_with_user: Template
template_with_name: Template
workspace_build: WorkspaceBuildTable
workspace_build_with_user: WorkspaceBuild
template_version: TemplateVersionTable