-
Notifications
You must be signed in to change notification settings - Fork 27
Support X-Trino-Role header
#322
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
base: main
Are you sure you want to change the base?
Changes from 1 commit
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 |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ import ( | |
| const ( | ||
| accessTokenKey = "accessToken" | ||
| trinoUserHeader = "X-Trino-User" | ||
| trinoRoleHeader = "X-Trino-Role" | ||
ssheikin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| trinoClientTagsKey = "X-Trino-Client-Tags" | ||
| bearerPrefix = "Bearer " | ||
| ) | ||
|
|
@@ -41,6 +42,10 @@ func (ds *SQLDatasourceWithTrinoUserContext) QueryData(ctx context.Context, req | |
| ctx = context.WithValue(ctx, trinoUserHeader, user) | ||
| } | ||
|
|
||
| if settings.Role != "" { | ||
| ctx = context.WithValue(ctx, trinoRoleHeader, "system=ROLE{"+settings.Role+"}") | ||
sourcery-ai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
ssheikin marked this conversation as resolved.
Show resolved
Hide resolved
Member
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. Note there's an open PR to support roles directly in the Go driver: trinodb/trino-go-client#144 It's not required here, but we had a discussion there about the format in which to specify roles. We tried being consistent with other drivers, like JDBC and Python.
Member
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. Sounds good to me. What is the golden standard here we should follow? https://trino.io/docs/current/client/jdbc.html ?
That makes sense. As I understand for system role we simply say
Author
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. @nineinchnick @kokosing
Member
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.
Hm... I was under impression that initial approach was similar, but a bit different than in JDBC. That your approach followed the protocol implementation, not the JDBC format.
Member
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.
Member
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. |
||
| } | ||
|
|
||
| if settings.ClientTags != "" { | ||
| ctx = context.WithValue(ctx, trinoClientTagsKey, settings.ClientTags) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,12 @@ async function setupDataSourceWithClientTags(page: Page, clientTags: string) { | |
| await page.getByTestId('data-testid Data source settings page Save and Test button').click(); | ||
| } | ||
|
|
||
| async function setupDataSourceWithRole(page: Page, role: string) { | ||
| await page.getByTestId('data-testid Datasource HTTP settings url').fill('http://trino:8080'); | ||
| await page.locator('div').filter({hasText: /^Role$/}).locator('input').fill(role); | ||
| await page.getByTestId('data-testid Data source settings page Save and Test button').click(); | ||
| } | ||
|
|
||
| async function runQueryAndCheckResults(page: Page) { | ||
| await page.getByLabel(EXPORT_DATA).click(); | ||
| await page.getByTestId('data-testid TimePicker Open Button').click(); | ||
|
|
@@ -91,3 +97,34 @@ test('test with client tags', async ({ page }) => { | |
| await setupDataSourceWithClientTags(page, 'tag1,tag2,tag3'); | ||
| await runQueryAndCheckResults(page); | ||
| }); | ||
|
|
||
| test('test with role', async ({ page }) => { | ||
| await login(page); | ||
| await goToTrinoSettings(page); | ||
| await setupDataSourceWithRole(page, '},system=ALL,hive=ROLE{admin'); | ||
|
Member
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. how you can set a role like this? |
||
| await runRoleQuery(page); | ||
| await expect(page.getByTestId('data-testid table body')).toContainText(/.*admin.*/); | ||
|
|
||
| }); | ||
|
|
||
| test('test without role', async ({ page }) => { | ||
| await login(page); | ||
| await goToTrinoSettings(page); | ||
| await setupDataSourceWithRole(page, ''); | ||
| await runRoleQuery(page); | ||
| await expect(page.getByText(/Access Denied: Cannot show roles/)).toBeVisible(); | ||
| }); | ||
|
|
||
| async function runRoleQuery(page: Page) { | ||
|
Member
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. why utility functions are on top and why some are on the bottom?
Author
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. The good practice, at least in trino java code to put utility functions on the bottom.
Member
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. We can reorder functions in this file in a separate commit
Author
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. That's not for free - the git history of the file will be overriden. |
||
| await page.getByLabel(EXPORT_DATA).click(); | ||
| await page.locator('div').filter({hasText: /^Format asChoose$/}).locator('svg').click(); | ||
| await page.getByRole('option', {name: 'Table'}).click(); | ||
| await setQuery(page, 'SHOW ROLES FROM hive') | ||
| await page.getByTestId('data-testid Code editor container').click(); | ||
| await page.getByTestId('data-testid RefreshPicker run button').click(); | ||
| } | ||
|
|
||
| async function setQuery(page: Page, query: string) { | ||
| await page.getByTestId('data-testid Code editor container').click({ clickCount: 4 }); | ||
| await page.keyboard.type(query); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| connector.name=hive | ||
| hive.metastore=file | ||
| hive.metastore.catalog.dir=/tmp/metastore | ||
| hive.security=sql-standard | ||
| fs.hadoop.enabled=true |
Uh oh!
There was an error while loading. Please reload this page.