gateway-admin-ui/admin-ui/app/provider-config-wizard/provider-config-wizard.component.ts (320 lines of code) (raw):
/*
* 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 {Component, OnInit, ViewChild} from '@angular/core';
import {ResourceTypesService} from '../resourcetypes/resourcetypes.service';
import {ResourceService} from '../resource/resource.service';
import {BsModalComponent} from 'ng2-bs3-modal';
import {ProviderConfig} from '../resource-detail/provider-config';
import {AuthenticationWizard} from './authentication-wizard';
import {CategoryWizard} from './category-wizard';
import {AuthorizationWizard} from './authorization-wizard';
import {IdentityAssertionWizard} from './identity-assertion-wizard';
import {HaWizard} from './ha-wizard';
import {Resource} from '../resource/resource';
import {DisplayBindingProviderConfig} from './display-binding-provider-config';
import {OrderedParamContainer} from './ordered-param-container';
import {HostMapProviderWizard} from './hostmap-provider-wizard';
import {ProviderContributorWizard} from './provider-contributor-wizard';
import {WebAppSecurityWizard} from './webappsec-wizard';
import {ValidationUtils} from '../utils/validation-utils';
import {HttpErrorResponse} from '@angular/common/http';
@Component({
selector: 'app-provider-config-wizard',
templateUrl: './provider-config-wizard.component.html',
styleUrls: ['./provider-config-wizard.component.css']
})
export class ProviderConfigWizardComponent implements OnInit {
private static CATEGORY_STEP = 1;
private static TYPE_STEP = 2;
private static PARAMS_STEP = 3;
// Provider Categories
private static CATEGORY_AUTHENTICATION = 'Authentication';
private static CATEGORY_AUTHORIZATION = 'Authorization';
private static CATEGORY_ID_ASSERTION = 'Identity Assertion';
private static CATEGORY_HA = 'HA';
private static CATEGORY_WEBAPPSEC = 'Web Application Security';
private static CATEGORY_HOSTMAP = 'Host Mapping';
private static providerCategories: string[] = [ProviderConfigWizardComponent.CATEGORY_AUTHENTICATION,
ProviderConfigWizardComponent.CATEGORY_AUTHORIZATION,
ProviderConfigWizardComponent.CATEGORY_ID_ASSERTION,
ProviderConfigWizardComponent.CATEGORY_WEBAPPSEC,
ProviderConfigWizardComponent.CATEGORY_HA,
ProviderConfigWizardComponent.CATEGORY_HOSTMAP
];
private static CATEGORY_TYPES: Map<string, CategoryWizard> =
new Map([
[ProviderConfigWizardComponent.CATEGORY_AUTHENTICATION, new AuthenticationWizard() as CategoryWizard],
[ProviderConfigWizardComponent.CATEGORY_AUTHORIZATION, new AuthorizationWizard() as CategoryWizard],
[ProviderConfigWizardComponent.CATEGORY_ID_ASSERTION, new IdentityAssertionWizard() as CategoryWizard],
[ProviderConfigWizardComponent.CATEGORY_HA, new HaWizard() as CategoryWizard],
[ProviderConfigWizardComponent.CATEGORY_WEBAPPSEC, new WebAppSecurityWizard() as CategoryWizard],
[ProviderConfigWizardComponent.CATEGORY_HOSTMAP, new HostMapProviderWizard() as CategoryWizard]
]);
@ViewChild('newProviderConfigModal')
childModal: BsModalComponent;
private step = 0;
name = '';
providers: Array<ProviderConfig> = [];
selectedCategory: string;
existingReadOnlyProvider = false;
static isProviderConfigValid(pc: ProviderConfig): boolean {
let isValid = true;
if (pc instanceof DisplayBindingProviderConfig) {
isValid = (pc as DisplayBindingProviderConfig).isValid();
}
return isValid;
}
// Type guard function to determine if a CategoryWizard is a ProviderContributorWizard
static isProviderContributorWizard(wizard: any): wizard is ProviderContributorWizard {
return (<ProviderContributorWizard>wizard).getProviderRole !== undefined;
}
// Type Guard for identifying OrderedParamContainer implementations
static isOrderedParamContainer = (x: any): x is OrderedParamContainer => x.orderParams;
constructor(private resourceTypesService: ResourceTypesService, private resourceService: ResourceService) {
}
ngOnInit() {
this.selectedCategory = ProviderConfigWizardComponent.CATEGORY_AUTHENTICATION; // Default to authentication
}
open(size?: string) {
this.reset();
this.childModal.open(size ? size : 'lg');
}
reset() {
this.getCategoryWizard(this.selectedCategory).reset();
this.step = 0;
this.name = '';
this.providers = [];
this.selectedCategory = ProviderConfigWizardComponent.CATEGORY_AUTHENTICATION;
this.existingReadOnlyProvider = false;
}
onFinishAdd() {
console.debug('ProviderConfigWizard --> Selected provider category: ' + this.selectedCategory);
let catWizard = this.getCategoryWizard(this.selectedCategory);
let type = catWizard ? catWizard.getSelectedType() : 'undefined';
console.debug('ProviderConfigWizard --> Selected provider type: ' + type);
if (catWizard) {
let pc: ProviderConfig;
let isContributed = false;
let isContributingWizard = false;
if (ProviderConfigWizardComponent.isProviderContributorWizard(catWizard)) {
isContributingWizard = true;
let contribWiz = catWizard as ProviderContributorWizard;
let role = contribWiz.getProviderRole();
console.debug('Wizard is ProviderContributorWizard for role ' + role);
for (let provider of this.providers) {
if (role === provider.role) {
console.debug('Found existing provider config for ' + role);
pc = provider;
break;
}
}
if (!pc) {
console.debug('No existing provider config found for ' + role + ', so creating one...');
pc = contribWiz.createNewProviderConfig();
this.providers.push(pc);
}
// If there is an existing provider config of the current type
if (pc) {
if (ProviderConfigWizardComponent.isProviderConfigValid(catWizard.getProviderConfig())) {
contribWiz.contribute(pc);
isContributed = true;
} else {
console.debug('CategoryWizard ProviderConfig is not valid.');
}
}
}
if (!pc && !isContributingWizard) { // If not a contributing wizard, just use the category wizard's provider config
pc = catWizard.getProviderConfig();
}
if (pc && (isContributed || (!isContributingWizard && ProviderConfigWizardComponent.isProviderConfigValid(pc)))) {
if (!isContributed) {
this.providers.push(pc);
}
console.debug('ProviderConfigWizard --> Provider: name=' + pc.name + ', role=' + pc.role + ', enabled=' + pc.enabled);
if (pc.params) {
// If the provider is managing its own param order, allow it to re-order the params now
if (ProviderConfigWizardComponent.isOrderedParamContainer(pc)) {
pc.params = (pc as OrderedParamContainer).orderParams(pc.params);
}
for (let name of Object.getOwnPropertyNames(pc.params)) {
console.debug('\tParam: ' + name + ' = ' + pc.params[name]);
}
}
this.step = 0; // Return to the beginning
// Clear the wizard state
this.getCategoryWizard(this.selectedCategory).reset();
} else {
console.debug('ProviderConfig is missing or invalid.');
}
}
}
save() {
// Identify the new resource
let newResource = new Resource();
newResource.name = this.name + '.json';
// Make constrained copies of ProviderConfig objects to avoid persisting unwanted object properties
let tmp = new Array<ProviderConfig>();
for (let p of this.providers) {
let pp = new ProviderConfig();
pp.role = p.role;
pp.name = p.name;
pp.enabled = p.enabled;
pp.params = p.params;
tmp.push(pp);
}
// Persist the new provider configuration
this.resourceService.createResource('Provider Configurations',
newResource,
this.resourceService.serializeProviderConfiguration(tmp, 'json'))
.then(() => {
// Reload the resource list presentation
this.resourceTypesService.selectResourceType('Provider Configurations');
// Set the new descriptor as the selected resource
this.resourceService.getProviderConfigResources().then(resources => {
for (let res of resources) {
if (res.name === newResource.name) {
this.resourceService.selectedResource(res);
break;
}
}
});
this.childModal.close(); // close the dialog if there was no error
}).catch((err: HttpErrorResponse) => {
this.existingReadOnlyProvider = (err.status === 409);
console.error('Error creating ' + newResource + ' : ' + err.message);
});
}
onNextStep() {
++this.step;
}
onPreviousStep() {
--this.step;
}
hasMoreSteps(): boolean {
let result = false;
let catWizard = this.getCategoryWizard(this.selectedCategory);
if (catWizard) {
result = (this.step < (catWizard.getSteps() - 1));
if (result) {
if (this.isProviderTypeStep()) { // Next step would be params
// Check for the need to display the params step
let pc = catWizard.getProviderConfig();
if (pc && pc instanceof DisplayBindingProviderConfig) {
let propNames: string[] = (pc as DisplayBindingProviderConfig).getDisplayPropertyNames();
result = propNames.length > 0;
}
}
}
}
return result;
}
isRootStep(): boolean {
return (this.step === 0);
}
isProviderCategoryStep(): boolean {
return (this.step === ProviderConfigWizardComponent.CATEGORY_STEP);
}
isProviderTypeStep(): boolean {
return (this.step === ProviderConfigWizardComponent.TYPE_STEP);
}
isProviderParamsStep(): boolean {
return (this.step === ProviderConfigWizardComponent.PARAMS_STEP);
}
getProviderCategories(): string[] {
return ProviderConfigWizardComponent.providerCategories;
}
getCategoryWizard(category?: string): CategoryWizard {
return ProviderConfigWizardComponent.CATEGORY_TYPES.get(category ? category : this.selectedCategory);
}
getProviderTypes(category?: string): string[] {
let catWizard = this.getCategoryWizard(category);
if (catWizard) {
return catWizard.getTypes();
} else {
console.debug('ProviderConfigWizard --> Unresolved category wizard for ' + (category ? category : this.selectedCategory));
}
return [];
}
getProviderParams(): string[] {
let catWizard = this.getCategoryWizard();
if (catWizard) {
let pc = catWizard.getProviderConfig();
if (pc) {
if (pc instanceof DisplayBindingProviderConfig) {
let dispPC = pc as DisplayBindingProviderConfig;
return dispPC.getDisplayPropertyNames();
} else {
return [];
}
} else {
console.log('ProviderConfigWizard --> No provider config from category wizard ' + typeof (catWizard));
}
} else {
console.debug('ProviderConfigWizard --> Unresolved category wizard for ' + this.selectedCategory);
}
return [];
}
setProviderParamBinding(name: string, value: string) {
let catWizard = this.getCategoryWizard();
if (catWizard) {
let pc = catWizard.getProviderConfig();
if (pc) {
if (pc instanceof DisplayBindingProviderConfig) {
let property = (pc as DisplayBindingProviderConfig).getDisplayNamePropertyBinding(name);
if (property) {
pc.setParam(property, value);
console.debug('ProviderConfigWizard --> Set ProviderConfig param value: ' + property + '=' + value);
} else {
console.debug('ProviderConfigWizard --> No provider property configured for ' + name);
}
}
}
}
}
getProviderParamBinding(name: string): string {
let catWizard = this.getCategoryWizard();
if (catWizard) {
let pc = catWizard.getProviderConfig();
if (pc) {
if (pc instanceof DisplayBindingProviderConfig) {
let dispPC = pc as DisplayBindingProviderConfig;
let value = pc.getParam(dispPC.getDisplayNamePropertyBinding(name));
return (value ? value : '');
}
}
}
return '';
}
getConfiguredProviderDisplayNames(): string[] {
let result: string[] = [];
for (let p of this.providers) {
let pName: string;
let pRole: string;
if (p instanceof DisplayBindingProviderConfig) {
pName = (p as DisplayBindingProviderConfig).getType();
pRole = p.getRole();
} else {
pName = p.name;
pRole = p.role;
}
result.push(pName + ' (' + pRole + ')');
}
return result;
}
isValidProviderConfigName(): boolean {
return ValidationUtils.isValidResourceName(this.name);
}
isPasswordParam(name: string) {
let result = false;
let p = this.getCategoryWizard().getProviderConfig();
if (p && p instanceof DisplayBindingProviderConfig) {
result = (p as DisplayBindingProviderConfig).isPasswordParam(name);
}
return result;
}
isValidParamValue(paramName: string) {
let isValid = true;
let pc: ProviderConfig = this.getCategoryWizard().getProviderConfig();
if (pc) {
if (pc instanceof DisplayBindingProviderConfig) {
isValid = (pc as DisplayBindingProviderConfig).isValidParamValue(paramName);
}
}
return isValid;
}
togglePasswordDisplay(propertyName: string) {
this['show' + propertyName] = !this['show' + propertyName];
}
getPasswordDisplay(propertName: string): boolean {
return this['show' + propertName];
}
isExistingReadOnlyProvider(): boolean {
return this.existingReadOnlyProvider;
}
}