Skip to content
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

Merged
merged 7 commits into from
Apr 23, 2021

Conversation

legrego
Copy link
Member

@legrego legrego commented Apr 21, 2021

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

@legrego
Copy link
Member Author

legrego commented Apr 22, 2021

@elasticmachine merge upstream

@legrego legrego added auto-backport Deprecated - use backport:version if exact versions are needed release_note:skip Skip the PR/issue when compiling release notes v7.13.0 v7.14.0 v8.0.0 labels Apr 22, 2021
@legrego legrego marked this pull request as ready for review April 22, 2021 16:25
@legrego legrego requested a review from a team as a code owner April 22, 2021 16:25
@legrego legrego requested a review from azasypkin April 22, 2021 17:47
@@ -25,6 +25,7 @@ export interface CloudConfigType {

interface CloudSetupDependencies {
home?: HomePublicPluginSetup;
security?: Pick<SecurityPluginSetup, 'authc'>;
Copy link
Contributor

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?

Copy link
Member

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.

Copy link
Member Author

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Na, this is fine

Comment on lines 92 to 95
this.checkIfAuthorizedForLinks().then((authorized) => {
if (authorized && baseUrl && deploymentUrl) {
coreStart.chrome.setCustomNavLink({
title: i18n.translate('xpack.cloud.deploymentLinkLabel', {
Copy link
Contributor

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?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, will do!

Copy link
Member

@azasypkin azasypkin left a 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({
Copy link
Member

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.

Copy link
Member Author

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;
Copy link
Member

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.

Copy link
Member Author

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

Copy link
Member

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'>;
Copy link
Member

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));
Copy link
Member

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?

Comment on lines 92 to 95
this.checkIfAuthorizedForLinks().then((authorized) => {
if (authorized && baseUrl && deploymentUrl) {
coreStart.chrome.setCustomNavLink({
title: i18n.translate('xpack.cloud.deploymentLinkLabel', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++

@legrego legrego requested a review from a team as a code owner April 23, 2021 11:39
@@ -62,4 +64,6 @@ export const securityMock = {
createSetup: createSetupMock,
createStart: createStartMock,
createApiResponse: createApiResponseMock,
createMockAuthenticatedUser: (props: MockAuthenticatedUserProps = {}) =>
Copy link
Member Author

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

Copy link
Member

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.

Copy link
Member Author

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())

Copy link
Member

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.

Copy link
Member Author

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 😬

@legrego legrego requested a review from azasypkin April 23, 2021 13:39
Copy link
Member

@azasypkin azasypkin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still LGTM, thanks!

x-pack/plugins/cloud/public/plugin.ts Outdated Show resolved Hide resolved
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
@legrego legrego enabled auto-merge (squash) April 23, 2021 14:07
@kibanamachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
cloud 4.9KB 5.5KB +569.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

@legrego legrego merged commit ec8ff3a into elastic:master Apr 23, 2021
kibanamachine added a commit to kibanamachine/kibana that referenced this pull request Apr 23, 2021
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
kibanamachine added a commit to kibanamachine/kibana that referenced this pull request Apr 23, 2021
Co-authored-by: Aleh Zasypkin <aleh.zasypkin@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
7.13
7.x

The backport PRs will be merged automatically after passing CI.

kibanamachine added a commit that referenced this pull request Apr 23, 2021
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>
kibanamachine added a commit that referenced this pull request Apr 23, 2021
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>
@legrego legrego deleted the cloud/user-links-for-superusers branch April 23, 2021 19:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed release_note:skip Skip the PR/issue when compiling release notes v7.13.0 v7.14.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Adding RBAC to new Cloud links
4 participants