Co-authored-by: Larry Gregory <larry.gregory@elastic.co>
This commit is contained in:
parent
1e7b83dbd1
commit
3a23dc1a17
|
@ -13,10 +13,7 @@ import { CloudPlugin } from './plugin';
|
|||
|
||||
describe('Cloud Plugin', () => {
|
||||
describe('#start', () => {
|
||||
function setupPlugin({
|
||||
roles = [],
|
||||
simulateUserError = false,
|
||||
}: { roles?: string[]; simulateUserError?: boolean } = {}) {
|
||||
function setupPlugin() {
|
||||
const plugin = new CloudPlugin(
|
||||
coreMock.createPluginInitializerContext({
|
||||
id: 'cloudId',
|
||||
|
@ -28,20 +25,10 @@ describe('Cloud Plugin', () => {
|
|||
);
|
||||
const coreSetup = coreMock.createSetup();
|
||||
const homeSetup = homePluginMock.createSetupContract();
|
||||
const securitySetup = securityMock.createSetup();
|
||||
if (simulateUserError) {
|
||||
securitySetup.authc.getCurrentUser.mockRejectedValue(new Error('Something happened'));
|
||||
} else {
|
||||
securitySetup.authc.getCurrentUser.mockResolvedValue(
|
||||
securityMock.createMockAuthenticatedUser({
|
||||
roles,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
plugin.setup(coreSetup, { home: homeSetup, security: securitySetup });
|
||||
plugin.setup(coreSetup, { home: homeSetup });
|
||||
|
||||
return { coreSetup, securitySetup, plugin };
|
||||
return { coreSetup, plugin };
|
||||
}
|
||||
|
||||
it('registers help support URL', async () => {
|
||||
|
@ -59,11 +46,37 @@ describe('Cloud Plugin', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
it('does not register custom nav links on anonymous pages', async () => {
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
coreStart.http.anonymousPaths.isAnonymous.mockReturnValue(true);
|
||||
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockResolvedValue(
|
||||
securityMock.createMockAuthenticatedUser({
|
||||
roles: ['superuser'],
|
||||
})
|
||||
);
|
||||
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
||||
expect(coreStart.chrome.setCustomNavLink).not.toHaveBeenCalled();
|
||||
expect(securityStart.authc.getCurrentUser).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('registers a custom nav link for superusers', async () => {
|
||||
const { plugin } = setupPlugin({ roles: ['superuser'] });
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockResolvedValue(
|
||||
securityMock.createMockAuthenticatedUser({
|
||||
roles: ['superuser'],
|
||||
})
|
||||
);
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
@ -81,10 +94,11 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
it('registers a custom nav link when there is an error retrieving the current user', async () => {
|
||||
const { plugin } = setupPlugin({ simulateUserError: true });
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockRejectedValue(new Error('something happened'));
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
@ -102,10 +116,15 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
it('does not register a custom nav link for non-superusers', async () => {
|
||||
const { plugin } = setupPlugin({ roles: ['not-a-superuser'] });
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockResolvedValue(
|
||||
securityMock.createMockAuthenticatedUser({
|
||||
roles: ['not-a-superuser'],
|
||||
})
|
||||
);
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
@ -114,10 +133,15 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
it('registers user profile links for superusers', async () => {
|
||||
const { plugin } = setupPlugin({ roles: ['superuser'] });
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockResolvedValue(
|
||||
securityMock.createMockAuthenticatedUser({
|
||||
roles: ['superuser'],
|
||||
})
|
||||
);
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
@ -145,10 +169,11 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
it('registers profile links when there is an error retrieving the current user', async () => {
|
||||
const { plugin } = setupPlugin({ simulateUserError: true });
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockRejectedValue(new Error('something happened'));
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
@ -176,10 +201,15 @@ describe('Cloud Plugin', () => {
|
|||
});
|
||||
|
||||
it('does not register profile links for non-superusers', async () => {
|
||||
const { plugin } = setupPlugin({ roles: ['not-a-superuser'] });
|
||||
const { plugin } = setupPlugin();
|
||||
|
||||
const coreStart = coreMock.createStart();
|
||||
const securityStart = securityMock.createStart();
|
||||
securityStart.authc.getCurrentUser.mockResolvedValue(
|
||||
securityMock.createMockAuthenticatedUser({
|
||||
roles: ['not-a-superuser'],
|
||||
})
|
||||
);
|
||||
plugin.start(coreStart, { security: securityStart });
|
||||
|
||||
await nextTick();
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'src/core/public';
|
||||
import { CoreSetup, CoreStart, Plugin, PluginInitializerContext, HttpStart } from 'src/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { AuthenticatedUser, SecurityPluginSetup, SecurityPluginStart } from '../../security/public';
|
||||
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';
|
||||
|
@ -45,14 +45,13 @@ export interface CloudSetup {
|
|||
export class CloudPlugin implements Plugin<CloudSetup> {
|
||||
private config!: CloudConfigType;
|
||||
private isCloudEnabled: boolean;
|
||||
private authenticatedUserPromise?: Promise<AuthenticatedUser | null>;
|
||||
|
||||
constructor(private readonly initializerContext: PluginInitializerContext) {
|
||||
this.config = this.initializerContext.config.get<CloudConfigType>();
|
||||
this.isCloudEnabled = false;
|
||||
}
|
||||
|
||||
public setup(core: CoreSetup, { home, security }: CloudSetupDependencies) {
|
||||
public setup(core: CoreSetup, { home }: CloudSetupDependencies) {
|
||||
const {
|
||||
id,
|
||||
cname,
|
||||
|
@ -70,10 +69,6 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
}
|
||||
}
|
||||
|
||||
if (security) {
|
||||
this.authenticatedUserPromise = security.authc.getCurrentUser().catch(() => null);
|
||||
}
|
||||
|
||||
return {
|
||||
cloudId: id,
|
||||
cname,
|
||||
|
@ -108,7 +103,7 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
}
|
||||
};
|
||||
|
||||
this.checkIfAuthorizedForLinks()
|
||||
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.
|
||||
|
@ -123,12 +118,21 @@ export class CloudPlugin implements Plugin<CloudSetup> {
|
|||
* 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() {
|
||||
private async checkIfAuthorizedForLinks({
|
||||
http,
|
||||
security,
|
||||
}: {
|
||||
http: HttpStart;
|
||||
security?: SecurityPluginStart;
|
||||
}) {
|
||||
if (http.anonymousPaths.isAnonymous(window.location.pathname)) {
|
||||
return false;
|
||||
}
|
||||
// Security plugin is disabled
|
||||
if (!this.authenticatedUserPromise) return true;
|
||||
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 this.authenticatedUserPromise;
|
||||
const user = await security.authc.getCurrentUser().catch(() => null);
|
||||
return user?.roles.includes('superuser') ?? true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue