diff --git a/deploy/kubernetes/console/README.md b/deploy/kubernetes/console/README.md index 3f5243a7ad..603a85ec47 100644 --- a/deploy/kubernetes/console/README.md +++ b/deploy/kubernetes/console/README.md @@ -75,7 +75,7 @@ The following table lists the configurable parameters of the Stratos Helm chart |console.templatesConfigMapName|Name of config map that provides the template files for user invitation emails|| |console.userInviteSubject|Email subject of the user invitation message|| |console.techPreview|Enable/disable Tech Preview features|false| -|console.apiKeysEnabled|Enable/disable API key-based access to Stratos API (disable, admin_only, all_users)|admin_only| +|console.apiKeysEnabled|Enable/disable API key-based access to Stratos API (disabled, admin_only, all_users)|admin_only| |console.ui.listMaxSize|Override the default maximum number of entities that a configured list can fetch. When a list meets this amount additional pages are not fetched|| |console.ui.listAllowLoadMaxed|If the maximum list size is met give the user the option to fetch all results|false| |console.localAdminPassword|Use local admin user instead of UAA - set to a password to enable|| diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-metric-page/autoscaler-metric-page.component.spec.ts b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-metric-page/autoscaler-metric-page.component.spec.ts index 951dceda5c..a6b358f4d1 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-metric-page/autoscaler-metric-page.component.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-metric-page/autoscaler-metric-page.component.spec.ts @@ -7,6 +7,7 @@ import { createEmptyStoreModule } from '@stratosui/store/testing'; import { ApplicationService } from '../../../../cloud-foundry/src/features/applications/application.service'; import { ApplicationServiceMock } from '../../../../cloud-foundry/test-framework/application-service-helper'; import { CoreModule } from '../../../../core/src/core/core.module'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { TabNavService } from '../../../../core/src/tab-nav.service'; import { CfAutoscalerTestingModule } from '../../cf-autoscaler-testing.module'; @@ -30,7 +31,8 @@ describe('AutoscalerMetricPageComponent', () => { providers: [ DatePipe, { provide: ApplicationService, useClass: ApplicationServiceMock }, - TabNavService + TabNavService, + CurrentUserPermissionsService ] }) .compileComponents(); diff --git a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-scale-history-page/autoscaler-scale-history-page.component.spec.ts b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-scale-history-page/autoscaler-scale-history-page.component.spec.ts index cdadad97b8..477a22f4fa 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/autoscaler-scale-history-page/autoscaler-scale-history-page.component.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/autoscaler-scale-history-page/autoscaler-scale-history-page.component.spec.ts @@ -7,6 +7,7 @@ import { createEmptyStoreModule } from '@stratosui/store/testing'; import { ApplicationService } from '../../../../cloud-foundry/src/features/applications/application.service'; import { ApplicationServiceMock } from '../../../../cloud-foundry/test-framework/application-service-helper'; import { CoreModule } from '../../../../core/src/core/core.module'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { TabNavService } from '../../../../core/src/tab-nav.service'; import { CfAutoscalerTestingModule } from '../../cf-autoscaler-testing.module'; @@ -30,7 +31,8 @@ describe('AutoscalerScaleHistoryPageComponent', () => { providers: [ DatePipe, { provide: ApplicationService, useClass: ApplicationServiceMock }, - TabNavService + TabNavService, + CurrentUserPermissionsService ] }) .compileComponents(); diff --git a/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.spec.ts b/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.spec.ts index 5c7e1f49fd..847513f52e 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-credential/edit-autoscaler-credential.component.spec.ts @@ -6,6 +6,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { ApplicationService } from '../../../../cloud-foundry/src/features/applications/application.service'; import { ApplicationServiceMock } from '../../../../cloud-foundry/test-framework/application-service-helper'; import { CoreModule } from '../../../../core/src/core/core.module'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { TabNavService } from '../../../../core/src/tab-nav.service'; import { createBasicStoreModule } from '../../../../store/testing/public-api'; @@ -33,6 +34,7 @@ describe('EditAutoscalerCredentialComponent', () => { DatePipe, { provide: ApplicationService, useClass: ApplicationServiceMock }, TabNavService, + CurrentUserPermissionsService ] }) .compileComponents(); diff --git a/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-policy/edit-autoscaler-policy.component.spec.ts b/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-policy/edit-autoscaler-policy.component.spec.ts index 5f6c6ccb6d..bfab3dab44 100644 --- a/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-policy/edit-autoscaler-policy.component.spec.ts +++ b/src/frontend/packages/cf-autoscaler/src/features/edit-autoscaler-policy/edit-autoscaler-policy.component.spec.ts @@ -7,6 +7,7 @@ import { createEmptyStoreModule } from '@stratosui/store/testing'; import { ApplicationService } from '../../../../cloud-foundry/src/features/applications/application.service'; import { ApplicationServiceMock } from '../../../../cloud-foundry/test-framework/application-service-helper'; import { CoreModule } from '../../../../core/src/core/core.module'; +import { CurrentUserPermissionsService } from '../../../../core/src/core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../../core/src/shared/shared.module'; import { TabNavService } from '../../../../core/src/tab-nav.service'; import { CfAutoscalerTestingModule } from '../../cf-autoscaler-testing.module'; @@ -43,6 +44,7 @@ describe('EditAutoscalerPolicyComponent', () => { { provide: ApplicationService, useClass: ApplicationServiceMock }, TabNavService, EditAutoscalerPolicyService, + CurrentUserPermissionsService ] }) .compileComponents(); diff --git a/src/frontend/packages/core/src/app.routing.ts b/src/frontend/packages/core/src/app.routing.ts index a57cda750d..a54b1c30d5 100644 --- a/src/frontend/packages/core/src/app.routing.ts +++ b/src/frontend/packages/core/src/app.routing.ts @@ -2,6 +2,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { APIKeyAuthGuardService } from './core/apiKey-auth-guard.service'; import { AuthGuardService } from './core/auth-guard.service'; import { CoreModule } from './core/core.module'; import { EndpointsService } from './core/endpoints.service'; @@ -94,7 +95,11 @@ const appRoutes: Routes = [ }, { path: 'about', loadChildren: () => import('./features/about/about.module').then(m => m.AboutModule) }, { path: 'user-profile', loadChildren: () => import('./features/user-profile/user-profile.module').then(m => m.UserProfileModule) }, - { path: 'api-keys', loadChildren: () => import('./features/api-keys/api-keys.module').then(m => m.ApiKeysModule) }, + { + path: 'api-keys', + loadChildren: () => import('./features/api-keys/api-keys.module').then(m => m.ApiKeysModule), + canActivate: [APIKeyAuthGuardService] + }, { path: 'events', loadChildren: () => import('./features/event-page/event-page.module').then(m => m.EventPageModule) }, { path: 'errors/:endpointId', diff --git a/src/frontend/packages/core/src/core/apiKey-auth-guard.service.ts b/src/frontend/packages/core/src/core/apiKey-auth-guard.service.ts new file mode 100644 index 0000000000..70e965da23 --- /dev/null +++ b/src/frontend/packages/core/src/core/apiKey-auth-guard.service.ts @@ -0,0 +1,30 @@ +import { Injectable } from '@angular/core'; +import { CanActivate } from '@angular/router'; +import { Store } from '@ngrx/store'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; + +import { RouterNav } from '../../../store/src/actions/router.actions'; +import { AppState } from '../../../store/src/app-state'; +import { CurrentUserPermissionsService } from './permissions/current-user-permissions.service'; +import { StratosCurrentUserPermissions } from './permissions/stratos-user-permissions.checker'; + +@Injectable() +export class APIKeyAuthGuardService implements CanActivate { + + constructor( + private store: Store, + private cups: CurrentUserPermissionsService, + ) { } + + canActivate(): Observable { + return this.cups.can(StratosCurrentUserPermissions.API_KEYS).pipe( + map(can => { + if (!can) { + this.store.dispatch(new RouterNav({ path: ['/'] })); + } + return can; + }) + ); + } +} \ No newline at end of file diff --git a/src/frontend/packages/core/src/core/core.module.ts b/src/frontend/packages/core/src/core/core.module.ts index 25b731b63e..792f489d5c 100644 --- a/src/frontend/packages/core/src/core/core.module.ts +++ b/src/frontend/packages/core/src/core/core.module.ts @@ -12,6 +12,7 @@ import { PaginationMonitorFactory } from '../../../store/src/monitors/pagination import { NoContentMessageComponent } from '../shared/components/no-content-message/no-content-message.component'; import { RecentEntitiesComponent } from '../shared/components/recent-entities/recent-entities.component'; import { UserAvatarComponent } from './../shared/components/user-avatar/user-avatar.component'; +import { APIKeyAuthGuardService } from './apiKey-auth-guard.service'; import { AuthGuardService } from './auth-guard.service'; import { ButtonBlurOnClickDirective } from './button-blur-on-click.directive'; import { BytesToHumanSize, MegaBytesToHumanSize } from './byte-formatters.pipe'; @@ -69,6 +70,7 @@ import { WindowRef } from './window-ref/window-ref.service'; ], providers: [ AuthGuardService, + APIKeyAuthGuardService, NotSetupGuardService, PageHeaderService, EventWatcherService, diff --git a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts index db4c382b26..39308b500a 100644 --- a/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts +++ b/src/frontend/packages/core/src/core/permissions/stratos-user-permissions.checker.ts @@ -1,12 +1,15 @@ import { Store } from '@ngrx/store'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; +import { switchMap } from 'rxjs/operators'; import { GeneralEntityAppState } from '../../../../store/src/app-state'; +import { selectSessionData } from '../../../../store/src/reducers/auth.reducer'; import { getCurrentUserStratosHasScope, getCurrentUserStratosRole, PermissionValues, } from '../../../../store/src/selectors/current-user-role.selectors'; +import { APIKeysEnabled } from '../../../../store/src/types/auth.types'; import { IPermissionConfigs, PermissionConfig, PermissionTypes } from './current-user-permissions.config'; import { BaseCurrentUserPermissionsChecker, @@ -19,6 +22,10 @@ import { export enum StratosCurrentUserPermissions { ENDPOINT_REGISTER = 'register.endpoint', PASSWORD_CHANGE = 'change-password', + /** + * Does the user have permission to view/create/delete their own API Keys? + */ + API_KEYS = 'api-keys' } export enum StratosPermissionStrings { @@ -34,7 +41,8 @@ export enum StratosScopeStrings { export enum StratosPermissionTypes { STRATOS = 'internal', - STRATOS_SCOPE = 'internal-scope' + STRATOS_SCOPE = 'internal-scope', + API_KEY = 'api-key' } // For each set permissions are checked by permission types of ENDPOINT, ENDPOINT_SCOPE, STRATOS_SCOPE, FEATURE_FLAG or a random bag. @@ -43,11 +51,12 @@ export enum StratosPermissionTypes { export const stratosPermissionConfigs: IPermissionConfigs = { [StratosCurrentUserPermissions.ENDPOINT_REGISTER]: new PermissionConfig(StratosPermissionTypes.STRATOS, StratosPermissionStrings.STRATOS_ADMIN), [StratosCurrentUserPermissions.PASSWORD_CHANGE]: new PermissionConfig(StratosPermissionTypes.STRATOS_SCOPE, StratosScopeStrings.STRATOS_CHANGE_PASSWORD), + [StratosCurrentUserPermissions.API_KEYS]: new PermissionConfig(StratosPermissionTypes.API_KEY, '') }; export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChecker implements ICurrentUserPermissionsChecker { - constructor(private store: Store, ) { - super() + constructor(private store: Store,) { + super(); } getPermissionConfig(action: string) { @@ -75,6 +84,8 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe return this.getInternalCheck(permissionConfig.permission as StratosPermissionStrings); case (StratosPermissionTypes.STRATOS_SCOPE): return this.getInternalScopesCheck(permissionConfig.permission as StratosScopeStrings); + case (StratosPermissionTypes.API_KEY): + return this.apiKeyCheck(); } } @@ -95,6 +106,20 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe return this.check(StratosPermissionTypes.STRATOS_SCOPE, permission); } + private apiKeyCheck(): Observable { + return this.store.select(selectSessionData()).pipe( + switchMap(sessionData => { + switch (sessionData.config.APIKeysEnabled) { + case APIKeysEnabled.ADMIN_ONLY: + return this.store.select(getCurrentUserStratosRole(StratosPermissionStrings.STRATOS_ADMIN)); + case APIKeysEnabled.ALL_USERS: + return of(true); + } + return of(false); + }) + ); + } + public getComplexCheck( permissionConfig: PermissionConfig[], ...args: any[] @@ -108,7 +133,7 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe checks: this.getInternalScopesChecks(configGroup), }; } - }) + }); // Checker must handle all configs return res.every(check => !!check) ? res : null; } diff --git a/src/frontend/packages/core/src/features/about/about-page/about-page.component.spec.ts b/src/frontend/packages/core/src/features/about/about-page/about-page.component.spec.ts index ab09df31b4..69f0863602 100644 --- a/src/frontend/packages/core/src/features/about/about-page/about-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/about/about-page/about-page.component.spec.ts @@ -4,6 +4,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { AboutPageComponent } from './about-page.component'; @@ -22,7 +23,10 @@ describe('AboutPageComponent', () => { CoreTestingModule, createBasicStoreModule(), ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/about/diagnostics-page/diagnostics-page.component.spec.ts b/src/frontend/packages/core/src/features/about/diagnostics-page/diagnostics-page.component.spec.ts index 9cbf0ffe41..16786352e6 100644 --- a/src/frontend/packages/core/src/features/about/diagnostics-page/diagnostics-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/about/diagnostics-page/diagnostics-page.component.spec.ts @@ -4,6 +4,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { DiagnosticsPageComponent } from './diagnostics-page.component'; @@ -22,7 +23,10 @@ describe('DiagnosticsPageComponent', () => { CoreTestingModule, createBasicStoreModule(), ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts index 8ebf8ea27c..cd45da187e 100644 --- a/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/about/eula-page/eula-page.component.spec.ts @@ -5,6 +5,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { EulaPageComponent } from './eula-page.component'; @@ -24,7 +25,10 @@ describe('EulaPageComponent', () => { HttpClientTestingModule, createBasicStoreModule(), ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-base-step/create-endpoint-base-step.component.spec.ts b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-base-step/create-endpoint-base-step.component.spec.ts index 715e655dc6..eae2dd40c7 100644 --- a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-base-step/create-endpoint-base-step.component.spec.ts +++ b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint-base-step/create-endpoint-base-step.component.spec.ts @@ -6,6 +6,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../../shared/shared.module'; import { TabNavService } from '../../../../tab-nav.service'; import { CreateEndpointBaseStepComponent } from './create-endpoint-base-step.component'; @@ -27,15 +28,19 @@ describe('CreateEndpointBaseStepComponent', () => { createBasicStoreModule(), NoopAnimationsModule ], - providers: [{ - provide: ActivatedRoute, - useValue: { - snapshot: { - queryParams: {}, - params: { type: 'metrics' } + providers: [ + { + provide: ActivatedRoute, + useValue: { + snapshot: { + queryParams: {}, + params: { type: 'metrics' } + } } - } - }, TabNavService], + }, + TabNavService, + CurrentUserPermissionsService + ], }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint.component.spec.ts b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint.component.spec.ts index 3df52ba96a..a074af1f7b 100644 --- a/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint.component.spec.ts +++ b/src/frontend/packages/core/src/features/endpoints/create-endpoint/create-endpoint.component.spec.ts @@ -7,6 +7,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SidePanelService } from '../../../shared/services/side-panel.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; @@ -49,7 +50,9 @@ describe('CreateEndpointComponent', () => { } }, TabNavService, - SidePanelService], + SidePanelService, + CurrentUserPermissionsService + ], }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint.component.spec.ts b/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint.component.spec.ts index 9e97689e70..6dbdbb0753 100644 --- a/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint.component.spec.ts +++ b/src/frontend/packages/core/src/features/endpoints/edit-endpoint/edit-endpoint.component.spec.ts @@ -6,6 +6,7 @@ import { RouterTestingModule } from '@angular/router/testing'; import { createBasicStoreModule } from '../../../../../store/testing/public-api'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { EditEndpointStepComponent } from './edit-endpoint-step/edit-endpoint-step.component'; @@ -36,7 +37,8 @@ describe('EditEndpointComponent', () => { } } }, - TabNavService + TabNavService, + CurrentUserPermissionsService ] }) .compileComponents(); diff --git a/src/frontend/packages/core/src/features/event-page/events-page/events-page.component.spec.ts b/src/frontend/packages/core/src/features/event-page/events-page/events-page.component.spec.ts index ed0314a253..c79c2d4d5d 100644 --- a/src/frontend/packages/core/src/features/event-page/events-page/events-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/event-page/events-page/events-page.component.spec.ts @@ -4,6 +4,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { EventsPageComponent } from './events-page.component'; @@ -22,7 +23,10 @@ describe('EventsPageComponent', () => { createBasicStoreModule(), RouterTestingModule ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/home/home/home-page.component.spec.ts b/src/frontend/packages/core/src/features/home/home/home-page.component.spec.ts index be4e9bfb8e..9579ad3f19 100644 --- a/src/frontend/packages/core/src/features/home/home/home-page.component.spec.ts +++ b/src/frontend/packages/core/src/features/home/home/home-page.component.spec.ts @@ -6,6 +6,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { HomePageComponent } from './home-page.component'; @@ -26,7 +27,10 @@ describe('HomePageComponent', () => { CoreTestingModule, createBasicStoreModule() ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.spec.ts b/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.spec.ts index b183a885f1..ae19f047f3 100644 --- a/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.spec.ts +++ b/src/frontend/packages/core/src/features/metrics/metrics/metrics.component.spec.ts @@ -6,6 +6,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; import { MetricsService } from '../services/metrics-service'; @@ -27,7 +28,11 @@ describe('MetricsComponent', () => { createBasicStoreModule(), ], declarations: [MetricsComponent], - providers: [MetricsService, TabNavService] + providers: [ + MetricsService, + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/no-endpoints-non-admin/no-endpoints-non-admin.component.spec.ts b/src/frontend/packages/core/src/features/no-endpoints-non-admin/no-endpoints-non-admin.component.spec.ts index e9cb274f2f..4e8f59f873 100644 --- a/src/frontend/packages/core/src/features/no-endpoints-non-admin/no-endpoints-non-admin.component.spec.ts +++ b/src/frontend/packages/core/src/features/no-endpoints-non-admin/no-endpoints-non-admin.component.spec.ts @@ -4,6 +4,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../test-framework/core-test.modules'; import { CoreModule } from '../../core/core.module'; +import { CurrentUserPermissionsService } from '../../core/permissions/current-user-permissions.service'; import { SharedModule } from '../../shared/shared.module'; import { TabNavService } from '../../tab-nav.service'; import { NoEndpointsNonAdminComponent } from './no-endpoints-non-admin.component'; @@ -22,7 +23,10 @@ describe('NoEndpointsNonAdminComponent', () => { CoreTestingModule, createBasicStoreModule(), ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/setup/local-account-wizard/local-account-wizard.component.spec.ts b/src/frontend/packages/core/src/features/setup/local-account-wizard/local-account-wizard.component.spec.ts index 9e2b3ba3d8..a15ea5f550 100644 --- a/src/frontend/packages/core/src/features/setup/local-account-wizard/local-account-wizard.component.spec.ts +++ b/src/frontend/packages/core/src/features/setup/local-account-wizard/local-account-wizard.component.spec.ts @@ -6,6 +6,7 @@ import { createEmptyStoreModule } from '@stratosui/store/testing'; import { CoreModule } from '../../../core/core.module'; import { MDAppModule } from '../../../core/md.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { PageHeaderModule } from '../../../shared/components/page-header/page-header.module'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; @@ -30,7 +31,10 @@ describe('LocalAccountWizardComponent', () => { createEmptyStoreModule(), NoopAnimationsModule, ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.spec.ts b/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.spec.ts index 558b44dcff..56353578c4 100644 --- a/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.spec.ts +++ b/src/frontend/packages/core/src/features/setup/uaa-wizard/console-uaa-wizard.component.spec.ts @@ -7,6 +7,7 @@ import { StoreModule } from '@ngrx/store'; import { appReducers } from '../../../../../store/src/reducers.module'; import { CoreModule } from '../../../core/core.module'; import { MDAppModule } from '../../../core/md.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { PageHeaderModule } from '../../../shared/components/page-header/page-header.module'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; @@ -31,7 +32,10 @@ describe('ConsoleUaaWizardComponent', () => { StoreModule.forRoot(appReducers), NoopAnimationsModule, ], - providers: [TabNavService] + providers: [ + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.spec.ts b/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.spec.ts index 496f43f9d2..e10f58880b 100644 --- a/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.spec.ts +++ b/src/frontend/packages/core/src/features/user-profile/profile-info/profile-info.component.spec.ts @@ -6,6 +6,7 @@ import { createBasicStoreModule } from '@stratosui/store/testing'; import { CoreTestingModule } from '../../../../test-framework/core-test.modules'; import { CoreModule } from '../../../core/core.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { UserProfileService } from '../../../core/user-profile.service'; import { SharedModule } from '../../../shared/shared.module'; import { TabNavService } from '../../../tab-nav.service'; @@ -27,7 +28,11 @@ describe('ProfileInfoComponent', () => { CoreTestingModule, createBasicStoreModule() ], - providers: [UserProfileService, TabNavService] + providers: [ + UserProfileService, + TabNavService, + CurrentUserPermissionsService + ] }) .compileComponents(); })); diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html index a7573fa455..5f6c34fe7d 100644 --- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html +++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.html @@ -75,7 +75,7 @@

Recent Activity

-
diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.spec.ts b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.spec.ts index fe79d0308e..dfa81f3643 100644 --- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.spec.ts +++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.spec.ts @@ -7,6 +7,7 @@ import { InternalEventMonitorFactory } from '../../../../../store/src/monitors/i import { appReducers } from '../../../../../store/src/reducers.module'; import { CoreModule } from '../../../core/core.module'; import { MDAppModule } from '../../../core/md.module'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; import { TabNavService } from '../../../tab-nav.service'; import { SharedModule } from '../../shared.module'; import { PageHeaderComponent } from './page-header.component'; @@ -28,7 +29,8 @@ describe('PageHeaderComponent', () => { } } }, - TabNavService + TabNavService, + CurrentUserPermissionsService ], imports: [ MDAppModule, diff --git a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts index 29d5ce0e56..2547077ff4 100644 --- a/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts +++ b/src/frontend/packages/core/src/shared/components/page-header/page-header.component.ts @@ -15,6 +15,8 @@ import { selectIsMobile } from '../../../../../store/src/selectors/dashboard.sel import { InternalEventSeverity } from '../../../../../store/src/types/internal-events.types'; import { StratosStatus } from '../../../../../store/src/types/shared.types'; import { IFavoriteMetadata, UserFavorite } from '../../../../../store/src/types/user-favorites.types'; +import { CurrentUserPermissionsService } from '../../../core/permissions/current-user-permissions.service'; +import { StratosCurrentUserPermissions } from '../../../core/permissions/stratos-user-permissions.checker'; import { UserProfileService } from '../../../core/user-profile.service'; import { IPageSideNavTab } from '../../../features/dashboard/page-side-nav/page-side-nav.component'; import { TabNavService } from '../../../tab-nav.service'; @@ -29,6 +31,7 @@ import { BREADCRUMB_URL_PARAM, IHeaderBreadcrumb, IHeaderBreadcrumbLink } from ' styleUrls: ['./page-header.component.scss'] }) export class PageHeaderComponent implements OnDestroy, AfterViewInit { + public canAPIKeys$: Observable; public breadcrumbDefinitions: IHeaderBreadcrumbLink[] = null; private breadcrumbKey: string; public eventSeverity = InternalEventSeverity; @@ -156,6 +159,7 @@ export class PageHeaderComponent implements OnDestroy, AfterViewInit { eventService: GlobalEventService, private favoritesConfigMapper: FavoritesConfigMapper, private userProfileService: UserProfileService, + private cups: CurrentUserPermissionsService, ) { this.events$ = eventService.events$.pipe( startWith([]) @@ -185,6 +189,8 @@ export class PageHeaderComponent implements OnDestroy, AfterViewInit { this.allowGravatar$ = this.store.select(selectDashboardState).pipe( map(dashboardState => dashboardState.gravatarEnabled) ); + + this.canAPIKeys$ = this.cups.can(StratosCurrentUserPermissions.API_KEYS); } ngOnDestroy() { diff --git a/src/frontend/packages/store/src/types/auth.types.ts b/src/frontend/packages/store/src/types/auth.types.ts index cef354d888..5787243ea7 100644 --- a/src/frontend/packages/store/src/types/auth.types.ts +++ b/src/frontend/packages/store/src/types/auth.types.ts @@ -22,10 +22,16 @@ export interface SessionEndpoints { export interface SessionEndpoint { [guid: string]: SessionDataEndpoint; } +export enum APIKeysEnabled { + DISABLED = 'disabled', + ADMIN_ONLY = 'admin_only', + ALL_USERS = 'all_users' +} export interface SessionDataConfig { enableTechPreview?: boolean; listMaxSize?: number; listAllowLoadMaxed?: boolean; + APIKeysEnabled?: APIKeysEnabled; } export interface SessionData { endpoints?: SessionEndpoints; @@ -44,7 +50,7 @@ export interface SessionData { ['plugin-config']?: PluginConfig; plugins: { demo: boolean, - [pluginName: string]: boolean + [pluginName: string]: boolean, }; config: SessionDataConfig; } diff --git a/src/jetstream/config.dev b/src/jetstream/config.dev index a98e5c3ec3..d6f6b930b3 100644 --- a/src/jetstream/config.dev +++ b/src/jetstream/config.dev @@ -53,3 +53,6 @@ AUTH_ENDPOINT_TYPE=local LOCAL_USER=admin LOCAL_USER_PASSWORD=admin LOCAL_USER_SCOPE=stratos.admin + +# Enable/disable API key-based access to Stratos API (disabled, admin_only, all_users). Default is admin_only +#API_KEYS_ENABLED=admin_only \ No newline at end of file