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

Commit

Permalink
Merge pull request #4 from cloudfoundry-incubator/v2-master
Browse files Browse the repository at this point in the history
Merge upstream/v2-master
  • Loading branch information
Irfan Habib committed May 24, 2018
2 parents ebdd104 + 8c89f82 commit fee6c9e
Show file tree
Hide file tree
Showing 155 changed files with 3,960 additions and 838 deletions.
37 changes: 26 additions & 11 deletions src/frontend/app/core/auth-guard.service.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import { RouterNav } from '../store/actions/router.actions';
import 'rxjs/add/operator/skipWhile';

import { Injectable } from '@angular/core';
import { ActivatedRoute, CanActivate, Router } from '@angular/router';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Rx';

import { VerifySession } from '../store/actions/auth.actions';
import { RouterNav } from '../store/actions/router.actions';
import { AppState } from '../store/app-state';
import { AuthState } from '../store/reducers/auth.reducer';

import { Store } from '@ngrx/store';

import { CanActivate, Router } from '@angular/router';
import { Injectable } from '@angular/core';

import 'rxjs/add/operator/skipWhile';

@Injectable()
export class AuthGuardService implements CanActivate {

queryParamMap() {
const map = {};
const query = window.location.search.substring(1);
if (query.length === 0) {
return map;
}
const vars = query.split('&');
for (let i = 0; i < vars.length; i++) {
const pair = vars[i].split('=');
map[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return map;
}

constructor(
private store: Store<AppState>,
private router: Router
private router: Router,
private route: ActivatedRoute
) { }

canActivate(): Observable<boolean> {
Expand All @@ -26,7 +38,10 @@ export class AuthGuardService implements CanActivate {
if (!state.sessionData || !state.sessionData.valid) {
this.store.dispatch(new RouterNav({
path: ['/login']
}, window.location.pathname));
}, {
path: window.location.pathname,
queryParams: this.queryParamMap()
}));
return false;
}
return true;
Expand Down
46 changes: 34 additions & 12 deletions src/frontend/app/core/current-user-permissions.checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '../store/selectors/current-user-roles-permissions-selectors/role.selectors';
import { endpointsRegisteredEntitiesSelector } from '../store/selectors/endpoint.selectors';
import { APIResource } from '../store/types/api.types';
import { IOrgRoleState, ISpaceRoleState } from '../store/types/current-user-roles.types';
import { IOrgRoleState, ISpaceRoleState, ISpacesRoleState } from '../store/types/current-user-roles.types';
import { IFeatureFlag } from './cf-api.types';
import {
PermissionConfig,
Expand All @@ -38,31 +38,45 @@ export enum CHECKER_GROUPS {

export type IConfigGroup = PermissionConfig[];
export class CurrentUserPermissionsChecker {
static readonly ALL_SPACES = 'PERMISSIONS__ALL_SPACES_PLEASE';
constructor(private store: Store<AppState>) { }
public check(type: PermissionTypes, permission: PermissionValues, endpointGuid?: string, orgOrSpaceGuid?: string, ) {
public check(
type: PermissionTypes,
permission: PermissionValues,
endpointGuid?: string,
orgOrSpaceGuid?: string,
allSpacesWithinOrg = false
) {
if (type === PermissionTypes.STRATOS) {
return this.store.select(getCurrentUserStratosRole(permission));
}

if (type === PermissionTypes.STRATOS_SCOPE) {
return this.store.select(getCurrentUserStratosHasScope(permission));
return this.store.select(getCurrentUserStratosHasScope(permission as ScopeStrings));
}

if (type === PermissionTypes.ENDPOINT_SCOPE) {
if (!endpointGuid) {
return Observable.of(false);
}
return this.store.select(getCurrentUserCFEndpointHasScope(endpointGuid, permission));
return this.store.select(getCurrentUserCFEndpointHasScope(endpointGuid, permission as ScopeStrings));
}

if (type === PermissionTypes.ENDPOINT) {
return this.store.select(getCurrentUserCFGlobalState(endpointGuid, permission));
}
return this.getEndpointState(endpointGuid).pipe(
filter(state => !!state),
map(state => state[type][orgOrSpaceGuid]),
filter(state => !!state),
map(state => this.selectPermission(state, permission as PermissionStrings)),
map(state => {
const permissionString = permission as PermissionStrings;
if (allSpacesWithinOrg) {
const orgOrSpaceState = state[PermissionTypes.ORGANIZATION][orgOrSpaceGuid];
const spaceState = state[PermissionTypes.SPACE];
return this.checkAllSpacesInOrg(orgOrSpaceState, spaceState, permissionString);
}
const orgOrSpaceState = state[type][orgOrSpaceGuid];
return this.selectPermission(orgOrSpaceState, permissionString);
}),
distinctUntilChanged(),
);
}
Expand Down Expand Up @@ -90,6 +104,13 @@ export class CurrentUserPermissionsChecker {
}
}

private checkAllSpacesInOrg(orgState: IOrgRoleState, endpointSpaces: ISpacesRoleState, permission: PermissionStrings) {
return orgState.spaceGuids.map(spaceGuid => {
const space = endpointSpaces[spaceGuid];
return space ? space[permission] || false : false;
}).some(check => check);
}

public getInternalChecks(
configs: PermissionConfig[]
) {
Expand Down Expand Up @@ -154,10 +175,11 @@ export class CurrentUserPermissionsChecker {

public getCfCheck(config: PermissionConfig, endpointGuid?: string, orgOrSpaceGuid?: string, spaceGuid?: string): Observable<boolean> {
const { type, permission } = config;
const actualGuid = type === PermissionTypes.SPACE && spaceGuid ? spaceGuid : orgOrSpaceGuid;
const checkAllSpaces = spaceGuid === CurrentUserPermissionsChecker.ALL_SPACES;
const actualGuid = type === PermissionTypes.SPACE && spaceGuid && !checkAllSpaces ? spaceGuid : orgOrSpaceGuid;
const cfPermissions = permission as PermissionStrings;
if (type === PermissionTypes.ENDPOINT || (endpointGuid && actualGuid)) {
return this.check(type, cfPermissions, endpointGuid, actualGuid);
return this.check(type, cfPermissions, endpointGuid, actualGuid, checkAllSpaces);
} else if (!actualGuid) {
const endpointGuids$ = this.getEndpointGuidObservable(endpointGuid);
return endpointGuids$.pipe(
Expand Down Expand Up @@ -281,7 +303,7 @@ export class CurrentUserPermissionsChecker {
return config.type;
}

private checkAllOfType(endpointGuid: string, type: PermissionTypes, permission: PermissionStrings) {
private checkAllOfType(endpointGuid: string, type: PermissionTypes, permission: PermissionStrings, orgGuid?: string) {
return this.getEndpointState(endpointGuid).pipe(
map(state => {
if (!state || !state[type]) {
Expand All @@ -304,8 +326,8 @@ export class CurrentUserPermissionsChecker {
return !endpointGuid ? this.getAllEndpointGuids() : Observable.of([endpointGuid]);
}

private selectPermission(state: IOrgRoleState | ISpaceRoleState, permission: PermissionStrings) {
return state[permission] || false;
private selectPermission(state: IOrgRoleState | ISpaceRoleState, permission: PermissionStrings): boolean {
return state ? state[permission] || false : false;
}

private getEndpointState(endpointGuid: string) {
Expand Down
9 changes: 8 additions & 1 deletion src/frontend/app/core/current-user-permissions.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export enum CurrentUserPermissions {
ORGANIZATION_DELETE = 'delete.org',
ORGANIZATION_EDIT = 'edit.org',
ORGANIZATION_SUSPEND = 'suspend.org',
SERVICE_INSTANCE_DELETE = 'delete.service-instance',
SERVICE_BINDING_EDIT = 'edit.service-binding',
FIREHOSE_VIEW = 'view-firehose',
ENDPOINT_REGISTER = 'register.endpoint',
PASSWORD_CHANGE = 'change-password'
}
Expand Down Expand Up @@ -99,7 +102,6 @@ export const permissionConfigs: IPermissionConfigs = {
new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.route_creation),
new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER)
],
// [CurrentUserPermissions.ROUTE_BINDING_CREATE]: new PermissionConfigLink(CurrentUserPermissions.ROUTE_CREATE),
[CurrentUserPermissions.ORGANIZATION_CREATE]: [
new PermissionConfig(PermissionTypes.FEATURE_FLAG, CFFeatureFlagTypes.user_org_creation),
new PermissionConfig(PermissionTypes.ORGANIZATION, PermissionStrings.ORG_MANAGER),
Expand All @@ -113,6 +115,11 @@ export const permissionConfigs: IPermissionConfigs = {
[CurrentUserPermissions.ORGANIZATION_DELETE]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP),
[CurrentUserPermissions.ORGANIZATION_EDIT]: new PermissionConfigLink(CurrentUserPermissions.ORGANIZATION_DELETE),
[CurrentUserPermissions.ORGANIZATION_SUSPEND]: new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_ADMIN_GROUP),
[CurrentUserPermissions.SERVICE_INSTANCE_DELETE]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER),
[CurrentUserPermissions.SERVICE_BINDING_EDIT]: new PermissionConfig(PermissionTypes.SPACE, PermissionStrings.SPACE_DEVELOPER),
[CurrentUserPermissions.FIREHOSE_VIEW]: [
new PermissionConfig(PermissionTypes.ENDPOINT_SCOPE, ScopeStrings.CF_READ_ONLY_ADMIN_GROUP)
],
[CurrentUserPermissions.ENDPOINT_REGISTER]: new PermissionConfig(PermissionTypes.STRATOS, PermissionStrings.STRATOS_ADMIN),
[CurrentUserPermissions.PASSWORD_CHANGE]: new PermissionConfig(PermissionTypes.STRATOS_SCOPE, ScopeStrings.STRATOS_CHANGE_PASSWORD),
};
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ <h3>Routes</h3>
</app-action-monitor>
</ng-container>
<ng-container *ngIf="selectedServiceInstances && selectedServiceInstances.length">
<h3>Instances</h3>
<h3>Services</h3>
<app-action-monitor [columns]="instanceDeleteColumns" [data$]="selectedServiceInstances$" [entityKey]="serviceInstancesSchemaKey" [monitorState]="deletingState" [getId]="getInstanceId"></app-action-monitor>
</ng-container>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,37 @@ import { DatePipe } from '@angular/common';
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';
import { ReplaySubject } from 'rxjs/ReplaySubject';
import { combineLatest } from 'rxjs/observable/combineLatest';
import { filter, first, map, pairwise, shareReplay, startWith, switchMap, tap } from 'rxjs/operators';
import { ReplaySubject } from 'rxjs/ReplaySubject';

import { IServiceBinding } from '../../../core/cf-api-svc.types';
import { IApp, IRoute } from '../../../core/cf-api.types';
import { AppMonitorComponentTypes } from '../../../shared/components/app-action-monitor-icon/app-action-monitor-icon.component';
import {
AppMonitorComponentTypes,
} from '../../../shared/components/app-action-monitor-icon/app-action-monitor-icon.component';
import { DataFunctionDefinition } from '../../../shared/components/list/data-sources-controllers/list-data-source';
import { ITableColumn } from '../../../shared/components/list/list-table/table.types';
import { CfAppRoutesListConfigService } from '../../../shared/components/list/list-types/app-route/cf-app-routes-list-config.service';
import { TableCellRouteComponent } from '../../../shared/components/list/list-types/app-route/table-cell-route/table-cell-route.component';
import {
TableCellTCPRouteComponent
CfAppRoutesListConfigService,
} from '../../../shared/components/list/list-types/app-route/cf-app-routes-list-config.service';
import {
TableCellRouteComponent,
} from '../../../shared/components/list/list-types/app-route/table-cell-route/table-cell-route.component';
import {
TableCellTCPRouteComponent,
} from '../../../shared/components/list/list-types/app-route/table-cell-tcproute/table-cell-tcproute.component';
import {
AppServiceBindingDataSource
AppServiceBindingDataSource,
} from '../../../shared/components/list/list-types/app-sevice-bindings/app-service-binding-data-source';
import {
AppServiceBindingListConfigService
AppServiceBindingListConfigService,
} from '../../../shared/components/list/list-types/app-sevice-bindings/app-service-binding-list-config.service';
import {
TableCellAppInstancesComponent
TableCellAppInstancesComponent,
} from '../../../shared/components/list/list-types/app/table-cell-app-instances/table-cell-app-instances.component';
import {
TableCellAppStatusComponent
TableCellAppStatusComponent,
} from '../../../shared/components/list/list-types/app/table-cell-app-status/table-cell-app-status.component';
import { EntityMonitor } from '../../../shared/monitors/entity-monitor';
import { EntityMonitorFactory } from '../../../shared/monitors/entity-monitor.factory.service';
Expand All @@ -36,12 +44,15 @@ import { RouterNav } from '../../../store/actions/router.actions';
import { DeleteServiceInstance } from '../../../store/actions/service-instances.actions';
import { AppState } from '../../../store/app-state';
import {
applicationSchemaKey, entityFactory, routeSchemaKey, serviceBindingSchemaKey, serviceInstancesSchemaKey
applicationSchemaKey,
entityFactory,
routeSchemaKey,
serviceBindingSchemaKey,
serviceInstancesSchemaKey,
} from '../../../store/helpers/entity-factory';
import { createEntityRelationKey } from '../../../store/helpers/entity-relations.types';
import { APIResource } from '../../../store/types/api.types';
import { ApplicationService } from '../application.service';
import { DataFunctionDefinition } from '../../../shared/components/list/data-sources-controllers/list-data-source';


@Component({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';

import { CliInfoApplicationComponent } from './cli-info-application.component';
import { CodeBlockComponent } from '../../../shared/components/code-block/code-block.component';
import { PageHeaderComponent } from '../../../shared/components/page-header/page-header.component';
import { CoreModule } from '../../../core/core.module';
import { SharedModule } from '../../../shared/shared.module';
import { MDAppModule } from '../../../core/md.module';
import { createBasicStoreModule } from '../../../test-framework/store-test-helper';
import { generateTestEntityServiceProvider } from '../../../test-framework/entity-service.helper';
import { entityFactory, applicationSchemaKey } from '../../../store/helpers/entity-factory';
import { ApplicationStateService } from '../../../shared/components/application-state/application-state.service';
import { SharedModule } from '../../../shared/shared.module';
import { GetApplication } from '../../../store/actions/application.actions';
import { applicationSchemaKey, entityFactory } from '../../../store/helpers/entity-factory';
import { generateTestApplicationServiceProvider } from '../../../test-framework/application-service-helper';
import { ApplicationStateService } from '../../../shared/components/application-state/application-state.service';
import { generateTestEntityServiceProvider } from '../../../test-framework/entity-service.helper';
import { createBasicStoreModule } from '../../../test-framework/store-test-helper';
import { ApplicationEnvVarsService } from '../application/application-tabs-base/tabs/build-tab/application-env-vars.service';
import { RouterTestingModule } from '@angular/router/testing';
import { CliInfoApplicationComponent } from './cli-info-application.component';

describe('CliInfoApplicationComponent', () => {
let component: CliInfoApplicationComponent;
Expand All @@ -24,7 +22,7 @@ describe('CliInfoApplicationComponent', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ CliInfoApplicationComponent ],
declarations: [CliInfoApplicationComponent],
imports: [
CoreModule,
SharedModule,
Expand All @@ -43,7 +41,7 @@ describe('CliInfoApplicationComponent', () => {
ApplicationEnvVarsService
]
})
.compileComponents();
.compileComponents();
}));

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material';
import { HttpClient } from '@angular/common/http';
import { Store } from '@ngrx/store';
import { QueueingSubject } from 'queueing-subject/lib';
import websocketConnect from 'rxjs-websockets';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { interval } from 'rxjs/observable/interval';
import { catchError, filter, map, mergeMap, share, switchMap, takeWhile, tap, first } from 'rxjs/operators';
import { catchError, filter, first, map, mergeMap, share, tap } from 'rxjs/operators';
import { Subscription } from 'rxjs/Subscription';

import { environment } from '../../../../environments/environment';
import {
CfAppsDataSource,
createGetAllAppAction,
} from '../../../shared/components/list/list-types/app/cf-apps-data-source';
import { StepOnNextFunction } from '../../../shared/components/stepper/step/step.component';
import { CfOrgSpaceDataService } from '../../../shared/data-services/cf-org-space-service.service';
import { GetAppEnvVarsAction } from '../../../store/actions/app-metadata.actions';
import { DeleteDeployAppSection } from '../../../store/actions/deploy-applications.actions';
import { RouterNav } from '../../../store/actions/router.actions';
import { AppState } from '../../../store/app-state';
import { organizationSchemaKey, spaceSchemaKey } from '../../../store/helpers/entity-factory';
import { selectEntity } from '../../../store/selectors/api.selectors';
Expand Down Expand Up @@ -112,7 +101,7 @@ export class DeployApplicationDeployer {
}

const readyFilter = this.fsFileInfo ? () => true :
(appDetail) => !!appDetail.applicationSource && !!appDetail.applicationSource.projectName;
(appDetail) => !!appDetail.applicationSource && !!appDetail.applicationSource.projectName;
this.isOpen = true;
this.connectSub = this.store.select(selectDeployAppState).pipe(
filter(appDetail => !!appDetail.cloudFoundryDetails && readyFilter(appDetail)),
Expand Down Expand Up @@ -154,7 +143,7 @@ export class DeployApplicationDeployer {
filter((log) => log.type === SocketEventTypes.DATA),
map((log) => log.message)
);
this.msgSub = this.messages.subscribe();
this.msgSub = this.messages.subscribe();
})
).subscribe();
}
Expand Down Expand Up @@ -261,7 +250,7 @@ export class DeployApplicationDeployer {
break;
case SocketEventTypes.SOURCE_REQUIRED:
this.inputStream.next(this.sendProjectInfo(this.applicationSource));
break;
break;
case SocketEventTypes.EVENT_CLONED:
case SocketEventTypes.EVENT_FETCHED_MANIFEST:
case SocketEventTypes.MANIFEST:
Expand All @@ -278,7 +267,7 @@ export class DeployApplicationDeployer {
// Update for the previous file transfer
if (this.currentFileTransfer) {
this.fileTransferStatus.bytesSent += this.currentFileTransfer.size;
this.fileTransferStatus.filesSent ++;
this.fileTransferStatus.filesSent++;
this.fileTransferStatus$.next(this.fileTransferStatus);
}

Expand Down
Loading

0 comments on commit fee6c9e

Please sign in to comment.