-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
Only add cloud-specific links for superusers #97870
Only add cloud-specific links for superusers #97870
Conversation
@elasticmachine merge upstream |
@@ -25,6 +25,7 @@ export interface CloudConfigType { | |||
|
|||
interface CloudSetupDependencies { | |||
home?: HomePublicPluginSetup; | |||
security?: Pick<SecurityPluginSetup, 'authc'>; |
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.
NIT: as you're using the whole type in the tests via securityMock
anyhow, any reason to use a Pick
here?
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 leave that to Larry, but I personally like the fact that we explicitly outline the part of the dependency contract we really need (too bad we don't have a more expressive syntax to do that). This can make the life much easier if you're changing/fixing the behavior of a certain portion of your public contract and want to quickly know what plugins may be affected without following all the paths where the contract is passed to.
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.
Yeah I did this mostly out of habit for the reasons Aleh mentioned. I don't mind reverting if you'd prefer the original approach
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.
Na, this is fine
this.checkIfAuthorizedForLinks().then((authorized) => { | ||
if (authorized && baseUrl && deploymentUrl) { | ||
coreStart.chrome.setCustomNavLink({ | ||
title: i18n.translate('xpack.cloud.deploymentLinkLabel', { |
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.
NIT: I know checkIfAuthorizedForLinks
cannot likely throw, but we may still want to add a catch
handler, just to follow the best practices against UnhandledPromiseRejection, wdyt?
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.
++
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.
Good idea, will do!
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.
Test locally, LGTM, thanks!
const coreSetup = coreMock.createSetup(); | ||
const homeSetup = homePluginMock.createSetupContract(); | ||
const securitySetup = securityMock.createSetup(); | ||
securitySetup.authc.getCurrentUser.mockResolvedValue({ |
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.
optional nit: wondering if it's time to expose existing mockAuthenticatedUser
from security/common/mocks
? Not a big deal, up to you.
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.
Good idea, will do! I forgot about this mock
// Otherwise check roles. If user is not defined due to an unexpected error, then fail *open*. | ||
// Cloud admin console will always perform the actual authorization checks. | ||
const user = await this.authenticatedUserPromise; | ||
return user?.roles.includes('superuser') ?? true; |
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.
question: sorry if I missed that in #97308, but for how long we expect this workaround to exist? If we're not sure, I'm wondering if we may want to leave an escape hatch and expose something like xpack.cloud.roles: schema.arrayOf(schema.string(), { defaultValue: ['superuser'] })
config value, so that in the worst case users could create an empty "marker" role if they need to.... I don't have a strong opinion on that, so feel free to ignore.
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.
This workaround will likely exist for a while - it's really up to the cloud team's roadmap to prioritize an API or similar mechanism for us to leverage.
I think it's premature to add an escape hatch, because we don't know what it would look like just yet. It's possible that we would instead want something under cloud's control, such as inspecting the user's metadata that their SSO realm attaches
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 think it's premature to add an escape hatch, because we don't know what it would look like just yet. It's possible that we would instead want something under cloud's control, such as inspecting the user's metadata that their SSO realm attaches
That makes sense, thanks. Works for me as long as it works for Cloud.
@@ -25,6 +25,7 @@ export interface CloudConfigType { | |||
|
|||
interface CloudSetupDependencies { | |||
home?: HomePublicPluginSetup; | |||
security?: Pick<SecurityPluginSetup, 'authc'>; |
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 leave that to Larry, but I personally like the fact that we explicitly outline the part of the dependency contract we really need (too bad we don't have a more expressive syntax to do that). This can make the life much easier if you're changing/fixing the behavior of a certain portion of your public contract and want to quickly know what plugins may be affected without following all the paths where the contract is passed to.
import { securityMock } from '../../security/public/mocks'; | ||
import { CloudPlugin } from './plugin'; | ||
|
||
const nextTick = async () => await new Promise<void>((resolve) => setTimeout(() => resolve(), 1)); |
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.
question: can we use import { nextTick } from '@kbn/test/jest';
instead?
this.checkIfAuthorizedForLinks().then((authorized) => { | ||
if (authorized && baseUrl && deploymentUrl) { | ||
coreStart.chrome.setCustomNavLink({ | ||
title: i18n.translate('xpack.cloud.deploymentLinkLabel', { |
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.
++
…nks-for-superusers
…kibana into cloud/user-links-for-superusers
@@ -62,4 +64,6 @@ export const securityMock = { | |||
createSetup: createSetupMock, | |||
createStart: createStartMock, | |||
createApiResponse: createApiResponseMock, | |||
createMockAuthenticatedUser: (props: MockAuthenticatedUserProps = {}) => |
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 didn't have to expose this from the server mock, but I felt like this was a good way to ensure consistency between the client and server mock contracts
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.
Any reason why not just createMockAuthenticatedUser: mockAuthenticatedUser
? No need to change anything, just curious.
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 debated exposing mockAuthenticatedUser
, but prefixing it with create
was more consistent with the other mock functions (createSetup
, createStart
, ...), and it felt more correct. When I first imported mockAuthenticatedUser
, I assumed based on the name that it was an object with a create
property or similar on it (mockAuthenticatedUser.create()
)
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.
Yeah, I like the createMockAuthenticatedUser
name, I was mostly curious if we need this additional arrow function or we can just assign mockAuthenticatedUser
driectly to createMockAuthenticatedUser
.
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 sorry I should have read your comment a little closer 🙈
We don't need the additional arrow function, I added that so my IDE would give me type information as I wrote it out 😬
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.
Still LGTM, thanks!
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
💚 Build SucceededMetrics [docs]Page load bundle
History
To update your PR or re-run it, just comment with: |
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Larry Gregory <larry.gregory@elastic.co> Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Larry Gregory <larry.gregory@elastic.co> Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
Summary
Adds cloud specific links for users who are likely authorized to view them. In this first iteration, we are checking if the current user is a superuser.
Link examples
Manage this deployment for Cloud users with superuser privileges
Profile and Account & Billing with Cloud links for superuser privileges
Profile link for self managed, or Cloud w/o superuser privileges
Resolves #97308