-
Notifications
You must be signed in to change notification settings - Fork 881
chore: change sql parameter for custom roles to be a (name,org)
tuple
#13480
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
Conversation
-- Using 'coalesce' to avoid troubles with null literals being an empty string. | ||
(name, coalesce(organization_id, '00000000-0000-0000-0000-000000000000' ::uuid)) = ANY (@lookup_roles::name_organization_pair[]) |
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.
Maybe we can bring NULL
back, but for the life of me I could not get it to work. I think it has to do with my understanding of representing NULL
as a literal
(name,org)
tuple
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.
Definitely seems like an improvement 👍, don't really have any issues
// | ||
// SELECT ARRAY[('customrole'::text,'ece79dac-926e-44ca-9790-2ff7c5eb6e0c'::uuid)]; | ||
func (a NameOrganizationPair) Value() (driver.Value, error) { | ||
return fmt.Sprintf(`(%s,%s)`, a.Name, a.OrganizationID.String()), nil |
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.
For the name here probably want to use https://pkg.go.dev/github.com/lib/pq#QuoteLiteral
unless I'm misunderstanding. This seems like direct sql injection.
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.
It cannot be quoted, I was trying that before. This is a parameter argument still, so it will replace ?#
.
I had considered a sql injection, but can a sql injection happen at a parameter substitution?
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.
Ah, good point actually. This is fine, sry
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 just tried to send in some invalid sql with --
and ;
as the names, and the query still works.
The defaultValueConverter
which implments this function for all primitive types just does the literal string value without quotes or escapes: https://github.com/golang/go/blob/master/src/database/sql/driver/types.go#L291-L293
That is the function behavior I am overriding. 👍
What this does
When looking up a role in the database, it requires a
name
andorganization_id
. Before this change I was usingname[:<org_id]
as a comparison string, but this is obviously not ideal.I found a way to instead pass a slice of
(name, org_id)
tuples as the search filter. This allows 1 query to grab all org roles across all orgs, and site roles in 1 query.This is used in APIKeyMW when pulling a user's roles via this
rolestore.Expand()
:coder/coderd/rbac/rolestore/rolestore.go
Lines 89 to 102 in a1a42b8
How this is done in sqlc
Value()
function to return a tuple literal (go does not have native tuples).coder/coderd/database/types.go
Lines 147 to 172 in a1a42b8
coder/coderd/database/migrations/000216_custom_role_pair_parameter.up.sql
Line 1 in a1a42b8
sqlc.yaml
because SQLc does not have the functionality to interpret these types:coder/coderd/database/sqlc.yaml
Lines 32 to 34 in a1a42b8
The result is a really nice auto-generated param
coder/coderd/database/queries.sql.go
Lines 5627 to 5631 in a1a42b8
Tested
A series of tests to verify it all works:
coder/coderd/database/querier_test.go
Line 520 in a1a42b8
DB Logging
DB logging was super helpful doing this: a305e70. I reverted the commit because it brings in an extra dependency. We should consider keeping something like this.