KNOX-1040 - Initial new descriptor and provider config wizard support
Project: http://git-wip-us.apache.org/repos/asf/knox/repo Commit: http://git-wip-us.apache.org/repos/asf/knox/commit/167053bd Tree: http://git-wip-us.apache.org/repos/asf/knox/tree/167053bd Diff: http://git-wip-us.apache.org/repos/asf/knox/diff/167053bd Branch: refs/heads/master Commit: 167053bd1ecbb403de8b8c377c8c0ede66b22956 Parents: 8c919a4 Author: Phil Zampino <[email protected]> Authored: Tue Mar 6 11:35:51 2018 -0500 Committer: Phil Zampino <[email protected]> Committed: Fri Mar 9 11:00:28 2018 -0500 ---------------------------------------------------------------------- gateway-admin-ui/src/app/app.module.ts | 8 +- .../new-desc-wizard.component.css | 5 + .../new-desc-wizard.component.html | 105 ++++++++ .../new-desc-wizard.component.spec.ts | 25 ++ .../new-desc-wizard.component.ts | 166 ++++++++++++ .../acls-authzn-provider-config.ts | 51 ++++ .../authentication-provider-config.ts | 33 +++ .../authentication-wizard.ts | 95 +++++++ .../authorization-wizard.ts | 61 +++++ .../cas-provider-config.ts | 54 ++++ .../provider-config-wizard/category-wizard.ts | 39 +++ .../concat-idassertion-provider-config.ts | 47 ++++ .../default-idassertion-provider-config.ts | 49 ++++ .../display-binding-provider-config.ts | 51 ++++ .../grouplookup-id-assertion-provider-config.ts | 43 ++++ .../src/app/provider-config-wizard/ha-wizard.ts | 46 ++++ .../identity-assertion-provider-config.ts | 32 +++ .../identity-assertion-wizard.ts | 75 ++++++ .../jwt-provider-config.ts | 43 ++++ .../kerberos-provider-config.ts | 81 ++++++ .../ldap-provider-config.ts | 59 +++++ .../oauth-provider-config.ts | 48 ++++ .../oidc-provider-config.ts | 67 +++++ .../pam-provider-config.ts | 48 ++++ .../preauth-sso-provider-config.ts | 55 ++++ .../provider-config-wizard.component.css | 5 + .../provider-config-wizard.component.html | 104 ++++++++ .../provider-config-wizard.component.spec.ts | 25 ++ .../provider-config-wizard.component.ts | 254 +++++++++++++++++++ .../regex-idassertion-provider-config.ts | 53 ++++ .../saml-provider-config.ts | 70 +++++ .../sso-cookie-provider-config.ts | 43 ++++ .../switchcase-idassertion-provider-config.ts | 47 ++++ .../resource-detail.component.html | 6 +- .../resource-detail.component.ts | 87 +------ .../src/app/resource/resource.component.html | 21 +- .../src/app/resource/resource.service.ts | 81 +++++- .../applications/admin-ui/app/index.html | 2 +- .../app/inline.01f49f7d13670ad68dea.bundle.js | 1 + .../app/inline.49efa231bf249ddc231a.bundle.js | 1 - .../app/main.511817c8d904b468f742.bundle.js | 1 - .../app/main.db638922a84cdef35de7.bundle.js | 1 + 42 files changed, 2097 insertions(+), 91 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/app.module.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/app.module.ts b/gateway-admin-ui/src/app/app.module.ts index fc682a3..ede59e7 100644 --- a/gateway-admin-ui/src/app/app.module.ts +++ b/gateway-admin-ui/src/app/app.module.ts @@ -38,7 +38,9 @@ import { ResourceComponent } from './resource/resource.component'; import { ResourceService } from './resource/resource.service'; import { DescriptorComponent } from './descriptor/descriptor.component'; import { ResourceDetailComponent } from './resource-detail/resource-detail.component'; -import { ProviderConfigSelectorComponent } from './provider-config-selector/provider-config-selector.component' +import { ProviderConfigSelectorComponent } from './provider-config-selector/provider-config-selector.component'; +import { NewDescWizardComponent } from './new-desc-wizard/new-desc-wizard.component'; +import { ProviderConfigWizardComponent } from './provider-config-wizard/provider-config-wizard.component' @NgModule({ imports: [ BrowserModule, @@ -59,7 +61,9 @@ import { ProviderConfigSelectorComponent } from './provider-config-selector/prov ResourceComponent, DescriptorComponent, ResourceDetailComponent, - ProviderConfigSelectorComponent + ProviderConfigSelectorComponent, + NewDescWizardComponent, + ProviderConfigWizardComponent ], providers: [ TopologyService, GatewayVersionService, http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.css ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.css b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.css new file mode 100644 index 0000000..0cc494a --- /dev/null +++ b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.css @@ -0,0 +1,5 @@ +td { + border-collapse: collapse; + padding: 8px; + vertical-align: top; +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.html ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.html b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.html new file mode 100644 index 0000000..4e6a407 --- /dev/null +++ b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.html @@ -0,0 +1,105 @@ +<bs-modal (onClose)="onClose()" #newDescriptorModal xmlns="http://www.w3.org/1999/html"> + <bs-modal-header [showDismiss]="true"> + <label class="modal-title">Create a New Descriptor</label> + </bs-modal-header> + <bs-modal-body> + <div class="panel-body"> + + <div> <!-- Descriptor Name --> + <strong>Name</strong> <input type="text" [(ngModel)]="descriptorName"> + </div> <!-- Descriptor Name --> + + <br> + + <div> <!-- Provider Config reference --> + <span class="col-md-sm pull-left"><strong>Provider Configuration</strong> </span> + <span class="col-md-sm inline-editable" (click)="editModePC=true" *ngIf="!editModePC">{{descriptor.providerConfig}}</span> + <span class="col-md-sm inline-editor inlineEditForm" *ngIf="editModePC"> + <input type="text" size="40" [(ngModel)]="descriptor.providerConfig"> + <button class="btn btn-xs" (click)="editModePC=false;descriptor.setDirty()"> + <span class="glyphicon glyphicon-ok"></span> + </button> + <button class="btn btn-xs" (click)="editModePC=false"> + <span class="glyphicon glyphicon-remove"></span> + </button> + </span> + + <button id="chooseProviderConfig" + class="btn btn-xs" + (click)="chooseProviderConfigModal.open(descriptor, 'sm')" + [disabled]="editModePC" + type="submit" + data-toggle="tooltip" + title="Choose Provider Configuration"> + <span class="glyphicon glyphicon-edit"></span> + </button> + <app-provider-config-selector #choosePC></app-provider-config-selector> + </div> <!-- Provider Config reference --> + + <br> + + <!-- Services --> + <div> + <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + (this['showServices'] ? 'minus' : 'plus')" + (click)="toggleBoolean('showServices')"></span> + <span (click)="toggleBoolean('showServices')"><strong>Services</strong></span> + </div> + <div class="panel panel-default col-md-12" *ngIf="this['showServices']"> + <table> + <tr> + <td *ngFor="let col of getServiceDisplayColumns()"> + <div *ngFor="let supportedService of col"> + <input type="checkbox" + [checked]="isSelected(supportedService)" + (click)="toggleServiceSelected(supportedService)"> + {{ supportedService }} + </div> + </td> + </tr> + </table> + </div> <!-- Services --> + + <br> + + <!-- Discovery --> + <div> + <span [class]="'clickable inline-glyph glyhpicon glyphicon-' + (this['showDiscovery'] ? 'minus' : 'plus')" + (click)="toggleBoolean('showDiscovery')"></span> + <span (click)="toggleBoolean('showDiscovery')"><strong>Discovery</strong></span> + </div> + <div class="panel panel-default col-md-12" *ngIf="this['showDiscovery']"> + <div> + <table> + <tr> + <td><strong>Address</strong></td> + <td><input type="text" [(ngModel)]="descriptor.discoveryAddress"></td> + </tr> + <tr> + <td><strong>Cluster</strong></td> + <td><input type="text" [(ngModel)]="descriptor.discoveryCluster"></td> + </tr> + <tr> + <td><strong>Username</strong></td> + <td><input type="text" [(ngModel)]="descriptor.discoveryUser"></td> + </tr> + <tr> + <td><strong>Password Alias</strong></td> + <td><input type="text" [(ngModel)]="descriptor.discoveryPassAlias"></td> + </tr> + </table> + </div> + </div> <!-- Discovery --> + + </div> + </bs-modal-body> + <bs-modal-footer> + <button type="button" + class="btn btn-default btn-sm" + data-dismiss="newDescriptorModal" + (click)="newDescriptorModal.dismiss()">Cancel</button> + <button type="button" + class="btn btn-primary btn-sm" + [disabled]="!descriptor || !descriptorName" + (click)="newDescriptorModal.close()">Ok</button> + </bs-modal-footer> +</bs-modal> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.spec.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.spec.ts b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.spec.ts new file mode 100644 index 0000000..b80e628 --- /dev/null +++ b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NewDescWizardComponent } from './new-desc-wizard.component'; + +describe('NewDescWizardComponent', () => { + let component: NewDescWizardComponent; + let fixture: ComponentFixture<NewDescWizardComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NewDescWizardComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NewDescWizardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.ts b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.ts new file mode 100644 index 0000000..b697351 --- /dev/null +++ b/gateway-admin-ui/src/app/new-desc-wizard/new-desc-wizard.component.ts @@ -0,0 +1,166 @@ +import {Component, OnInit, ViewChild} from '@angular/core'; +import {BsModalComponent} from "ng2-bs3-modal"; + +import { ProviderConfigSelectorComponent } from "../provider-config-selector/provider-config-selector.component"; +import {Descriptor} from "../resource-detail/descriptor"; +import {ResourceService} from "../resource/resource.service"; +import {Resource} from "../resource/resource"; +import {ResourceTypesService} from "../resourcetypes/resourcetypes.service"; + +@Component({ + selector: 'app-new-desc-wizard', + templateUrl: './new-desc-wizard.component.html', + styleUrls: ['./new-desc-wizard.component.css'] +}) +export class NewDescWizardComponent implements OnInit { + + // The maximum length of columns in the service selection display + private static SERVICE_COLS_MAX_LENGTH = 10; + + // The set of supported services which can be declared in a descriptor + private static supportedServices: string[] = [ 'AMBARI', + 'AMBARIUI', + 'ATLAS', + 'ATLAS-API', + 'DRUID-BROKER', + 'DRUID-COORDINATOR', + 'DRUID-COORDINATOR-UI', + 'DRUID-OVERLORD', + 'DRUID-OVERLORD-UI', + 'DRUID-ROUTER', + 'FALCON', + 'HBASEUI', + 'HDFSUI', + 'HIVE', + 'JOBTRACKER', + 'JOBHISTORYUI', + 'LIVYSERVER', + 'NAMENODE', + 'OOZIE', + 'OOZIEUI', + 'RANGER', + 'RANGERUI', + 'RESOURCEMANAGER', + 'SOLR', + 'SPARKHISTORYUI', + 'STORM', + 'STORMLOGVIEWER', + 'SUPERSET', + 'WEBHBASE', + 'WEBHCAT', + 'WEBHDFS', + 'YARNUI', + 'ZEPPELIN', + 'ZEPPELINUI', + 'ZEPPELINWS'] ; + + @ViewChild('newDescriptorModal') + childModal: BsModalComponent; + + @ViewChild('choosePC') + chooseProviderConfigModal: ProviderConfigSelectorComponent; + + resource: Resource; + + descriptorName: string; + + descriptor: Descriptor; + + editModePC: boolean; + + constructor(private resourceTypesService: ResourceTypesService, private resourceService: ResourceService) { } + + ngOnInit() { + this.descriptor = new Descriptor(); + } + + open(size?: string) { + this.reset(); + this.childModal.open(size ? size : 'lg'); + } + + reset() { + this['showDiscovery'] = false; + this['showServices'] = true; + this.resource = new Resource(); + this.descriptor = new Descriptor(); + this.descriptorName = ''; + + // Reset any previously-selected services + for (let serviceName of NewDescWizardComponent.supportedServices) { + if (this.isSelected(serviceName)) { + // Clear the service selection + this.toggleServiceSelected(serviceName); + } + } + } + + onClose() { + // Set the service declarations on the descriptor + for (let serviceName of NewDescWizardComponent.supportedServices) { + if (this.isSelected(serviceName)) { + // Add the selected service to the descriptor + this.descriptor.addService(serviceName); + + // Clear the service selection + this.toggleServiceSelected(serviceName); + } + } + + // Identify the new resource + let newResource = new Resource(); + newResource.name = this.descriptorName + '.json'; + + // Persist the new descriptor + this.resourceService.createResource('Descriptors', + newResource, + this.resourceService.serializeDescriptor(this.descriptor, 'json')) + .then(() => { + // Reload the resource list presentation + this.resourceTypesService.selectResourceType('Descriptors'); + + // Set the new descriptor as the selected resource + this.resourceService.getDescriptorResources().then(resources => { + for (let res of resources) { + if (res.name === newResource.name) { + this.resourceService.selectedResource(res); + break; + } + } + }); + }); + } + + getServiceDisplayColumns() { + let cols = []; + let svcCount = NewDescWizardComponent.supportedServices.length; + let colCount = svcCount / NewDescWizardComponent.SERVICE_COLS_MAX_LENGTH; + + let svcIndex = 0; + + for (let colIndex = 0 ; colIndex < colCount; colIndex++) { + cols[colIndex] = []; + for (let j = 0; j < NewDescWizardComponent.SERVICE_COLS_MAX_LENGTH; j++) { + cols[colIndex][j] = NewDescWizardComponent.supportedServices[svcIndex++]; + if (svcIndex >= svcCount) { + break; + } + } + } + + return cols; + } + + toggleServiceSelected(serviceName: string) { + this[serviceName + '_selected'] = !this.isSelected(serviceName) + } + + isSelected(serviceName: string) { + return this[serviceName + '_selected']; + } + + toggleBoolean(propertyName: string) { + this[propertyName] = !this[propertyName]; + } + +} http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/acls-authzn-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/acls-authzn-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/acls-authzn-provider-config.ts new file mode 100644 index 0000000..fc5a2f5 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/acls-authzn-provider-config.ts @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; + +export class ACLsAuthznProviderConfig extends DisplayBindingProviderConfig { + + private static DEFAULT_MODE: string = 'Default Mode'; + private static DEFAULT_ACL: string = 'Default ACL'; + + private static displayPropertyNames: string[] = [ ACLsAuthznProviderConfig.DEFAULT_MODE, + ACLsAuthznProviderConfig.DEFAULT_ACL + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ [ACLsAuthznProviderConfig.DEFAULT_ACL, 'acl'], + [ACLsAuthznProviderConfig.DEFAULT_MODE, 'acl.mode'] + ]); + + constructor() { + super(); + console.debug('new ACLsAuthznProviderConfig()'); + this.name = 'AclsAuthz'; + this.role = 'authorization'; + this.enabled = 'true'; + this.params = {}; + } + + getDisplayPropertyNames(): string[] { + return ACLsAuthznProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return ACLsAuthznProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/authentication-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/authentication-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/authentication-provider-config.ts new file mode 100644 index 0000000..59923ff --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/authentication-provider-config.ts @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; + +export abstract class AuthenticationProviderConfig extends DisplayBindingProviderConfig { + + static AUTHENTICATION_ROLE: string = 'authentication'; + static FEDERATION_ROLE: string = 'federation'; + + constructor(name: string, role?: string) { + super(); + this.name = name; + this.role = role ? role : AuthenticationProviderConfig.AUTHENTICATION_ROLE; + this.params = {}; + this.enabled = 'true'; // enable by default + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/authentication-wizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/authentication-wizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/authentication-wizard.ts new file mode 100644 index 0000000..576fc56 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/authentication-wizard.ts @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {CategoryWizard} from "./category-wizard"; +import {AuthenticationProviderConfig} from "./authentication-provider-config"; +import {LDAPProviderConfig} from "./ldap-provider-config"; +import {PAMProviderConfig} from "./pam-provider-config"; +import {KerberosProviderConfig} from "./kerberos-provider-config"; +import {PreAuthSSOProviderConfig} from "./preauth-sso-provider-config"; +import {SSOCookieProviderConfig} from "./sso-cookie-provider-config"; +import {JWTProviderConfig} from "./jwt-provider-config"; +import {CASProviderConfig} from "./cas-provider-config"; +import {SAMLProviderConfig} from "./saml-provider-config"; +import {OIDCProviderConfig} from "./oidc-provider-config"; +import {OAUTHProviderConfig} from "./oauth-provider-config"; + +export class AuthenticationWizard extends CategoryWizard { + + private stepCount: number = 4; + + // Authentication provider types + private static AUTH_LDAP: string = 'LDAP'; + private static AUTH_PAM: string = 'PAM'; + private static AUTH_HADOOP: string = 'Kerberos'; + private static AUTH_SSO: string = 'SSO'; + private static AUTH_SSO_COOKIE: string = 'SSO Cookie'; + private static AUTH_JWT: string = 'JWT'; + private static AUTH_CAS: string = 'CAS'; + private static AUTH_OAUTH: string = 'OAuth'; + private static AUTH_SAML: string = 'SAML'; + private static AUTH_OIDC: string = 'OpenID Connect'; + private static authTypes: string[] = [ AuthenticationWizard.AUTH_LDAP, + AuthenticationWizard.AUTH_PAM, + AuthenticationWizard.AUTH_HADOOP, + AuthenticationWizard.AUTH_SSO, + AuthenticationWizard.AUTH_SSO_COOKIE, + AuthenticationWizard.AUTH_JWT, + AuthenticationWizard.AUTH_CAS, + AuthenticationWizard.AUTH_OAUTH, + AuthenticationWizard.AUTH_SAML, + AuthenticationWizard.AUTH_OIDC + ]; + + private static typeConfigMap: Map<string, typeof AuthenticationProviderConfig> = + new Map([ [AuthenticationWizard.AUTH_LDAP, LDAPProviderConfig], + [AuthenticationWizard.AUTH_PAM, PAMProviderConfig], + [AuthenticationWizard.AUTH_HADOOP, KerberosProviderConfig], + [AuthenticationWizard.AUTH_SSO, PreAuthSSOProviderConfig], + [AuthenticationWizard.AUTH_SSO_COOKIE, SSOCookieProviderConfig], + [AuthenticationWizard.AUTH_JWT, JWTProviderConfig], + [AuthenticationWizard.AUTH_CAS, CASProviderConfig], + [AuthenticationWizard.AUTH_OAUTH, OAUTHProviderConfig], + [AuthenticationWizard.AUTH_SAML, SAMLProviderConfig], + [AuthenticationWizard.AUTH_OIDC, OIDCProviderConfig], + ] as [string, typeof AuthenticationProviderConfig][]); + + + getTypes(): string[] { + return AuthenticationWizard.authTypes; + } + + getSteps(): number { + return this.stepCount; + } + + onChange() { + let configType = AuthenticationWizard.typeConfigMap.get(this.selectedType); + if (configType) { + this.providerConfig = Object.create(configType.prototype) as AuthenticationProviderConfig; + this.providerConfig.constructor.apply(this.providerConfig); + } else { + console.debug('AuthenticationWizard --> No provider configuration type mapped for ' + this.selectedType); + this.providerConfig = null; + } + } + + getProviderConfig(): AuthenticationProviderConfig { + return (this.providerConfig as AuthenticationProviderConfig); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/authorization-wizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/authorization-wizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/authorization-wizard.ts new file mode 100644 index 0000000..bb690b9 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/authorization-wizard.ts @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {CategoryWizard} from "./category-wizard"; +import {ACLsAuthznProviderConfig} from "./acls-authzn-provider-config"; +import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; + +export class AuthorizationWizard extends CategoryWizard { + + private stepCount: number = 4; + + + // Authorization provider types + private static AUTHZN_ACLS: string = 'Access Control Lists'; + + private static authznTypes: string[] = [ AuthorizationWizard.AUTHZN_ACLS ]; + + private static typeConfigMap: Map<string, typeof DisplayBindingProviderConfig> = + new Map([ + [AuthorizationWizard.AUTHZN_ACLS, ACLsAuthznProviderConfig] + ] as [string, typeof DisplayBindingProviderConfig][]); + + getTypes(): string[] { + return AuthorizationWizard.authznTypes; + } + + getSteps(): number { + return this.stepCount; + } + + onChange() { + let configType = AuthorizationWizard.typeConfigMap.get(this.selectedType); + if (configType) { + console.debug(configType.prototype.toString() + ' resolved for config type ' + this.selectedType); + this.providerConfig = Object.create(configType.prototype) as DisplayBindingProviderConfig; + this.providerConfig.constructor.apply(this.providerConfig); + } else { + console.debug('AuthorizationWizard --> No provider configuration type mapped for ' + this.selectedType); + this.providerConfig = null; + } + } + + getProviderConfig(): DisplayBindingProviderConfig { + return (this.providerConfig as DisplayBindingProviderConfig); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/cas-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/cas-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/cas-provider-config.ts new file mode 100644 index 0000000..6debee1 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/cas-provider-config.ts @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class CASProviderConfig extends AuthenticationProviderConfig { + + static CALLBACK_URL = 'Callback URL'; + static LOGIN_URL = 'Login URL'; + static PROTOCOL = 'Protocol'; + static COOKIE_DOMAIN_SUFFIX = 'Cookie Domain Suffix'; + + private static displayPropertyNames = [ CASProviderConfig.CALLBACK_URL, + CASProviderConfig.LOGIN_URL, + CASProviderConfig.PROTOCOL, + CASProviderConfig.COOKIE_DOMAIN_SUFFIX + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [CASProviderConfig.CALLBACK_URL, 'pac4j.callbackUrl'], + [CASProviderConfig.COOKIE_DOMAIN_SUFFIX, 'pac4j.cookie.domain.suffix'], + [CASProviderConfig.LOGIN_URL, 'cas.loginUrl'], + [CASProviderConfig.PROTOCOL, 'cas.protocol'] + ]); + + + constructor() { + super('pac4j', AuthenticationProviderConfig.FEDERATION_ROLE); + } + + getDisplayPropertyNames(): string[] { + return CASProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return CASProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/category-wizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/category-wizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/category-wizard.ts new file mode 100644 index 0000000..d6cc36b --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/category-wizard.ts @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {ProviderConfig} from "../resource-detail/provider-config"; + +export abstract class CategoryWizard { + + selectedType: string; + + providerConfig: ProviderConfig; + + + getSelectedType(): string { + return this.selectedType; + }; + + abstract getTypes(): string[]; + + abstract getSteps(): number; + + abstract onChange(); + + abstract getProviderConfig(): ProviderConfig; + +} http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/concat-idassertion-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/concat-idassertion-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/concat-idassertion-provider-config.ts new file mode 100644 index 0000000..699b715 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/concat-idassertion-provider-config.ts @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {IdentityAssertionProviderConfig} from "./identity-assertion-provider-config"; + +export class ConcatAssertionProviderConfig extends IdentityAssertionProviderConfig { + + static PREFIX = 'Prefix'; + static SUFFIX = 'Suffix'; + + private static displayPropertyNames = [ ConcatAssertionProviderConfig.PREFIX, + ConcatAssertionProviderConfig.SUFFIX + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [ConcatAssertionProviderConfig.PREFIX, 'concat.prefix'], + [ConcatAssertionProviderConfig.SUFFIX, 'concat.suffix'] + ]); + + constructor() { + super('Concat'); + } + + getDisplayPropertyNames(): string[] { + return ConcatAssertionProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return ConcatAssertionProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/default-idassertion-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/default-idassertion-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/default-idassertion-provider-config.ts new file mode 100644 index 0000000..484e0d1 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/default-idassertion-provider-config.ts @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {IdentityAssertionProviderConfig} from "./identity-assertion-provider-config"; + +export class DefaultIdAssertionProviderConfig extends IdentityAssertionProviderConfig { + + static PRINCIPAL_MAPPING = 'Principal Mapping'; + static GROUP_PRINCIPAL_MAPPING = 'Group Principal Mapping'; + + private static displayPropertyNames = [ DefaultIdAssertionProviderConfig.PRINCIPAL_MAPPING, + DefaultIdAssertionProviderConfig.GROUP_PRINCIPAL_MAPPING + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [DefaultIdAssertionProviderConfig.PRINCIPAL_MAPPING, 'principal.mapping'], + [DefaultIdAssertionProviderConfig.GROUP_PRINCIPAL_MAPPING, 'group.principal.mapping'] + ]); + + + constructor() { + console.debug('new DefaultIdAssertionProviderConfig()'); + super('Default'); + } + + getDisplayPropertyNames(): string[] { + return DefaultIdAssertionProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return DefaultIdAssertionProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/display-binding-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/display-binding-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/display-binding-provider-config.ts new file mode 100644 index 0000000..4cc4d6c --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/display-binding-provider-config.ts @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {ProviderConfig} from "../resource-detail/provider-config"; + +export abstract class DisplayBindingProviderConfig extends ProviderConfig { + + getName(): string { + return this.name; + } + + getRole(): string { + return this.role; + } + + isEnabled() { + return this.enabled; + } + + setParam(name: string, value: string) { + console.debug('ProviderConfig --> setParam(' + name + ', ' + value + ')'); + this.params[name] = value; + } + + getParamNames(): string[] { + return Object.getOwnPropertyNames(this.params); + } + + getParam(name: string): string { + return this.params[name]; + } + + abstract getDisplayPropertyNames(): string[]; + + abstract getDisplayNamePropertyBinding(name: string): string; + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/grouplookup-id-assertion-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/grouplookup-id-assertion-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/grouplookup-id-assertion-provider-config.ts new file mode 100644 index 0000000..6562f26 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/grouplookup-id-assertion-provider-config.ts @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {IdentityAssertionProviderConfig} from "./identity-assertion-provider-config"; + +export class GroupLookupAssertionProviderConfig extends IdentityAssertionProviderConfig { + + static TODO = 'ToDo'; // TODO: PJZ: Actual properties for + + private static displayPropertyNames = [ GroupLookupAssertionProviderConfig.TODO ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [GroupLookupAssertionProviderConfig.TODO, 'todo'] + ]); + + constructor() { + super('HadoopGroupProvider'); + } + + getDisplayPropertyNames(): string[] { + return GroupLookupAssertionProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return GroupLookupAssertionProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts new file mode 100644 index 0000000..ee6b30e --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/ha-wizard.ts @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {CategoryWizard} from "./category-wizard"; +import {ProviderConfig} from "../resource-detail/provider-config"; + +export class HaWizard extends CategoryWizard { + + private stepCount: number = 2; + + getTypes(): string[] { + return []; + } + + getSteps(): number { + return this.stepCount; + } + + onChange() { + // Nothing to do + } + + getProviderConfig(): ProviderConfig { + this.providerConfig = new ProviderConfig(); + this.providerConfig.name = 'HaProvider'; + this.providerConfig.role = 'ha'; + this.providerConfig.enabled = 'true'; + this.providerConfig.params = {}; + return this.providerConfig; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-provider-config.ts new file mode 100644 index 0000000..32f9e92 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-provider-config.ts @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {DisplayBindingProviderConfig} from "./display-binding-provider-config"; + +export abstract class IdentityAssertionProviderConfig extends DisplayBindingProviderConfig { + + static ID_ASSERTION_ROLE: string = 'identity-assertion'; + + constructor(name: string, role?: string) { + super(); + this.name = name; + this.role = role ? role : IdentityAssertionProviderConfig.ID_ASSERTION_ROLE; + this.params = {}; + this.enabled = 'true'; // enable by default + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-wizard.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-wizard.ts b/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-wizard.ts new file mode 100644 index 0000000..180ed64 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/identity-assertion-wizard.ts @@ -0,0 +1,75 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {CategoryWizard} from "./category-wizard"; +import {ProviderConfig} from "../resource-detail/provider-config"; +import {IdentityAssertionProviderConfig} from "./identity-assertion-provider-config"; +import {DefaultIdAssertionProviderConfig} from "./default-idassertion-provider-config"; +import {ConcatAssertionProviderConfig} from "./concat-idassertion-provider-config"; +import {SwitchCaseAssertionProviderConfig} from "./switchcase-idassertion-provider-config"; +import {RegexAssertionProviderConfig} from "./regex-idassertion-provider-config"; +import {GroupLookupAssertionProviderConfig} from "./grouplookup-id-assertion-provider-config"; + +export class IdentityAssertionWizard extends CategoryWizard { + + private stepCount: number = 4; + + private static DEFAULT: string = 'Default'; + private static CONCAT: string = 'Concatentation'; + private static SWITCHCASE: string = 'SwitchCase'; + private static REGEXP: string = 'Regular Expression'; + private static GROUP_LOOKUP: string = 'Group Lookup'; + + private static assertionTypes: string[] = [ IdentityAssertionWizard.DEFAULT, + IdentityAssertionWizard.CONCAT, + IdentityAssertionWizard.SWITCHCASE, + IdentityAssertionWizard.REGEXP, + IdentityAssertionWizard.GROUP_LOOKUP + ]; + + private static typeConfigMap: Map<string, typeof IdentityAssertionProviderConfig> = + new Map([ [IdentityAssertionWizard.DEFAULT, DefaultIdAssertionProviderConfig], + [IdentityAssertionWizard.CONCAT, ConcatAssertionProviderConfig], + [IdentityAssertionWizard.SWITCHCASE, SwitchCaseAssertionProviderConfig], + [IdentityAssertionWizard.REGEXP, RegexAssertionProviderConfig], + [IdentityAssertionWizard.GROUP_LOOKUP, GroupLookupAssertionProviderConfig], + ] as [string, typeof IdentityAssertionProviderConfig][]); + + getTypes(): string[] { + return IdentityAssertionWizard.assertionTypes; + } + + getSteps(): number { + return this.stepCount; + } + + onChange() { + let configType = IdentityAssertionWizard.typeConfigMap.get(this.selectedType); + if (configType) { + this.providerConfig = Object.create(configType.prototype) as IdentityAssertionProviderConfig; + this.providerConfig.constructor.apply(this.providerConfig); + } else { + console.debug('IdentityAssertionWizard --> No provider configuration type mapped for ' + this.selectedType); + this.providerConfig = null; + } + } + + getProviderConfig(): ProviderConfig { + return (this.providerConfig as IdentityAssertionProviderConfig); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/jwt-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/jwt-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/jwt-provider-config.ts new file mode 100644 index 0000000..3f91fa1 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/jwt-provider-config.ts @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class JWTProviderConfig extends AuthenticationProviderConfig { + + static KNOXTOKEN_AUDIENCES = 'KnoxToken Audiences'; + + private static displayPropertyNames = [ JWTProviderConfig.KNOXTOKEN_AUDIENCES ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ [JWTProviderConfig.KNOXTOKEN_AUDIENCES, 'knox.token.audiences'] ]); + + + constructor() { + console.debug('new JWTProviderConfig()'); + super('JWTProvider', AuthenticationProviderConfig.FEDERATION_ROLE); + } + + getDisplayPropertyNames(): string[] { + return JWTProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return JWTProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/kerberos-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/kerberos-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/kerberos-provider-config.ts new file mode 100644 index 0000000..30dc49f --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/kerberos-provider-config.ts @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class KerberosProviderConfig extends AuthenticationProviderConfig { + + static CONFIG_PREFIX = 'Config Prefix'; + static SIG_SECRET = 'Signature Secret'; + static TYPE = 'Type'; + static ANON_ALLOWED = 'Allow Anonymous'; + static TOKEN_VALIDITY = 'Token Expiration'; + static COOKIE_DOMAIN = 'Domain'; + static COOKIE_PATH = 'Path'; + static KRB_PRINCIPAL = 'Principal'; + static KRB_KEYTAB = 'KeyTab'; + static KRB_RULES = 'Name Rules'; + + + private static displayPropertyNames = [ KerberosProviderConfig.CONFIG_PREFIX, + KerberosProviderConfig.SIG_SECRET, + KerberosProviderConfig.TYPE, + KerberosProviderConfig.ANON_ALLOWED, + KerberosProviderConfig.TOKEN_VALIDITY, + KerberosProviderConfig.COOKIE_DOMAIN, + KerberosProviderConfig.COOKIE_PATH, + KerberosProviderConfig.KRB_PRINCIPAL, + KerberosProviderConfig.KRB_KEYTAB, + KerberosProviderConfig.KRB_RULES + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [KerberosProviderConfig.CONFIG_PREFIX, 'config.prefix'], + [KerberosProviderConfig.SIG_SECRET, '.signature.secret'], + [KerberosProviderConfig.TYPE, '.type'], + [KerberosProviderConfig.ANON_ALLOWED, '.simple.anonymous.allowed'], + [KerberosProviderConfig.TOKEN_VALIDITY, '.token.validity'], + [KerberosProviderConfig.COOKIE_DOMAIN, '.cookie.domain'], + [KerberosProviderConfig.COOKIE_PATH, '.cookie.path'], + [KerberosProviderConfig.KRB_PRINCIPAL, '.kerberos.principal'], + [KerberosProviderConfig.KRB_KEYTAB, '.kerberos.keytab'], + [KerberosProviderConfig.KRB_RULES, '.kerberos.name.rules'] + ]); + + + constructor() { + super('HadoopAuth'); + } + + getDisplayPropertyNames(): string[] { + return KerberosProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + if (name === KerberosProviderConfig.CONFIG_PREFIX) { + return KerberosProviderConfig.displayPropertyNameBindings.get(name); + } else { + let prefix = this.getParam(KerberosProviderConfig.displayPropertyNameBindings.get(KerberosProviderConfig.CONFIG_PREFIX)); + if (prefix) { + return prefix + KerberosProviderConfig.displayPropertyNameBindings.get(name); + } + } + return null; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/ldap-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/ldap-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/ldap-provider-config.ts new file mode 100644 index 0000000..38e3b81 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/ldap-provider-config.ts @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class LDAPProviderConfig extends AuthenticationProviderConfig { + + static SESSION_TIMEOUT = 'Session Timeout'; + static DN_TEMPLATE = 'User DN Template'; + static URL = 'URL'; + static MECHANISM = 'Mechanism'; + + private static displayPropertyNames = [ LDAPProviderConfig.SESSION_TIMEOUT, + LDAPProviderConfig.DN_TEMPLATE, + LDAPProviderConfig.URL, + LDAPProviderConfig.MECHANISM + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [LDAPProviderConfig.SESSION_TIMEOUT, 'sessionTimeout'], + [LDAPProviderConfig.DN_TEMPLATE, 'main.ldapRealm.userDnTemplate'], + [LDAPProviderConfig.URL, 'main.ldapRealm.contextFactory.url'], + [LDAPProviderConfig.MECHANISM, 'main.ldapRealm.contextFactory.authenticationMechanism'] + ]); + + + constructor() { + super('ShiroProvider'); + this.setParam('main.ldapRealm', 'org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm'); + this.setParam('main.ldapContextFactory', 'org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory'); + this.setParam('main.ldapRealm.contextFactory', '$ldapContextFactory'); + this.setParam('urls./**', 'authcBasic'); + } + + getDisplayPropertyNames(): string[] { + return LDAPProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return LDAPProviderConfig.displayPropertyNameBindings.get(name); + } + + // TODO: PJZ: Shiro-based providers have param ordering requirements; need to accommodate that +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/oauth-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/oauth-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/oauth-provider-config.ts new file mode 100644 index 0000000..71df337 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/oauth-provider-config.ts @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class OAUTHProviderConfig extends AuthenticationProviderConfig { + + static CALLBACK_URL = 'Callback URL'; + static COOKIE_DOMAIN_SUFFIX = 'Cookie Domain Suffix'; + + private static displayPropertyNames: string[] = [ OAUTHProviderConfig.CALLBACK_URL, + OAUTHProviderConfig.COOKIE_DOMAIN_SUFFIX + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [OAUTHProviderConfig.CALLBACK_URL, 'pac4j.callbackUrl'], + [OAUTHProviderConfig.COOKIE_DOMAIN_SUFFIX, 'pac4j.cookie.domain.suffix'] + ]); + + + constructor() { + super('pac4j', AuthenticationProviderConfig.FEDERATION_ROLE); + } + + getDisplayPropertyNames(): string[] { + return OAUTHProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return OAUTHProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/oidc-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/oidc-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/oidc-provider-config.ts new file mode 100644 index 0000000..8cf2e7f --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/oidc-provider-config.ts @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class OIDCProviderConfig extends AuthenticationProviderConfig { + + static CALLBACK_URL = 'Callback URL'; + static PROVIDER_ID = 'Provider Identifier'; + static PROVIDER_SECRET = 'Provider Secret'; + static PROVIDER_DISCOVERY_URL = 'Provider Discovery URL'; + static USE_NONCE = 'Use Nonce'; + static PREF_JWS_ALGO = 'Preferred JWS Algorithm'; + static MAX_CLOCK_SKEW = 'Maximum Clock Skew'; + static COOKIE_DOMAIN_SUFFIX = 'Cookie Domain Suffix'; + + + private static displayPropertyNames = [ OIDCProviderConfig.CALLBACK_URL, + OIDCProviderConfig.PROVIDER_ID, + OIDCProviderConfig.PROVIDER_SECRET, + OIDCProviderConfig.PROVIDER_DISCOVERY_URL, + OIDCProviderConfig.USE_NONCE, + OIDCProviderConfig.PREF_JWS_ALGO, + OIDCProviderConfig.MAX_CLOCK_SKEW, + OIDCProviderConfig.COOKIE_DOMAIN_SUFFIX + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [OIDCProviderConfig.CALLBACK_URL, 'pac4j.callbackUrl'], + [OIDCProviderConfig.COOKIE_DOMAIN_SUFFIX, 'pac4j.cookie.domain.suffix'], + [OIDCProviderConfig.PROVIDER_ID, 'oidc.id'], + [OIDCProviderConfig.PROVIDER_SECRET, 'oidc.secret'], + [OIDCProviderConfig.PROVIDER_DISCOVERY_URL, 'oidc.discoveryUri'], + [OIDCProviderConfig.USE_NONCE, 'oidc.useNonce'], + [OIDCProviderConfig.PREF_JWS_ALGO, 'oidc.preferredJwsAlgorithm'], + [OIDCProviderConfig.MAX_CLOCK_SKEW, 'oidc.maxClockSkew'], + ]); + + + constructor() { + super('pac4j', AuthenticationProviderConfig.FEDERATION_ROLE); + } + + getDisplayPropertyNames(): string[] { + return OIDCProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return OIDCProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/pam-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/pam-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/pam-provider-config.ts new file mode 100644 index 0000000..f93c94e --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/pam-provider-config.ts @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class PAMProviderConfig extends AuthenticationProviderConfig { + + static SESSION_TIMEOUT = 'Session Timeout'; + + private static displayPropertyNames = [ PAMProviderConfig.SESSION_TIMEOUT ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [PAMProviderConfig.SESSION_TIMEOUT, 'sessionTimeout'] + ]); + + + constructor() { + super('ShiroProvider'); + this.setParam('main.pamRealm', 'org.apache.knox.gateway.shirorealm.KnoxPamRealm'); + this.setParam('main.pamRealm.service', 'login'); + this.setParam('urls./**', 'authcBasic'); + } + + getDisplayPropertyNames(): string[] { + return PAMProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return PAMProviderConfig.displayPropertyNameBindings.get(name); + } + + // TODO: PJZ: Shiro-based providers have param ordering requirements; need to accommodate that +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/preauth-sso-provider-config.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/preauth-sso-provider-config.ts b/gateway-admin-ui/src/app/provider-config-wizard/preauth-sso-provider-config.ts new file mode 100644 index 0000000..d7e8d3d --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/preauth-sso-provider-config.ts @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {AuthenticationProviderConfig} from "./authentication-provider-config"; + +export class PreAuthSSOProviderConfig extends AuthenticationProviderConfig { + + static VALIDATION_METHOD = 'Validation Method'; + static IP_ADDRESSES = 'Addresses'; + static CUSTOM_HEADER = 'Custom Header'; + static CUSTOM_GRP_HEADER = 'Custom Group Header'; + + private static displayPropertyNames = [ PreAuthSSOProviderConfig.VALIDATION_METHOD, + PreAuthSSOProviderConfig.IP_ADDRESSES, + PreAuthSSOProviderConfig.CUSTOM_HEADER, + PreAuthSSOProviderConfig.CUSTOM_GRP_HEADER + ]; + + private static displayPropertyNameBindings: Map<string, string> = + new Map([ + [PreAuthSSOProviderConfig.VALIDATION_METHOD, 'preauth.validation.method'], + [PreAuthSSOProviderConfig.IP_ADDRESSES, 'preauth.ip.addresses'], + [PreAuthSSOProviderConfig.CUSTOM_HEADER, 'preauth.custom.header'], + [PreAuthSSOProviderConfig.CUSTOM_GRP_HEADER, 'preauth.custom.group.header'] + ]); + + + constructor() { + console.debug('new PreAuthSSOProviderConfig()'); + super('HeaderPreAuth', AuthenticationProviderConfig.FEDERATION_ROLE); + } + + getDisplayPropertyNames(): string[] { + return PreAuthSSOProviderConfig.displayPropertyNames; + } + + getDisplayNamePropertyBinding(name: string) { + return PreAuthSSOProviderConfig.displayPropertyNameBindings.get(name); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.css ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.css b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.css new file mode 100644 index 0000000..625129f --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.css @@ -0,0 +1,5 @@ +td { + border-collapse: collapse; + padding: 8px; + vertical-align: top; +} http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.html ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.html b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.html new file mode 100644 index 0000000..db97d96 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.html @@ -0,0 +1,104 @@ +<bs-modal (onClose)="onClose()" #newProviderConfigModal xmlns="http://www.w3.org/1999/html"> + <bs-modal-header [showDismiss]="true"> + <label class="modal-title">Create a New Provider Configuration</label> + </bs-modal-header> + <bs-modal-body> + + <div *ngIf="isRootStep()"> + <!-- Provider Configuration Name --> + <div> + <table> + <tr> + <td><strong>Name</strong></td> + <td><input type="textbox" + size="60" + [(ngModel)]="name"></td> + </tr> + </table> + </div> <!-- Provider Configuration Name --> + + <br/> + + <!-- Display New Providers --> + <div> + <strong>Providers</strong><br/> + <div *ngFor="let pc of providers"> + {{pc.name}} + </div> + </div> <!-- Display New Providers --> + + <br/> + + <!-- Root Step --> + <div> + <button type="button" + class="btn btn-default btn-sm" + data-dismiss="newProviderConfigModal" + (click)="onNextStep()">Add Provider</button> + </div> <!-- Root Step --> + </div> + + <!-- Provider Category Selection Step --> + <div *ngIf="isProviderCategoryStep()"> + <strong>Choose a Provider Category</strong><br/><br/> + <div *ngFor="let pc of getProviderCategories()"> + <label> + <input type="radio" + [name]="pc" + [(ngModel)]="selectedCategory" + [value]="pc">{{pc}} + </label> + </div> + </div> <!-- Provider Category Selection Step --> + + <!-- Provider Type Selection Step --> + <div *ngIf="isProviderTypeStep()"> + <strong>Choose a {{ selectedCategory }} Provider Type</strong><br/><br/> + <div *ngFor="let pt of getProviderTypes()"> + <label> + <input type="radio" + [name]="pt" + (change)="getCategoryWizard().onChange()" + [(ngModel)]="getCategoryWizard().selectedType" + [value]="pt">{{pt}} + </label> + </div> + </div> <!-- Provider Type Selection Step --> + + <!-- Provider Type Params Step --> + <div *ngIf="isProviderParamsStep()"> + <strong>Specify {{ getCategoryWizard().getSelectedType() }} Provider Parameters</strong><br/><br/> + <table> + <tr *ngFor="let pt of getProviderParams()"> + <td><strong>{{pt}}</strong></td> + <td><input type="textbox" + size="60" + #paramInput + (change)="setProviderParamBinding(pt, paramInput.value)" + [value]="getProviderParamBinding(pt)"></td> + </tr> + </table> + </div> <!-- Provider Type Params Step --> + + + </bs-modal-body> + <bs-modal-footer> + <button type="button" + class="btn btn-default btn-sm pull-left" + data-dismiss="newProviderConfigModal" + (click)="newProviderConfigModal.dismiss()">Cancel</button> + <button type="button" + *ngIf="!isRootStep()" + class="btn btn-primary btn-sm" + (click)="onPreviousStep()">Back</button> + <button type="button" + *ngIf="isRootStep() || !hasMoreSteps()" + class="btn btn-primary btn-sm" + [disabled]="(isRootStep() && !name)" + (click)="isRootStep() ? newProviderConfigModal.close() : onFinishAdd()">Ok</button> + <button type="button" + *ngIf="!isRootStep() && hasMoreSteps()" + class="btn btn-primary btn-sm" + (click)="onNextStep()">Next</button> + </bs-modal-footer> +</bs-modal> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/knox/blob/167053bd/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.spec.ts ---------------------------------------------------------------------- diff --git a/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.spec.ts b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.spec.ts new file mode 100644 index 0000000..7c4dd21 --- /dev/null +++ b/gateway-admin-ui/src/app/provider-config-wizard/provider-config-wizard.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProviderConfigWizardComponent } from './provider-config-wizard.component'; + +describe('ProviderConfigWizardComponent', () => { + let component: ProviderConfigWizardComponent; + let fixture: ComponentFixture<ProviderConfigWizardComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ProviderConfigWizardComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ProviderConfigWizardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +});
