Code development platform for open source projects from the European Union institutions

Skip to content
Snippets Groups Projects
Commit 89eee931 authored by Joze RIHTARSIC's avatar Joze RIHTARSIC
Browse files

ServiceGroup edit dialog schema regexp updated from database

parent eab6bce0
No related branches found
No related tags found
No related merge requests found
Showing
with 143 additions and 17 deletions
......@@ -2,7 +2,7 @@
"/rest/**": {
"target": "http://localhost:8080/smp/ui/",
"changeOrigin": true,
"secure": false,
"secure": true ,
"logLevel": "debug"
}
}
export interface SmpConfig {
smlIntegrationOn?: boolean;
smlParticipantMultiDomainOn?: boolean;
participantSchemaRegExp?: string;
participantSchemaRegExpMessage?: string;
}
import {Injectable} from '@angular/core';
import {HttpClient, HttpResponse} from '@angular/common/http';
import {Observable, ReplaySubject} from 'rxjs';
import {Router} from '@angular/router';
import {SmpConfig} from './smp-config.model';
import {SmpConstants} from "../smp.constants";
@Injectable()
export class SmpConfigService {
constructor(private http: HttpClient, private router: Router) {
}
getSmpInfo(): Observable<SmpConfig> {
let subject = new ReplaySubject<SmpConfig>();
this.http.get<SmpConfig>(SmpConstants.REST_CONFIG)
.subscribe((res: SmpConfig) => {
subject.next(res);
}, error => {
console.log("getSmpConfig:" + error);
}
);
return subject.asObservable();
}
}
......@@ -8,7 +8,7 @@ import {Role} from "../security/role.model";
import {AlertService} from "../alert/alert.service";
import {Subscription} from "rxjs/internal/Subscription";
import {SmpInfo} from "../app-info/smp-info.model";
import {ReplaySubject} from "rxjs/index";
import {SmpConfig} from "../app-config/smp-config.model";
/**
* Purpose of object is to fetch lookups as domains and users
......@@ -27,6 +27,7 @@ export class GlobalLookups implements OnInit {
cachedCertificateList: Array<any> = [];
cachedCertificateAliasList: Array<String> = [];
cachedApplicationInfo: SmpInfo;
cachedApplicationConfig: SmpConfig;
cachedTrustedCertificateList: Array<any> = [];
......@@ -36,8 +37,8 @@ export class GlobalLookups implements OnInit {
this.refreshUserLookup();
this.refreshCertificateLookup();
this.refreshApplicationInfo();
this.refreshApplicationConfiguration();
this.refreshTrustedCertificateLookup();
}
ngOnInit() {
......@@ -71,6 +72,20 @@ export class GlobalLookups implements OnInit {
);
}
public refreshApplicationConfiguration() {
// check if authenticated
this.securityService.isAuthenticated(false).subscribe((isAuthenticated: boolean) => {
if(isAuthenticated) {
this.http.get<SmpConfig>(SmpConstants.REST_CONFIG)
.subscribe((res: SmpConfig) => {
this.cachedApplicationConfig = res;
}, error => {
console.log("getSmpConfig:" + error);
}
);
}
});
}
public refreshUserLookup() {
// call only for authenticated users.
......
......@@ -28,7 +28,7 @@
<input matInput placeholder="Participant scheme" name="participantScheme"
id="participantScheme_id"
[formControl]="dialogForm.controls['participantScheme']"
maxlength="25" required>
maxlength="255" required>
<div
*ngIf="(!editMode && dialogForm.controls['participantScheme'].touched || editMode) && dialogForm.controls['participantScheme'].hasError('required')"
style="color:red; font-size: 70%">
......@@ -38,7 +38,7 @@
*ngIf="(!editMode && dialogForm.controls['participantScheme'].touched || editMode) &&
dialogForm.controls['participantScheme'].hasError('pattern')"
style="color:red; font-size: 70%">
Participant scheme must be up to 25 characters long. The Scheme Identifier MUST take the form [domain]-[identifierArea]-[identifierType] (ex.: 'busdox-actorid-upis') and may only contain the following characters: [a-z0-9]+-[a-z0-9]+-[a-z0-9]+.
{{participantSchemeMessage}}
</div>
</mat-form-field>
</div>
......
......@@ -28,7 +28,8 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
static readonly EDIT_MODE = 'ServiceGroup Edit';
readonly participantSchemePattern ='^[a-z0-9]+-[a-z0-9]+-[a-z0-9]+$';
participantSchemePattern = '^[a-z0-9]+-[a-z0-9]+-[a-z0-9]+$';
participantSchemeMessage = '';
@ViewChild('domainSelector') domainSelector: any;
......@@ -55,7 +56,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
multiDomainOn(multidomainOn: boolean) {
return (c: AbstractControl): { [key: string]: any } => {
if (c.value && c.value.length < 2 || multidomainOn )
if (c.value && c.value.length < 2 || multidomainOn)
return null;
return {'multiDomainError': {valid: false}};
......@@ -88,6 +89,13 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
extension: '',
status: SearchTableEntityStatus.NEW,
};
if (this.lookups.cachedApplicationConfig) {
this.participantSchemePattern = this.lookups.cachedApplicationConfig.participantSchemaRegExp != null ?
this.lookups.cachedApplicationConfig.participantSchemaRegExp : ".*"
this.participantSchemeMessage = this.lookups.cachedApplicationConfig.participantSchemaRegExpMessage;
}
// user is new when reopening the new item in edit mode!
// allow to change data but warn on error!
......@@ -132,7 +140,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
this.changeDetector.detectChanges()
}
isDomainProperlyConfigured(domain: DomainRo){
isDomainProperlyConfigured(domain: DomainRo) {
if (this.lookups.cachedApplicationInfo.smlIntegrationOn) {
return domain.smlSmpId && (domain.smlClientKeyAlias || domain.smlClientCertHeader);
} else {
......@@ -151,7 +159,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
participantScheme: this.dialogForm.controls['participantScheme'].value,
participantIdentifier: this.dialogForm.controls['participantIdentifier'].value,
extension: this.dialogForm.controls['extension'].value,
statusAction: this.editMode?SearchTableEntityStatus.UPDATED:SearchTableEntityStatus.NEW,
statusAction: this.editMode ? SearchTableEntityStatus.UPDATED : SearchTableEntityStatus.NEW,
}
//
let validationObservable = this.http.post<ServiceGroupValidationRo>(SmpConstants.REST_SERVICE_GROUP_EXTENSION_VALIDATE, request);
......@@ -161,7 +169,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
this.isExtensionValid = false;
this.showSpinner = false;
if (res.errorCode == ServiceGroupValidationErrorCodeModel.ERROR_CODE_SERVICE_GROUP_EXISTS){
if (res.errorCode == ServiceGroupValidationErrorCodeModel.ERROR_CODE_SERVICE_GROUP_EXISTS) {
this.dialogForm.controls['participantIdentifier'].setErrors({'dbExist': true});
} else {
this.extensionValidationMessage = res.errorMessage;
......@@ -248,12 +256,12 @@ export class ServiceGroupDetailsDialogComponent implements OnInit {
return this.current;
}
dataChanged(){
if (this.current.status === SearchTableEntityStatus.NEW){
dataChanged() {
if (this.current.status === SearchTableEntityStatus.NEW) {
return true;
}
return this.current.users !== this.dialogForm.value['users'];
this.current.extension !== this.dialogForm.value['extension'];
this.current.extension !== this.dialogForm.value['extension'];
}
onExtensionDelete() {
......
......@@ -38,6 +38,7 @@ export class ServiceGroupEditComponent implements OnInit {
// if smp admin it needs to have update user list for detail dialog!
if (this.securityService.isCurrentUserSMPAdmin() || this.securityService.isCurrentUserServiceGroupAdmin()) {
this.lookups.refreshUserLookup();
this.lookups.refreshApplicationConfiguration();
}
}
......
......@@ -8,6 +8,7 @@ export class SmpConstants {
public static readonly REST_SECURITY_AUTHENTICATION = 'rest/security/authentication';
public static readonly REST_SECURITY_USER = 'rest/security/user';
public static readonly REST_APPLICATION = 'rest/application/info';
public static readonly REST_CONFIG = 'rest/application/config';
public static readonly REST_KEYSTORE = 'rest/keystore';
public static readonly REST_TRUSTSTORE = 'rest/truststore';
......
package eu.europa.ec.edelivery.smp.data.ui;
import java.io.Serializable;
public class SmpConfigRO implements Serializable {
private static final long serialVersionUID = -49712226560325303L;
boolean smlIntegrationOn;
boolean smlParticipantMultiDomainOn;
String participantSchemaRegExp;
String participantSchemaRegExpMessage;
public boolean isSmlIntegrationOn() {
return smlIntegrationOn;
}
public void setSmlIntegrationOn(boolean smlIntegrationOn) {
this.smlIntegrationOn = smlIntegrationOn;
}
public boolean isSmlParticipantMultiDomainOn() {
return smlParticipantMultiDomainOn;
}
public void setSmlParticipantMultiDomainOn(boolean smlParticipantMultidomainOn) {
this.smlParticipantMultiDomainOn = smlParticipantMultidomainOn;
}
public String getParticipantSchemaRegExp() {
return participantSchemaRegExp;
}
public void setParticipantSchemaRegExp(String participantSchemaRegExp) {
this.participantSchemaRegExp = participantSchemaRegExp;
}
public String getParticipantSchemaRegExpMessage() {
return participantSchemaRegExpMessage;
}
public void setParticipantSchemaRegExpMessage(String participantSchemaRegExpMessage) {
this.participantSchemaRegExpMessage = participantSchemaRegExpMessage;
}
}
......@@ -12,7 +12,10 @@ public enum SMPPropertyEnum {
OUTPUT_CONTEXT_PATH ("contextPath.output","true","This property controls pattern of URLs produced by SMP in GET ServiceGroup responses." , true, false , SMPPropertyTypeEnum.BOOLEAN),
PARTC_SCH_REGEXP ("identifiersBehaviour.ParticipantIdentifierScheme.validationRegex","^(?!^.{26})([a-z0-9]+-[a-z0-9]+-[a-z0-9]+)","Participant Identifier Schema of each PUT ServiceGroup request is validated against this schema.", false, false , SMPPropertyTypeEnum.REGEXP),
PARTC_SCH_REGEXP ("identifiersBehaviour.ParticipantIdentifierScheme.validationRegex","^((?!^.{26})([a-z0-9]+-[a-z0-9]+-[a-z0-9]+)|urn:oasis:names:tc:ebcore:partyid-type:(iso6523:|unregistered:).+)","Participant Identifier Schema of each PUT ServiceGroup request is validated against this schema.", false, false , SMPPropertyTypeEnum.REGEXP),
PARTC_SCH_REGEXP_MSG ("identifiersBehaviour.ParticipantIdentifierScheme.validationRegexMessage",
"Participant scheme must start with:urn:oasis:names:tc:ebcore:partyid-type:(iso6523:|unregistered:) OR must be up to 25 characters long. The Scheme Identifier MUST take the form [domain]-[identifierArea]-[identifierType] (ex.: 'busdox-actorid-upis') and may only contain the following characters: [a-z0-9]+-[a-z0-9]+-[a-z0-9]+. ", "Error message for UI",false, false , SMPPropertyTypeEnum.STRING),
CS_PARTICIPANTS("identifiersBehaviour.caseSensitive.ParticipantIdentifierSchemes","casesensitive-participant-scheme1|casesensitive-participant-scheme2","Specifies schemes of participant identifiers that must be considered CASE-SENSITIVE.", false, false , SMPPropertyTypeEnum.LIST_STRING),
CS_DOCUMENTS("identifiersBehaviour.caseSensitive.DocumentIdentifierSchemes","casesensitive-doc-scheme1|casesensitive-doc-scheme2","Specifies schemes of document identifiers that must be considered CASE-SENSITIVE.", false, false , SMPPropertyTypeEnum.LIST_STRING),
......
......@@ -61,16 +61,22 @@ public class ConfigurationService {
return (Pattern)configurationDAO.getCachedPropertyValue(PARTC_SCH_REGEXP);
}
public String getParticipantIdentifierSchemeRexExpPattern(){
return configurationDAO.getCachedProperty(PARTC_SCH_REGEXP);
}
public String getParticipantIdentifierSchemeRexExpMessage(){
return configurationDAO.getCachedProperty(PARTC_SCH_REGEXP_MSG);
}
public String getHttpProxyHost() {
return configurationDAO.getCachedProperty(HTTP_PROXY_HOST);
}
public String getHttpNoProxyHosts() {
return configurationDAO.getCachedProperty(HTTP_NO_PROXY_HOSTS);
}
public Optional<Integer> getHttpProxyPort() {
Integer intVal = (Integer) configurationDAO.getCachedPropertyValue(HTTP_PROXY_PORT);
return Optional.ofNullable(intVal);
......
package eu.europa.ec.edelivery.smp.ui;
import eu.europa.ec.edelivery.smp.auth.SMPAuthority;
import eu.europa.ec.edelivery.smp.data.ui.SmpConfigRO;
import eu.europa.ec.edelivery.smp.data.ui.SmpInfoRO;
import eu.europa.ec.edelivery.smp.services.ConfigurationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
......@@ -55,6 +58,20 @@ public class ApplicationResource {
return info;
}
@RequestMapping(method = RequestMethod.GET, path = "config")
@Secured({SMPAuthority.S_AUTHORITY_TOKEN_SYSTEM_ADMIN,SMPAuthority.S_AUTHORITY_TOKEN_SMP_ADMIN,
SMPAuthority.S_AUTHORITY_TOKEN_SERVICE_GROUP_ADMIN})
public SmpConfigRO getApplicationConfig() {
SmpConfigRO info = new SmpConfigRO();
info.setSmlIntegrationOn(configurationService.isSMLIntegrationEnabled());
info.setSmlParticipantMultiDomainOn(configurationService.isSMLMultiDomainEnabled());
info.setParticipantSchemaRegExp(configurationService.getParticipantIdentifierSchemeRexExpPattern());
info.setParticipantSchemaRegExpMessage(configurationService.getParticipantIdentifierSchemeRexExpMessage());
return info;
}
public String getDisplayVersion() {
StringBuilder display = new StringBuilder();
......
......@@ -43,7 +43,7 @@ encodedSlashesAllowedInUrl=false
## - limits length of scheme to 25 characters
## - forces pattern to consist of 3 alpha-numeric segments delimited with "-", i.e: aa1-bb2-cc3
## To turn validation OFF, set regex to "match all": .*
identifiersBehaviour.ParticipantIdentifierScheme.validationRegex=^(?!^.{26})([a-z0-9]+-[a-z0-9]+-[a-z0-9]+)
identifiersBehaviour.ParticipantIdentifierScheme.validationRegex=^((?!^.{26})([a-z0-9]+-[a-z0-9]+-[a-z0-9]+)|urn:oasis:names:tc:ebcore:partyid-type:(iso6523:|unregistered:).+)
## All Identifiers by default are CASE-INSENSITIVE.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment