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; } }