Browse Source

UI updated OAuth2 for new endpoint

pull/3557/head
Vladyslav_Prykhodko 6 years ago
parent
commit
1f3bae922e
  1. 20
      ui-ngx/src/app/core/http/admin.service.ts
  2. 43
      ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.html
  3. 220
      ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts
  4. 3
      ui-ngx/src/app/shared/models/entity-type.models.ts
  5. 10
      ui-ngx/src/app/shared/models/settings.models.ts
  6. 4
      ui-ngx/src/assets/locale/locale.constant-en_US.json

20
ui-ngx/src/app/core/http/admin.service.ts

@ -60,17 +60,27 @@ export class AdminService {
defaultHttpOptionsFromConfig(config)); defaultHttpOptionsFromConfig(config));
} }
public getOAuth2Settings(config?: RequestConfig): Observable<OAuth2Settings> { public getOAuth2Settings(config?: RequestConfig): Observable<Array<OAuth2Settings>> {
return this.http.get<OAuth2Settings>(`/api/oauth2/config`, defaultHttpOptionsFromConfig(config)); return this.http.get<Array<OAuth2Settings>>(`/api/oauth2/config`, defaultHttpOptionsFromConfig(config));
} }
public getOAuth2Template(config?: RequestConfig): Observable<Array<ClientProviderTemplated>> { public getOAuth2Template(config?: RequestConfig): Observable<Array<ClientProviderTemplated>> {
return this.http.get<Array<ClientProviderTemplated>>(`/api/oauth2/config/template`, defaultHttpOptionsFromConfig(config)); return this.http.get<Array<ClientProviderTemplated>>(`/api/oauth2/config/template`, defaultHttpOptionsFromConfig(config));
} }
public saveOAuth2Settings(OAuth2Setting: OAuth2Settings, public saveOAuth2Settings(OAuth2Setting: OAuth2Settings[],
config?: RequestConfig): Observable<OAuth2Settings> { config?: RequestConfig): Observable<Array<OAuth2Settings>> {
return this.http.post<OAuth2Settings>('/api/oauth2/config', OAuth2Setting, return this.http.post<Array<OAuth2Settings>>('/api/oauth2/config', OAuth2Setting,
defaultHttpOptionsFromConfig(config));
}
public deleteOAuth2Domain(OAuth2Domain: string, config?: RequestConfig) {
return this.http.delete(`/api/oauth2/config/domain/${OAuth2Domain}`,
defaultHttpOptionsFromConfig(config));
}
public deleteOAuthCclientRegistrationId(clientRegistrationId: string, config?: RequestConfig) {
return this.http.delete(`/api/oauth2/config/${clientRegistrationId}`,
defaultHttpOptionsFromConfig(config)); defaultHttpOptionsFromConfig(config));
} }

43
ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.html

@ -30,10 +30,10 @@
<mat-card-content style="padding-top: 16px;"> <mat-card-content style="padding-top: 16px;">
<form [formGroup]="oauth2SettingsForm" (ngSubmit)="save()"> <form [formGroup]="oauth2SettingsForm" (ngSubmit)="save()">
<fieldset [disabled]="isLoading$ | async"> <fieldset [disabled]="isLoading$ | async">
<ng-container formArrayName="clientsDomainsParams"> <ng-container formArrayName="clientDomains">
<div class="container"> <div class="container">
<mat-accordion multi> <mat-accordion multi>
<ng-container *ngFor="let domain of clientsDomainsParams.controls; let i = index; let last = last;"> <ng-container *ngFor="let domain of clientDomains.controls; let i = index; let last = last;">
<mat-expansion-panel [formGroupName]="i" [expanded]="last"> <mat-expansion-panel [formGroupName]="i" [expanded]="last">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title fxLayoutAlign="start center"> <mat-panel-title fxLayoutAlign="start center">
@ -75,7 +75,7 @@
class="registration-card mat-elevation-z0"> class="registration-card mat-elevation-z0">
<mat-expansion-panel-header> <mat-expansion-panel-header>
<mat-panel-title fxLayoutAlign="start center"> <mat-panel-title fxLayoutAlign="start center">
{{ registration.get('providerName').value }} {{ getProviderName(registration) }}
</mat-panel-title> </mat-panel-title>
<mat-panel-description fxLayoutAlign="end center"> <mat-panel-description fxLayoutAlign="end center">
<button mat-icon-button <button mat-icon-button
@ -90,14 +90,17 @@
<ng-template matExpansionPanelContent> <ng-template matExpansionPanelContent>
<section [formGroupName]="j"> <section [formGroupName]="j">
<mat-form-field fxFlex class="mat-block"> <section formGroupName="additionalInfo" fxLayout="row">
<mat-label translate>admin.oauth2.login-provider</mat-label> <mat-form-field fxFlex class="mat-block">
<mat-select formControlName="providerName"> <mat-label translate>admin.oauth2.login-provider</mat-label>
<mat-option *ngFor="let provider of templateProvider" [value]="provider"> <mat-select formControlName="providerName">
{{ provider | uppercase }} <mat-option *ngFor="let provider of templateProvider" [value]="provider">
</mat-option> {{ provider | uppercase }}
</mat-select> </mat-option>
</mat-form-field> </mat-select>
</mat-form-field>
<div [tb-help]="getHelpLink(registration)" *ngIf="getProviderName(registration) !== 'Custom'"></div>
</section>
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px"> <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px">
<mat-form-field fxFlex class="mat-block"> <mat-form-field fxFlex class="mat-block">
@ -118,9 +121,9 @@
</div> </div>
<mat-expansion-panel class="mat-elevation-z0 custom-settings" <mat-expansion-panel class="mat-elevation-z0 custom-settings"
[disabled]="registration.get('providerName').value === 'Custom'" [disabled]="getProviderName(registration) === 'Custom'"
[expanded]="registration.get('providerName').value === 'Custom'"> [expanded]="getProviderName(registration) === 'Custom'">
<mat-expansion-panel-header [fxHide]="registration.get('providerName').value === 'Custom'"> <mat-expansion-panel-header [fxHide]="getProviderName(registration) === 'Custom'">
<mat-panel-description fxLayoutAlign="end center"> <mat-panel-description fxLayoutAlign="end center">
{{ 'admin.oauth2.custom-setting' | translate }} {{ 'admin.oauth2.custom-setting' | translate }}
</mat-panel-description> </mat-panel-description>
@ -135,7 +138,7 @@
<button mat-icon-button matSuffix <button mat-icon-button matSuffix
type="button" type="button"
(click)="toggleEditMode(registration, 'accessTokenUri')" (click)="toggleEditMode(registration, 'accessTokenUri')"
*ngIf="registration.get('providerName').value !== 'Custom'"> *ngIf="getProviderName(registration) !== 'Custom'">
<mat-icon class="material-icons">create</mat-icon> <mat-icon class="material-icons">create</mat-icon>
</button> </button>
<mat-error *ngIf="registration.get('accessTokenUri').hasError('required')"> <mat-error *ngIf="registration.get('accessTokenUri').hasError('required')">
@ -152,7 +155,7 @@
<button mat-icon-button matSuffix <button mat-icon-button matSuffix
type="button" type="button"
(click)="toggleEditMode(registration, 'authorizationUri')" (click)="toggleEditMode(registration, 'authorizationUri')"
*ngIf="registration.get('providerName').value !== 'Custom'"> *ngIf="getProviderName(registration) !== 'Custom'">
<mat-icon class="material-icons">create</mat-icon> <mat-icon class="material-icons">create</mat-icon>
</button> </button>
<mat-error *ngIf="registration.get('authorizationUri').hasError('required')"> <mat-error *ngIf="registration.get('authorizationUri').hasError('required')">
@ -171,7 +174,7 @@
<button mat-icon-button matSuffix <button mat-icon-button matSuffix
type="button" aria-label="Clear" type="button" aria-label="Clear"
(click)="toggleEditMode(registration, 'jwkSetUri')" (click)="toggleEditMode(registration, 'jwkSetUri')"
*ngIf="registration.get('providerName').value !== 'Custom'"> *ngIf="getProviderName(registration) !== 'Custom'">
<mat-icon class="material-icons">create</mat-icon> <mat-icon class="material-icons">create</mat-icon>
</button> </button>
<mat-error *ngIf="registration.get('jwkSetUri').hasError('pattern')"> <mat-error *ngIf="registration.get('jwkSetUri').hasError('pattern')">
@ -185,7 +188,7 @@
<button mat-icon-button matSuffix <button mat-icon-button matSuffix
type="button" type="button"
(click)="toggleEditMode(registration, 'userInfoUri')" (click)="toggleEditMode(registration, 'userInfoUri')"
*ngIf="registration.get('providerName').value !== 'Custom'"> *ngIf="getProviderName(registration) !== 'Custom'">
<mat-icon class="material-icons">create</mat-icon> <mat-icon class="material-icons">create</mat-icon>
</button> </button>
<mat-error *ngIf="registration.get('userInfoUri').hasError('required')"> <mat-error *ngIf="registration.get('userInfoUri').hasError('required')">
@ -207,7 +210,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" *ngIf="registration.get('providerName').value === 'Custom'"> <div fxLayout="row" fxLayout.xs="column" fxLayoutGap.gt-xs="8px" *ngIf="getProviderName(registration) === 'Custom'">
<mat-form-field fxFlex class="mat-block"> <mat-form-field fxFlex class="mat-block">
<mat-label translate>admin.oauth2.login-button-label</mat-label> <mat-label translate>admin.oauth2.login-button-label</mat-label>
<input matInput formControlName="loginButtonLabel" required> <input matInput formControlName="loginButtonLabel" required>
@ -304,7 +307,7 @@
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex class="mat-block" *ngIf="registration.get('mapperConfig.basic.tenantNameStrategy').value === 'CUSTOM'"> <mat-form-field fxFlex class="mat-block" [fxShow]="registration.get('mapperConfig.basic.tenantNameStrategy').value === 'CUSTOM'">
<mat-label translate>admin.oauth2.tenant-name-pattern</mat-label> <mat-label translate>admin.oauth2.tenant-name-pattern</mat-label>
<input matInput <input matInput
formControlName="tenantNamePattern" formControlName="tenantNamePattern"

220
ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts

@ -20,7 +20,9 @@ import {
ClientAuthenticationMethod, ClientAuthenticationMethod,
ClientProviderTemplated, ClientProviderTemplated,
ClientRegistration, ClientRegistration,
DomainParams, MapperConfig,
MapperConfigBasic,
MapperConfigCustom,
MapperConfigType, MapperConfigType,
OAuth2Settings, OAuth2Settings,
TenantNameStrategy TenantNameStrategy
@ -73,7 +75,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
readonly separatorKeysCodes: number[] = [ENTER, COMMA]; readonly separatorKeysCodes: number[] = [ENTER, COMMA];
oauth2SettingsForm: FormGroup; oauth2SettingsForm: FormGroup;
oauth2Settings: OAuth2Settings; oauth2Settings: OAuth2Settings[];
clientAuthenticationMethods: ClientAuthenticationMethod[] = ['BASIC', 'POST']; clientAuthenticationMethods: ClientAuthenticationMethod[] = ['BASIC', 'POST'];
converterTypesExternalUser: MapperConfigType[] = ['BASIC', 'CUSTOM']; converterTypesExternalUser: MapperConfigType[] = ['BASIC', 'CUSTOM'];
@ -103,7 +105,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
this.initTemplates(templates); this.initTemplates(templates);
this.oauth2Settings = oauth2Settings; this.oauth2Settings = oauth2Settings;
this.initOAuth2Settings(this.oauth2Settings); this.initOAuth2Settings(this.oauth2Settings);
this.oauth2SettingsForm.reset(this.oauth2Settings); // this.oauth2SettingsForm.get('clientDomains').updateValueAndValidity();
} }
); );
} }
@ -121,59 +123,65 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
this.templateProvider.sort(); this.templateProvider.sort();
} }
get clientsDomainsParams(): FormArray { get clientDomains(): FormArray {
return this.oauth2SettingsForm.get('clientsDomainsParams') as FormArray; return this.oauth2SettingsForm.get('clientDomains') as FormArray;
} }
private get formBasicGroup(): FormGroup { private formBasicGroup(mapperConfigBasic?: MapperConfigBasic): FormGroup {
let tenantNamePattern;
if (mapperConfigBasic?.tenantNamePattern) {
tenantNamePattern = mapperConfigBasic.tenantNamePattern;
} else {
tenantNamePattern = {value: null, disabled: true};
}
const basicGroup = this.fb.group({ const basicGroup = this.fb.group({
emailAttributeKey: ['email', [Validators.required]], emailAttributeKey: [mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email', Validators.required],
firstNameAttributeKey: [''], firstNameAttributeKey: [mapperConfigBasic?.firstNameAttributeKey ? mapperConfigBasic.firstNameAttributeKey : ''],
lastNameAttributeKey: [''], lastNameAttributeKey: [mapperConfigBasic?.lastNameAttributeKey ? mapperConfigBasic.lastNameAttributeKey : ''],
tenantNameStrategy: ['DOMAIN'], tenantNameStrategy: [mapperConfigBasic?.tenantNameStrategy ? mapperConfigBasic.tenantNameStrategy : 'DOMAIN'],
tenantNamePattern: [null], tenantNamePattern: [tenantNamePattern, Validators.required],
customerNamePattern: [null], customerNamePattern: [mapperConfigBasic?.customerNamePattern ? mapperConfigBasic.customerNamePattern : null],
defaultDashboardName: [null], defaultDashboardName: [mapperConfigBasic?.defaultDashboardName ? mapperConfigBasic.defaultDashboardName : null],
alwaysFullScreen: [false] alwaysFullScreen: [mapperConfigBasic?.alwaysFullScreen ? mapperConfigBasic.alwaysFullScreen : false]
}); });
this.subscriptions.push(basicGroup.get('tenantNameStrategy').valueChanges.subscribe((domain) => { this.subscriptions.push(basicGroup.get('tenantNameStrategy').valueChanges.subscribe((domain) => {
if (domain === 'CUSTOM') { if (domain === 'CUSTOM') {
basicGroup.get('tenantNamePattern').setValidators(Validators.required); basicGroup.get('tenantNamePattern').enable();
} else { } else {
basicGroup.get('tenantNamePattern').clearValidators(); basicGroup.get('tenantNamePattern').disable();
} }
})); }));
return basicGroup; return basicGroup;
} }
get formCustomGroup(): FormGroup { private formCustomGroup(mapperConfigCustom?: MapperConfigCustom): FormGroup {
return this.fb.group({ return this.fb.group({
url: [null, [Validators.required, Validators.pattern(this.URL_REGEXP)]], url: [mapperConfigCustom?.url ? mapperConfigCustom.url : null, [Validators.required, Validators.pattern(this.URL_REGEXP)]],
username: [null], username: [mapperConfigCustom?.username ? mapperConfigCustom.username : null],
password: [null] password: [mapperConfigCustom?.password ? mapperConfigCustom.password : null]
}); });
} }
private buildOAuth2SettingsForm(): void { private buildOAuth2SettingsForm(): void {
this.oauth2SettingsForm = this.fb.group({ this.oauth2SettingsForm = this.fb.group({
clientsDomainsParams: this.fb.array([], Validators.required) clientDomains: this.fb.array([])
}); });
} }
private initOAuth2Settings(oauth2Settings: OAuth2Settings): void { private initOAuth2Settings(oauth2Settings: OAuth2Settings[]): void {
if (oauth2Settings.clientsDomainsParams) { if (oauth2Settings) {
oauth2Settings.clientsDomainsParams.forEach((domaindomain) => { oauth2Settings.forEach((domain) => {
this.clientsDomainsParams.push(this.buildSettingsDomain(domaindomain)); this.clientDomains.push(this.buildSettingsDomain(domain));
}); });
} }
} }
private uniqueDomainValidator(control: AbstractControl): { [key: string]: boolean } | null { private uniqueDomainValidator(control: AbstractControl): { [key: string]: boolean } | null {
if (control.value !== null && control?.root) { if (control.root.value.clientDomains?.length > 1) {
const listDomainName = []; const listDomainName = [];
control.root.value.clientsDomainsParams.forEach((domain) => { control.root.value.clientDomains.forEach((domain) => {
listDomainName.push(domain.domainName); listDomainName.push(domain.domainName);
}); });
if (listDomainName.indexOf(control.value) > -1) { if (listDomainName.indexOf(control.value) > -1) {
@ -183,7 +191,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
return null; return null;
} }
private buildSettingsDomain(domainParams?: DomainParams): FormGroup { private buildSettingsDomain(domainParams?: OAuth2Settings): FormGroup {
let url = this.window.location.protocol + '//' + this.window.location.hostname; let url = this.window.location.protocol + '//' + this.window.location.hostname;
const port = this.window.location.port; const port = this.window.location.port;
if (port !== '80' && port !== '443') { if (port !== '80' && port !== '443') {
@ -191,8 +199,13 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
} }
url += '/login/oauth2/code/'; url += '/login/oauth2/code/';
const formDomain = this.fb.group({ const formDomain = this.fb.group({
domainName: [null, [Validators.required, Validators.pattern('((?![:/]).)*$'), this.uniqueDomainValidator]], domainName: [domainParams?.domainName ? domainParams.domainName : this.window.location.hostname, [
redirectUriTemplate: [url, [Validators.required, Validators.pattern(this.URL_REGEXP)]], Validators.required,
Validators.pattern('((?![:/]).)*$'),
this.uniqueDomainValidator]],
redirectUriTemplate: [domainParams?.redirectUriTemplate ? domainParams.redirectUriTemplate : url, [
Validators.required,
Validators.pattern(this.URL_REGEXP)]],
clientRegistrations: this.fb.array([], Validators.required) clientRegistrations: this.fb.array([], Validators.required)
}); });
@ -201,7 +214,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
domain = this.window.location.hostname; domain = this.window.location.hostname;
} }
const uri = this.window.location.protocol + `//${domain}/login/oauth2/code/`; const uri = this.window.location.protocol + `//${domain}/login/oauth2/code/`;
formDomain.get('redirectUriTemplate').patchValue(uri); formDomain.get('redirectUriTemplate').patchValue(uri, {emitEvent: false});
})); }));
if (domainParams) { if (domainParams) {
@ -216,40 +229,59 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
} }
private buildSettingsRegistration(registrationData?: ClientRegistration): FormGroup { private buildSettingsRegistration(registrationData?: ClientRegistration): FormGroup {
let additionalInfo = null;
if (registrationData?.additionalInfo) {
additionalInfo = JSON.parse(registrationData.additionalInfo);
if (this.templateProvider.indexOf(additionalInfo.providerName) === -1) {
additionalInfo.providerName = 'Custom';
}
}
const clientRegistration = this.fb.group({ const clientRegistration = this.fb.group({
providerName: ['Custom', [Validators.required]], id: this.fb.group({
loginButtonLabel: [null, [Validators.required]], id: [registrationData?.id?.id ? registrationData.id.id : null],
loginButtonIcon: [null], entityType: [registrationData?.id?.entityType ? registrationData.id.entityType : null]
clientId: ['', [Validators.required]], }),
clientSecret: ['', [Validators.required]], additionalInfo: this.fb.group({
accessTokenUri: ['', [Validators.required, Validators.pattern(this.URL_REGEXP)]], providerName: [additionalInfo?.providerName ? additionalInfo?.providerName : 'Custom', Validators.required]
authorizationUri: ['', [Validators.required, Validators.pattern(this.URL_REGEXP)]], }),
scope: this.fb.array([], [Validators.required]), loginButtonLabel: [registrationData?.loginButtonLabel ? registrationData.loginButtonLabel : null, Validators.required],
jwkSetUri: ['', [Validators.pattern(this.URL_REGEXP)]], loginButtonIcon: [registrationData?.loginButtonIcon ? registrationData.loginButtonIcon : null],
userInfoUri: ['', [Validators.required, Validators.pattern(this.URL_REGEXP)]], clientId: [registrationData?.clientId ? registrationData.clientId : '', Validators.required],
clientAuthenticationMethod: ['POST', [Validators.required]], clientSecret: [registrationData?.clientSecret ? registrationData.clientSecret : '', Validators.required],
userNameAttributeName: ['email', [Validators.required]], accessTokenUri: [registrationData?.accessTokenUri ? registrationData.accessTokenUri : '', [
Validators.required,
Validators.pattern(this.URL_REGEXP)]],
authorizationUri: [registrationData?.authorizationUri ? registrationData.authorizationUri : '', [
Validators.required,
Validators.pattern(this.URL_REGEXP)]],
scope: this.fb.array(registrationData?.scope ? registrationData.scope : []),
jwkSetUri: [registrationData?.jwkSetUri ? registrationData.jwkSetUri : '', Validators.pattern(this.URL_REGEXP)],
userInfoUri: [registrationData?.userInfoUri ? registrationData.userInfoUri : '', [
Validators.required,
Validators.pattern(this.URL_REGEXP)]],
clientAuthenticationMethod: [
registrationData?.clientAuthenticationMethod ? registrationData.clientAuthenticationMethod : 'POST', Validators.required],
userNameAttributeName: [
registrationData?.userNameAttributeName ? registrationData.userNameAttributeName : 'email', Validators.required],
mapperConfig: this.fb.group({ mapperConfig: this.fb.group({
allowUserCreation: [true], allowUserCreation: [registrationData?.mapperConfig?.allowUserCreation ? registrationData.mapperConfig.allowUserCreation : true],
activateUser: [false], activateUser: [registrationData?.mapperConfig?.activateUser ? registrationData.mapperConfig.activateUser : false],
type: ['BASIC', [Validators.required]], type: [registrationData?.mapperConfig?.type ? registrationData.mapperConfig.type : 'BASIC', Validators.required]
basic: this.formBasicGroup
} }
) )
}); });
if (registrationData) {
this.changeMapperConfigType(clientRegistration, registrationData.mapperConfig.type, registrationData.mapperConfig);
} else {
this.changeMapperConfigType(clientRegistration, 'BASIC');
}
this.subscriptions.push(clientRegistration.get('mapperConfig.type').valueChanges.subscribe((value) => { this.subscriptions.push(clientRegistration.get('mapperConfig.type').valueChanges.subscribe((value) => {
const mapperConfig = clientRegistration.get('mapperConfig') as FormGroup; this.changeMapperConfigType(clientRegistration, value);
if (value === 'BASIC') {
mapperConfig.removeControl('custom');
mapperConfig.addControl('basic', this.formBasicGroup);
} else {
mapperConfig.removeControl('basic');
mapperConfig.addControl('custom', this.formCustomGroup);
}
})); }));
this.subscriptions.push(clientRegistration.get('providerName').valueChanges.subscribe((provider) => { this.subscriptions.push(clientRegistration.get('additionalInfo.providerName').valueChanges.subscribe((provider) => {
(clientRegistration.get('scope') as FormArray).clear(); (clientRegistration.get('scope') as FormArray).clear();
if (provider === 'Custom') { if (provider === 'Custom') {
clientRegistration.reset(this.defaultProvider, {emitEvent: false}); clientRegistration.reset(this.defaultProvider, {emitEvent: false});
@ -259,6 +291,8 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
clientRegistration.get('userInfoUri').enable(); clientRegistration.get('userInfoUri').enable();
} else { } else {
const template = this.templates.get(provider); const template = this.templates.get(provider);
delete template.id;
delete template.additionalInfo;
template.scope.forEach(() => { template.scope.forEach(() => {
(clientRegistration.get('scope') as FormArray).push(this.fb.control('')); (clientRegistration.get('scope') as FormArray).push(this.fb.control(''));
}); });
@ -270,20 +304,23 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
} }
})); }));
if (registrationData) {
registrationData.scope.forEach(() => {
(clientRegistration.get('scope') as FormArray).push(this.fb.control(''));
});
if (registrationData.mapperConfig.type !== 'BASIC') {
clientRegistration.get('mapperConfig.type').patchValue('CUSTOM');
}
}
return clientRegistration; return clientRegistration;
} }
private changeMapperConfigType(control: AbstractControl, type: MapperConfigType, predefinedValue?: MapperConfig) {
const mapperConfig = control.get('mapperConfig') as FormGroup;
if (type === 'BASIC') {
mapperConfig.removeControl('custom');
mapperConfig.addControl('basic', this.formBasicGroup(predefinedValue?.basic));
} else {
mapperConfig.removeControl('basic');
mapperConfig.addControl('custom', this.formCustomGroup(predefinedValue?.custom));
}
}
save(): void { save(): void {
this.adminService.saveOAuth2Settings(this.oauth2SettingsForm.value).subscribe( const setting = this.prepareFormValue(this.oauth2SettingsForm.getRawValue().clientDomains);
this.adminService.saveOAuth2Settings(setting).subscribe(
(oauth2Settings) => { (oauth2Settings) => {
this.oauth2Settings = oauth2Settings; this.oauth2Settings = oauth2Settings;
this.oauth2SettingsForm.markAsPristine(); this.oauth2SettingsForm.markAsPristine();
@ -292,6 +329,18 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
); );
} }
private prepareFormValue(formValue: OAuth2Settings[]): OAuth2Settings[]{
formValue.forEach((setting) => {
setting.clientRegistrations.forEach((registration) => {
registration.additionalInfo = JSON.stringify(registration.additionalInfo);
if (registration.id.id === null) {
delete registration.id;
}
});
});
return formValue;
}
confirmForm(): FormGroup { confirmForm(): FormGroup {
return this.oauth2SettingsForm; return this.oauth2SettingsForm;
} }
@ -315,7 +364,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
} }
addDomain(): void { addDomain(): void {
this.clientsDomainsParams.push(this.buildSettingsDomain()); this.clientDomains.push(this.buildSettingsDomain());
} }
deleteDomain($event: Event, index: number): void { deleteDomain($event: Event, index: number): void {
@ -324,14 +373,21 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
$event.preventDefault(); $event.preventDefault();
} }
const domainName = this.clientsDomainsParams.at(index).get('domainName').value; const domainName = this.clientDomains.at(index).get('domainName').value;
this.dialogService.confirm( this.dialogService.confirm(
this.translate.instant('admin.oauth2.delete-domain-title', {domainName: domainName || ''}), this.translate.instant('admin.oauth2.delete-domain-title', {domainName: domainName || ''}),
this.translate.instant('admin.oauth2.delete-domain-text'), null, this.translate.instant('admin.oauth2.delete-domain-text'), null,
this.translate.instant('action.delete') this.translate.instant('action.delete')
).subscribe((data) => { ).subscribe((data) => {
if (data) { if (data) {
this.clientsDomainsParams.removeAt(index); if (index < this.oauth2Settings.length) {
this.adminService.deleteOAuth2Domain(this.oauth2Settings[index].domainName).subscribe(() => {
this.oauth2Settings.splice(index, 1);
this.clientDomains.removeAt(index);
});
} else {
this.clientDomains.removeAt(index);
}
} }
}); });
} }
@ -344,20 +400,27 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
this.clientDomainRegistrations(control).push(this.buildSettingsRegistration()); this.clientDomainRegistrations(control).push(this.buildSettingsRegistration());
} }
deleteRegistration($event: Event, controler: AbstractControl, index: number): void { deleteRegistration($event: Event, control: AbstractControl, index: number): void {
if ($event) { if ($event) {
$event.stopPropagation(); $event.stopPropagation();
$event.preventDefault(); $event.preventDefault();
} }
const providerName = this.clientDomainRegistrations(controler).at(index).get('providerName').value; const providerName = this.clientDomainRegistrations(control).at(index).get('additionalInfo.providerName').value;
this.dialogService.confirm( this.dialogService.confirm(
this.translate.instant('admin.oauth2.delete-registration-title', {name: providerName || ''}), this.translate.instant('admin.oauth2.delete-registration-title', {name: providerName || ''}),
this.translate.instant('admin.oauth2.delete-registration-text'), null, this.translate.instant('admin.oauth2.delete-registration-text'), null,
this.translate.instant('action.delete') this.translate.instant('action.delete')
).subscribe((data) => { ).subscribe((data) => {
if (data) { if (data) {
this.clientDomainRegistrations(controler).removeAt(index); const registrationId = this.clientDomainRegistrations(control).at(index).get('id.id').value;
if (registrationId) {
this.adminService.deleteOAuthCclientRegistrationId(registrationId).subscribe(() => {
this.clientDomainRegistrations(control).removeAt(index);
});
} else {
this.clientDomainRegistrations(control).removeAt(index);
}
} }
}); });
} }
@ -385,7 +448,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
overlayRef.dispose(); overlayRef.dispose();
}); });
const redirectURI = this.clientsDomainsParams.at(index).get('redirectUriTemplate').value; const redirectURI = this.clientDomains.at(index).get('redirectUriTemplate').value;
const injectionTokens = new WeakMap<any, any>([ const injectionTokens = new WeakMap<any, any>([
[EDIT_REDIRECT_URI_PANEL_DATA, { [EDIT_REDIRECT_URI_PANEL_DATA, {
@ -399,7 +462,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
componentRef.onDestroy(() => { componentRef.onDestroy(() => {
if (componentRef.instance.result !== null) { if (componentRef.instance.result !== null) {
const attributeValue = componentRef.instance.result; const attributeValue = componentRef.instance.result;
this.clientsDomainsParams.at(index).get('redirectUriTemplate').patchValue(attributeValue, {emitEvent: true}); this.clientDomains.at(index).get('redirectUriTemplate').patchValue(attributeValue, {emitEvent: true});
} }
}); });
} }
@ -407,4 +470,13 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
toggleEditMode(control: AbstractControl, path: string) { toggleEditMode(control: AbstractControl, path: string) {
control.get(path).disabled ? control.get(path).enable() : control.get(path).disable(); control.get(path).disabled ? control.get(path).enable() : control.get(path).disable();
} }
getProviderName(controller: AbstractControl): string {
return controller.get('additionalInfo.providerName').value;
}
getHelpLink(controller: AbstractControl): string {
const provider = controller.get('additionalInfo.providerName').value;
return this.templates.get(provider).helpLink;
}
} }

3
ui-ngx/src/app/shared/models/entity-type.models.ts

@ -45,7 +45,8 @@ export enum EntityType {
RULE_NODE = 'RULE_NODE', RULE_NODE = 'RULE_NODE',
ENTITY_VIEW = 'ENTITY_VIEW', ENTITY_VIEW = 'ENTITY_VIEW',
WIDGETS_BUNDLE = 'WIDGETS_BUNDLE', WIDGETS_BUNDLE = 'WIDGETS_BUNDLE',
WIDGET_TYPE = 'WIDGET_TYPE' WIDGET_TYPE = 'WIDGET_TYPE',
OAUTH2_CLIENT_REGISTRATION = 'OAUTH2_CLIENT_REGISTRATION'
} }
export enum AliasEntityType { export enum AliasEntityType {

10
ui-ngx/src/app/shared/models/settings.models.ts

@ -69,21 +69,15 @@ export interface UpdateMessage {
} }
export interface OAuth2Settings { export interface OAuth2Settings {
clientsDomainsParams: DomainParams[];
}
export interface DomainParams {
domainName: string; domainName: string;
redirectUriTemplate: string; redirectUriTemplate: string;
clientRegistrations: ClientRegistration[]; clientRegistrations: ClientRegistration[];
} }
export interface ClientProviderTemplated extends ClientRegistration{ export interface ClientProviderTemplated extends ClientRegistration{
additionalInfo: string;
comment: string; comment: string;
createdTime: number; createdTime: number;
helpLink: string; helpLink: string;
id: EntityId;
name: string; name: string;
providerId: string; providerId: string;
tenantId: TenantId; tenantId: TenantId;
@ -97,11 +91,13 @@ export interface ClientRegistration {
accessTokenUri: string; accessTokenUri: string;
authorizationUri: string; authorizationUri: string;
scope: string[]; scope: string[];
jwkSetUri: string; jwkSetUri?: string;
userInfoUri: string; userInfoUri: string;
clientAuthenticationMethod: ClientAuthenticationMethod; clientAuthenticationMethod: ClientAuthenticationMethod;
userNameAttributeName: string; userNameAttributeName: string;
mapperConfig: MapperConfig; mapperConfig: MapperConfig;
id?: EntityId;
additionalInfo: string;
} }
export interface MapperConfig { export interface MapperConfig {

4
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -166,8 +166,8 @@
"url": "URL", "url": "URL",
"url-required": "URL is required.", "url-required": "URL is required.",
"url-pattern": "Invalid URL format.", "url-pattern": "Invalid URL format.",
"login-button-label": "Login button label", "login-button-label": "Label (Login with ${label})",
"login-button-label-required": "Login button label is required.", "login-button-label-required": "Label is required.",
"login-button-icon": "Login button icon", "login-button-icon": "Login button icon",
"delete-domain-title": "Are you sure you want to delete the domain '{{domainName}}'?", "delete-domain-title": "Are you sure you want to delete the domain '{{domainName}}'?",
"delete-domain-text": "Be careful, after the confirmation a domain and all registration data will be unavailable.", "delete-domain-text": "Be careful, after the confirmation a domain and all registration data will be unavailable.",

Loading…
Cancel
Save