diff --git a/smp-angular/src/app/common/search-table/search-table.component.ts b/smp-angular/src/app/common/search-table/search-table.component.ts index 6cf23ac42838ff5348ea171d02fc49b3b89c0504..17e356bdd0d451d46a48ef5f749a1854369947e7 100644 --- a/smp-angular/src/app/common/search-table/search-table.component.ts +++ b/smp-angular/src/app/common/search-table/search-table.component.ts @@ -398,7 +398,7 @@ export class SearchTableComponent implements OnInit { private editSearchTableEntity(rowNumber: number) { const row = this.rows[rowNumber]; const formRef: MatDialogRef<any> = this.searchTableController.newDialog({ - data: {edit: true, row} + data: {edit: row?.status!=SearchTableEntityStatus.NEW, row} }); formRef.afterClosed().subscribe(result => { if (result) { diff --git a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts index 5db36fe232ad899f9273007badd61f027a96f93f..e83361472923bd8e511d6d78a6fd59b074afc311 100644 --- a/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts +++ b/smp-angular/src/app/domain/domain-details-dialog/domain-details-dialog.component.ts @@ -50,7 +50,7 @@ export class DomainDetailsDialogComponent { this.editMode = data.edit; this.formTitle = this.editMode ? DomainDetailsDialogComponent.EDIT_MODE : DomainDetailsDialogComponent.NEW_MODE; - this.current = this.editMode + this.current = !!data.row ? { ...data.row, } diff --git a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html index 744e3dd16b76d2cc48e6e540fabfa16dcf07c1db..c28eb7fe66b1e028779cd8276fd0268d90193136 100644 --- a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html +++ b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.html @@ -62,7 +62,6 @@ </mat-panel-description> </mat-expansion-panel-header> <mat-selection-list #usersSelected - [disabled]="!securityService.isCurrentUserSMPAdmin()" [compareWith]="compareUserByUserId" [formControl]="dialogForm.controls['users']" style="min-height: 100px; height: 150px; overflow-y: scroll; overflow-x: auto;"> @@ -98,7 +97,6 @@ </mat-panel-description> </mat-expansion-panel-header> <mat-selection-list #domainSelector - [disabled]="!securityService.isCurrentUserSMPAdmin()" [compareWith]="compareDomain" [formControl]="dialogForm.controls['serviceGroupDomains']" (selectionChange)="onDomainSelectionChanged($event)" diff --git a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts index 6c865718b265b76e136285713317b14e47868afd..3b629142491e6a2a7e706fc56bd5effe7b594aab 100644 --- a/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-details-dialog/service-group-details-dialog.component.ts @@ -75,7 +75,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { this.editMode = this.data.edit; this.formTitle = this.editMode ? ServiceGroupDetailsDialogComponent.EDIT_MODE : ServiceGroupDetailsDialogComponent.NEW_MODE; - this.current = this.editMode + this.current = !!this.data.row ? { ...this.data.row, // copy serviceGroupDomain array @@ -111,15 +111,22 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { 'participantScheme': new FormControl({value: '', disabled: this.current.status !== SearchTableEntityStatus.NEW}, this.current.status === SearchTableEntityStatus.NEW ? [Validators.pattern(this.participantSchemePattern)] : null), - 'serviceGroupDomains': new FormControl({value: []}, [this.minSelectedListCount(1), - this.multiDomainOn(this.lookups.cachedApplicationConfig.smlParticipantMultiDomainOn)]), - 'users': new FormControl({value: []}, [this.minSelectedListCount(1)]), + 'serviceGroupDomains': new FormControl({ + value: [], + disabled: !securityService.isCurrentUserSMPAdmin() + }, + [this.minSelectedListCount(1), + this.multiDomainOn(this.lookups.cachedApplicationConfig.smlParticipantMultiDomainOn)]), + 'users': new FormControl({ + value: [], + disabled: !securityService.isCurrentUserSMPAdmin() + }, [this.minSelectedListCount(1)]), 'extension': new FormControl({value: ''}, []), }); - if (!!lookups.cachedApplicationConfig.partyIDSchemeMandatory && this.current.status == SearchTableEntityStatus.NEW){ - this.dialogForm.controls['participantScheme'].addValidators(Validators.required) ; + if (!!lookups.cachedApplicationConfig.partyIDSchemeMandatory && this.current.status == SearchTableEntityStatus.NEW) { + this.dialogForm.controls['participantScheme'].addValidators(Validators.required); } // update values @@ -134,7 +141,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { // retrieve xml extension for this service group if (this.current.status !== SearchTableEntityStatus.NEW && !this.current.extension) { // init domains - this.extensionObserver = this.http.get<ServiceGroupValidationRo>(SmpConstants.REST_PUBLIC_SERVICE_GROUP_ENTITY_EXTENSION.replace('{service-group-id}',this.current.id+"")); + this.extensionObserver = this.http.get<ServiceGroupValidationRo>(SmpConstants.REST_PUBLIC_SERVICE_GROUP_ENTITY_EXTENSION.replace('{service-group-id}', this.current.id + "")); this.extensionObserver.subscribe((res: ServiceGroupValidationRo) => { this.dialogForm.get('extension').setValue(res.extension); this.current.extension = res.extension; @@ -182,9 +189,7 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { } }).catch((err) => { console.log("Error occurred on Validation Extension: " + err); - });; - - + }); } checkValidity(g: FormGroup) { @@ -198,8 +203,6 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { Object.keys(g.controls).forEach(key => { g.get(key).updateValueAndValidity(); }); - - } @@ -218,13 +221,10 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { this.current.participantIdentifier = this.dialogForm.value['participantIdentifier']; this.current.participantScheme = this.dialogForm.value['participantScheme']; } else { - this.current.extensionStatus = - SearchTableEntityStatus.UPDATED; + this.current.extensionStatus = SearchTableEntityStatus.UPDATED; } this.current.users = this.dialogForm.value['users']; this.current.extension = this.dialogForm.value['extension']; - - let domainOptions = this.domainSelector.options._results; domainOptions.forEach(opt => { let domValue = opt.value; @@ -265,8 +265,8 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { return this.current.users !== this.dialogForm.value['users']; } - extensionChanged():boolean { - return !this.isEqual(this.current.extension, this.dialogForm.value['extension'].toString()); + extensionChanged(): boolean { + return !this.isEqual(this.current.extension, this.dialogForm.value['extension'].toString()); } onExtensionDelete() { @@ -313,20 +313,16 @@ export class ServiceGroupDetailsDialogComponent implements OnInit { } - onPrettyPrintExtension() { - - } - onDomainSelectionChanged(event) { // if deselected warn serviceMetadata will be deleted let domainCode = event.option.value.domainCode; if (!event.option.selected) { let smdCount = this.getServiceMetadataCountOnDomain(domainCode); - if (smdCount >0) { + if (smdCount > 0) { this.dialog.open(ConfirmationDialogComponent, { data: { title: "Registered serviceMetadata on domain!", - description: "Unregistering service group from domain will also delete its serviceMetadata (count: "+smdCount+") from the domain! Do you want to continue?" + description: "Unregistering service group from domain will also delete its serviceMetadata (count: " + smdCount + ") from the domain! Do you want to continue?" } }).afterClosed().subscribe(result => { if (!result) { diff --git a/smp-angular/src/app/service-group-edit/service-group-edit-controller.ts b/smp-angular/src/app/service-group-edit/service-group-edit-controller.ts index b04b013d96f5b531f94b5753b23c9431dd0dadaf..35c61f9600725dbb81f3f0ec59fd997a48e0631e 100644 --- a/smp-angular/src/app/service-group-edit/service-group-edit-controller.ts +++ b/smp-angular/src/app/service-group-edit/service-group-edit-controller.ts @@ -11,7 +11,8 @@ import {SearchTableEntity} from "../common/search-table/search-table-entity.mode export class ServiceGroupEditController implements SearchTableController { - compareSGProperties = ["extension", "users", "serviceGroupDomains"]; + compareUpdateSGProperties = ["extension", "users", "serviceGroupDomains"]; + compareNewSGProperties = ["participantScheme", "participantIdentifier", "", "extension", "users", "serviceGroupDomains"]; constructor(public dialog: MatDialog) { } @@ -92,19 +93,24 @@ export class ServiceGroupEditController implements SearchTableController { } isRecordChanged(oldModel, newModel): boolean { + // different set of properties to compare in case if new entry is reedited or already saved entry is reedited. + let propsToCompare = newModel.status === SearchTableEntityStatus.NEW ? + this.compareNewSGProperties : this.compareUpdateSGProperties; + // check if other properties were changed - let propSize = this.compareSGProperties.length; + let propSize = propsToCompare.length; for (let i = 0; i < propSize; i++) { - let property = this.compareSGProperties[i]; + let property = propsToCompare[i]; let isEqual = false; - if (property ==='users' - || property ==='serviceGroupDomains') { - isEqual = this.isEqualListByAttribute(newModel[property], oldModel[property], "id"); - }else { - isEqual = this.isEqual(newModel[property], oldModel[property]); + if (property === 'users') { + isEqual = this.isEqualListByAttribute(newModel[property], oldModel[property], "userId"); + } else if (property === 'serviceGroupDomains') { + isEqual = this.isEqualListByAttribute(newModel[property], oldModel[property], "domainCode"); + } else { + isEqual = this.isEqual(JSON.stringify(newModel[property]), JSON.stringify(oldModel[property])); } - console.log("Property: "+property+" new: " +newModel[property] + "old: " +oldModel[property] + " val: " + isEqual ); + console.log("Property: " + property + " new: " + JSON.stringify(newModel[property]) + "old: " + JSON.stringify(oldModel[property]) + " val: " + isEqual); if (!isEqual) { return true; // Property has changed } @@ -113,16 +119,16 @@ export class ServiceGroupEditController implements SearchTableController { } isEqualListByAttribute(array1, array2, compareByAttribute): boolean { - let result1 = array1.filter(function(o1){ + let result1 = array1.filter(function (o1) { // filter out (!) items in result2 - return !array2.some(function(o2){ + return !array2.some(function (o2) { return o1[compareByAttribute] === o2[compareByAttribute]; // unique id }); }); - let result2 = array2.filter(function(o1){ + let result2 = array2.filter(function (o1) { // filter out (!) items in result2 - return !array1.some(function(o2){ + return !array1.some(function (o2) { return o1[compareByAttribute] === o2[compareByAttribute]; // unique id }); }); diff --git a/smp-angular/src/app/service-group-edit/service-group-edit.component.ts b/smp-angular/src/app/service-group-edit/service-group-edit.component.ts index d9307336f0cc026c8e830b717c0f1ace5c96f793..44e51d3f607584fcdf9e21a6912241b00aafe827 100644 --- a/smp-angular/src/app/service-group-edit/service-group-edit.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-edit.component.ts @@ -144,7 +144,11 @@ export class ServiceGroupEditComponent implements OnInit, AfterViewInit, AfterVi let metadataRowNumber = serviceGroupRow.serviceMetadata.indexOf(metaDataRow); const formRef: MatDialogRef<any> = this.serviceGroupEditController.newMetadataDialog({ - data: {edit: true, serviceGroup: serviceGroupRow, metadata: metaDataRow} + data: { + edit: metaDataRow.status !== SearchTableEntityStatus.NEW, + serviceGroup: serviceGroupRow, + metadata: metaDataRow + } }); formRef.afterClosed().subscribe(result => { if (result) { @@ -160,7 +164,6 @@ export class ServiceGroupEditComponent implements OnInit, AfterViewInit, AfterVi ? SearchTableEntityStatus.UPDATED : metaDataRow; - metaDataRow.status = statusMetadata; metaDataRow = {...formRef.componentInstance.getCurrent()}; diff --git a/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts b/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts index 6e38137e0b520818a0774f67e6f11c819fc09229..b35b1981b1ddf95df5fde90e73a992bd924fc7dc 100644 --- a/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts +++ b/smp-angular/src/app/service-group-edit/service-group-metadata-dialog/service-group-metadata-dialog.component.ts @@ -46,9 +46,9 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { private fb: FormBuilder) { this.editMode = data.edit; - this.formTitle = this.editMode ? ServiceGroupMetadataDialogComponent.EDIT_MODE : ServiceGroupMetadataDialogComponent.NEW_MODE; + this.formTitle = !!data.metadata ? ServiceGroupMetadataDialogComponent.EDIT_MODE : ServiceGroupMetadataDialogComponent.NEW_MODE; this.currentServiceGroup = data.serviceGroup; - this.current = this.editMode + this.current = !!data.metadata ? { ...data.metadata, } @@ -91,7 +91,7 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { this.xmlServiceMetadataObserver.subscribe((res: ServiceMetadataEditRo) => { this.dialogForm.get('xmlContent').setValue(res.xmlContent); // store init xml to current value for change validation - this.current.xmlContent=res.xmlContent; + this.current.xmlContent = res.xmlContent; }); } @@ -117,11 +117,11 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { let request: ServiceMetadataValidationEditRo = { participantScheme: this.dialogForm.controls['participantScheme'].value, participantIdentifier: this.dialogForm.controls['participantIdentifier'].value, - documentIdentifierScheme: !this.dialogForm.controls['documentIdentifierScheme'].value?null: - this.dialogForm.controls['documentIdentifierScheme'].value, + documentIdentifierScheme: !this.dialogForm.controls['documentIdentifierScheme'].value ? null : + this.dialogForm.controls['documentIdentifierScheme'].value, documentIdentifier: this.dialogForm.controls['documentIdentifier'].value, xmlContent: this.dialogForm.controls['xmlContent'].value, - statusAction: this.editMode?SearchTableEntityStatus.UPDATED:SearchTableEntityStatus.NEW, + statusAction: this.editMode ? SearchTableEntityStatus.UPDATED : SearchTableEntityStatus.NEW, } // let validationObservable = this.http.post<ServiceMetadataValidationEditRo>(SmpConstants.REST_METADATA_VALIDATE, request); @@ -168,14 +168,13 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { } - - const formRef: MatDialogRef<any> = this.dialog.open(ServiceMetadataWizardDialogComponent,wizardInit); + const formRef: MatDialogRef<any> = this.dialog.open(ServiceMetadataWizardDialogComponent, wizardInit); formRef.afterClosed().subscribe(result => { if (result) { - let smw: ServiceMetadataWizardRo = formRef.componentInstance.getCurrent(); + let smw: ServiceMetadataWizardRo = formRef.componentInstance.getCurrent(); this.dialogForm.controls['xmlContent'].setValue(smw.contentXML); - if(!this.editMode){ + if (!this.editMode) { this.dialogForm.controls['documentIdentifierScheme'].setValue(smw.documentIdentifierScheme); this.dialogForm.controls['documentIdentifier'].setValue(smw.documentIdentifier); } @@ -185,21 +184,21 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { getParticipantElementXML(): string { let schema = this.dialogForm.controls['participantScheme'].value; - let value= this.dialogForm.controls['participantIdentifier'].value; + let value = this.dialogForm.controls['participantIdentifier'].value; if (!!schema && this.lookups.cachedApplicationConfig.concatEBCorePartyId && - schema.startsWith(ServiceMetadataWizardDialogComponent.EBCORE_IDENTIFIER_PREFIX) ) { - value = schema + ":" + value; - schema =null; + schema.startsWith(ServiceMetadataWizardDialogComponent.EBCORE_IDENTIFIER_PREFIX)) { + value = schema + ":" + value; + schema = null; } - return '<ParticipantIdentifier ' + - (!schema?'': 'scheme="' + this.xmlSpecialChars(schema) + '"')+ '>' - + this.xmlSpecialChars(value)+ '</ParticipantIdentifier>'; + return '<ParticipantIdentifier ' + + (!schema ? '' : 'scheme="' + this.xmlSpecialChars(schema) + '"') + '>' + + this.xmlSpecialChars(value) + '</ParticipantIdentifier>'; } getDocumentElementXML(): string { - return ' <DocumentIdentifier ' + - (!this.dialogForm.controls['documentIdentifierScheme'].value?'': 'scheme="' + return ' <DocumentIdentifier ' + + (!this.dialogForm.controls['documentIdentifierScheme'].value ? '' : 'scheme="' + this.xmlSpecialChars(this.dialogForm.controls['documentIdentifierScheme'].value) + '"') + '>' + this.xmlSpecialChars(this.dialogForm.controls['documentIdentifier'].value) + '</DocumentIdentifier>'; } @@ -228,7 +227,7 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { } xmlSpecialChars(unsafe) { - return !unsafe?'':unsafe + return !unsafe ? '' : unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") @@ -241,11 +240,11 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { participantScheme: this.dialogForm.controls['participantScheme'].value, participantIdentifier: this.dialogForm.controls['participantIdentifier'].value, - documentIdentifierScheme: !this.dialogForm.controls['documentIdentifierScheme'].value?null: + documentIdentifierScheme: !this.dialogForm.controls['documentIdentifierScheme'].value ? null : this.dialogForm.controls['documentIdentifierScheme'].value, documentIdentifier: this.dialogForm.controls['documentIdentifier'].value, xmlContent: this.dialogForm.controls['xmlContent'].value, - statusAction: this.editMode?SearchTableEntityStatus.UPDATED:SearchTableEntityStatus.NEW, + statusAction: this.editMode ? SearchTableEntityStatus.UPDATED : SearchTableEntityStatus.NEW, } // let validationObservable = this.http.post<ServiceMetadataValidationEditRo>(SmpConstants.REST_METADATA_VALIDATE, request); @@ -280,11 +279,12 @@ export class ServiceGroupMetadataDialogComponent implements OnInit { } //!! this two method must be called before getCurrent - public isMetaDataXMLChanged():boolean{ - return this.dialogForm.value['xmlContent'] !== this.current.xmlContent; + public isMetaDataXMLChanged(): boolean { + return this.dialogForm.value['xmlContent'] !== this.current.xmlContent; } - public isServiceMetaDataChanged():boolean{ - return this.isMetaDataXMLChanged() || !this.isEqual(this.current.domainCode, this.domainList.selected.value.domainCode) ; + + public isServiceMetaDataChanged(): boolean { + return this.isMetaDataXMLChanged() || !this.isEqual(this.current.domainCode, this.domainList.selected.value.domainCode); } compareDomainCode(sgDomain: ServiceGroupDomainEditRo, domainCode: String): boolean { diff --git a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts index 15c667989b38a191ad3c0193d734932818df7188..c6b327d9d4ebb5eefb4a618ea307262c356a7b9f 100644 --- a/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts +++ b/smp-angular/src/app/user/user-details-dialog/user-details-dialog.component.ts @@ -107,7 +107,7 @@ export class UserDetailsDialogComponent { this.userId = data.row && data.row.userId; this.editMode = this.mode !== UserDetailsDialogMode.NEW_MODE; - this.current = this.editMode + this.current = !!data.row ? { ...data.row, password: '', // ensures the user password is cleared before editing @@ -125,7 +125,6 @@ export class UserDetailsDialogComponent { status: SearchTableEntityStatus.NEW, statusPassword: SearchTableEntityStatus.NEW, certificate: this.newCertificateRo(), - }; const bSetPassword: boolean = false; @@ -143,7 +142,7 @@ export class UserDetailsDialogComponent { disabled: this.mode === UserDetailsDialogMode.PREFERENCES_MODE }, Validators.required), // username/password authentication - 'username': new FormControl({value: '', disabled: this.editMode }, + 'username': new FormControl({value: '', disabled: this.editMode}, !this.editMode || !this.current.username ? [Validators.nullValidator, Validators.pattern(this.usernamePattern), this.notInList(this.lookups.cachedServiceGroupOwnerList.map(a => a.username ? a.username.toLowerCase() : null))] : null), @@ -312,7 +311,7 @@ export class UserDetailsDialogComponent { } public getCurrent(): UserRo { - if (this.mode === UserDetailsDialogMode.NEW_MODE){ + if (this.mode === UserDetailsDialogMode.NEW_MODE) { this.current.username = this.userForm.get('username').value; } diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/SmpInfoRO.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/SmpInfoRO.java index 1d0d73a4077c00175e7068096cd3770a0ab8f7e8..52889dc13f1505fbd9e45c2878931c47f54583b4 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/SmpInfoRO.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/data/ui/SmpInfoRO.java @@ -6,6 +6,7 @@ import java.util.List; /** * Public SmpInfoRO properties. + * * @author Joze Rihtarsic * @since 4.1 */ @@ -15,7 +16,7 @@ public class SmpInfoRO implements Serializable { String ssoAuthenticationLabel; String ssoAuthenticationURI; String contextPath; - List<String> authTypes = new ArrayList<>();; + List<String> authTypes = new ArrayList<>(); public String getVersion() { return version; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java index 388e362bd53f2de839bb6b026ad00b49a2f830bc..d9b6e893b8fa433aeecb8455656a132f7a5e47e7 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupService.java @@ -25,7 +25,6 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ServiceMetadata; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -96,11 +95,11 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service sg.setCount(iCnt); if (iCnt > 0) { - int iStartIndex = pageSize<0?-1:page * pageSize; - if (iStartIndex >= iCnt && page > 0){ - page = page -1; + int iStartIndex = pageSize < 0 ? -1 : page * pageSize; + if (iStartIndex >= iCnt && page > 0) { + page = page - 1; sg.setPage(page); // go back for a page - iStartIndex = pageSize<0?-1:page * pageSize; + iStartIndex = pageSize < 0 ? -1 : page * pageSize; } List<DBServiceGroup> lst = serviceGroupDao.getServiceGroupList(iStartIndex, pageSize, sortField, sortOrder, filter); @@ -136,7 +135,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service return ex; } - private String getConvertExtensionToString(Long id, byte[] extension){ + private String getConvertExtensionToString(Long id, byte[] extension) { try { return new String(extension, "UTF-8"); } catch (UnsupportedEncodingException e) { @@ -169,34 +168,34 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service /** * Final process of SML records. If participant is to be unregistered it does not update status to database because * it should not be there anymore! For registering it update status! + * * @param lstRecords */ - public void processSMLRecords( List<ParticipantSMLRecord> lstRecords){ - if (!smlIntegrationService.isSMLIntegrationEnabled()){ + public void processSMLRecords(List<ParticipantSMLRecord> lstRecords) { + if (!smlIntegrationService.isSMLIntegrationEnabled()) { return; } - for (ParticipantSMLRecord record: lstRecords){ - if (record.getStatus()== SMLStatusEnum.REGISTER){ + for (ParticipantSMLRecord record : lstRecords) { + if (record.getStatus() == SMLStatusEnum.REGISTER) { boolean result = smlIntegrationService.registerParticipantToSML(record.getParticipantIdentifier(), record.getParticipantScheme(), record.getDomain()); updateServiceGroupDomainStatus(result, record); - }else if (record.getStatus()== SMLStatusEnum.UNREGISTER){ + } else if (record.getStatus() == SMLStatusEnum.UNREGISTER) { boolean result = smlIntegrationService.unregisterParticipantFromSML(record.getParticipantIdentifier(), record.getParticipantScheme(), record.getDomain()); // no need to update database because record is deleted updateServiceGroupDomainStatus(result, record); - } } } - protected void updateServiceGroupDomainStatus(boolean smlActionStatus, ParticipantSMLRecord record){ + protected void updateServiceGroupDomainStatus(boolean smlActionStatus, ParticipantSMLRecord record) { Optional<DBServiceGroupDomain> optionalServiceGroupDomain = serviceGroupDao.findServiceGroupDomain(record.getParticipantIdentifier(), record.getParticipantScheme(), record.getDomain().getDomainCode()); if (optionalServiceGroupDomain.isPresent()) { DBServiceGroupDomain serviceGroupDomain = optionalServiceGroupDomain.get(); - if (serviceGroupDomain.isSmlRegistered()!= smlActionStatus){ + if (serviceGroupDomain.isSmlRegistered() != smlActionStatus) { serviceGroupDomain.setSmlRegistered(smlActionStatus); serviceGroupDao.updateServiceGroupDomain(serviceGroupDomain); } @@ -206,25 +205,25 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service /** * Remove service group + * * @param dRo * @return */ - public List<ParticipantSMLRecord> removeServiceGroup(ServiceGroupRO dRo){ + public List<ParticipantSMLRecord> removeServiceGroup(ServiceGroupRO dRo) { List<ParticipantSMLRecord> participantSMLRecordList = new ArrayList<>(); DBServiceGroup dbServiceGroup = getDatabaseDao().find(dRo.getId()); // first update domains List<DBServiceGroupDomain> dbServiceGroupDomainList = dbServiceGroup.getServiceGroupDomains(); dbServiceGroupDomainList.forEach(dro -> { - participantSMLRecordList.add( new ParticipantSMLRecord(SMLStatusEnum.UNREGISTER, dro.getServiceGroup().getParticipantIdentifier(), - dro.getServiceGroup().getParticipantScheme(),dro.getDomain())); + participantSMLRecordList.add(new ParticipantSMLRecord(SMLStatusEnum.UNREGISTER, dro.getServiceGroup().getParticipantIdentifier(), + dro.getServiceGroup().getParticipantScheme(), dro.getDomain())); }); serviceGroupDao.removeServiceGroup(dbServiceGroup); return participantSMLRecordList; } - /** * Method validates and converts UI resource object entity to database entity and persists it to database * @@ -297,8 +296,8 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service // everything ok find domain and add it to service group Optional<DBDomain> dmn = domainDao.getDomainByCode(dro.getDomainCode()); if (dmn.isPresent()) { - DBServiceGroupDomain domain = dbServiceGroup.addDomain(dmn.get()); - participantSMLRecordList.add( new ParticipantSMLRecord(SMLStatusEnum.REGISTER, + DBServiceGroupDomain domain = dbServiceGroup.addDomain(dmn.get()); + participantSMLRecordList.add(new ParticipantSMLRecord(SMLStatusEnum.REGISTER, serviceGroupRO.getParticipantIdentifier(), serviceGroupRO.getParticipantScheme(), domain.getDomain())); @@ -326,7 +325,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service updateUsersOnServiceGroup(serviceGroupRO, dbServiceGroup); // update domain - List<ParticipantSMLRecord> participantSMLRecordList = updateDomainsForServiceGroup(serviceGroupRO, dbServiceGroup); + List<ParticipantSMLRecord> participantSMLRecordList = updateDomainsForServiceGroup(serviceGroupRO, dbServiceGroup); //update service metadata List<ServiceMetadataRO> serviceMetadataROList = serviceGroupRO.getServiceMetadata(); @@ -369,28 +368,27 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service if (!Objects.equals(serviceMetadataRO.getDomainCode(), dbServiceGroupDomain.getDomain().getDomainCode())) { // remove from old domain - LOG.info("Move service metadata from domain {} to domain: {}" , dbServiceGroupDomain.getDomain().getDomainCode(), - serviceMetadataRO.getDomainCode( )); + LOG.info("Move service metadata from domain {} to domain: {}", dbServiceGroupDomain.getDomain().getDomainCode(), + serviceMetadataRO.getDomainCode()); DBServiceMetadata smd = dbServiceGroupDomain.removeServiceMetadata(serviceMetadataRO.getDocumentIdentifier(), serviceMetadataRO.getDocumentIdentifierScheme()); - // find new domain and add Optional<DBServiceGroupDomain> optNewDomain = dbServiceGroup.getServiceGroupForDomain(serviceMetadataRO.getDomainCode()); if (optNewDomain.isPresent()) { - LOG.info("ADD service metadata to domain {} " , optNewDomain.get().getDomain().getDomainCode(), - serviceMetadataRO.getDomainCode( )); - // create new because the old service metadata will be deleted - DBServiceMetadata smdNew = new DBServiceMetadata(); - smdNew.setDocumentIdentifier(dbServiceMetadata.getDocumentIdentifier()); - smdNew.setDocumentIdentifierScheme(dbServiceMetadata.getDocumentIdentifierScheme()); - smdNew.setServiceGroupDomain(optNewDomain.get()); - smdNew.setServiceMetadataXml(dbServiceMetadata.getServiceMetadataXml()); - smdNew.setCreatedOn(dbServiceMetadata.getCreatedOn()); - - optNewDomain.get().addServiceMetadata(smdNew); + LOG.info("ADD service metadata to domain {} ", optNewDomain.get().getDomain().getDomainCode(), + serviceMetadataRO.getDomainCode()); + // create new because the old service metadata will be deleted + DBServiceMetadata smdNew = new DBServiceMetadata(); + smdNew.setDocumentIdentifier(dbServiceMetadata.getDocumentIdentifier()); + smdNew.setDocumentIdentifierScheme(dbServiceMetadata.getDocumentIdentifierScheme()); + smdNew.setServiceGroupDomain(optNewDomain.get()); + smdNew.setServiceMetadataXml(dbServiceMetadata.getServiceMetadataXml()); + smdNew.setCreatedOn(dbServiceMetadata.getCreatedOn()); + + optNewDomain.get().addServiceMetadata(smdNew); } else { throw new SMPRuntimeException(SG_NOT_REGISTRED_FOR_DOMAIN, serviceMetadataRO.getDomainCode(), @@ -448,8 +446,8 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service Optional<DBDomain> dmn = domainDao.getDomainByCode(serviceGroupDomainRO.getDomainCode()); if (dmn.isPresent()) { - DBServiceGroupDomain sgd = dbServiceGroup.addDomain(dmn.get()); - participantSMLRecordList.add(new ParticipantSMLRecord( SMLStatusEnum.REGISTER, + DBServiceGroupDomain sgd = dbServiceGroup.addDomain(dmn.get()); + participantSMLRecordList.add(new ParticipantSMLRecord(SMLStatusEnum.REGISTER, sgd.getServiceGroup().getParticipantIdentifier(), sgd.getServiceGroup().getParticipantScheme(), sgd.getDomain())); @@ -460,7 +458,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service }); // remove old domains lstOldSGDomains.forEach(dbServiceGroupDomain -> { - participantSMLRecordList.add(new ParticipantSMLRecord( SMLStatusEnum.UNREGISTER, + participantSMLRecordList.add(new ParticipantSMLRecord(SMLStatusEnum.UNREGISTER, dbServiceGroupDomain.getServiceGroup().getParticipantIdentifier(), dbServiceGroupDomain.getServiceGroup().getParticipantScheme(), dbServiceGroupDomain.getDomain())); @@ -486,7 +484,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service Optional<DBUser> optUser = userDao.findUser(userid); if (!optUser.isPresent()) { throw new SMPRuntimeException(INTERNAL_ERROR, - "Database changed", "User "+userRO.getUsername()+ " not exists! (Refresh data)"); + "Database changed", "User " + userRO.getUsername() + " not exists! (Refresh data)"); } dbServiceGroup.getUsers().add(optUser.get()); } @@ -505,7 +503,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service } // validate service group id boolean schemeMandatory = configurationService.getParticipantSchemeMandatory(); - LOG.debug("Validate service group [{}] with [{}] scheme", serviceGroupRO.getParticipantIdentifier(), (schemeMandatory?"mandatory":"optional")); + LOG.debug("Validate service group [{}] with [{}] scheme", serviceGroupRO.getParticipantIdentifier(), (schemeMandatory ? "mandatory" : "optional")); DBServiceGroup dbServiceGroup = getDatabaseDao().find(serviceGroupRO.getId()); @@ -539,7 +537,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service } ServiceMetadata smd = ServiceMetadataConverter.unmarshal(buff); - if (smd.getServiceInformation()!=null) { + if (smd.getServiceInformation() != null) { DocumentIdentifier di = caseSensitivityNormalizer.normalize(smd.getServiceInformation().getDocumentIdentifier()); if (Objects.equals(di.getScheme(), serviceMetadataRO.getDocumentIdentifierScheme()) && Objects.equals(di.getValue(), serviceMetadataRO.getDocumentIdentifier())) { @@ -619,7 +617,7 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service byte[] buff = validateServiceMetadata(serviceMetadataRO); DBServiceMetadata dbServiceMetadata = new DBServiceMetadata(); - DocumentIdentifier docIdent= caseSensitivityNormalizer.normalizeDocumentIdentifier(serviceMetadataRO.getDocumentIdentifierScheme(),serviceMetadataRO.getDocumentIdentifier() ); + DocumentIdentifier docIdent = caseSensitivityNormalizer.normalizeDocumentIdentifier(serviceMetadataRO.getDocumentIdentifierScheme(), serviceMetadataRO.getDocumentIdentifier()); dbServiceMetadata.setDocumentIdentifier(docIdent.getValue()); dbServiceMetadata.setDocumentIdentifierScheme(docIdent.getScheme()); dbServiceMetadata.setXmlContent(buff); @@ -661,14 +659,14 @@ public class UIServiceGroupService extends UIServiceBase<DBServiceGroup, Service throw new SMPRuntimeException(INVALID_REQUEST, "Validate extension", "Missing Extension parameter"); } // if new check if service group already exist - if (serviceGroup.getStatusAction() == EntityROStatus.NEW.getStatusNumber()){ + if (serviceGroup.getStatusAction() == EntityROStatus.NEW.getStatusNumber()) { ParticipantIdentifierType normalizedParticipant = caseSensitivityNormalizer.normalizeParticipantIdentifier( serviceGroup.getParticipantScheme(), serviceGroup.getParticipantIdentifier()); - Optional<DBServiceGroup> sg= serviceGroupDao.findServiceGroup(normalizedParticipant.getValue(), + Optional<DBServiceGroup> sg = serviceGroupDao.findServiceGroup(normalizedParticipant.getValue(), normalizedParticipant.getScheme()); if (sg.isPresent()) { - serviceGroup.setErrorMessage("Service group: " +serviceGroup.getParticipantScheme()+ ":"+serviceGroup.getParticipantIdentifier()+ + serviceGroup.setErrorMessage("Service group: " + serviceGroup.getParticipantScheme() + ":" + serviceGroup.getParticipantIdentifier() + " already exists!"); serviceGroup.setErrorCode(ERROR_CODE_SERVICE_GROUP_EXISTS); return serviceGroup; diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java index 278c2686947545ab456a7b5ad284540c8d15a095..7762b65c21074e2a6e7e8faff9364afa9f01a574 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UITruststoreService.java @@ -425,7 +425,6 @@ public class UITruststoreService { public String addCertificate(String alias, X509Certificate certificate) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException { KeyStore truststore = loadTruststore(getTruststoreFile()); - if (truststore != null) { String aliasPrivate = StringUtils.isBlank(alias) ? createAliasFromCert(certificate, truststore) : alias.trim(); diff --git a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java index 481581aeff534cecff7625dde021cb4a56f2fc27..3d5182446b7dc3014103d57c1e2b5c3dd9cdf551 100644 --- a/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java +++ b/smp-server-library/src/main/java/eu/europa/ec/edelivery/smp/services/ui/UIUserService.java @@ -192,55 +192,71 @@ public class UIUserService extends UIServiceBase<DBUser, UserRO> { LOG.error("Can not update user because user for id [{}] does not exist!", userId); throw new SMPRuntimeException(ErrorCode.INVALID_REQUEST, "UserId", "Can not find user id!"); } + // the only think what user can update now on user dat dbUser.setEmailAddress(user.getEmailAddress()); - if (user.getCertificate() != null && - (dbUser.getCertificate() == null - || !StringUtils.equals(dbUser.getCertificate().getCertificateId(), user.getCertificate().getCertificateId()))) { - - CertificateRO certRo = user.getCertificate(); - - if (dbUser.getCertificate() != null) { - dbUser.getCertificate().setCertificateId(certRo.getCertificateId()); - dbUser.getCertificate().setCrlUrl(certRo.getCrlUrl()); - dbUser.getCertificate().setPemEncoding(certRo.getEncodedValue()); - dbUser.getCertificate().setSubject(certRo.getSubject()); - dbUser.getCertificate().setIssuer(certRo.getIssuer()); - dbUser.getCertificate().setSerialNumber(certRo.getSerialNumber()); - if (certRo.getValidTo() != null) { - dbUser.getCertificate().setValidTo(certRo.getValidTo().toInstant() - .atOffset(ZoneOffset.UTC)); - } - if (certRo.getValidFrom() != null) { - dbUser.getCertificate().setValidFrom(certRo.getValidFrom().toInstant() - .atOffset(ZoneOffset.UTC)); - } - } else { - DBCertificate certificate = conversionService.convert(certRo, DBCertificate.class); - dbUser.setCertificate(certificate); - } + // update certificate + if (user.getCertificate() == null && dbUser.getCertificate() == null) { + return; + } - if (user.getCertificate().getEncodedValue() == null) { - LOG.debug("User has certificate data without certificate bytearray. "); - return; - } + // clear certificate data + if (user.getCertificate() == null || StringUtils.isBlank(user.getCertificate().getCertificateId())) { + dbUser.setCertificate(null); + LOG.info("Clear certificate credentials from the user [{}] with id [{}]", dbUser.getUsername(), dbUser.getId()); + return; + } - if (!configurationService.trustCertificateOnUserRegistration()) { - LOG.debug("User certificate is not automatically trusted! Certificate is not added to truststore!"); - return; - } + if (dbUser.getCertificate() != null && StringUtils.equals(dbUser.getCertificate().getCertificateId(), user.getCertificate().getCertificateId())) { + LOG.debug("Certificate id was not changed for the user [{}] with id [{}]. Skip updating the certificate data!", + dbUser.getCertificate().getCertificateId(), dbUser.getUsername(), dbUser.getId()); + return; + } - String certificateAlias; - try { - X509Certificate x509Certificate = X509CertificateUtils.getX509Certificate(Base64.getMimeDecoder().decode(certRo.getEncodedValue())); - certificateAlias = truststoreService.addCertificate(certRo.getAlias(), x509Certificate); - LOG.debug("User certificate is added to truststore!"); - } catch (NoSuchAlgorithmException | KeyStoreException | IOException | CertificateException e) { - LOG.error("Error occurred while adding certificate to truststore.", e); - throw new SMPRuntimeException(ErrorCode.INTERNAL_ERROR, "AddUserCertificate", ExceptionUtils.getRootCauseMessage(e)); + CertificateRO certRo = user.getCertificate(); + if (dbUser.getCertificate() == null) { + DBCertificate certificate = conversionService.convert(certRo, DBCertificate.class); + dbUser.setCertificate(certificate); + } else { + LOG.info("Update certificate credentials for user:"); + dbUser.getCertificate().setCertificateId(certRo.getCertificateId()); + dbUser.getCertificate().setCrlUrl(certRo.getCrlUrl()); + dbUser.getCertificate().setPemEncoding(certRo.getEncodedValue()); + dbUser.getCertificate().setSubject(certRo.getSubject()); + dbUser.getCertificate().setIssuer(certRo.getIssuer()); + dbUser.getCertificate().setSerialNumber(certRo.getSerialNumber()); + if (certRo.getValidTo() != null) { + dbUser.getCertificate().setValidTo(certRo.getValidTo().toInstant() + .atOffset(ZoneOffset.UTC)); + } + if (certRo.getValidFrom() != null) { + dbUser.getCertificate().setValidFrom(certRo.getValidFrom().toInstant() + .atOffset(ZoneOffset.UTC)); } - certRo.setAlias(certificateAlias); } + + if (user.getCertificate().getEncodedValue() == null) { + LOG.debug("User has certificate data without certificate bytearray. "); + return; + } + + if (!configurationService.trustCertificateOnUserRegistration()) { + LOG.debug("User certificate is not automatically trusted! Certificate is not added to truststore!"); + return; + } + + String certificateAlias; + try { + X509Certificate x509Certificate = X509CertificateUtils.getX509Certificate(Base64.getMimeDecoder().decode(certRo.getEncodedValue())); + + certificateAlias = truststoreService.addCertificate(certRo.getAlias(), x509Certificate); + LOG.debug("User certificate is added to truststore!"); + } catch (NoSuchAlgorithmException | KeyStoreException | IOException | CertificateException e) { + LOG.error("Error occurred while adding certificate to truststore.", e); + throw new SMPRuntimeException(ErrorCode.INTERNAL_ERROR, "AddUserCertificate", ExceptionUtils.getRootCauseMessage(e)); + } + certRo.setAlias(certificateAlias); + } protected void createOrUpdateUser(UserRO userRO, OffsetDateTime passwordChange) { diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java index 3b077ff86c14201aa470b2dd4397a07cffc5c807..39304d6f88761b6624209350edbf7296e6b632ec 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIUserServiceIntegrationTest.java @@ -434,7 +434,7 @@ public class UIUserServiceIntegrationTest extends AbstractServiceIntegrationTest CertificateRO certificateRO = TestROUtils.createCertificateRO(certSubject, BigInteger.TEN); UserRO userRO = new UserRO(); userRO.setCertificate(certificateRO); - ; + testInstance.updateUserdata(user.getId(), userRO); diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResource.java index e366a5508956d39bfd80db4c3214b6889f40b91b..f4b17af39678478adcfab6e67965722436cd059c 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/external/ApplicationResource.java @@ -1,6 +1,7 @@ package eu.europa.ec.edelivery.smp.ui.external; +import eu.europa.ec.edelivery.smp.auth.enums.SMPUserAuthenticationTypes; import eu.europa.ec.edelivery.smp.data.ui.SmpConfigRO; import eu.europa.ec.edelivery.smp.data.ui.SmpInfoRO; import eu.europa.ec.edelivery.smp.data.ui.auth.SMPAuthority; @@ -14,6 +15,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Collections; +import java.util.List; import java.util.TimeZone; /** @@ -52,8 +55,12 @@ public class ApplicationResource { public SmpInfoRO getApplicationInfo() { SmpInfoRO info = new SmpInfoRO(); info.setVersion(getDisplayVersion()); - info.addAuthTypes(configurationService.getUIAuthenticationTypes()); - if (configurationService.getUIAuthenticationTypes().contains("SSO")){ + List<String> authTypes = configurationService.getUIAuthenticationTypes(); + // set default password + authTypes = authTypes ==null || authTypes.isEmpty()? + Collections.singletonList(SMPUserAuthenticationTypes.PASSWORD.name()):authTypes; + info.addAuthTypes(authTypes); + if (authTypes.contains(SMPUserAuthenticationTypes.SSO.name())){ info.setSsoAuthenticationLabel(configurationService.getCasUILabel()); info.setSsoAuthenticationURI(configurationService.getCasSMPLoginRelativePath()); }