kibana/x-pack/plugins/cloud/public/plugin.ts

139 lines
4.5 KiB
TypeScript

/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext, HttpStart } from 'src/core/public';
import { i18n } from '@kbn/i18n';
import { SecurityPluginSetup, SecurityPluginStart } from '../../security/public';
import { getIsCloudEnabled } from '../common/is_cloud_enabled';
import { ELASTIC_SUPPORT_LINK } from '../common/constants';
import { HomePublicPluginSetup } from '../../../../src/plugins/home/public';
import { createUserMenuLinks } from './user_menu_links';
import { getFullCloudUrl } from './utils';
export interface CloudConfigType {
id?: string;
cname?: string;
base_url?: string;
profile_url?: string;
deployment_url?: string;
organization_url?: string;
}
interface CloudSetupDependencies {
home?: HomePublicPluginSetup;
security?: Pick<SecurityPluginSetup, 'authc'>;
}
interface CloudStartDependencies {
security?: SecurityPluginStart;
}
export interface CloudSetup {
cloudId?: string;
cname?: string;
baseUrl?: string;
deploymentUrl?: string;
profileUrl?: string;
organizationUrl?: string;
isCloudEnabled: boolean;
}
export class CloudPlugin implements Plugin<CloudSetup> {
private config!: CloudConfigType;
private isCloudEnabled: boolean;
constructor(private readonly initializerContext: PluginInitializerContext) {
this.config = this.initializerContext.config.get<CloudConfigType>();
this.isCloudEnabled = false;
}
public setup(core: CoreSetup, { home }: CloudSetupDependencies) {
const {
id,
cname,
profile_url: profileUrl,
organization_url: organizationUrl,
deployment_url: deploymentUrl,
base_url: baseUrl,
} = this.config;
this.isCloudEnabled = getIsCloudEnabled(id);
if (home) {
home.environment.update({ cloud: this.isCloudEnabled });
if (this.isCloudEnabled) {
home.tutorials.setVariable('cloud', { id, baseUrl, profileUrl });
}
}
return {
cloudId: id,
cname,
baseUrl,
deploymentUrl: getFullCloudUrl(baseUrl, deploymentUrl),
profileUrl: getFullCloudUrl(baseUrl, profileUrl),
organizationUrl: getFullCloudUrl(baseUrl, organizationUrl),
isCloudEnabled: this.isCloudEnabled,
};
}
public start(coreStart: CoreStart, { security }: CloudStartDependencies) {
const { deployment_url: deploymentUrl, base_url: baseUrl } = this.config;
coreStart.chrome.setHelpSupportUrl(ELASTIC_SUPPORT_LINK);
const setLinks = (authorized: boolean) => {
if (!authorized) return;
if (baseUrl && deploymentUrl) {
coreStart.chrome.setCustomNavLink({
title: i18n.translate('xpack.cloud.deploymentLinkLabel', {
defaultMessage: 'Manage this deployment',
}),
euiIconType: 'arrowLeft',
href: getFullCloudUrl(baseUrl, deploymentUrl),
});
}
if (security && this.isCloudEnabled) {
const userMenuLinks = createUserMenuLinks(this.config);
security.navControlService.addUserMenuLinks(userMenuLinks);
}
};
this.checkIfAuthorizedForLinks({ http: coreStart.http, security })
.then(setLinks)
// In the event of an unexpected error, fail *open*.
// Cloud admin console will always perform the actual authorization checks.
.catch(() => setLinks(true));
}
/**
* Determines if the current user should see links back to Cloud.
* This isn't a true authorization check, but rather a heuristic to
* see if the current user is *likely* a cloud deployment administrator.
*
* At this point, we do not have enough information to reliably make this determination,
* but we do know that all cloud deployment admins are superusers by default.
*/
private async checkIfAuthorizedForLinks({
http,
security,
}: {
http: HttpStart;
security?: SecurityPluginStart;
}) {
if (http.anonymousPaths.isAnonymous(window.location.pathname)) {
return false;
}
// Security plugin is disabled
if (!security) return true;
// 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 security.authc.getCurrentUser().catch(() => null);
return user?.roles.includes('superuser') ?? true;
}
}