Skip to content
This repository has been archived by the owner on Jan 24, 2023. It is now read-only.

Enable/disable API keys UI given API keys config setting #4559

Merged
merged 12 commits into from
Sep 7, 2020
Merged
2 changes: 1 addition & 1 deletion deploy/kubernetes/console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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|
richard-cox marked this conversation as resolved.
Show resolved Hide resolved
|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||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -30,7 +31,8 @@ describe('AutoscalerMetricPageComponent', () => {
providers: [
DatePipe,
{ provide: ApplicationService, useClass: ApplicationServiceMock },
TabNavService
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -30,7 +31,8 @@ describe('AutoscalerScaleHistoryPageComponent', () => {
providers: [
DatePipe,
{ provide: ApplicationService, useClass: ApplicationServiceMock },
TabNavService
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -33,6 +34,7 @@ describe('EditAutoscalerCredentialComponent', () => {
DatePipe,
{ provide: ApplicationService, useClass: ApplicationServiceMock },
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -43,6 +44,7 @@ describe('EditAutoscalerPolicyComponent', () => {
{ provide: ApplicationService, useClass: ApplicationServiceMock },
TabNavService,
EditAutoscalerPolicyService,
CurrentUserPermissionsService
]
})
.compileComponents();
Expand Down
7 changes: 6 additions & 1 deletion src/frontend/packages/core/src/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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',
Expand Down
30 changes: 30 additions & 0 deletions src/frontend/packages/core/src/core/apiKey-auth-guard.service.ts
Original file line number Diff line number Diff line change
@@ -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<AppState>,
private cups: CurrentUserPermissionsService,
) { }

canActivate(): Observable<boolean> {
return this.cups.can(StratosCurrentUserPermissions.API_KEYS).pipe(
map(can => {
if (!can) {
this.store.dispatch(new RouterNav({ path: ['/'] }));
}
return can;
})
);
}
}
2 changes: 2 additions & 0 deletions src/frontend/packages/core/src/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -69,6 +70,7 @@ import { WindowRef } from './window-ref/window-ref.service';
],
providers: [
AuthGuardService,
APIKeyAuthGuardService,
NotSetupGuardService,
PageHeaderService,
EventWatcherService,
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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 {
Expand All @@ -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.
Expand All @@ -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<GeneralEntityAppState>, ) {
super()
constructor(private store: Store<GeneralEntityAppState>,) {
super();
}

getPermissionConfig(action: string) {
Expand Down Expand Up @@ -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();
}
}

Expand All @@ -95,6 +106,20 @@ export class StratosUserPermissionsChecker extends BaseCurrentUserPermissionsChe
return this.check(StratosPermissionTypes.STRATOS_SCOPE, permission);
}

private apiKeyCheck(): Observable<boolean> {
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[]
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -22,7 +23,10 @@ describe('AboutPageComponent', () => {
CoreTestingModule,
createBasicStoreModule(),
],
providers: [TabNavService]
providers: [
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -22,7 +23,10 @@ describe('DiagnosticsPageComponent', () => {
CoreTestingModule,
createBasicStoreModule(),
],
providers: [TabNavService]
providers: [
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -24,7 +25,10 @@ describe('EulaPageComponent', () => {
HttpClientTestingModule,
createBasicStoreModule(),
],
providers: [TabNavService]
providers: [
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -49,7 +50,9 @@ describe('CreateEndpointComponent', () => {
}
},
TabNavService,
SidePanelService],
SidePanelService,
CurrentUserPermissionsService
],
})
.compileComponents();
}));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -36,7 +37,8 @@ describe('EditEndpointComponent', () => {
}
}
},
TabNavService
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -22,7 +23,10 @@ describe('EventsPageComponent', () => {
createBasicStoreModule(),
RouterTestingModule
],
providers: [TabNavService]
providers: [
TabNavService,
CurrentUserPermissionsService
]
})
.compileComponents();
}));
Expand Down
Loading