From bd1deb701a1ee6daa7ec68fdb4a9606db1f8bfb5 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Wed, 9 Jul 2025 00:00:54 +0200 Subject: [PATCH 01/11] WIP --- .../commons/constants/BootstrAPI.java | 4 +- .../commons/model/AbstractDirectoryModel.java | 3 + .../commons/model/type/_AllModelStatus.java | 33 +++++ .../rest/_AbstractAllResourceImpl.java | 24 ++++ .../commons/rest/api/_AllResource.java | 34 +++++ .../service/_AbstractAllServiceImpl.java | 59 +++++++++ .../commons/service/api/_AllService.java | 14 ++ confluence/Apis/AllApi.md | 34 +++++ confluence/Models/AbstractDirectoryModel.md | 2 +- confluence/Models/DirectoryCrowdModel.md | 2 +- confluence/Models/DirectoryDelegatingModel.md | 2 +- confluence/Models/DirectoryGenericModel.md | 2 +- confluence/Models/DirectoryInternalModel.md | 2 +- confluence/Models/DirectoryLdapModel.md | 2 +- confluence/Models/_AllModel.md | 12 ++ confluence/Models/_AllModelStatus.md | 11 ++ confluence/README.md | 3 + .../confluence/model/_AllModel.java | 33 +++++ .../confluence/rest/_AllResourceImpl.java | 28 ++++ crowd/Apis/AllApi.md | 34 +++++ crowd/Models/AbstractDirectoryModel.md | 2 +- crowd/Models/DirectoryCrowdModel.md | 2 +- crowd/Models/DirectoryDelegatingModel.md | 2 +- crowd/Models/DirectoryGenericModel.md | 2 +- crowd/Models/DirectoryInternalModel.md | 2 +- crowd/Models/DirectoryLdapModel.md | 2 +- crowd/Models/_AllModel.md | 12 ++ crowd/Models/_AllModelStatus.md | 11 ++ crowd/README.md | 3 + .../crowd/config/ServiceConfig.java | 9 ++ .../bootstrapi/crowd/model/AllModel.java | 26 ---- .../bootstrapi/crowd/model/_AllModel.java | 33 +++++ .../crowd/rest/_AllResourceImpl.java | 28 ++++ .../crowd/service/_AllServiceImpl.java | 125 ++++++++++++++++++ .../crowd/service/api/AllService.java | 10 -- .../crowd/rest/AllResourceTest.java | 64 +++++++++ .../crowd/service/DirectoriesServiceTest.java | 1 - jira/Apis/AllApi.md | 34 +++++ jira/Models/AbstractDirectoryModel.md | 2 +- jira/Models/DirectoryCrowdModel.md | 2 +- jira/Models/DirectoryDelegatingModel.md | 2 +- jira/Models/DirectoryGenericModel.md | 2 +- jira/Models/DirectoryInternalModel.md | 2 +- jira/Models/DirectoryLdapModel.md | 2 +- jira/Models/_AllModel.md | 12 ++ jira/Models/_AllModelStatus.md | 11 ++ jira/README.md | 3 + .../bootstrapi/jira/model/_AllModel.java | 34 +++++ .../jira/rest/_AllResourceImpl.java | 28 ++++ 49 files changed, 750 insertions(+), 56 deletions(-) create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java create mode 100644 confluence/Apis/AllApi.md create mode 100644 confluence/Models/_AllModel.md create mode 100644 confluence/Models/_AllModelStatus.md create mode 100644 confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java create mode 100644 confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceImpl.java create mode 100644 crowd/Apis/AllApi.md create mode 100644 crowd/Models/_AllModel.md create mode 100644 crowd/Models/_AllModelStatus.md delete mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/AllModel.java create mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java create mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceImpl.java create mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java delete mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/AllService.java create mode 100644 crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java create mode 100644 jira/Apis/AllApi.md create mode 100644 jira/Models/_AllModel.md create mode 100644 jira/Models/_AllModelStatus.md create mode 100644 jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java create mode 100644 jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceImpl.java diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java index 644ae427..0578727b 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java @@ -2,7 +2,9 @@ public class BootstrAPI { - public static final String ALL = "all"; + public static final String _ALL = "_all"; + public static final String _ROOT = "/"; + public static final String APPLICATION = "application"; public static final String APPLICATIONS = "applications"; public static final String APPLICATION_LINK = "application-link"; diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java index 19e534a4..a9050606 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java @@ -61,4 +61,7 @@ public abstract class AbstractDirectoryModel { @XmlElement private Date updatedDate; + @XmlElement + private Boolean testConnection; + } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java new file mode 100644 index 00000000..8dfcc8f0 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java @@ -0,0 +1,33 @@ +package com.deftdevs.bootstrapi.commons.model.type; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.ws.rs.core.Response; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = "status") +public class _AllModelStatus { + + @XmlElement + private int status; + + @XmlElement + private String message; + + @XmlElement + private String details; + + public static _AllModelStatus success() { + return new _AllModelStatus(Response.Status.OK.getStatusCode(), "Success", null); + } + + public static _AllModelStatus error(Response.Status status, String message, String details) { + return new _AllModelStatus(status.getStatusCode(), message, details); + } +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java new file mode 100644 index 00000000..c1b6d948 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java @@ -0,0 +1,24 @@ +package com.deftdevs.bootstrapi.commons.rest; + +import com.deftdevs.bootstrapi.commons.rest.api._AllResource; +import com.deftdevs.bootstrapi.commons.service.api._AllService; + +import javax.ws.rs.core.Response; + +public abstract class _AbstractAllResourceImpl<_AllModel> + implements _AllResource<_AllModel> { + + private final _AllService<_AllModel> allService; + + public _AbstractAllResourceImpl( + final _AllService<_AllModel> allService) { + + this.allService = allService; + } + + public Response setAll( + final _AllModel allModel) { + + return Response.ok(allService.setAll(allModel)).build(); + } +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java new file mode 100644 index 00000000..7b548d35 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java @@ -0,0 +1,34 @@ +package com.deftdevs.bootstrapi.commons.rest.api; + +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.model.ErrorCollection; +import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; + +import javax.validation.constraints.NotNull; +import javax.ws.rs.PUT; +import javax.ws.rs.core.Response; + +public interface _AllResource<_AllModel> { + + @PUT + @Operation( + summary = BootstrAPI._ALL, + responses = { + @ApiResponse( + responseCode = "200", content = @Content(schema = @Schema(implementation = SettingsModel.class)), + description = BootstrAPI._ALL + ), + @ApiResponse( + responseCode = "default", content = @Content(schema = @Schema(implementation = ErrorCollection.class)), + description = BootstrAPI._ALL + ), + } + ) + Response setAll( + @NotNull final _AllModel bean); + +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java new file mode 100644 index 00000000..da63c299 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -0,0 +1,59 @@ +package com.deftdevs.bootstrapi.commons.service; + +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service.api._AllService; + +import javax.ws.rs.core.Response; +import java.util.Map; +import java.util.function.Consumer; +import java.util.function.Function; + +public abstract class _AbstractAllServiceImpl<_A> implements _AllService<_A> { + + protected _AllModelStatus setEntity( + final T entity, + final Function updateFunction, + final Consumer resultConsumer) { + + if (entity == null) { + return null; + } + + try { + final T updatedEntity = updateFunction.apply(entity); + resultConsumer.accept(updatedEntity); + return _AllModelStatus.success(); + } catch (Exception e) { + return _AllModelStatus.error( + Response.Status.INTERNAL_SERVER_ERROR, + "Failed to apply ...", + e.getMessage() + ); + } + } + + @SuppressWarnings("unchecked") + protected _AllModelStatus setEntities( + final Map entityMap, + final Function getIdentifier, + final Function, Map> updateFunction, + final Consumer> resultConsumer) { + + if (entityMap == null || entityMap.isEmpty()) { + return null; + } + + try { + final Map updatedEntities = updateFunction.apply(entityMap); + resultConsumer.accept((Map) updatedEntities); + return _AllModelStatus.success(); + } catch (Exception e) { + return _AllModelStatus.error( + Response.Status.INTERNAL_SERVER_ERROR, + "Failed to apply ...", + e.getMessage() + ); + } + } + +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java new file mode 100644 index 00000000..61adc85f --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java @@ -0,0 +1,14 @@ +package com.deftdevs.bootstrapi.commons.service.api; + +public interface _AllService<_AllModel> { + + /** + * Apply a complete configuration. + * + * @param allModel the configuration to apply + * @return the updated configuration with status + */ + _AllModel setAll( + _AllModel allModel); + +} diff --git a/confluence/Apis/AllApi.md b/confluence/Apis/AllApi.md new file mode 100644 index 00000000..99f0bab6 --- /dev/null +++ b/confluence/Apis/AllApi.md @@ -0,0 +1,34 @@ +# AllApi + +All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**setAll**](AllApi.md#setAll) | **PUT** / | _all | + + + +# **setAll** +> SettingsModel setAll(\_AllModel) + +_all + +### Parameters + +|Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **\_AllModel** | [**_AllModel**](../Models/_AllModel.md)| | | + +### Return type + +[**SettingsModel**](../Models/SettingsModel.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + diff --git a/confluence/Models/AbstractDirectoryModel.md b/confluence/Models/AbstractDirectoryModel.md index 7ef166ee..cde79f6a 100644 --- a/confluence/Models/AbstractDirectoryModel.md +++ b/confluence/Models/AbstractDirectoryModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **connector** | [**DirectoryDelegatingConnector**](DirectoryDelegatingConnector.md) | | [optional] [default to null] | | **configuration** | [**DirectoryDelegatingConfiguration**](DirectoryDelegatingConfiguration.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryCrowdModel.md b/confluence/Models/DirectoryCrowdModel.md index 655455e4..d58a9ad3 100644 --- a/confluence/Models/DirectoryCrowdModel.md +++ b/confluence/Models/DirectoryCrowdModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryCrowdServer**](DirectoryCrowdServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryCrowdPermissions**](DirectoryCrowdPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryCrowdAdvanced**](DirectoryCrowdAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryDelegatingModel.md b/confluence/Models/DirectoryDelegatingModel.md index 241e45d1..01c3480b 100644 --- a/confluence/Models/DirectoryDelegatingModel.md +++ b/confluence/Models/DirectoryDelegatingModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryGenericModel.md b/confluence/Models/DirectoryGenericModel.md index ec59bab6..71c67548 100644 --- a/confluence/Models/DirectoryGenericModel.md +++ b/confluence/Models/DirectoryGenericModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryInternalModel.md b/confluence/Models/DirectoryInternalModel.md index 472b0c05..2ccbe759 100644 --- a/confluence/Models/DirectoryInternalModel.md +++ b/confluence/Models/DirectoryInternalModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryLdapModel.md b/confluence/Models/DirectoryLdapModel.md index c5c48bfe..97eb576e 100644 --- a/confluence/Models/DirectoryLdapModel.md +++ b/confluence/Models/DirectoryLdapModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/_AllModel.md b/confluence/Models/_AllModel.md new file mode 100644 index 00000000..34153397 --- /dev/null +++ b/confluence/Models/_AllModel.md @@ -0,0 +1,12 @@ +# _AllModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **settings** | [**SettingsModel**](SettingsModel.md) | | [optional] [default to null] | +| **users** | [**Map**](UserModel.md) | | [optional] [default to null] | +| **groups** | [**Map**](GroupModel.md) | | [optional] [default to null] | +| **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/confluence/Models/_AllModelStatus.md b/confluence/Models/_AllModelStatus.md new file mode 100644 index 00000000..ed699765 --- /dev/null +++ b/confluence/Models/_AllModelStatus.md @@ -0,0 +1,11 @@ +# _AllModelStatus +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **status** | **Integer** | | [optional] [default to null] | +| **message** | **String** | | [optional] [default to null] | +| **details** | **String** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/confluence/README.md b/confluence/README.md index fe3bab2e..2b15d90f 100644 --- a/confluence/README.md +++ b/confluence/README.md @@ -7,6 +7,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| +| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | _all | | *ApplicationLinkApi* | [**createApplicationLink**](Apis/ApplicationLinkApi.md#createApplicationLink) | **POST** /application-link | Create an application link | *ApplicationLinkApi* | [**deleteApplicationLink**](Apis/ApplicationLinkApi.md#deleteApplicationLink) | **DELETE** /application-link/{uuid} | Delete an application link | *ApplicationLinkApi* | [**getApplicationLink**](Apis/ApplicationLinkApi.md#getApplicationLink) | **GET** /application-link/{uuid} | Get an application link | @@ -94,6 +95,8 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* - [SettingsModel](./Models/SettingsModel.md) - [SettingsSecurityModel](./Models/SettingsSecurityModel.md) - [UserModel](./Models/UserModel.md) + - [_AllModel](./Models/_AllModel.md) + - [_AllModelStatus](./Models/_AllModelStatus.md) diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java new file mode 100644 index 00000000..60641c97 --- /dev/null +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java @@ -0,0 +1,33 @@ +package com.deftdevs.bootstrapi.confluence.model; + +import com.deftdevs.bootstrapi.commons.model.GroupModel; +import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.UserModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = "all") +public class _AllModel { + + @XmlElement + private SettingsModel settings; + + @XmlElement + private Map users; + + @XmlElement + private Map groups; + + @XmlElement + private Map status; + +} diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceImpl.java new file mode 100644 index 00000000..8ba18e21 --- /dev/null +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceImpl.java @@ -0,0 +1,28 @@ +package com.deftdevs.bootstrapi.confluence.rest; + +import com.atlassian.plugins.rest.api.security.annotation.SystemAdminOnly; +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.rest._AbstractAllResourceImpl; +import com.deftdevs.bootstrapi.commons.service.api._AllService; +import com.deftdevs.bootstrapi.confluence.model._AllModel; +import io.swagger.v3.oas.annotations.tags.Tag; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path(BootstrAPI._ROOT) +@Tag(name = BootstrAPI._ALL) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@SystemAdminOnly +public class _AllResourceImpl extends _AbstractAllResourceImpl<_AllModel> { + + public _AllResourceImpl( + final _AllService<_AllModel> allService) { + + super(allService); + } + +} diff --git a/crowd/Apis/AllApi.md b/crowd/Apis/AllApi.md new file mode 100644 index 00000000..e5c536e4 --- /dev/null +++ b/crowd/Apis/AllApi.md @@ -0,0 +1,34 @@ +# AllApi + +All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**setAll**](AllApi.md#setAll) | **PUT** / | _all | + + + +# **setAll** +> SettingsModel setAll(\_AllModel) + +_all + +### Parameters + +|Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **\_AllModel** | [**_AllModel**](../Models/_AllModel.md)| | | + +### Return type + +[**SettingsModel**](../Models/SettingsModel.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + diff --git a/crowd/Models/AbstractDirectoryModel.md b/crowd/Models/AbstractDirectoryModel.md index 7ef166ee..cde79f6a 100644 --- a/crowd/Models/AbstractDirectoryModel.md +++ b/crowd/Models/AbstractDirectoryModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **connector** | [**DirectoryDelegatingConnector**](DirectoryDelegatingConnector.md) | | [optional] [default to null] | | **configuration** | [**DirectoryDelegatingConfiguration**](DirectoryDelegatingConfiguration.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryCrowdModel.md b/crowd/Models/DirectoryCrowdModel.md index 655455e4..d58a9ad3 100644 --- a/crowd/Models/DirectoryCrowdModel.md +++ b/crowd/Models/DirectoryCrowdModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryCrowdServer**](DirectoryCrowdServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryCrowdPermissions**](DirectoryCrowdPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryCrowdAdvanced**](DirectoryCrowdAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryDelegatingModel.md b/crowd/Models/DirectoryDelegatingModel.md index 241e45d1..01c3480b 100644 --- a/crowd/Models/DirectoryDelegatingModel.md +++ b/crowd/Models/DirectoryDelegatingModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryGenericModel.md b/crowd/Models/DirectoryGenericModel.md index ec59bab6..71c67548 100644 --- a/crowd/Models/DirectoryGenericModel.md +++ b/crowd/Models/DirectoryGenericModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryInternalModel.md b/crowd/Models/DirectoryInternalModel.md index 472b0c05..2ccbe759 100644 --- a/crowd/Models/DirectoryInternalModel.md +++ b/crowd/Models/DirectoryInternalModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryLdapModel.md b/crowd/Models/DirectoryLdapModel.md index c5c48bfe..97eb576e 100644 --- a/crowd/Models/DirectoryLdapModel.md +++ b/crowd/Models/DirectoryLdapModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/_AllModel.md b/crowd/Models/_AllModel.md new file mode 100644 index 00000000..c7e7c5d1 --- /dev/null +++ b/crowd/Models/_AllModel.md @@ -0,0 +1,12 @@ +# _AllModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **settings** | [**SettingsModel**](SettingsModel.md) | | [optional] [default to null] | +| **applications** | [**Map**](ApplicationModel.md) | | [optional] [default to null] | +| **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | +| **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/crowd/Models/_AllModelStatus.md b/crowd/Models/_AllModelStatus.md new file mode 100644 index 00000000..ed699765 --- /dev/null +++ b/crowd/Models/_AllModelStatus.md @@ -0,0 +1,11 @@ +# _AllModelStatus +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **status** | **Integer** | | [optional] [default to null] | +| **message** | **String** | | [optional] [default to null] | +| **details** | **String** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/crowd/README.md b/crowd/README.md index fddb0417..b78b7fd1 100644 --- a/crowd/README.md +++ b/crowd/README.md @@ -7,6 +7,7 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| +| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | _all | | *ApplicationApi* | [**createApplication**](Apis/ApplicationApi.md#createApplication) | **POST** /application | Create an application | *ApplicationApi* | [**deleteApplication**](Apis/ApplicationApi.md#deleteApplication) | **DELETE** /application/{id} | Delete an application | *ApplicationApi* | [**getApplication**](Apis/ApplicationApi.md#getApplication) | **GET** /application/{id} | Get an application | @@ -89,6 +90,8 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* - [SettingsBrandingLoginPageModel](./Models/SettingsBrandingLoginPageModel.md) - [SettingsModel](./Models/SettingsModel.md) - [UserModel](./Models/UserModel.md) + - [_AllModel](./Models/_AllModel.md) + - [_AllModelStatus](./Models/_AllModelStatus.md) diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java index 8528fb6b..13b82256 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java @@ -1,6 +1,7 @@ package com.deftdevs.bootstrapi.crowd.config; import com.deftdevs.bootstrapi.commons.service.api.*; +import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.*; import com.deftdevs.bootstrapi.crowd.service.api.*; import org.springframework.beans.factory.annotation.Autowired; @@ -16,6 +17,14 @@ public class ServiceConfig { @Autowired private HelperConfig helperConfig; + @Bean + public _AllService<_AllModel> _allService() { + return new _AllServiceImpl( + crowdSettingsGeneralService(), + directoriesService(), + applicationsService()); + } + @Bean public ApplicationLinksService applicationLinksService() { return new ApplicationLinksServiceImpl( diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/AllModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/AllModel.java deleted file mode 100644 index 94eb5694..00000000 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/AllModel.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.deftdevs.bootstrapi.crowd.model; - -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.Builder; -import lombok.NoArgsConstructor; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.List; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@XmlRootElement(name = "all") -public class AllModel { - - @XmlElement - private SettingsModel settings; - - @XmlElement - private List applications; - -} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java new file mode 100644 index 00000000..2c2e43ff --- /dev/null +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java @@ -0,0 +1,33 @@ +package com.deftdevs.bootstrapi.crowd.model; + +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; +import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = BootstrAPI._ALL) +public class _AllModel { + + @XmlElement + private SettingsModel settings; + + @XmlElement + private Map applications; + + @XmlElement + private Map directories; + + @XmlElement + private Map status; + +} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceImpl.java new file mode 100644 index 00000000..b2d0ee92 --- /dev/null +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceImpl.java @@ -0,0 +1,28 @@ +package com.deftdevs.bootstrapi.crowd.rest; + +import com.atlassian.plugins.rest.api.security.annotation.SystemAdminOnly; +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.rest._AbstractAllResourceImpl; +import com.deftdevs.bootstrapi.commons.service.api._AllService; +import com.deftdevs.bootstrapi.crowd.model._AllModel; +import io.swagger.v3.oas.annotations.tags.Tag; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path(BootstrAPI._ROOT) +@Tag(name = BootstrAPI._ALL) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@SystemAdminOnly +public class _AllResourceImpl extends _AbstractAllResourceImpl<_AllModel> { + + public _AllResourceImpl( + final _AllService<_AllModel> allService) { + + super(allService); + } + +} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java new file mode 100644 index 00000000..201db601 --- /dev/null +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -0,0 +1,125 @@ +package com.deftdevs.bootstrapi.crowd.service; + +import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; +import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; +import com.deftdevs.bootstrapi.crowd.model.ApplicationModel; +import com.deftdevs.bootstrapi.crowd.model._AllModel; +import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; +import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; + +import javax.ws.rs.core.Response; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import java.util.function.Function; + +public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { + + private final CrowdSettingsGeneralService settingsService; + private final DirectoriesService directoriesService; + private final ApplicationsService applicationsService; + + public _AllServiceImpl( + final CrowdSettingsGeneralService settingsService, + final DirectoriesService directoriesService, + final ApplicationsService applicationsService) { + + this.settingsService = settingsService; + this.directoriesService = directoriesService; + this.applicationsService = applicationsService; + } + + @Override + public _AllModel setAll( + final _AllModel allModel) { + + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + + setEntity(allModel.getSettings(), settingsService::setSettingsGeneral, result::setSettings); + + setEntities(allModel.getDirectories(), AbstractDirectoryModel::getName, directoriesService::setDirectories, result::setDirectories); + + setEntities(allModel.getApplications(), ApplicationModel::getName, applicationsService::setApplications, result::setApplications); + +// // Process entities using a generic handler +// processEntities(allModel.getGroups(), "groups", GroupModel::getName, GroupsService::setGroups, result::setGroups, status); +// +// processEntities(allModel.getUsers(), "users", UserModel::getUsername, +// users -> usersService.setUsers(1L, users), result::setUsers, status); +// +// processEntities(allModel.getApplications(), "applications", ApplicationModel::getName, +// applicationsService::setApplications, result::setApplications, status); + + result.setStatus(status); + return result; + } + + private void processEntities( + Map entityMap, + String entityType, + Function getIdentifier, + Function, List> updateFunction, + BiFunction, _AllModel, _AllModel> resultSetter, + Map status) { + + if (entityMap == null || entityMap.isEmpty()) { + return; + } + + try { + // Validate entity identifiers + for (Map.Entry entry : entityMap.entrySet()) { + String key = entry.getKey(); + T entity = entry.getValue(); + String identifier = getIdentifier.apply(entity); + + if (identifier == null) { + // Try to set the key as the identifier using reflection + try { + entity.getClass().getMethod("set" + entityType.substring(0, 1).toUpperCase() + + entityType.substring(1, entityType.length() - 1), String.class) + .invoke(entity, key); + } catch (Exception e) { + // If reflection fails, report the error + status.put(entityType, _AllModelStatus.error( + Response.Status.BAD_REQUEST, + entityType + " identifier missing", + "Could not set identifier for key: " + key + )); + return; + } + } else if (!key.equals(identifier)) { + status.put(entityType, _AllModelStatus.error( + Response.Status.BAD_REQUEST, + entityType.substring(0, 1).toUpperCase() + entityType.substring(1) + " identifier mismatch", + String.format("Map key '%s' does not match %s '%s'", key, entityType.substring(0, entityType.length() - 1), identifier) + )); + return; + } + } + + if (!status.containsKey(entityType)) { + List entityList = new ArrayList<>(entityMap.values()); + List updatedEntities = updateFunction.apply(entityList); + + Map resultMap = new HashMap<>(); + for (T entity : updatedEntities) { + resultMap.put(getIdentifier.apply(entity), entity); + } + resultSetter.apply(resultMap, null); + status.put(entityType, _AllModelStatus.success()); + } + } catch (Exception e) { + status.put(entityType, _AllModelStatus.error( + Response.Status.BAD_REQUEST, + "Failed to apply " + entityType + " configuration", + e.getMessage() + )); + } + } +} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/AllService.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/AllService.java deleted file mode 100644 index 71e5a090..00000000 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/AllService.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.deftdevs.bootstrapi.crowd.service.api; - -import com.deftdevs.bootstrapi.crowd.model.AllModel; - -public interface AllService { - - void setAll( - AllModel allModel); - -} diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java new file mode 100644 index 00000000..2ef1d69c --- /dev/null +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java @@ -0,0 +1,64 @@ +package com.deftdevs.bootstrapi.crowd.rest; + +import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.crowd.model.ApplicationModel; +import com.deftdevs.bootstrapi.crowd.model._AllModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service.api._AllService; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.ws.rs.core.Response; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class AllResourceTest { + + @Mock + private _AllService<_AllModel> allService; + + private _AllResourceImpl configurationResource; + + private _AllModel allModel; + + @BeforeEach + public void setup() { + configurationResource = new _AllResourceImpl(allService); + + // Setup test data + allModel = new _AllModel(); + allModel.setSettings(SettingsModel.EXAMPLE_1); + + // Setup applications map + Map applications = new HashMap<>(); + applications.put(ApplicationModel.EXAMPLE_1.getName(), ApplicationModel.EXAMPLE_1); + allModel.setApplications(applications); + + Map status = new HashMap<>(); + status.put("settings", _AllModelStatus.success()); + status.put("users", _AllModelStatus.success()); + status.put("groups", _AllModelStatus.success()); + status.put("applications", _AllModelStatus.success()); + allModel.setStatus(status); + } + + @Test + public void testSetConfiguration() { + doReturn(allModel).when(allService).setAll(any()); + + Response response = configurationResource.setAll(allModel); + assertEquals(200, response.getStatus()); + + _AllModel responseModel = (_AllModel) response.getEntity(); + assertEquals(allModel, responseModel); + + verify(allService).setAll(allModel); + } +} diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/DirectoriesServiceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/DirectoriesServiceTest.java index 4fcf66ca..9f89f027 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/DirectoriesServiceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/DirectoriesServiceTest.java @@ -139,7 +139,6 @@ public void testSetDirectoriesAddNewUnsupportedType() { final AbstractDirectoryModel directoryModel = DirectoryModelUtil.toDirectoryModel(directoryAzureAd); final Map directoryModels = Collections.singletonMap(directoryModel.getName(), directoryModel); - final boolean testConnection = false; assertThrows(BadRequestException.class, () -> { spy.setDirectories(directoryModels); diff --git a/jira/Apis/AllApi.md b/jira/Apis/AllApi.md new file mode 100644 index 00000000..83d417e4 --- /dev/null +++ b/jira/Apis/AllApi.md @@ -0,0 +1,34 @@ +# AllApi + +All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* + +| Method | HTTP request | Description | +|------------- | ------------- | -------------| +| [**setAll**](AllApi.md#setAll) | **PUT** / | _all | + + + +# **setAll** +> SettingsModel setAll(\_AllModel) + +_all + +### Parameters + +|Name | Type | Description | Notes | +|------------- | ------------- | ------------- | -------------| +| **\_AllModel** | [**_AllModel**](../Models/_AllModel.md)| | | + +### Return type + +[**SettingsModel**](../Models/SettingsModel.md) + +### Authorization + +[basicAuth](../README.md#basicAuth) + +### HTTP request headers + +- **Content-Type**: application/json +- **Accept**: application/json + diff --git a/jira/Models/AbstractDirectoryModel.md b/jira/Models/AbstractDirectoryModel.md index 7ef166ee..cde79f6a 100644 --- a/jira/Models/AbstractDirectoryModel.md +++ b/jira/Models/AbstractDirectoryModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **connector** | [**DirectoryDelegatingConnector**](DirectoryDelegatingConnector.md) | | [optional] [default to null] | | **configuration** | [**DirectoryDelegatingConfiguration**](DirectoryDelegatingConfiguration.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryCrowdModel.md b/jira/Models/DirectoryCrowdModel.md index 655455e4..d58a9ad3 100644 --- a/jira/Models/DirectoryCrowdModel.md +++ b/jira/Models/DirectoryCrowdModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryCrowdServer**](DirectoryCrowdServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryCrowdPermissions**](DirectoryCrowdPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryCrowdAdvanced**](DirectoryCrowdAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryDelegatingModel.md b/jira/Models/DirectoryDelegatingModel.md index 241e45d1..01c3480b 100644 --- a/jira/Models/DirectoryDelegatingModel.md +++ b/jira/Models/DirectoryDelegatingModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryGenericModel.md b/jira/Models/DirectoryGenericModel.md index ec59bab6..71c67548 100644 --- a/jira/Models/DirectoryGenericModel.md +++ b/jira/Models/DirectoryGenericModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryInternalModel.md b/jira/Models/DirectoryInternalModel.md index 472b0c05..2ccbe759 100644 --- a/jira/Models/DirectoryInternalModel.md +++ b/jira/Models/DirectoryInternalModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryLdapModel.md b/jira/Models/DirectoryLdapModel.md index c5c48bfe..97eb576e 100644 --- a/jira/Models/DirectoryLdapModel.md +++ b/jira/Models/DirectoryLdapModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **type** | **String** | | [default to null] | | **testConnection** | **Boolean** | | [optional] [default to null] | +| **type** | **String** | | [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/_AllModel.md b/jira/Models/_AllModel.md new file mode 100644 index 00000000..34153397 --- /dev/null +++ b/jira/Models/_AllModel.md @@ -0,0 +1,12 @@ +# _AllModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **settings** | [**SettingsModel**](SettingsModel.md) | | [optional] [default to null] | +| **users** | [**Map**](UserModel.md) | | [optional] [default to null] | +| **groups** | [**Map**](GroupModel.md) | | [optional] [default to null] | +| **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/jira/Models/_AllModelStatus.md b/jira/Models/_AllModelStatus.md new file mode 100644 index 00000000..ed699765 --- /dev/null +++ b/jira/Models/_AllModelStatus.md @@ -0,0 +1,11 @@ +# _AllModelStatus +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **status** | **Integer** | | [optional] [default to null] | +| **message** | **String** | | [optional] [default to null] | +| **details** | **String** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/jira/README.md b/jira/README.md index 70f20fbf..ebb27321 100644 --- a/jira/README.md +++ b/jira/README.md @@ -7,6 +7,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| +| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | _all | | *ApplicationLinkApi* | [**createApplicationLink**](Apis/ApplicationLinkApi.md#createApplicationLink) | **POST** /application-link | Create an application link | *ApplicationLinkApi* | [**deleteApplicationLink**](Apis/ApplicationLinkApi.md#deleteApplicationLink) | **DELETE** /application-link/{uuid} | Delete an application link | *ApplicationLinkApi* | [**getApplicationLink**](Apis/ApplicationLinkApi.md#getApplicationLink) | **GET** /application-link/{uuid} | Get an application link | @@ -79,6 +80,8 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* - [SettingsModel](./Models/SettingsModel.md) - [SettingsSecurityModel](./Models/SettingsSecurityModel.md) - [UserModel](./Models/UserModel.md) + - [_AllModel](./Models/_AllModel.md) + - [_AllModelStatus](./Models/_AllModelStatus.md) diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java new file mode 100644 index 00000000..46fdfa07 --- /dev/null +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java @@ -0,0 +1,34 @@ +package com.deftdevs.bootstrapi.jira.model; + +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.model.GroupModel; +import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.UserModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = BootstrAPI._ALL) +public class _AllModel { + + @XmlElement + private SettingsModel settings; + + @XmlElement + private Map users; + + @XmlElement + private Map groups; + + @XmlElement + private Map status; + +} diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceImpl.java new file mode 100644 index 00000000..0b0af18e --- /dev/null +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceImpl.java @@ -0,0 +1,28 @@ +package com.deftdevs.bootstrapi.jira.rest; + +import com.atlassian.plugins.rest.api.security.annotation.SystemAdminOnly; +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.rest._AbstractAllResourceImpl; +import com.deftdevs.bootstrapi.commons.service.api._AllService; +import com.deftdevs.bootstrapi.jira.model._AllModel; +import io.swagger.v3.oas.annotations.tags.Tag; + +import javax.ws.rs.Consumes; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; + +@Path(BootstrAPI._ROOT) +@Tag(name = BootstrAPI._ALL) +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@SystemAdminOnly +public class _AllResourceImpl extends _AbstractAllResourceImpl<_AllModel> { + + public _AllResourceImpl( + final _AllService<_AllModel> allService) { + + super(allService); + } + +} From 9caf6a4ba7c6b9e34fe0988407b0d385408f0202 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 24 Feb 2026 21:26:46 +0800 Subject: [PATCH 02/11] WIP_REWORK --- .../commons/model/AbstractDirectoryModel.java | 3 - .../commons/model/type/_AllModelAccessor.java | 9 ++ .../rest/_AbstractAllResourceImpl.java | 22 ++++- .../commons/rest/api/_AllResource.java | 12 +-- .../service/_AbstractAllServiceImpl.java | 48 +++++++--- .../commons/service/api/_AllService.java | 4 +- .../confluence/model/_AllModel.java | 3 +- .../bootstrapi/crowd/model/_AllModel.java | 3 +- .../crowd/service/_AllServiceImpl.java | 90 ++----------------- .../crowd/rest/AllResourceTest.java | 3 +- .../bootstrapi/jira/model/_AllModel.java | 3 +- 11 files changed, 85 insertions(+), 115 deletions(-) create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelAccessor.java diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java index a9050606..19e534a4 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractDirectoryModel.java @@ -61,7 +61,4 @@ public abstract class AbstractDirectoryModel { @XmlElement private Date updatedDate; - @XmlElement - private Boolean testConnection; - } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelAccessor.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelAccessor.java new file mode 100644 index 00000000..c586adff --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelAccessor.java @@ -0,0 +1,9 @@ +package com.deftdevs.bootstrapi.commons.model.type; + +import java.util.Map; + +public interface _AllModelAccessor { + + Map getStatus(); + +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java index c1b6d948..423ce4f7 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java @@ -1,11 +1,14 @@ package com.deftdevs.bootstrapi.commons.rest; +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.rest.api._AllResource; import com.deftdevs.bootstrapi.commons.service.api._AllService; import javax.ws.rs.core.Response; +import java.util.Map; -public abstract class _AbstractAllResourceImpl<_AllModel> +public abstract class _AbstractAllResourceImpl<_AllModel extends _AllModelAccessor> implements _AllResource<_AllModel> { private final _AllService<_AllModel> allService; @@ -19,6 +22,21 @@ public _AbstractAllResourceImpl( public Response setAll( final _AllModel allModel) { - return Response.ok(allService.setAll(allModel)).build(); + final _AllModel result = allService.setAll(allModel); + final int overallStatus = computeOverallStatus(result.getStatus()); + return Response.status(overallStatus).entity(result).build(); + } + + private static int computeOverallStatus( + final Map statusMap) { + + if (statusMap == null || statusMap.isEmpty()) { + return Response.Status.OK.getStatusCode(); + } + + return statusMap.values().stream() + .mapToInt(_AllModelStatus::getStatus) + .max() + .orElse(Response.Status.OK.getStatusCode()); } } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java index 7b548d35..e0df0a7b 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/_AllResource.java @@ -2,7 +2,7 @@ import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import com.deftdevs.bootstrapi.commons.model.ErrorCollection; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -12,19 +12,19 @@ import javax.ws.rs.PUT; import javax.ws.rs.core.Response; -public interface _AllResource<_AllModel> { +public interface _AllResource<_AllModel extends _AllModelAccessor> { @PUT @Operation( - summary = BootstrAPI._ALL, + summary = "Apply a complete configuration", responses = { @ApiResponse( - responseCode = "200", content = @Content(schema = @Schema(implementation = SettingsModel.class)), - description = BootstrAPI._ALL + responseCode = "200", + description = "Configuration applied successfully" ), @ApiResponse( responseCode = "default", content = @Content(schema = @Schema(implementation = ErrorCollection.class)), - description = BootstrAPI._ALL + description = BootstrAPI.ERROR_COLLECTION_RESPONSE_DESCRIPTION ), } ) diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index da63c299..7db34a8c 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -1,5 +1,6 @@ package com.deftdevs.bootstrapi.commons.service; +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service.api._AllService; @@ -8,12 +9,14 @@ import java.util.function.Consumer; import java.util.function.Function; -public abstract class _AbstractAllServiceImpl<_A> implements _AllService<_A> { +public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { protected _AllModelStatus setEntity( + final String entityType, final T entity, final Function updateFunction, - final Consumer resultConsumer) { + final Consumer resultConsumer, + final Map statusMap) { if (entity == null) { return null; @@ -22,22 +25,27 @@ protected _AllModelStatus setEntity( try { final T updatedEntity = updateFunction.apply(entity); resultConsumer.accept(updatedEntity); - return _AllModelStatus.success(); + final _AllModelStatus status = _AllModelStatus.success(); + statusMap.put(entityType, status); + return status; } catch (Exception e) { - return _AllModelStatus.error( - Response.Status.INTERNAL_SERVER_ERROR, - "Failed to apply ...", - e.getMessage() + final _AllModelStatus status = _AllModelStatus.error( + resolveStatus(e), + String.format("Failed to apply %s configuration", entityType), + e.getMessage() ); + statusMap.put(entityType, status); + return status; } } @SuppressWarnings("unchecked") protected _AllModelStatus setEntities( + final String entityType, final Map entityMap, - final Function getIdentifier, final Function, Map> updateFunction, - final Consumer> resultConsumer) { + final Consumer> resultConsumer, + final Map statusMap) { if (entityMap == null || entityMap.isEmpty()) { return null; @@ -46,14 +54,28 @@ protected _AllModelStatus setEntities( try { final Map updatedEntities = updateFunction.apply(entityMap); resultConsumer.accept((Map) updatedEntities); - return _AllModelStatus.success(); + final _AllModelStatus status = _AllModelStatus.success(); + statusMap.put(entityType, status); + return status; } catch (Exception e) { - return _AllModelStatus.error( - Response.Status.INTERNAL_SERVER_ERROR, - "Failed to apply ...", + final _AllModelStatus status = _AllModelStatus.error( + resolveStatus(e), + String.format("Failed to apply %s configuration", entityType), e.getMessage() ); + statusMap.put(entityType, status); + return status; + } + } + + private static Response.Status resolveStatus(final Exception e) { + if (e instanceof com.deftdevs.bootstrapi.commons.exception.web.BadRequestException) { + return Response.Status.BAD_REQUEST; + } + if (e instanceof com.deftdevs.bootstrapi.commons.exception.web.NotFoundException) { + return Response.Status.NOT_FOUND; } + return Response.Status.INTERNAL_SERVER_ERROR; } } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java index 61adc85f..9afbbbf9 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/_AllService.java @@ -1,6 +1,8 @@ package com.deftdevs.bootstrapi.commons.service.api; -public interface _AllService<_AllModel> { +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; + +public interface _AllService<_AllModel extends _AllModelAccessor> { /** * Apply a complete configuration. diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java index 60641c97..486353bd 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java @@ -3,6 +3,7 @@ import com.deftdevs.bootstrapi.commons.model.GroupModel; import com.deftdevs.bootstrapi.commons.model.SettingsModel; import com.deftdevs.bootstrapi.commons.model.UserModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import lombok.AllArgsConstructor; import lombok.Data; @@ -16,7 +17,7 @@ @NoArgsConstructor @AllArgsConstructor @XmlRootElement(name = "all") -public class _AllModel { +public class _AllModel implements _AllModelAccessor { @XmlElement private SettingsModel settings; diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java index 2c2e43ff..f973f55d 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java @@ -3,6 +3,7 @@ import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import lombok.AllArgsConstructor; import lombok.Data; @@ -16,7 +17,7 @@ @NoArgsConstructor @AllArgsConstructor @XmlRootElement(name = BootstrAPI._ALL) -public class _AllModel { +public class _AllModel implements _AllModelAccessor { @XmlElement private SettingsModel settings; diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 201db601..f74c83ad 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,21 +1,14 @@ package com.deftdevs.bootstrapi.crowd.service; -import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; -import com.deftdevs.bootstrapi.crowd.model.ApplicationModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; -import javax.ws.rs.core.Response; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; -import java.util.function.BiFunction; -import java.util.function.Function; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -38,88 +31,15 @@ public _AllModel setAll( final _AllModel allModel) { final _AllModel result = new _AllModel(); - final Map status = new HashMap<>(); + final Map statusMap = new HashMap<>(); - setEntity(allModel.getSettings(), settingsService::setSettingsGeneral, result::setSettings); + setEntity("settings", allModel.getSettings(), settingsService::setSettingsGeneral, result::setSettings, statusMap); - setEntities(allModel.getDirectories(), AbstractDirectoryModel::getName, directoriesService::setDirectories, result::setDirectories); + setEntities("directories", allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); - setEntities(allModel.getApplications(), ApplicationModel::getName, applicationsService::setApplications, result::setApplications); + setEntities("applications", allModel.getApplications(), applicationsService::setApplications, result::setApplications, statusMap); -// // Process entities using a generic handler -// processEntities(allModel.getGroups(), "groups", GroupModel::getName, GroupsService::setGroups, result::setGroups, status); -// -// processEntities(allModel.getUsers(), "users", UserModel::getUsername, -// users -> usersService.setUsers(1L, users), result::setUsers, status); -// -// processEntities(allModel.getApplications(), "applications", ApplicationModel::getName, -// applicationsService::setApplications, result::setApplications, status); - - result.setStatus(status); + result.setStatus(statusMap); return result; } - - private void processEntities( - Map entityMap, - String entityType, - Function getIdentifier, - Function, List> updateFunction, - BiFunction, _AllModel, _AllModel> resultSetter, - Map status) { - - if (entityMap == null || entityMap.isEmpty()) { - return; - } - - try { - // Validate entity identifiers - for (Map.Entry entry : entityMap.entrySet()) { - String key = entry.getKey(); - T entity = entry.getValue(); - String identifier = getIdentifier.apply(entity); - - if (identifier == null) { - // Try to set the key as the identifier using reflection - try { - entity.getClass().getMethod("set" + entityType.substring(0, 1).toUpperCase() + - entityType.substring(1, entityType.length() - 1), String.class) - .invoke(entity, key); - } catch (Exception e) { - // If reflection fails, report the error - status.put(entityType, _AllModelStatus.error( - Response.Status.BAD_REQUEST, - entityType + " identifier missing", - "Could not set identifier for key: " + key - )); - return; - } - } else if (!key.equals(identifier)) { - status.put(entityType, _AllModelStatus.error( - Response.Status.BAD_REQUEST, - entityType.substring(0, 1).toUpperCase() + entityType.substring(1) + " identifier mismatch", - String.format("Map key '%s' does not match %s '%s'", key, entityType.substring(0, entityType.length() - 1), identifier) - )); - return; - } - } - - if (!status.containsKey(entityType)) { - List entityList = new ArrayList<>(entityMap.values()); - List updatedEntities = updateFunction.apply(entityList); - - Map resultMap = new HashMap<>(); - for (T entity : updatedEntities) { - resultMap.put(getIdentifier.apply(entity), entity); - } - resultSetter.apply(resultMap, null); - status.put(entityType, _AllModelStatus.success()); - } - } catch (Exception e) { - status.put(entityType, _AllModelStatus.error( - Response.Status.BAD_REQUEST, - "Failed to apply " + entityType + " configuration", - e.getMessage() - )); - } - } } diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java index 2ef1d69c..69242953 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java @@ -43,8 +43,7 @@ public void setup() { Map status = new HashMap<>(); status.put("settings", _AllModelStatus.success()); - status.put("users", _AllModelStatus.success()); - status.put("groups", _AllModelStatus.success()); + status.put("directories", _AllModelStatus.success()); status.put("applications", _AllModelStatus.success()); allModel.setStatus(status); } diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java index 46fdfa07..2ab910ad 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java @@ -4,6 +4,7 @@ import com.deftdevs.bootstrapi.commons.model.GroupModel; import com.deftdevs.bootstrapi.commons.model.SettingsModel; import com.deftdevs.bootstrapi.commons.model.UserModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import lombok.AllArgsConstructor; import lombok.Data; @@ -17,7 +18,7 @@ @NoArgsConstructor @AllArgsConstructor @XmlRootElement(name = BootstrAPI._ALL) -public class _AllModel { +public class _AllModel implements _AllModelAccessor { @XmlElement private SettingsModel settings; From bed18c4552f7be2b6cc4ea6a67055360ad6d993a Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 24 Feb 2026 22:35:42 +0800 Subject: [PATCH 03/11] WIP_ALL_IMPL --- .../commons/model/AuthenticationModel.java | 25 ++++ .../commons/model/MailServerModel.java | 31 +++++ ...gsModel.java => SettingsGeneralModel.java} | 6 +- .../AbstractSettingsGeneralResourceImpl.java | 31 +++++ .../rest/AbstractSettingsResourceImpl.java | 31 ----- ...urce.java => SettingsGeneralResource.java} | 8 +- ...rvice.java => SettingsGeneralService.java} | 4 +- ...est.java => SettingsGeneralModelTest.java} | 0 ....java => SettingsGeneralResourceTest.java} | 22 ++-- .../impl/TestSettingsGeneralResourceImpl.java | 12 ++ .../rest/impl/TestSettingsResourceImpl.java | 12 -- ...tractSettingsGeneralResourceFuncTest.java} | 12 +- confluence/Apis/AllApi.md | 4 +- confluence/Apis/SettingsApi.md | 10 +- confluence/Models/SettingsGeneralModel.md | 13 ++ confluence/Models/SettingsModel.md | 9 +- confluence/Models/_AllModel.md | 8 +- confluence/README.md | 1 + .../confluence/config/ServiceConfig.java | 14 +++ .../confluence/model/SettingsModel.java | 33 ++++++ .../confluence/model/_AllModel.java | 28 ++++- ....java => SettingsGeneralResourceImpl.java} | 8 +- .../service/SettingsServiceImpl.java | 8 +- .../confluence/service/_AllServiceImpl.java | 112 ++++++++++++++++++ .../api/ConfluenceSettingsService.java | 6 +- .../service/SettingsServiceTest.java | 14 +-- .../rest/SettingsGeneralResourceFuncTest.java | 12 ++ .../rest/SettingsResourceFuncTest.java | 12 -- crowd/Apis/AllApi.md | 4 +- crowd/Apis/SettingsApi.md | 10 +- crowd/Models/SettingsGeneralModel.md | 13 ++ crowd/Models/SettingsModel.md | 7 +- crowd/Models/_AllModel.md | 8 +- crowd/README.md | 1 + .../crowd/config/ServiceConfig.java | 9 +- .../bootstrapi/crowd/model/SettingsModel.java | 25 ++++ .../bootstrapi/crowd/model/_AllModel.java | 24 +++- ....java => SettingsGeneralResourceImpl.java} | 8 +- .../crowd/service/SettingsServiceImpl.java | 8 +- .../crowd/service/_AllServiceImpl.java | 76 +++++++++++- .../api/CrowdSettingsGeneralService.java | 6 +- .../crowd/rest/AllResourceTest.java | 9 +- .../crowd/service/SettingsServiceTest.java | 6 +- .../rest/SettingsGeneralResourceFuncTest.java | 16 +++ .../crowd/rest/SettingsResourceFuncTest.java | 16 --- jira/Apis/AllApi.md | 4 +- jira/Apis/SettingsApi.md | 10 +- jira/Models/SettingsGeneralModel.md | 13 ++ jira/Models/SettingsModel.md | 8 +- jira/Models/_AllModel.md | 8 +- jira/README.md | 1 + .../bootstrapi/jira/config/ServiceConfig.java | 13 ++ .../bootstrapi/jira/model/SettingsModel.java | 29 +++++ .../bootstrapi/jira/model/_AllModel.java | 25 +++- ....java => SettingsGeneralResourceImpl.java} | 8 +- .../jira/service/SettingsServiceImpl.java | 10 +- .../jira/service/_AllServiceImpl.java | 106 +++++++++++++++++ .../jira/service/api/JiraSettingsService.java | 6 +- .../jira/service/JiraSettingsServiceTest.java | 12 +- .../jira/service/SettingsServiceTest.java | 12 +- .../rest/SettingsGeneralResourceFuncTest.java | 5 + .../jira/rest/SettingsResourceFuncTest.java | 5 - 62 files changed, 787 insertions(+), 220 deletions(-) create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AuthenticationModel.java create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java rename commons/src/main/java/com/deftdevs/bootstrapi/commons/model/{SettingsModel.java => SettingsGeneralModel.java} (86%) create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceImpl.java delete mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceImpl.java rename commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/{SettingsResource.java => SettingsGeneralResource.java} (86%) rename commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/{SettingsService.java => SettingsGeneralService.java} (72%) rename commons/src/test/java/com/deftdevs/bootstrapi/commons/model/{SettingsModelTest.java => SettingsGeneralModelTest.java} (100%) rename commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/{SettingsResourceTest.java => SettingsGeneralResourceTest.java} (56%) create mode 100644 commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsGeneralResourceImpl.java delete mode 100644 commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsResourceImpl.java rename commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/{AbstractSettingsResourceFuncTest.java => AbstractSettingsGeneralResourceFuncTest.java} (84%) create mode 100644 confluence/Models/SettingsGeneralModel.md create mode 100644 confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/SettingsModel.java rename confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/{SettingsResourceImpl.java => SettingsGeneralResourceImpl.java} (69%) create mode 100644 confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java create mode 100644 confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceFuncTest.java delete mode 100644 confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceFuncTest.java create mode 100644 crowd/Models/SettingsGeneralModel.md create mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsModel.java rename crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/{SettingsResourceImpl.java => SettingsGeneralResourceImpl.java} (69%) create mode 100644 crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceFuncTest.java delete mode 100644 crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceFuncTest.java create mode 100644 jira/Models/SettingsGeneralModel.md create mode 100644 jira/src/main/java/com/deftdevs/bootstrapi/jira/model/SettingsModel.java rename jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/{SettingsResourceImpl.java => SettingsGeneralResourceImpl.java} (69%) create mode 100644 jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java create mode 100644 jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceFuncTest.java delete mode 100644 jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsResourceFuncTest.java diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AuthenticationModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AuthenticationModel.java new file mode 100644 index 00000000..909488f4 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AuthenticationModel.java @@ -0,0 +1,25 @@ +package com.deftdevs.bootstrapi.commons.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Map; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = AUTHENTICATION) +public class AuthenticationModel { + + @XmlElement + private Map idps; + + @XmlElement + private AuthenticationSsoModel sso; + +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java new file mode 100644 index 00000000..0b75d942 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java @@ -0,0 +1,31 @@ +package com.deftdevs.bootstrapi.commons.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = MAIL_SERVER) +public class MailServerModel { + + @XmlElement + private MailServerSmtpModel smtp; + + @XmlElement + private MailServerPopModel pop; + + // Example instances for documentation and tests + + public static final MailServerModel EXAMPLE_1 = new MailServerModel( + MailServerSmtpModel.EXAMPLE_1, + MailServerPopModel.EXAMPLE_1 + ); + +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java similarity index 86% rename from commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsModel.java rename to commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java index 1689a097..64e4f7d6 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java @@ -19,7 +19,7 @@ @AllArgsConstructor @XmlRootElement(name = BootstrAPI.SETTINGS) @XmlAccessorType(XmlAccessType.FIELD) -public class SettingsModel { +public class SettingsGeneralModel { @XmlElement private URI baseUrl; @@ -46,7 +46,7 @@ public String getMode() { // Example instances for documentation and tests - public static final SettingsModel EXAMPLE_1 = SettingsModel.builder() + public static final SettingsGeneralModel EXAMPLE_1 = SettingsGeneralModel.builder() .title("Example") .baseUrl(URI.create("https://example.com")) .mode("private") @@ -54,7 +54,7 @@ public String getMode() { .externalUserManagement(true) .build(); - public static final SettingsModel EXAMPLE_1_NO_MODE = SettingsModel.builder() + public static final SettingsGeneralModel EXAMPLE_1_NO_MODE = SettingsGeneralModel.builder() .title("Example") .baseUrl(URI.create("https://example.com")) .mode(null) diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceImpl.java new file mode 100644 index 00000000..b93da638 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceImpl.java @@ -0,0 +1,31 @@ +package com.deftdevs.bootstrapi.commons.rest; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.rest.api.SettingsGeneralResource; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; + +import javax.ws.rs.core.Response; + +public abstract class AbstractSettingsGeneralResourceImpl> + implements SettingsGeneralResource { + + private final S settingsService; + + public AbstractSettingsGeneralResourceImpl( + final S settingsService) { + + this.settingsService = settingsService; + } + + @Override + public Response getSettings() { + final B settingsModel = settingsService.getSettingsGeneral(); + return Response.ok(settingsModel).build(); + } + + @Override + public Response setSettings(B settingsModel) { + final B updatedSettingsGeneralModel = settingsService.setSettingsGeneral(settingsModel); + return Response.ok(updatedSettingsGeneralModel).build(); + } +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceImpl.java deleted file mode 100644 index c1c4c405..00000000 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceImpl.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.deftdevs.bootstrapi.commons.rest; - -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.rest.api.SettingsResource; -import com.deftdevs.bootstrapi.commons.service.api.SettingsService; - -import javax.ws.rs.core.Response; - -public abstract class AbstractSettingsResourceImpl> - implements SettingsResource { - - private final S settingsService; - - public AbstractSettingsResourceImpl( - final S settingsService) { - - this.settingsService = settingsService; - } - - @Override - public Response getSettings() { - final B settingsModel = settingsService.getSettingsGeneral(); - return Response.ok(settingsModel).build(); - } - - @Override - public Response setSettings(B settingsModel) { - final B updatedSettingsModel = settingsService.setSettingsGeneral(settingsModel); - return Response.ok(updatedSettingsModel).build(); - } -} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/SettingsResource.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/SettingsGeneralResource.java similarity index 86% rename from commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/SettingsResource.java rename to commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/SettingsGeneralResource.java index 8e415842..6bfcbe8a 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/SettingsResource.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/api/SettingsGeneralResource.java @@ -2,7 +2,7 @@ import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import com.deftdevs.bootstrapi.commons.model.ErrorCollection; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -12,14 +12,14 @@ import javax.ws.rs.PUT; import javax.ws.rs.core.Response; -public interface SettingsResource { +public interface SettingsGeneralResource { @GET @Operation( summary = BootstrAPI.SETTINGS_GENERAL_GET_SUMMARY, responses = { @ApiResponse( - responseCode = "200", content = @Content(schema = @Schema(implementation = SettingsModel.class)), + responseCode = "200", content = @Content(schema = @Schema(implementation = SettingsGeneralModel.class)), description = BootstrAPI.SETTINGS_GENERAL_GET_RESPONSE_DESCRIPTION ), @ApiResponse( @@ -35,7 +35,7 @@ public interface SettingsResource { summary = BootstrAPI.SETTINGS_GENERAL_PUT_SUMMARY, responses = { @ApiResponse( - responseCode = "200", content = @Content(schema = @Schema(implementation = SettingsModel.class)), + responseCode = "200", content = @Content(schema = @Schema(implementation = SettingsGeneralModel.class)), description = BootstrAPI.SETTINGS_GENERAL_PUT_RESPONSE_DESCRIPTION ), @ApiResponse( diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/SettingsService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/SettingsGeneralService.java similarity index 72% rename from commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/SettingsService.java rename to commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/SettingsGeneralService.java index 7bbf8fa2..bb41c8e0 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/SettingsService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/SettingsGeneralService.java @@ -1,9 +1,9 @@ package com.deftdevs.bootstrapi.commons.service.api; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; -public interface SettingsService { +public interface SettingsGeneralService { /** * Get the settings. diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/model/SettingsModelTest.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModelTest.java similarity index 100% rename from commons/src/test/java/com/deftdevs/bootstrapi/commons/model/SettingsModelTest.java rename to commons/src/test/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModelTest.java diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/SettingsResourceTest.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/SettingsGeneralResourceTest.java similarity index 56% rename from commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/SettingsResourceTest.java rename to commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/SettingsGeneralResourceTest.java index 588bd515..327076d4 100644 --- a/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/SettingsResourceTest.java +++ b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/SettingsGeneralResourceTest.java @@ -1,8 +1,8 @@ package com.deftdevs.bootstrapi.commons.rest; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.rest.impl.TestSettingsResourceImpl; -import com.deftdevs.bootstrapi.commons.service.api.SettingsService; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.rest.impl.TestSettingsGeneralResourceImpl; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -15,40 +15,40 @@ import static org.mockito.Mockito.doReturn; @ExtendWith(MockitoExtension.class) -class SettingsResourceTest { +class SettingsGeneralResourceTest { @Mock - private SettingsService settingsService; + private SettingsGeneralService settingsService; - private TestSettingsResourceImpl resource; + private TestSettingsGeneralResourceImpl resource; @BeforeEach public void setup() { - resource = new TestSettingsResourceImpl(settingsService); + resource = new TestSettingsGeneralResourceImpl(settingsService); } @Test void testGetSettings() { - final SettingsModel bean = SettingsModel.EXAMPLE_1; + final SettingsGeneralModel bean = SettingsGeneralModel.EXAMPLE_1; doReturn(bean).when(settingsService).getSettingsGeneral(); final Response response = resource.getSettings(); assertEquals(200, response.getStatus()); - final SettingsModel settingsModel = (SettingsModel) response.getEntity(); + final SettingsGeneralModel settingsModel = (SettingsGeneralModel) response.getEntity(); assertEquals(settingsModel, bean); } @Test void testSetSettings() { - final SettingsModel bean = SettingsModel.EXAMPLE_1; + final SettingsGeneralModel bean = SettingsGeneralModel.EXAMPLE_1; doReturn(bean).when(settingsService).setSettingsGeneral(bean); final Response response = resource.setSettings(bean); assertEquals(200, response.getStatus()); - final SettingsModel settingsModel = (SettingsModel) response.getEntity(); + final SettingsGeneralModel settingsModel = (SettingsGeneralModel) response.getEntity(); assertEquals(settingsModel, bean); } diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsGeneralResourceImpl.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsGeneralResourceImpl.java new file mode 100644 index 00000000..135137c6 --- /dev/null +++ b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsGeneralResourceImpl.java @@ -0,0 +1,12 @@ +package com.deftdevs.bootstrapi.commons.rest.impl; + +import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceImpl; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; + +public class TestSettingsGeneralResourceImpl extends AbstractSettingsGeneralResourceImpl { + + public TestSettingsGeneralResourceImpl(SettingsGeneralService settingsService) { + super(settingsService); + } + +} diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsResourceImpl.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsResourceImpl.java deleted file mode 100644 index db9c2e44..00000000 --- a/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/impl/TestSettingsResourceImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.deftdevs.bootstrapi.commons.rest.impl; - -import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceImpl; -import com.deftdevs.bootstrapi.commons.service.api.SettingsService; - -public class TestSettingsResourceImpl extends AbstractSettingsResourceImpl { - - public TestSettingsResourceImpl(SettingsService settingsService) { - super(settingsService); - } - -} diff --git a/commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceFuncTest.java b/commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceFuncTest.java similarity index 84% rename from commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceFuncTest.java rename to commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceFuncTest.java index 91266a6f..88cb147f 100644 --- a/commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsResourceFuncTest.java +++ b/commons/src/test/java/it/com/deftdevs/bootstrapi/commons/rest/AbstractSettingsGeneralResourceFuncTest.java @@ -1,7 +1,7 @@ package it.com.deftdevs.bootstrapi.commons.rest; import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*; -public abstract class AbstractSettingsResourceFuncTest { +public abstract class AbstractSettingsGeneralResourceFuncTest { private final ObjectMapper objectMapper = new ObjectMapper(); @@ -21,7 +21,7 @@ void testGetSettings() throws Exception { .request(); assertEquals(Response.Status.OK.getStatusCode(), settingsResponse.statusCode()); - final SettingsModel settingsModel = objectMapper.readValue(settingsResponse.body(), SettingsModel.class); + final SettingsGeneralModel settingsModel = objectMapper.readValue(settingsResponse.body(), SettingsGeneralModel.class); assertNotNull(settingsModel.getTitle()); } @@ -31,7 +31,7 @@ void testSetSettings() throws Exception { .request(HttpMethod.PUT, getExampleModel()); assertEquals(Response.Status.OK.getStatusCode(), settingsResponse.statusCode()); - final SettingsModel settingsModel = objectMapper.readValue(settingsResponse.body(), SettingsModel.class); + final SettingsGeneralModel settingsModel = objectMapper.readValue(settingsResponse.body(), SettingsGeneralModel.class); assertEquals(getExampleModel(), settingsModel); } @@ -73,7 +73,7 @@ void testSetSettingsUnauthorized() throws Exception { assertEquals(Response.Status.FORBIDDEN.getStatusCode(), settingsResponse.statusCode()); } - protected SettingsModel getExampleModel() { - return SettingsModel.EXAMPLE_1; + protected SettingsGeneralModel getExampleModel() { + return SettingsGeneralModel.EXAMPLE_1; } } diff --git a/confluence/Apis/AllApi.md b/confluence/Apis/AllApi.md index 99f0bab6..2ee156ed 100644 --- a/confluence/Apis/AllApi.md +++ b/confluence/Apis/AllApi.md @@ -9,7 +9,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* # **setAll** -> SettingsModel setAll(\_AllModel) +> _AllModel setAll(\_AllModel) _all @@ -21,7 +21,7 @@ _all ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**_AllModel**](../Models/_AllModel.md) ### Authorization diff --git a/confluence/Apis/SettingsApi.md b/confluence/Apis/SettingsApi.md index ced46831..723e19c3 100644 --- a/confluence/Apis/SettingsApi.md +++ b/confluence/Apis/SettingsApi.md @@ -108,7 +108,7 @@ This endpoint does not need any parameter. # **getSettings** -> SettingsModel getSettings() +> SettingsGeneralModel getSettings() Get the general settings @@ -117,7 +117,7 @@ This endpoint does not need any parameter. ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**SettingsGeneralModel**](../Models/SettingsGeneralModel.md) ### Authorization @@ -252,7 +252,7 @@ Set the custom HTML # **setSettings** -> SettingsModel setSettings(SettingsModel) +> SettingsGeneralModel setSettings(SettingsGeneralModel) Set the general settings @@ -260,11 +260,11 @@ Set the general settings |Name | Type | Description | Notes | |------------- | ------------- | ------------- | -------------| -| **SettingsModel** | [**SettingsModel**](../Models/SettingsModel.md)| | [optional] | +| **SettingsGeneralModel** | [**SettingsGeneralModel**](../Models/SettingsGeneralModel.md)| | [optional] | ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**SettingsGeneralModel**](../Models/SettingsGeneralModel.md) ### Authorization diff --git a/confluence/Models/SettingsGeneralModel.md b/confluence/Models/SettingsGeneralModel.md new file mode 100644 index 00000000..8ebe677b --- /dev/null +++ b/confluence/Models/SettingsGeneralModel.md @@ -0,0 +1,13 @@ +# SettingsGeneralModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **baseUrl** | **URI** | | [optional] [default to null] | +| **mode** | **String** | | [optional] [default to null] | +| **title** | **String** | | [optional] [default to null] | +| **contactMessage** | **String** | | [optional] [default to null] | +| **externalUserManagement** | **Boolean** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/confluence/Models/SettingsModel.md b/confluence/Models/SettingsModel.md index f4eb0e7f..a9c90eac 100644 --- a/confluence/Models/SettingsModel.md +++ b/confluence/Models/SettingsModel.md @@ -3,11 +3,10 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| -| **baseUrl** | **URI** | | [optional] [default to null] | -| **mode** | **String** | | [optional] [default to null] | -| **title** | **String** | | [optional] [default to null] | -| **contactMessage** | **String** | | [optional] [default to null] | -| **externalUserManagement** | **Boolean** | | [optional] [default to null] | +| **general** | [**SettingsGeneralModel**](SettingsGeneralModel.md) | | [optional] [default to null] | +| **security** | [**SettingsSecurityModel**](SettingsSecurityModel.md) | | [optional] [default to null] | +| **branding** | [**SettingsBrandingColorSchemeModel**](SettingsBrandingColorSchemeModel.md) | | [optional] [default to null] | +| **customHtml** | [**SettingsCustomHtmlModel**](SettingsCustomHtmlModel.md) | | [optional] [default to null] | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/confluence/Models/_AllModel.md b/confluence/Models/_AllModel.md index 34153397..cd6000f3 100644 --- a/confluence/Models/_AllModel.md +++ b/confluence/Models/_AllModel.md @@ -4,8 +4,12 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| | **settings** | [**SettingsModel**](SettingsModel.md) | | [optional] [default to null] | -| **users** | [**Map**](UserModel.md) | | [optional] [default to null] | -| **groups** | [**Map**](GroupModel.md) | | [optional] [default to null] | +| **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | +| **applicationLinks** | [**Map**](ApplicationLinkModel.md) | | [optional] [default to null] | +| **authentication** | [**AuthenticationModel**](AuthenticationModel.md) | | [optional] [default to null] | +| **licenses** | **List** | | [optional] [default to null] | +| **mailServer** | [**MailServerModel**](MailServerModel.md) | | [optional] [default to null] | +| **permissionsGlobal** | [**PermissionsGlobalModel**](PermissionsGlobalModel.md) | | [optional] [default to null] | | **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/confluence/README.md b/confluence/README.md index 2b15d90f..1487b2b2 100644 --- a/confluence/README.md +++ b/confluence/README.md @@ -92,6 +92,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* - [PermissionsGlobalModel](./Models/PermissionsGlobalModel.md) - [SettingsBrandingColorSchemeModel](./Models/SettingsBrandingColorSchemeModel.md) - [SettingsCustomHtmlModel](./Models/SettingsCustomHtmlModel.md) + - [SettingsGeneralModel](./Models/SettingsGeneralModel.md) - [SettingsModel](./Models/SettingsModel.md) - [SettingsSecurityModel](./Models/SettingsSecurityModel.md) - [UserModel](./Models/UserModel.md) diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java index d0f39f51..c9e079ea 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java @@ -1,6 +1,7 @@ package com.deftdevs.bootstrapi.confluence.config; import com.deftdevs.bootstrapi.commons.service.api.*; +import com.deftdevs.bootstrapi.confluence.model._AllModel; import com.deftdevs.bootstrapi.confluence.service.*; import com.deftdevs.bootstrapi.confluence.service.api.CachesService; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; @@ -18,6 +19,19 @@ public class ServiceConfig { @Autowired private HelperConfig helperConfig; + @Bean + public _AllService<_AllModel> _allService() { + return new _AllServiceImpl( + confluenceSettingsService(), + directoriesService(), + applicationLinksService(), + confluenceAuthenticationService(), + licensesService(), + mailServerService(), + permissionsService(), + settingsBrandingService()); + } + @Bean public ApplicationLinksService applicationLinksService() { return new ApplicationLinksServiceImpl( diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/SettingsModel.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/SettingsModel.java new file mode 100644 index 00000000..a03142a0 --- /dev/null +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/SettingsModel.java @@ -0,0 +1,33 @@ +package com.deftdevs.bootstrapi.confluence.model; + +import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = SETTINGS) +public class SettingsModel { + + @XmlElement + private SettingsGeneralModel general; + + @XmlElement + private SettingsSecurityModel security; + + @XmlElement + private SettingsBrandingColorSchemeModel branding; + + @XmlElement + private SettingsCustomHtmlModel customHtml; + +} diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java index 486353bd..230a91df 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java @@ -1,8 +1,11 @@ package com.deftdevs.bootstrapi.confluence.model; -import com.deftdevs.bootstrapi.commons.model.GroupModel; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.model.UserModel; +import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; +import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; +import com.deftdevs.bootstrapi.commons.model.ApplicationLinkModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import lombok.AllArgsConstructor; @@ -11,22 +14,35 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; import java.util.Map; @Data @NoArgsConstructor @AllArgsConstructor -@XmlRootElement(name = "all") +@XmlRootElement(name = BootstrAPI._ALL) public class _AllModel implements _AllModelAccessor { @XmlElement private SettingsModel settings; @XmlElement - private Map users; + private Map directories; @XmlElement - private Map groups; + private Map applicationLinks; + + @XmlElement + private AuthenticationModel authentication; + + @XmlElement + private List licenses; + + @XmlElement + private MailServerModel mailServer; + + @XmlElement + private PermissionsGlobalModel permissionsGlobal; @XmlElement private Map status; diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceImpl.java similarity index 69% rename from confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceImpl.java rename to confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceImpl.java index 8809c6c3..948a1436 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceImpl.java @@ -2,8 +2,8 @@ import com.atlassian.plugins.rest.api.security.annotation.SystemAdminOnly; import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceImpl; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceImpl; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceSettingsService; import io.swagger.v3.oas.annotations.tags.Tag; @@ -18,10 +18,10 @@ @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SystemAdminOnly -public class SettingsResourceImpl extends AbstractSettingsResourceImpl { +public class SettingsGeneralResourceImpl extends AbstractSettingsGeneralResourceImpl { @Inject - public SettingsResourceImpl( + public SettingsGeneralResourceImpl( final ConfluenceSettingsService settingsService) { super(settingsService); diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java index 645bc895..438a4d42 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java @@ -3,7 +3,7 @@ import com.atlassian.confluence.setup.settings.CustomHtmlSettings; import com.atlassian.confluence.setup.settings.GlobalSettingsManager; import com.atlassian.confluence.setup.settings.Settings; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceSettingsService; @@ -21,10 +21,10 @@ public SettingsServiceImpl( } @Override - public SettingsModel getSettingsGeneral() { + public SettingsGeneralModel getSettingsGeneral() { final Settings settings = globalSettingsManager.getGlobalSettings(); - return SettingsModel.builder() + return SettingsGeneralModel.builder() .baseUrl(URI.create(settings.getBaseUrl())) .title(settings.getSiteTitle()) .contactMessage(settings.getCustomContactMessage()) @@ -33,7 +33,7 @@ public SettingsModel getSettingsGeneral() { } @Override - public SettingsModel setSettingsGeneral(SettingsModel settingsModel) { + public SettingsGeneralModel setSettingsGeneral(SettingsGeneralModel settingsModel) { final Settings settings = globalSettingsManager.getGlobalSettings(); if (settingsModel.getBaseUrl() != null) { diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java new file mode 100644 index 00000000..568cf721 --- /dev/null +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -0,0 +1,112 @@ +package com.deftdevs.bootstrapi.confluence.service; + +import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; +import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; +import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; +import com.deftdevs.bootstrapi.commons.service.api.LicensesService; +import com.deftdevs.bootstrapi.commons.service.api.MailServerService; +import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; +import com.deftdevs.bootstrapi.confluence.model.SettingsModel; +import com.deftdevs.bootstrapi.confluence.model._AllModel; +import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; +import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceSettingsService; + +import java.util.HashMap; +import java.util.Map; + +public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { + + private final ConfluenceSettingsService settingsService; + private final DirectoriesService directoriesService; + private final ApplicationLinksService applicationLinksService; + private final ConfluenceAuthenticationService authenticationService; + private final LicensesService licensesService; + private final MailServerService mailServerService; + private final PermissionsService permissionsService; + private final SettingsBrandingService settingsBrandingService; + + public _AllServiceImpl( + final ConfluenceSettingsService settingsService, + final DirectoriesService directoriesService, + final ApplicationLinksService applicationLinksService, + final ConfluenceAuthenticationService authenticationService, + final LicensesService licensesService, + final MailServerService mailServerService, + final PermissionsService permissionsService, + final SettingsBrandingService settingsBrandingService) { + + this.settingsService = settingsService; + this.directoriesService = directoriesService; + this.applicationLinksService = applicationLinksService; + this.authenticationService = authenticationService; + this.licensesService = licensesService; + this.mailServerService = mailServerService; + this.permissionsService = permissionsService; + this.settingsBrandingService = settingsBrandingService; + } + + @Override + public _AllModel setAll( + final _AllModel allModel) { + + final _AllModel result = new _AllModel(); + final Map statusMap = new HashMap<>(); + + // Settings wrapper + final SettingsModel settingsInput = allModel.getSettings(); + if (settingsInput != null) { + final SettingsModel settingsResult = new SettingsModel(); + setEntity("settings/general", settingsInput.getGeneral(), + settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); + setEntity("settings/security", settingsInput.getSecurity(), + settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); + setEntity("settings/branding", settingsInput.getBranding(), + settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); + setEntity("settings/customHtml", settingsInput.getCustomHtml(), + settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); + result.setSettings(settingsResult); + } + + setEntities("directories", allModel.getDirectories(), + directoriesService::setDirectories, result::setDirectories, statusMap); + + setEntities("applicationLinks", allModel.getApplicationLinks(), + applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); + + // Authentication wrapper + final AuthenticationModel authInput = allModel.getAuthentication(); + if (authInput != null) { + final AuthenticationModel authResult = new AuthenticationModel(); + setEntities("authentication/idps", authInput.getIdps(), + authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); + setEntity("authentication/sso", authInput.getSso(), + authenticationService::setAuthenticationSso, authResult::setSso, statusMap); + result.setAuthentication(authResult); + } + + setEntity("licenses", allModel.getLicenses(), + keys -> { licensesService.setLicenses(keys); return keys; }, + result::setLicenses, statusMap); + + // Mail server wrapper + final MailServerModel mailServerInput = allModel.getMailServer(); + if (mailServerInput != null) { + final MailServerModel mailServerResult = new MailServerModel(); + setEntity("mailServer/smtp", mailServerInput.getSmtp(), + mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); + setEntity("mailServer/pop", mailServerInput.getPop(), + mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); + result.setMailServer(mailServerResult); + } + + setEntity("permissionsGlobal", allModel.getPermissionsGlobal(), + permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); + + result.setStatus(statusMap); + return result; + } +} diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java index cb60ebc7..a820dea6 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java @@ -1,13 +1,13 @@ package com.deftdevs.bootstrapi.confluence.service.api; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; -import com.deftdevs.bootstrapi.commons.service.api.SettingsService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; public interface ConfluenceSettingsService extends - SettingsService, + SettingsGeneralService, SettingsSecurityService { SettingsCustomHtmlModel getCustomHtml(); diff --git a/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceTest.java b/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceTest.java index 06f07919..c0315750 100644 --- a/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceTest.java +++ b/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceTest.java @@ -5,7 +5,7 @@ import com.atlassian.confluence.setup.settings.CustomHtmlSettings; import com.atlassian.confluence.setup.settings.GlobalSettingsManager; import com.atlassian.confluence.setup.settings.Settings; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import org.junit.jupiter.api.BeforeEach; @@ -39,9 +39,9 @@ void testGetSettingsGeneral() { doReturn(settings).when(globalSettingsManager).getGlobalSettings(); - final SettingsModel settingsModel = settingsService.getSettingsGeneral(); + final SettingsGeneralModel settingsModel = settingsService.getSettingsGeneral(); - final SettingsModel settingsModelRef = SettingsModel.builder() + final SettingsGeneralModel settingsModelRef = SettingsGeneralModel.builder() .baseUrl(URI.create(settings.getBaseUrl())) .title(settings.getSiteTitle()) .contactMessage(settings.getCustomContactMessage()) @@ -58,20 +58,20 @@ void testSetSettingsGeneral() { final Settings updateSettings = new OtherTestSettings(); - final SettingsModel requestModel = SettingsModel.builder() + final SettingsGeneralModel requestModel = SettingsGeneralModel.builder() .baseUrl(URI.create(updateSettings.getBaseUrl())) .title(updateSettings.getSiteTitle()) .contactMessage(updateSettings.getCustomContactMessage()) .externalUserManagement(updateSettings.isExternalUserManagement()) .build(); - final SettingsModel responseModel = settingsService.setSettingsGeneral(requestModel); + final SettingsGeneralModel responseModel = settingsService.setSettingsGeneral(requestModel); final ArgumentCaptor settingsCaptor = ArgumentCaptor.forClass(Settings.class); verify(globalSettingsManager).updateGlobalSettings(settingsCaptor.capture()); final Settings settings = settingsCaptor.getValue(); - final SettingsModel settingsModel = SettingsModel.builder() + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder() .baseUrl(URI.create(settings.getBaseUrl())) .title(settings.getSiteTitle()) .contactMessage(settings.getCustomContactMessage()) @@ -84,7 +84,7 @@ void testSetSettingsGeneral() { @Test void testSetSettingsDefaultConfig(){ - final SettingsModel settingsModel = SettingsModel.builder().build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().build(); final Settings defaultSettings = new DefaultTestSettings(); doReturn(defaultSettings).when(globalSettingsManager).getGlobalSettings(); diff --git a/confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceFuncTest.java b/confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceFuncTest.java new file mode 100644 index 00000000..0ce82df3 --- /dev/null +++ b/confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsGeneralResourceFuncTest.java @@ -0,0 +1,12 @@ +package it.com.deftdevs.bootstrapi.confluence.rest; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import it.com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceFuncTest; + +public class SettingsGeneralResourceFuncTest extends AbstractSettingsGeneralResourceFuncTest { + + @Override + protected SettingsGeneralModel getExampleModel() { + return SettingsGeneralModel.EXAMPLE_1_NO_MODE; + } +} diff --git a/confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceFuncTest.java b/confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceFuncTest.java deleted file mode 100644 index fbfb0ebb..00000000 --- a/confluence/src/test/java/it/com/deftdevs/bootstrapi/confluence/rest/SettingsResourceFuncTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package it.com.deftdevs.bootstrapi.confluence.rest; - -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import it.com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceFuncTest; - -public class SettingsResourceFuncTest extends AbstractSettingsResourceFuncTest { - - @Override - protected SettingsModel getExampleModel() { - return SettingsModel.EXAMPLE_1_NO_MODE; - } -} diff --git a/crowd/Apis/AllApi.md b/crowd/Apis/AllApi.md index e5c536e4..dadcc835 100644 --- a/crowd/Apis/AllApi.md +++ b/crowd/Apis/AllApi.md @@ -9,7 +9,7 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* # **setAll** -> SettingsModel setAll(\_AllModel) +> _AllModel setAll(\_AllModel) _all @@ -21,7 +21,7 @@ _all ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**_AllModel**](../Models/_AllModel.md) ### Authorization diff --git a/crowd/Apis/SettingsApi.md b/crowd/Apis/SettingsApi.md index 7b783d13..a9b82cdd 100644 --- a/crowd/Apis/SettingsApi.md +++ b/crowd/Apis/SettingsApi.md @@ -35,7 +35,7 @@ This endpoint does not need any parameter. # **getSettings** -> SettingsModel getSettings() +> SettingsGeneralModel getSettings() Get the general settings @@ -44,7 +44,7 @@ This endpoint does not need any parameter. ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**SettingsGeneralModel**](../Models/SettingsGeneralModel.md) ### Authorization @@ -107,7 +107,7 @@ Set the logo # **setSettings** -> SettingsModel setSettings(SettingsModel) +> SettingsGeneralModel setSettings(SettingsGeneralModel) Set the general settings @@ -115,11 +115,11 @@ Set the general settings |Name | Type | Description | Notes | |------------- | ------------- | ------------- | -------------| -| **SettingsModel** | [**SettingsModel**](../Models/SettingsModel.md)| | [optional] | +| **SettingsGeneralModel** | [**SettingsGeneralModel**](../Models/SettingsGeneralModel.md)| | [optional] | ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**SettingsGeneralModel**](../Models/SettingsGeneralModel.md) ### Authorization diff --git a/crowd/Models/SettingsGeneralModel.md b/crowd/Models/SettingsGeneralModel.md new file mode 100644 index 00000000..8ebe677b --- /dev/null +++ b/crowd/Models/SettingsGeneralModel.md @@ -0,0 +1,13 @@ +# SettingsGeneralModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **baseUrl** | **URI** | | [optional] [default to null] | +| **mode** | **String** | | [optional] [default to null] | +| **title** | **String** | | [optional] [default to null] | +| **contactMessage** | **String** | | [optional] [default to null] | +| **externalUserManagement** | **Boolean** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/crowd/Models/SettingsModel.md b/crowd/Models/SettingsModel.md index f4eb0e7f..6a6a5063 100644 --- a/crowd/Models/SettingsModel.md +++ b/crowd/Models/SettingsModel.md @@ -3,11 +3,8 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| -| **baseUrl** | **URI** | | [optional] [default to null] | -| **mode** | **String** | | [optional] [default to null] | -| **title** | **String** | | [optional] [default to null] | -| **contactMessage** | **String** | | [optional] [default to null] | -| **externalUserManagement** | **Boolean** | | [optional] [default to null] | +| **general** | [**SettingsGeneralModel**](SettingsGeneralModel.md) | | [optional] [default to null] | +| **branding** | [**SettingsBrandingLoginPageModel**](SettingsBrandingLoginPageModel.md) | | [optional] [default to null] | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/crowd/Models/_AllModel.md b/crowd/Models/_AllModel.md index c7e7c5d1..32538708 100644 --- a/crowd/Models/_AllModel.md +++ b/crowd/Models/_AllModel.md @@ -4,8 +4,14 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| | **settings** | [**SettingsModel**](SettingsModel.md) | | [optional] [default to null] | -| **applications** | [**Map**](ApplicationModel.md) | | [optional] [default to null] | | **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | +| **applications** | [**Map**](ApplicationModel.md) | | [optional] [default to null] | +| **applicationLinks** | [**Map**](ApplicationLinkModel.md) | | [optional] [default to null] | +| **licenses** | **List** | | [optional] [default to null] | +| **mailServer** | [**MailServerModel**](MailServerModel.md) | | [optional] [default to null] | +| **mailTemplates** | [**MailTemplatesModel**](MailTemplatesModel.md) | | [optional] [default to null] | +| **sessionConfig** | [**SessionConfigModel**](SessionConfigModel.md) | | [optional] [default to null] | +| **trustedProxies** | **List** | | [optional] [default to null] | | **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/crowd/README.md b/crowd/README.md index b78b7fd1..1332e75e 100644 --- a/crowd/README.md +++ b/crowd/README.md @@ -88,6 +88,7 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* - [MailTemplatesModel](./Models/MailTemplatesModel.md) - [SessionConfigModel](./Models/SessionConfigModel.md) - [SettingsBrandingLoginPageModel](./Models/SettingsBrandingLoginPageModel.md) + - [SettingsGeneralModel](./Models/SettingsGeneralModel.md) - [SettingsModel](./Models/SettingsModel.md) - [UserModel](./Models/UserModel.md) - [_AllModel](./Models/_AllModel.md) diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java index 13b82256..454bb481 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java @@ -21,8 +21,15 @@ public class ServiceConfig { public _AllService<_AllModel> _allService() { return new _AllServiceImpl( crowdSettingsGeneralService(), + settingsBrandingService(), directoriesService(), - applicationsService()); + applicationsService(), + applicationLinksService(), + licensesService(), + mailServerService(), + mailTemplatesService(), + sessionConfigService(), + trustedProxiesService()); } @Bean diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsModel.java new file mode 100644 index 00000000..d698125d --- /dev/null +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsModel.java @@ -0,0 +1,25 @@ +package com.deftdevs.bootstrapi.crowd.model; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = SETTINGS) +public class SettingsModel { + + @XmlElement + private SettingsGeneralModel general; + + @XmlElement + private SettingsBrandingLoginPageModel branding; + +} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java index f973f55d..d049c546 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java @@ -2,7 +2,8 @@ import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.ApplicationLinkModel; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import lombok.AllArgsConstructor; @@ -11,6 +12,7 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; import java.util.Map; @Data @@ -22,11 +24,29 @@ public class _AllModel implements _AllModelAccessor { @XmlElement private SettingsModel settings; + @XmlElement + private Map directories; + @XmlElement private Map applications; @XmlElement - private Map directories; + private Map applicationLinks; + + @XmlElement + private List licenses; + + @XmlElement + private MailServerModel mailServer; + + @XmlElement + private MailTemplatesModel mailTemplates; + + @XmlElement + private SessionConfigModel sessionConfig; + + @XmlElement + private List trustedProxies; @XmlElement private Map status; diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceImpl.java similarity index 69% rename from crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceImpl.java rename to crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceImpl.java index 22299041..fd13dea8 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceImpl.java @@ -2,8 +2,8 @@ import com.atlassian.plugins.rest.api.security.annotation.SystemAdminOnly; import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceImpl; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceImpl; import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; import io.swagger.v3.oas.annotations.tags.Tag; @@ -19,10 +19,10 @@ @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SystemAdminOnly -public class SettingsResourceImpl extends AbstractSettingsResourceImpl { +public class SettingsGeneralResourceImpl extends AbstractSettingsGeneralResourceImpl { @Inject - public SettingsResourceImpl( + public SettingsGeneralResourceImpl( final CrowdSettingsGeneralService settingsService) { super(settingsService); diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceImpl.java index ec4f6d64..a8cee89d 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceImpl.java @@ -3,7 +3,7 @@ import com.atlassian.crowd.manager.property.PropertyManager; import com.atlassian.crowd.manager.property.PropertyManagerException; import com.deftdevs.bootstrapi.commons.exception.web.InternalServerErrorException; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; public class SettingsServiceImpl @@ -18,9 +18,9 @@ public SettingsServiceImpl( } @Override - public SettingsModel getSettingsGeneral() { + public SettingsGeneralModel getSettingsGeneral() { try { - return SettingsModel.builder() + return SettingsGeneralModel.builder() .baseUrl(propertyManager.getBaseUrl()) .title(propertyManager.getDeploymentTitle()) .build(); @@ -30,7 +30,7 @@ public SettingsModel getSettingsGeneral() { } @Override - public SettingsModel setSettingsGeneral(SettingsModel settingsModel) { + public SettingsGeneralModel setSettingsGeneral(SettingsGeneralModel settingsModel) { if (settingsModel.getBaseUrl() != null) { propertyManager.setBaseUrl(settingsModel.getBaseUrl()); } diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index f74c83ad..19ceea62 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,11 +1,20 @@ package com.deftdevs.bootstrapi.crowd.service; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; +import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; +import com.deftdevs.bootstrapi.commons.service.api.LicensesService; +import com.deftdevs.bootstrapi.commons.service.api.MailServerService; +import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; +import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsBrandingService; import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; +import com.deftdevs.bootstrapi.crowd.service.api.MailTemplatesService; +import com.deftdevs.bootstrapi.crowd.service.api.SessionConfigService; +import com.deftdevs.bootstrapi.crowd.service.api.TrustedProxiesService; import java.util.HashMap; import java.util.Map; @@ -13,17 +22,38 @@ public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { private final CrowdSettingsGeneralService settingsService; + private final CrowdSettingsBrandingService brandingService; private final DirectoriesService directoriesService; private final ApplicationsService applicationsService; + private final ApplicationLinksService applicationLinksService; + private final LicensesService licensesService; + private final MailServerService mailServerService; + private final MailTemplatesService mailTemplatesService; + private final SessionConfigService sessionConfigService; + private final TrustedProxiesService trustedProxiesService; public _AllServiceImpl( final CrowdSettingsGeneralService settingsService, + final CrowdSettingsBrandingService brandingService, final DirectoriesService directoriesService, - final ApplicationsService applicationsService) { + final ApplicationsService applicationsService, + final ApplicationLinksService applicationLinksService, + final LicensesService licensesService, + final MailServerService mailServerService, + final MailTemplatesService mailTemplatesService, + final SessionConfigService sessionConfigService, + final TrustedProxiesService trustedProxiesService) { this.settingsService = settingsService; + this.brandingService = brandingService; this.directoriesService = directoriesService; this.applicationsService = applicationsService; + this.applicationLinksService = applicationLinksService; + this.licensesService = licensesService; + this.mailServerService = mailServerService; + this.mailTemplatesService = mailTemplatesService; + this.sessionConfigService = sessionConfigService; + this.trustedProxiesService = trustedProxiesService; } @Override @@ -33,11 +63,49 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - setEntity("settings", allModel.getSettings(), settingsService::setSettingsGeneral, result::setSettings, statusMap); + // Settings wrapper + final SettingsModel settingsInput = allModel.getSettings(); + if (settingsInput != null) { + final SettingsModel settingsResult = new SettingsModel(); + setEntity("settings/general", settingsInput.getGeneral(), + settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); + setEntity("settings/branding", settingsInput.getBranding(), + brandingService::setLoginPage, settingsResult::setBranding, statusMap); + result.setSettings(settingsResult); + } - setEntities("directories", allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); + setEntities("directories", allModel.getDirectories(), + directoriesService::setDirectories, result::setDirectories, statusMap); - setEntities("applications", allModel.getApplications(), applicationsService::setApplications, result::setApplications, statusMap); + setEntities("applications", allModel.getApplications(), + applicationsService::setApplications, result::setApplications, statusMap); + + setEntities("applicationLinks", allModel.getApplicationLinks(), + applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); + + setEntity("licenses", allModel.getLicenses(), + keys -> { licensesService.setLicenses(keys); return keys; }, + result::setLicenses, statusMap); + + // Mail server wrapper + final MailServerModel mailServerInput = allModel.getMailServer(); + if (mailServerInput != null) { + final MailServerModel mailServerResult = new MailServerModel(); + setEntity("mailServer/smtp", mailServerInput.getSmtp(), + mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); + setEntity("mailServer/pop", mailServerInput.getPop(), + mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); + result.setMailServer(mailServerResult); + } + + setEntity("mailTemplates", allModel.getMailTemplates(), + mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); + + setEntity("sessionConfig", allModel.getSessionConfig(), + sessionConfigService::setSessionConfig, result::setSessionConfig, statusMap); + + setEntity("trustedProxies", allModel.getTrustedProxies(), + trustedProxiesService::setTrustedProxies, result::setTrustedProxies, statusMap); result.setStatus(statusMap); return result; diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsGeneralService.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsGeneralService.java index a7098e91..610100cb 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsGeneralService.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsGeneralService.java @@ -1,8 +1,8 @@ package com.deftdevs.bootstrapi.crowd.service.api; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.service.api.SettingsService; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; public interface CrowdSettingsGeneralService extends - SettingsService { + SettingsGeneralService { } diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java index 69242953..b763fa8a 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java @@ -1,7 +1,8 @@ package com.deftdevs.bootstrapi.crowd.rest; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.crowd.model.ApplicationModel; +import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service.api._AllService; @@ -34,7 +35,9 @@ public void setup() { // Setup test data allModel = new _AllModel(); - allModel.setSettings(SettingsModel.EXAMPLE_1); + final SettingsModel settings = new SettingsModel(); + settings.setGeneral(SettingsGeneralModel.EXAMPLE_1); + allModel.setSettings(settings); // Setup applications map Map applications = new HashMap<>(); @@ -42,7 +45,7 @@ public void setup() { allModel.setApplications(applications); Map status = new HashMap<>(); - status.put("settings", _AllModelStatus.success()); + status.put("settings/general", _AllModelStatus.success()); status.put("directories", _AllModelStatus.success()); status.put("applications", _AllModelStatus.success()); allModel.setStatus(status); diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceTest.java index c146d736..c1af5d19 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/service/SettingsServiceTest.java @@ -3,7 +3,7 @@ import com.atlassian.crowd.manager.property.PropertyManager; import com.atlassian.crowd.manager.property.PropertyManagerException; import com.deftdevs.bootstrapi.commons.exception.web.InternalServerErrorException; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -12,7 +12,7 @@ import java.net.URISyntaxException; -import static com.deftdevs.bootstrapi.commons.model.SettingsModel.EXAMPLE_1_NO_MODE; +import static com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel.EXAMPLE_1_NO_MODE; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.*; @@ -23,7 +23,7 @@ public class SettingsServiceTest { @Mock private PropertyManager propertyManager; - public static final SettingsModel SETTINGS_MODEL = EXAMPLE_1_NO_MODE; + public static final SettingsGeneralModel SETTINGS_MODEL = EXAMPLE_1_NO_MODE; private SettingsServiceImpl settingsService; diff --git a/crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceFuncTest.java b/crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceFuncTest.java new file mode 100644 index 00000000..df5912df --- /dev/null +++ b/crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsGeneralResourceFuncTest.java @@ -0,0 +1,16 @@ +package it.com.deftdevs.bootstrapi.crowd.rest; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import it.com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceFuncTest; + +public class SettingsGeneralResourceFuncTest extends AbstractSettingsGeneralResourceFuncTest { + + @Override + protected SettingsGeneralModel getExampleModel() { + return SettingsGeneralModel.builder() + .baseUrl(SettingsGeneralModel.EXAMPLE_1.getBaseUrl()) + .title(SettingsGeneralModel.EXAMPLE_1.getTitle()) + .build(); + } + +} diff --git a/crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceFuncTest.java b/crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceFuncTest.java deleted file mode 100644 index ca31a892..00000000 --- a/crowd/src/test/java/it/com/deftdevs/bootstrapi/crowd/rest/SettingsResourceFuncTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package it.com.deftdevs.bootstrapi.crowd.rest; - -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import it.com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceFuncTest; - -public class SettingsResourceFuncTest extends AbstractSettingsResourceFuncTest { - - @Override - protected SettingsModel getExampleModel() { - return SettingsModel.builder() - .baseUrl(SettingsModel.EXAMPLE_1.getBaseUrl()) - .title(SettingsModel.EXAMPLE_1.getTitle()) - .build(); - } - -} diff --git a/jira/Apis/AllApi.md b/jira/Apis/AllApi.md index 83d417e4..a71ed295 100644 --- a/jira/Apis/AllApi.md +++ b/jira/Apis/AllApi.md @@ -9,7 +9,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* # **setAll** -> SettingsModel setAll(\_AllModel) +> _AllModel setAll(\_AllModel) _all @@ -21,7 +21,7 @@ _all ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**_AllModel**](../Models/_AllModel.md) ### Authorization diff --git a/jira/Apis/SettingsApi.md b/jira/Apis/SettingsApi.md index 5f33d6c1..adc60745 100644 --- a/jira/Apis/SettingsApi.md +++ b/jira/Apis/SettingsApi.md @@ -36,7 +36,7 @@ This endpoint does not need any parameter. # **getSettings** -> SettingsModel getSettings() +> SettingsGeneralModel getSettings() Get the general settings @@ -45,7 +45,7 @@ This endpoint does not need any parameter. ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**SettingsGeneralModel**](../Models/SettingsGeneralModel.md) ### Authorization @@ -105,7 +105,7 @@ Set the banner # **setSettings** -> SettingsModel setSettings(SettingsModel) +> SettingsGeneralModel setSettings(SettingsGeneralModel) Set the general settings @@ -113,11 +113,11 @@ Set the general settings |Name | Type | Description | Notes | |------------- | ------------- | ------------- | -------------| -| **SettingsModel** | [**SettingsModel**](../Models/SettingsModel.md)| | [optional] | +| **SettingsGeneralModel** | [**SettingsGeneralModel**](../Models/SettingsGeneralModel.md)| | [optional] | ### Return type -[**SettingsModel**](../Models/SettingsModel.md) +[**SettingsGeneralModel**](../Models/SettingsGeneralModel.md) ### Authorization diff --git a/jira/Models/SettingsGeneralModel.md b/jira/Models/SettingsGeneralModel.md new file mode 100644 index 00000000..8ebe677b --- /dev/null +++ b/jira/Models/SettingsGeneralModel.md @@ -0,0 +1,13 @@ +# SettingsGeneralModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **baseUrl** | **URI** | | [optional] [default to null] | +| **mode** | **String** | | [optional] [default to null] | +| **title** | **String** | | [optional] [default to null] | +| **contactMessage** | **String** | | [optional] [default to null] | +| **externalUserManagement** | **Boolean** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/jira/Models/SettingsModel.md b/jira/Models/SettingsModel.md index f4eb0e7f..23d5cc40 100644 --- a/jira/Models/SettingsModel.md +++ b/jira/Models/SettingsModel.md @@ -3,11 +3,9 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| -| **baseUrl** | **URI** | | [optional] [default to null] | -| **mode** | **String** | | [optional] [default to null] | -| **title** | **String** | | [optional] [default to null] | -| **contactMessage** | **String** | | [optional] [default to null] | -| **externalUserManagement** | **Boolean** | | [optional] [default to null] | +| **general** | [**SettingsGeneralModel**](SettingsGeneralModel.md) | | [optional] [default to null] | +| **security** | [**SettingsSecurityModel**](SettingsSecurityModel.md) | | [optional] [default to null] | +| **banner** | [**SettingsBannerModel**](SettingsBannerModel.md) | | [optional] [default to null] | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/jira/Models/_AllModel.md b/jira/Models/_AllModel.md index 34153397..cd6000f3 100644 --- a/jira/Models/_AllModel.md +++ b/jira/Models/_AllModel.md @@ -4,8 +4,12 @@ | Name | Type | Description | Notes | |------------ | ------------- | ------------- | -------------| | **settings** | [**SettingsModel**](SettingsModel.md) | | [optional] [default to null] | -| **users** | [**Map**](UserModel.md) | | [optional] [default to null] | -| **groups** | [**Map**](GroupModel.md) | | [optional] [default to null] | +| **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | +| **applicationLinks** | [**Map**](ApplicationLinkModel.md) | | [optional] [default to null] | +| **authentication** | [**AuthenticationModel**](AuthenticationModel.md) | | [optional] [default to null] | +| **licenses** | **List** | | [optional] [default to null] | +| **mailServer** | [**MailServerModel**](MailServerModel.md) | | [optional] [default to null] | +| **permissionsGlobal** | [**PermissionsGlobalModel**](PermissionsGlobalModel.md) | | [optional] [default to null] | | **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/jira/README.md b/jira/README.md index ebb27321..2f5bbfbd 100644 --- a/jira/README.md +++ b/jira/README.md @@ -77,6 +77,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* - [MailServerSmtpModel](./Models/MailServerSmtpModel.md) - [PermissionsGlobalModel](./Models/PermissionsGlobalModel.md) - [SettingsBannerModel](./Models/SettingsBannerModel.md) + - [SettingsGeneralModel](./Models/SettingsGeneralModel.md) - [SettingsModel](./Models/SettingsModel.md) - [SettingsSecurityModel](./Models/SettingsSecurityModel.md) - [UserModel](./Models/UserModel.md) diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/config/ServiceConfig.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/config/ServiceConfig.java index bc0b1f91..0671d8c7 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/config/ServiceConfig.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/config/ServiceConfig.java @@ -1,6 +1,7 @@ package com.deftdevs.bootstrapi.jira.config; import com.deftdevs.bootstrapi.commons.service.api.*; +import com.deftdevs.bootstrapi.jira.model._AllModel; import com.deftdevs.bootstrapi.jira.service.*; import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; import com.deftdevs.bootstrapi.jira.service.api.JiraSettingsService; @@ -17,6 +18,18 @@ public class ServiceConfig { @Autowired private HelperConfig helperConfig; + @Bean + public _AllService<_AllModel> _allService() { + return new _AllServiceImpl( + jiraSettingsService(), + directoriesService(), + applicationLinksService(), + jiraAuthenticationService(), + licensesService(), + mailServerService(), + permissionsService()); + } + @Bean public ApplicationLinksService applicationLinksService() { return new ApplicationLinksServiceImpl( diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/SettingsModel.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/SettingsModel.java new file mode 100644 index 00000000..40f39555 --- /dev/null +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/SettingsModel.java @@ -0,0 +1,29 @@ +package com.deftdevs.bootstrapi.jira.model; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@XmlRootElement(name = SETTINGS) +public class SettingsModel { + + @XmlElement + private SettingsGeneralModel general; + + @XmlElement + private SettingsSecurityModel security; + + @XmlElement + private SettingsBannerModel banner; + +} diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java index 2ab910ad..daaa9b5f 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java @@ -1,9 +1,11 @@ package com.deftdevs.bootstrapi.jira.model; import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; -import com.deftdevs.bootstrapi.commons.model.GroupModel; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.model.UserModel; +import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; +import com.deftdevs.bootstrapi.commons.model.ApplicationLinkModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import lombok.AllArgsConstructor; @@ -12,6 +14,7 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; import java.util.Map; @Data @@ -24,10 +27,22 @@ public class _AllModel implements _AllModelAccessor { private SettingsModel settings; @XmlElement - private Map users; + private Map directories; @XmlElement - private Map groups; + private Map applicationLinks; + + @XmlElement + private AuthenticationModel authentication; + + @XmlElement + private List licenses; + + @XmlElement + private MailServerModel mailServer; + + @XmlElement + private PermissionsGlobalModel permissionsGlobal; @XmlElement private Map status; diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/SettingsResourceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceImpl.java similarity index 69% rename from jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/SettingsResourceImpl.java rename to jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceImpl.java index f8b5773b..0730eea6 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/SettingsResourceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceImpl.java @@ -2,8 +2,8 @@ import com.atlassian.plugins.rest.api.security.annotation.SystemAdminOnly; import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; -import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceImpl; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceImpl; import com.deftdevs.bootstrapi.jira.service.api.JiraSettingsService; import io.swagger.v3.oas.annotations.tags.Tag; @@ -18,10 +18,10 @@ @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @SystemAdminOnly -public class SettingsResourceImpl extends AbstractSettingsResourceImpl { +public class SettingsGeneralResourceImpl extends AbstractSettingsGeneralResourceImpl { @Inject - public SettingsResourceImpl( + public SettingsGeneralResourceImpl( final JiraSettingsService settingsService) { super(settingsService); diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceImpl.java index 961a3437..dad34f63 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceImpl.java @@ -3,7 +3,7 @@ import com.atlassian.jira.config.properties.APKeys; import com.atlassian.jira.config.properties.ApplicationProperties; import com.deftdevs.bootstrapi.commons.exception.web.BadRequestException; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import com.deftdevs.bootstrapi.jira.service.api.JiraSettingsService; @@ -28,14 +28,14 @@ public SettingsServiceImpl( } @Override - public SettingsModel getSettingsGeneral() { + public SettingsGeneralModel getSettingsGeneral() { final String baseUrl = applicationProperties.getString(JIRA_BASEURL); final String mode = applicationProperties.getString(JIRA_MODE); final String title = applicationProperties.getString(JIRA_TITLE); final String contactMessage = applicationProperties.getString(JIRA_CONTACT_ADMINISTRATORS_MESSSAGE); final Boolean externalUserManagement = Boolean.parseBoolean(applicationProperties.getString(JIRA_OPTION_USER_EXTERNALMGT)); - final SettingsModel settingsModel = SettingsModel.builder() + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder() .baseUrl(baseUrl != null ? URI.create(baseUrl) : null) .mode(mode) .title(title) @@ -47,8 +47,8 @@ public SettingsModel getSettingsGeneral() { } @Override - public SettingsModel setSettingsGeneral( - final SettingsModel settingsModel) { + public SettingsGeneralModel setSettingsGeneral( + final SettingsGeneralModel settingsModel) { if (settingsModel.getBaseUrl() != null) { applicationProperties.setString(JIRA_BASEURL, settingsModel.getBaseUrl().toString()); diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java new file mode 100644 index 00000000..f500c5a2 --- /dev/null +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -0,0 +1,106 @@ +package com.deftdevs.bootstrapi.jira.service; + +import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; +import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; +import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; +import com.deftdevs.bootstrapi.commons.service.api.LicensesService; +import com.deftdevs.bootstrapi.commons.service.api.MailServerService; +import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; +import com.deftdevs.bootstrapi.jira.model.SettingsModel; +import com.deftdevs.bootstrapi.jira.model._AllModel; +import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; +import com.deftdevs.bootstrapi.jira.service.api.JiraSettingsService; + +import java.util.HashMap; +import java.util.Map; + +public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { + + private final JiraSettingsService settingsService; + private final DirectoriesService directoriesService; + private final ApplicationLinksService applicationLinksService; + private final JiraAuthenticationService authenticationService; + private final LicensesService licensesService; + private final MailServerService mailServerService; + private final PermissionsService permissionsService; + + public _AllServiceImpl( + final JiraSettingsService settingsService, + final DirectoriesService directoriesService, + final ApplicationLinksService applicationLinksService, + final JiraAuthenticationService authenticationService, + final LicensesService licensesService, + final MailServerService mailServerService, + final PermissionsService permissionsService) { + + this.settingsService = settingsService; + this.directoriesService = directoriesService; + this.applicationLinksService = applicationLinksService; + this.authenticationService = authenticationService; + this.licensesService = licensesService; + this.mailServerService = mailServerService; + this.permissionsService = permissionsService; + } + + @Override + public _AllModel setAll( + final _AllModel allModel) { + + final _AllModel result = new _AllModel(); + final Map statusMap = new HashMap<>(); + + // Settings wrapper + final SettingsModel settingsInput = allModel.getSettings(); + if (settingsInput != null) { + final SettingsModel settingsResult = new SettingsModel(); + setEntity("settings/general", settingsInput.getGeneral(), + settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); + setEntity("settings/security", settingsInput.getSecurity(), + settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); + setEntity("settings/banner", settingsInput.getBanner(), + settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); + result.setSettings(settingsResult); + } + + setEntities("directories", allModel.getDirectories(), + directoriesService::setDirectories, result::setDirectories, statusMap); + + setEntities("applicationLinks", allModel.getApplicationLinks(), + applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); + + // Authentication wrapper + final AuthenticationModel authInput = allModel.getAuthentication(); + if (authInput != null) { + final AuthenticationModel authResult = new AuthenticationModel(); + setEntities("authentication/idps", authInput.getIdps(), + authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); + setEntity("authentication/sso", authInput.getSso(), + authenticationService::setAuthenticationSso, authResult::setSso, statusMap); + result.setAuthentication(authResult); + } + + setEntity("licenses", allModel.getLicenses(), + keys -> { licensesService.setLicenses(keys); return keys; }, + result::setLicenses, statusMap); + + // Mail server wrapper + final MailServerModel mailServerInput = allModel.getMailServer(); + if (mailServerInput != null) { + final MailServerModel mailServerResult = new MailServerModel(); + setEntity("mailServer/smtp", mailServerInput.getSmtp(), + mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); + setEntity("mailServer/pop", mailServerInput.getPop(), + mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); + result.setMailServer(mailServerResult); + } + + setEntity("permissionsGlobal", allModel.getPermissionsGlobal(), + permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); + + result.setStatus(statusMap); + return result; + } +} diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java index 7c6b54d8..8242bb3a 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java @@ -1,13 +1,13 @@ package com.deftdevs.bootstrapi.jira.service.api; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; -import com.deftdevs.bootstrapi.commons.service.api.SettingsService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; public interface JiraSettingsService extends - SettingsService, + SettingsGeneralService, SettingsSecurityService { SettingsBannerModel getSettingsBanner(); diff --git a/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/JiraSettingsServiceTest.java b/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/JiraSettingsServiceTest.java index dbd56e8a..ddcba2aa 100644 --- a/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/JiraSettingsServiceTest.java +++ b/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/JiraSettingsServiceTest.java @@ -2,7 +2,7 @@ import com.atlassian.jira.config.properties.ApplicationProperties; import com.deftdevs.bootstrapi.commons.exception.web.BadRequestException; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -43,7 +43,7 @@ void testGetSettingsGeneral() { doReturn(CONTACT_MESSAGE).when(applicationProperties).getString(JIRA_CONTACT_ADMINISTRATORS_MESSSAGE); doReturn(EXTERNAL_USER_MANAGEMENT).when(applicationProperties).getString(JIRA_OPTION_USER_EXTERNALMGT); - final SettingsModel settingsModel = settingsService.getSettingsGeneral(); + final SettingsGeneralModel settingsModel = settingsService.getSettingsGeneral(); assertEquals(BASE_URL, settingsModel.getBaseUrl()); assertEquals(MODE_PUBLIC, settingsModel.getMode()); @@ -54,7 +54,7 @@ void testGetSettingsGeneral() { @Test void testSetSettingsGeneral() { - final SettingsModel settingsModel = SettingsModel.builder() + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder() .baseUrl(BASE_URL) .mode(MODE_PUBLIC) .title(TITLE) @@ -73,7 +73,7 @@ void testSetSettingsGeneral() { @Test void testSetSettingsGeneralEmptyModel() { - final SettingsModel settingsModel = SettingsModel.builder().build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().build(); settingsService.setSettingsGeneral(settingsModel); @@ -85,7 +85,7 @@ void testSetSettingsGeneralEmptyModel() { @Test void testSetSettingsGeneralUnsupportedMode() { - final SettingsModel settingsModel = SettingsModel.builder().mode("unsupported").build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().mode("unsupported").build(); assertThrows(BadRequestException.class, () -> { settingsService.setSettingsGeneral(settingsModel); @@ -94,7 +94,7 @@ void testSetSettingsGeneralUnsupportedMode() { @Test void testSetSettingsGeneralInvalidCombination() { - final SettingsModel settingsModel = SettingsModel.builder().mode(MODE_PUBLIC).build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().mode(MODE_PUBLIC).build(); doReturn(true).when(applicationProperties).getOption(JIRA_OPTION_USER_EXTERNALMGT); assertThrows(BadRequestException.class, () -> { diff --git a/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceTest.java b/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceTest.java index c4992884..c176c44f 100644 --- a/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceTest.java +++ b/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/SettingsServiceTest.java @@ -2,7 +2,7 @@ import com.atlassian.jira.config.properties.ApplicationProperties; import com.deftdevs.bootstrapi.commons.exception.web.BadRequestException; -import com.deftdevs.bootstrapi.commons.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import org.junit.jupiter.api.BeforeEach; @@ -45,7 +45,7 @@ void testGetSettingsGeneral() { doReturn(CONTACT_MESSAGE).when(applicationProperties).getString(JIRA_CONTACT_ADMINISTRATORS_MESSSAGE); doReturn(EXTERNAL_USER_MANAGEMENT).when(applicationProperties).getString(JIRA_OPTION_USER_EXTERNALMGT); - final SettingsModel settingsModel = settingsService.getSettingsGeneral(); + final SettingsGeneralModel settingsModel = settingsService.getSettingsGeneral(); assertEquals(BASE_URL, settingsModel.getBaseUrl()); assertEquals(MODE_PUBLIC, settingsModel.getMode()); @@ -56,7 +56,7 @@ void testGetSettingsGeneral() { @Test void testSetSettingsGeneral() { - final SettingsModel settingsModel = SettingsModel.builder() + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder() .baseUrl(BASE_URL) .mode(MODE_PUBLIC) .title(TITLE) @@ -75,7 +75,7 @@ void testSetSettingsGeneral() { @Test void testSetSettingsGeneralEmptyModel() { - final SettingsModel settingsModel = SettingsModel.builder().build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().build(); settingsService.setSettingsGeneral(settingsModel); @@ -109,7 +109,7 @@ void testSetSettingsSecurity() { @Test void testSetSettingsGeneralUnsupportedMode() { - final SettingsModel settingsModel = SettingsModel.builder().mode("unsupported").build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().mode("unsupported").build(); assertThrows(BadRequestException.class, () -> { settingsService.setSettingsGeneral(settingsModel); @@ -118,7 +118,7 @@ void testSetSettingsGeneralUnsupportedMode() { @Test void testSetSettingsGeneralInvalidCombination() { - final SettingsModel settingsModel = SettingsModel.builder().mode(MODE_PUBLIC).build(); + final SettingsGeneralModel settingsModel = SettingsGeneralModel.builder().mode(MODE_PUBLIC).build(); doReturn(true).when(applicationProperties).getOption(JIRA_OPTION_USER_EXTERNALMGT); assertThrows(BadRequestException.class, () -> { diff --git a/jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceFuncTest.java b/jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceFuncTest.java new file mode 100644 index 00000000..d8d7c2d8 --- /dev/null +++ b/jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsGeneralResourceFuncTest.java @@ -0,0 +1,5 @@ +package it.com.deftdevs.bootstrapi.jira.rest; + +import it.com.deftdevs.bootstrapi.commons.rest.AbstractSettingsGeneralResourceFuncTest; + +public class SettingsGeneralResourceFuncTest extends AbstractSettingsGeneralResourceFuncTest { } diff --git a/jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsResourceFuncTest.java b/jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsResourceFuncTest.java deleted file mode 100644 index cc6cc1a1..00000000 --- a/jira/src/test/java/it/com/deftdevs/bootstrapi/jira/rest/SettingsResourceFuncTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package it.com.deftdevs.bootstrapi.jira.rest; - -import it.com.deftdevs.bootstrapi.commons.rest.AbstractSettingsResourceFuncTest; - -public class SettingsResourceFuncTest extends AbstractSettingsResourceFuncTest { } From 9a56f55e8a8f5fc07b44bc4af9be479e94074106 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Wed, 25 Feb 2026 13:06:54 +0800 Subject: [PATCH 04/11] WIP_CONSTANTS --- .../commons/constants/BootstrAPI.java | 4 +++ .../commons/model/SettingsGeneralModel.java | 6 +++-- .../confluence/service/_AllServiceImpl.java | 26 ++++++++++--------- .../crowd/service/_AllServiceImpl.java | 24 +++++++++-------- .../crowd/rest/AllResourceTest.java | 7 ++--- .../jira/service/_AllServiceImpl.java | 24 +++++++++-------- 6 files changed, 52 insertions(+), 39 deletions(-) diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java index 0578727b..ed6fbc8d 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java @@ -40,20 +40,24 @@ public class BootstrAPI { public static final String MAIL_SERVERS = "mail-servers"; public static final String MAIL_SERVER_POP = "pop"; public static final String MAIL_SERVER_SMTP = "smtp"; + public static final String MAIL_TEMPLATES = "mail-templates"; public static final String PERMISSION = "permission"; public static final String PERMISSIONS = "permissions"; public static final String PERMISSION_ANONYMOUS_ACCESS = "anonymous-access"; public static final String PERMISSIONS_GLOBAL = "global"; public static final String PING = "ping"; + public static final String SESSION_CONFIG = "session-config"; public static final String SETTINGS = "settings"; public static final String SETTINGS_BANNER = "banner"; public static final String SETTINGS_BRANDING = "branding"; public static final String SETTINGS_BRANDING_LOGIN_PAGE = "login-page"; public static final String SETTINGS_BRANDING_LOGO = "logo"; public static final String SETTINGS_CUSTOM_HTML = "custom-html"; + public static final String SETTINGS_GENERAL = "general"; public static final String SETTINGS_SECURITY = "security"; public static final String USER = "user"; public static final String USERS = "users"; + public static final String TRUSTED_PROXIES = "trusted-proxies"; public static final String USER_PASSWORD = "password"; public static final String MEDIA_TYPE_IMAGE = "image/*"; diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java index 64e4f7d6..db8e9dbe 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsGeneralModel.java @@ -1,6 +1,5 @@ package com.deftdevs.bootstrapi.commons.model; -import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Builder; @@ -13,11 +12,14 @@ import javax.xml.bind.annotation.XmlRootElement; import java.net.URI; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; + @Data @Builder @NoArgsConstructor @AllArgsConstructor -@XmlRootElement(name = BootstrAPI.SETTINGS) +@XmlRootElement(name = SETTINGS + "-" + SETTINGS_GENERAL) @XmlAccessorType(XmlAccessType.FIELD) public class SettingsGeneralModel { diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index 568cf721..6e133b2d 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -18,6 +18,8 @@ import java.util.HashMap; import java.util.Map; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; + public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { private final ConfluenceSettingsService settingsService; @@ -60,35 +62,35 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity("settings/general", settingsInput.getGeneral(), + setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity("settings/security", settingsInput.getSecurity(), + setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity("settings/branding", settingsInput.getBranding(), + setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); - setEntity("settings/customHtml", settingsInput.getCustomHtml(), + setEntity(SETTINGS + "/" + SETTINGS_CUSTOM_HTML, settingsInput.getCustomHtml(), settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); result.setSettings(settingsResult); } - setEntities("directories", allModel.getDirectories(), + setEntities(DIRECTORIES, allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); - setEntities("applicationLinks", allModel.getApplicationLinks(), + setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); // Authentication wrapper final AuthenticationModel authInput = allModel.getAuthentication(); if (authInput != null) { final AuthenticationModel authResult = new AuthenticationModel(); - setEntities("authentication/idps", authInput.getIdps(), + setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity("authentication/sso", authInput.getSso(), + setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } - setEntity("licenses", allModel.getLicenses(), + setEntity(LICENSES, allModel.getLicenses(), keys -> { licensesService.setLicenses(keys); return keys; }, result::setLicenses, statusMap); @@ -96,14 +98,14 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity("mailServer/smtp", mailServerInput.getSmtp(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity("mailServer/pop", mailServerInput.getPop(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity("permissionsGlobal", allModel.getPermissionsGlobal(), + setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 19ceea62..12cb0021 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -19,6 +19,8 @@ import java.util.HashMap; import java.util.Map; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; + public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { private final CrowdSettingsGeneralService settingsService; @@ -67,23 +69,23 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity("settings/general", settingsInput.getGeneral(), + setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity("settings/branding", settingsInput.getBranding(), + setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), brandingService::setLoginPage, settingsResult::setBranding, statusMap); result.setSettings(settingsResult); } - setEntities("directories", allModel.getDirectories(), + setEntities(DIRECTORIES, allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); - setEntities("applications", allModel.getApplications(), + setEntities(APPLICATIONS, allModel.getApplications(), applicationsService::setApplications, result::setApplications, statusMap); - setEntities("applicationLinks", allModel.getApplicationLinks(), + setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - setEntity("licenses", allModel.getLicenses(), + setEntity(LICENSES, allModel.getLicenses(), keys -> { licensesService.setLicenses(keys); return keys; }, result::setLicenses, statusMap); @@ -91,20 +93,20 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity("mailServer/smtp", mailServerInput.getSmtp(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity("mailServer/pop", mailServerInput.getPop(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity("mailTemplates", allModel.getMailTemplates(), + setEntity(MAIL_TEMPLATES, allModel.getMailTemplates(), mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); - setEntity("sessionConfig", allModel.getSessionConfig(), + setEntity(SESSION_CONFIG, allModel.getSessionConfig(), sessionConfigService::setSessionConfig, result::setSessionConfig, statusMap); - setEntity("trustedProxies", allModel.getTrustedProxies(), + setEntity(TRUSTED_PROXIES, allModel.getTrustedProxies(), trustedProxiesService::setTrustedProxies, result::setTrustedProxies, statusMap); result.setStatus(statusMap); diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java index b763fa8a..144762eb 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.Map; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.*; @@ -45,9 +46,9 @@ public void setup() { allModel.setApplications(applications); Map status = new HashMap<>(); - status.put("settings/general", _AllModelStatus.success()); - status.put("directories", _AllModelStatus.success()); - status.put("applications", _AllModelStatus.success()); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, _AllModelStatus.success()); + status.put(APPLICATIONS, _AllModelStatus.success()); allModel.setStatus(status); } diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index f500c5a2..71606181 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -17,6 +17,8 @@ import java.util.HashMap; import java.util.Map; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; + public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { private final JiraSettingsService settingsService; @@ -56,33 +58,33 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity("settings/general", settingsInput.getGeneral(), + setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity("settings/security", settingsInput.getSecurity(), + setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity("settings/banner", settingsInput.getBanner(), + setEntity(SETTINGS + "/" + SETTINGS_BANNER, settingsInput.getBanner(), settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); result.setSettings(settingsResult); } - setEntities("directories", allModel.getDirectories(), + setEntities(DIRECTORIES, allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); - setEntities("applicationLinks", allModel.getApplicationLinks(), + setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); // Authentication wrapper final AuthenticationModel authInput = allModel.getAuthentication(); if (authInput != null) { final AuthenticationModel authResult = new AuthenticationModel(); - setEntities("authentication/idps", authInput.getIdps(), + setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity("authentication/sso", authInput.getSso(), + setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } - setEntity("licenses", allModel.getLicenses(), + setEntity(LICENSES, allModel.getLicenses(), keys -> { licensesService.setLicenses(keys); return keys; }, result::setLicenses, statusMap); @@ -90,14 +92,14 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity("mailServer/smtp", mailServerInput.getSmtp(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity("mailServer/pop", mailServerInput.getPop(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity("permissionsGlobal", allModel.getPermissionsGlobal(), + setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); From 1a714a5e5fef1d496c6e9312b075fa9443f7f1b3 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 5 May 2026 19:45:21 +0800 Subject: [PATCH 05/11] WIP_IDK --- .../SettingsBrandingColorSchemeModel.java | 2 +- .../service/_AbstractAllServiceImpl.java | 48 +++++++++++++++++++ confluence/Apis/AllApi.md | 8 ++-- confluence/Models/AbstractDirectoryModel.md | 2 +- confluence/Models/AuthenticationModel.md | 10 ++++ confluence/Models/DirectoryCrowdModel.md | 2 +- confluence/Models/DirectoryDelegatingModel.md | 2 +- confluence/Models/DirectoryGenericModel.md | 2 +- confluence/Models/DirectoryInternalModel.md | 2 +- confluence/Models/DirectoryLdapModel.md | 2 +- confluence/Models/MailServerModel.md | 10 ++++ confluence/README.md | 4 +- .../confluence/service/_AllServiceImpl.java | 26 ++++++---- crowd/Apis/AllApi.md | 8 ++-- crowd/Models/AbstractDirectoryModel.md | 2 +- crowd/Models/DirectoryCrowdModel.md | 2 +- crowd/Models/DirectoryDelegatingModel.md | 2 +- crowd/Models/DirectoryGenericModel.md | 2 +- crowd/Models/DirectoryInternalModel.md | 2 +- crowd/Models/DirectoryLdapModel.md | 2 +- crowd/Models/MailServerModel.md | 10 ++++ crowd/Models/MailServerPopModel.md | 16 +++++++ crowd/README.md | 4 +- .../model/SettingsBrandingLoginPageModel.java | 6 ++- .../crowd/service/_AllServiceImpl.java | 18 ++++--- jira/Apis/AllApi.md | 8 ++-- jira/Models/AbstractDirectoryModel.md | 2 +- jira/Models/AuthenticationModel.md | 10 ++++ jira/Models/DirectoryCrowdModel.md | 2 +- jira/Models/DirectoryDelegatingModel.md | 2 +- jira/Models/DirectoryGenericModel.md | 2 +- jira/Models/DirectoryInternalModel.md | 2 +- jira/Models/DirectoryLdapModel.md | 2 +- jira/Models/MailServerModel.md | 10 ++++ jira/README.md | 4 +- .../jira/service/_AllServiceImpl.java | 23 +++++---- 36 files changed, 202 insertions(+), 59 deletions(-) create mode 100644 confluence/Models/AuthenticationModel.md create mode 100644 confluence/Models/MailServerModel.md create mode 100644 crowd/Models/MailServerModel.md create mode 100644 crowd/Models/MailServerPopModel.md create mode 100644 jira/Models/AuthenticationModel.md create mode 100644 jira/Models/MailServerModel.md diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsBrandingColorSchemeModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsBrandingColorSchemeModel.java index 29fe6548..66740ab0 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsBrandingColorSchemeModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/SettingsBrandingColorSchemeModel.java @@ -16,7 +16,7 @@ @Builder @NoArgsConstructor @AllArgsConstructor -@XmlRootElement(name = SETTINGS + "-" + SETTINGS_BRANDING + "-" + COLOR_SCHEME) +@XmlRootElement(name = SETTINGS + "-" + SETTINGS_BRANDING) @XmlAccessorType(XmlAccessType.FIELD) public class SettingsBrandingColorSchemeModel { diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index 7db34a8c..21d2c6bb 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -5,12 +5,60 @@ import com.deftdevs.bootstrapi.commons.service.api._AllService; import javax.ws.rs.core.Response; +import javax.xml.bind.annotation.XmlRootElement; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { + /** + * Resolves the entity type identifier from the {@link XmlRootElement} annotation + * of the given model class. + * + * @param entityClass the model class + * @return the root element name + */ + protected static String entityType( + final Class entityClass) { + + final XmlRootElement rootElement = entityClass.getAnnotation(XmlRootElement.class); + if (rootElement == null || "##default".equals(rootElement.name())) { + throw new IllegalArgumentException( + entityClass.getName() + " must have @XmlRootElement with explicit name"); + } + return rootElement.name(); + } + + /** + * Resolves a hierarchical entity type identifier from the {@link XmlRootElement} annotations + * of the parent and child model classes by stripping the parent prefix from the child name. + *

+ * For example, given parent {@code SettingsModel} with root element {@code "settings"} + * and child {@code SettingsGeneralModel} with root element {@code "settings-general"}, + * this returns {@code "settings/general"}. + * + * @param parentClass the wrapper model class + * @param childClass the child model class + * @return the hierarchical entity type (e.g. "settings/general") + */ + protected static String entityType( + final Class parentClass, + final Class childClass) { + + final String parentName = entityType(parentClass); + final String childName = entityType(childClass); + final String expectedPrefix = parentName + "-"; + + if (!childName.startsWith(expectedPrefix)) { + throw new IllegalArgumentException( + childClass.getName() + " root element '" + childName + + "' does not follow parent prefix convention '" + expectedPrefix + "'"); + } + + return parentName + "/" + childName.substring(expectedPrefix.length()); + } + protected _AllModelStatus setEntity( final String entityType, final T entity, diff --git a/confluence/Apis/AllApi.md b/confluence/Apis/AllApi.md index 2ee156ed..4636a333 100644 --- a/confluence/Apis/AllApi.md +++ b/confluence/Apis/AllApi.md @@ -4,14 +4,14 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* | Method | HTTP request | Description | |------------- | ------------- | -------------| -| [**setAll**](AllApi.md#setAll) | **PUT** / | _all | +| [**setAll**](AllApi.md#setAll) | **PUT** / | Apply a complete configuration | # **setAll** -> _AllModel setAll(\_AllModel) +> setAll(\_AllModel) -_all +Apply a complete configuration ### Parameters @@ -21,7 +21,7 @@ _all ### Return type -[**_AllModel**](../Models/_AllModel.md) +null (empty response body) ### Authorization diff --git a/confluence/Models/AbstractDirectoryModel.md b/confluence/Models/AbstractDirectoryModel.md index cde79f6a..7ef166ee 100644 --- a/confluence/Models/AbstractDirectoryModel.md +++ b/confluence/Models/AbstractDirectoryModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **connector** | [**DirectoryDelegatingConnector**](DirectoryDelegatingConnector.md) | | [optional] [default to null] | | **configuration** | [**DirectoryDelegatingConfiguration**](DirectoryDelegatingConfiguration.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | diff --git a/confluence/Models/AuthenticationModel.md b/confluence/Models/AuthenticationModel.md new file mode 100644 index 00000000..b873bdc6 --- /dev/null +++ b/confluence/Models/AuthenticationModel.md @@ -0,0 +1,10 @@ +# AuthenticationModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **idps** | [**Map**](AbstractAuthenticationIdpModel.md) | | [optional] [default to null] | +| **sso** | [**AuthenticationSsoModel**](AuthenticationSsoModel.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/confluence/Models/DirectoryCrowdModel.md b/confluence/Models/DirectoryCrowdModel.md index d58a9ad3..655455e4 100644 --- a/confluence/Models/DirectoryCrowdModel.md +++ b/confluence/Models/DirectoryCrowdModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryCrowdServer**](DirectoryCrowdServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryCrowdPermissions**](DirectoryCrowdPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryCrowdAdvanced**](DirectoryCrowdAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryDelegatingModel.md b/confluence/Models/DirectoryDelegatingModel.md index 01c3480b..241e45d1 100644 --- a/confluence/Models/DirectoryDelegatingModel.md +++ b/confluence/Models/DirectoryDelegatingModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryGenericModel.md b/confluence/Models/DirectoryGenericModel.md index 71c67548..ec59bab6 100644 --- a/confluence/Models/DirectoryGenericModel.md +++ b/confluence/Models/DirectoryGenericModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryInternalModel.md b/confluence/Models/DirectoryInternalModel.md index 2ccbe759..472b0c05 100644 --- a/confluence/Models/DirectoryInternalModel.md +++ b/confluence/Models/DirectoryInternalModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/DirectoryLdapModel.md b/confluence/Models/DirectoryLdapModel.md index 97eb576e..c5c48bfe 100644 --- a/confluence/Models/DirectoryLdapModel.md +++ b/confluence/Models/DirectoryLdapModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/confluence/Models/MailServerModel.md b/confluence/Models/MailServerModel.md new file mode 100644 index 00000000..34c39bf7 --- /dev/null +++ b/confluence/Models/MailServerModel.md @@ -0,0 +1,10 @@ +# MailServerModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **smtp** | [**MailServerSmtpModel**](MailServerSmtpModel.md) | | [optional] [default to null] | +| **pop** | [**MailServerPopModel**](MailServerPopModel.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/confluence/README.md b/confluence/README.md index 1487b2b2..b7ade9ea 100644 --- a/confluence/README.md +++ b/confluence/README.md @@ -7,7 +7,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| -| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | _all | +| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | Apply a complete configuration | | *ApplicationLinkApi* | [**createApplicationLink**](Apis/ApplicationLinkApi.md#createApplicationLink) | **POST** /application-link | Create an application link | *ApplicationLinkApi* | [**deleteApplicationLink**](Apis/ApplicationLinkApi.md#deleteApplicationLink) | **DELETE** /application-link/{uuid} | Delete an application link | *ApplicationLinkApi* | [**getApplicationLink**](Apis/ApplicationLinkApi.md#getApplicationLink) | **GET** /application-link/{uuid} | Get an application link | @@ -65,6 +65,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* - [ApplicationLinkModel](./Models/ApplicationLinkModel.md) - [AuthenticationIdpOidcModel](./Models/AuthenticationIdpOidcModel.md) - [AuthenticationIdpSamlModel](./Models/AuthenticationIdpSamlModel.md) + - [AuthenticationModel](./Models/AuthenticationModel.md) - [AuthenticationSsoModel](./Models/AuthenticationSsoModel.md) - [CacheModel](./Models/CacheModel.md) - [DirectoryCrowdAdvanced](./Models/DirectoryCrowdAdvanced.md) @@ -87,6 +88,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* - [ErrorCollection](./Models/ErrorCollection.md) - [GroupModel](./Models/GroupModel.md) - [LicenseModel](./Models/LicenseModel.md) + - [MailServerModel](./Models/MailServerModel.md) - [MailServerPopModel](./Models/MailServerPopModel.md) - [MailServerSmtpModel](./Models/MailServerSmtpModel.md) - [PermissionsGlobalModel](./Models/PermissionsGlobalModel.md) diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index 6e133b2d..a1858180 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -1,7 +1,14 @@ package com.deftdevs.bootstrapi.confluence.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; +import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; +import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -10,6 +17,7 @@ import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; +import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import com.deftdevs.bootstrapi.confluence.model.SettingsModel; import com.deftdevs.bootstrapi.confluence.model._AllModel; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; @@ -62,13 +70,13 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), + setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), + setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), + setEntity(entityType(SettingsModel.class, SettingsBrandingColorSchemeModel.class), settingsInput.getBranding(), settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_CUSTOM_HTML, settingsInput.getCustomHtml(), + setEntity(entityType(SettingsModel.class, SettingsCustomHtmlModel.class), settingsInput.getCustomHtml(), settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); result.setSettings(settingsResult); } @@ -83,9 +91,9 @@ public _AllModel setAll( final AuthenticationModel authInput = allModel.getAuthentication(); if (authInput != null) { final AuthenticationModel authResult = new AuthenticationModel(); - setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), + setEntities(entityType(AuthenticationModel.class) + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), + setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } @@ -98,14 +106,14 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), + setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), + setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), + setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/crowd/Apis/AllApi.md b/crowd/Apis/AllApi.md index dadcc835..2e3d15cd 100644 --- a/crowd/Apis/AllApi.md +++ b/crowd/Apis/AllApi.md @@ -4,14 +4,14 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* | Method | HTTP request | Description | |------------- | ------------- | -------------| -| [**setAll**](AllApi.md#setAll) | **PUT** / | _all | +| [**setAll**](AllApi.md#setAll) | **PUT** / | Apply a complete configuration | # **setAll** -> _AllModel setAll(\_AllModel) +> setAll(\_AllModel) -_all +Apply a complete configuration ### Parameters @@ -21,7 +21,7 @@ _all ### Return type -[**_AllModel**](../Models/_AllModel.md) +null (empty response body) ### Authorization diff --git a/crowd/Models/AbstractDirectoryModel.md b/crowd/Models/AbstractDirectoryModel.md index cde79f6a..7ef166ee 100644 --- a/crowd/Models/AbstractDirectoryModel.md +++ b/crowd/Models/AbstractDirectoryModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **connector** | [**DirectoryDelegatingConnector**](DirectoryDelegatingConnector.md) | | [optional] [default to null] | | **configuration** | [**DirectoryDelegatingConfiguration**](DirectoryDelegatingConfiguration.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryCrowdModel.md b/crowd/Models/DirectoryCrowdModel.md index d58a9ad3..655455e4 100644 --- a/crowd/Models/DirectoryCrowdModel.md +++ b/crowd/Models/DirectoryCrowdModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryCrowdServer**](DirectoryCrowdServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryCrowdPermissions**](DirectoryCrowdPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryCrowdAdvanced**](DirectoryCrowdAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryDelegatingModel.md b/crowd/Models/DirectoryDelegatingModel.md index 01c3480b..241e45d1 100644 --- a/crowd/Models/DirectoryDelegatingModel.md +++ b/crowd/Models/DirectoryDelegatingModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryGenericModel.md b/crowd/Models/DirectoryGenericModel.md index 71c67548..ec59bab6 100644 --- a/crowd/Models/DirectoryGenericModel.md +++ b/crowd/Models/DirectoryGenericModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryInternalModel.md b/crowd/Models/DirectoryInternalModel.md index 2ccbe759..472b0c05 100644 --- a/crowd/Models/DirectoryInternalModel.md +++ b/crowd/Models/DirectoryInternalModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/DirectoryLdapModel.md b/crowd/Models/DirectoryLdapModel.md index 97eb576e..c5c48bfe 100644 --- a/crowd/Models/DirectoryLdapModel.md +++ b/crowd/Models/DirectoryLdapModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/crowd/Models/MailServerModel.md b/crowd/Models/MailServerModel.md new file mode 100644 index 00000000..34c39bf7 --- /dev/null +++ b/crowd/Models/MailServerModel.md @@ -0,0 +1,10 @@ +# MailServerModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **smtp** | [**MailServerSmtpModel**](MailServerSmtpModel.md) | | [optional] [default to null] | +| **pop** | [**MailServerPopModel**](MailServerPopModel.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/crowd/Models/MailServerPopModel.md b/crowd/Models/MailServerPopModel.md new file mode 100644 index 00000000..72025fb3 --- /dev/null +++ b/crowd/Models/MailServerPopModel.md @@ -0,0 +1,16 @@ +# MailServerPopModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **name** | **String** | | [optional] [default to null] | +| **description** | **String** | | [optional] [default to null] | +| **host** | **String** | | [optional] [default to null] | +| **port** | **Integer** | | [optional] [default to null] | +| **protocol** | **String** | | [optional] [default to null] | +| **timeout** | **Long** | | [optional] [default to null] | +| **username** | **String** | | [optional] [default to null] | +| **password** | **String** | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/crowd/README.md b/crowd/README.md index 1332e75e..a3260ab0 100644 --- a/crowd/README.md +++ b/crowd/README.md @@ -7,7 +7,7 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| -| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | _all | +| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | Apply a complete configuration | | *ApplicationApi* | [**createApplication**](Apis/ApplicationApi.md#createApplication) | **POST** /application | Create an application | *ApplicationApi* | [**deleteApplication**](Apis/ApplicationApi.md#deleteApplication) | **DELETE** /application/{id} | Delete an application | *ApplicationApi* | [**getApplication**](Apis/ApplicationApi.md#getApplication) | **GET** /application/{id} | Get an application | @@ -84,6 +84,8 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* - [ErrorCollection](./Models/ErrorCollection.md) - [GroupModel](./Models/GroupModel.md) - [LicenseModel](./Models/LicenseModel.md) + - [MailServerModel](./Models/MailServerModel.md) + - [MailServerPopModel](./Models/MailServerPopModel.md) - [MailServerSmtpModel](./Models/MailServerSmtpModel.md) - [MailTemplatesModel](./Models/MailTemplatesModel.md) - [SessionConfigModel](./Models/SessionConfigModel.md) diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsBrandingLoginPageModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsBrandingLoginPageModel.java index 3107978b..d1a327a2 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsBrandingLoginPageModel.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/SettingsBrandingLoginPageModel.java @@ -1,6 +1,5 @@ package com.deftdevs.bootstrapi.crowd.model; -import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import lombok.AllArgsConstructor; import lombok.Data; import lombok.Builder; @@ -9,11 +8,14 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BRANDING; + @Data @Builder @NoArgsConstructor @AllArgsConstructor -@XmlRootElement(name = BootstrAPI.SETTINGS_BRANDING_LOGIN_PAGE) +@XmlRootElement(name = SETTINGS + "-" + SETTINGS_BRANDING) public class SettingsBrandingLoginPageModel { @XmlElement diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 12cb0021..52913ac8 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,12 +1,18 @@ package com.deftdevs.bootstrapi.crowd.service; import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; +import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; +import com.deftdevs.bootstrapi.crowd.model.MailTemplatesModel; +import com.deftdevs.bootstrapi.crowd.model.SessionConfigModel; +import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; @@ -69,9 +75,9 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), + setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), + setEntity(entityType(SettingsModel.class, SettingsBrandingLoginPageModel.class), settingsInput.getBranding(), brandingService::setLoginPage, settingsResult::setBranding, statusMap); result.setSettings(settingsResult); } @@ -93,17 +99,17 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), + setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), + setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(MAIL_TEMPLATES, allModel.getMailTemplates(), + setEntity(entityType(MailTemplatesModel.class), allModel.getMailTemplates(), mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); - setEntity(SESSION_CONFIG, allModel.getSessionConfig(), + setEntity(entityType(SessionConfigModel.class), allModel.getSessionConfig(), sessionConfigService::setSessionConfig, result::setSessionConfig, statusMap); setEntity(TRUSTED_PROXIES, allModel.getTrustedProxies(), diff --git a/jira/Apis/AllApi.md b/jira/Apis/AllApi.md index a71ed295..3a239341 100644 --- a/jira/Apis/AllApi.md +++ b/jira/Apis/AllApi.md @@ -4,14 +4,14 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* | Method | HTTP request | Description | |------------- | ------------- | -------------| -| [**setAll**](AllApi.md#setAll) | **PUT** / | _all | +| [**setAll**](AllApi.md#setAll) | **PUT** / | Apply a complete configuration | # **setAll** -> _AllModel setAll(\_AllModel) +> setAll(\_AllModel) -_all +Apply a complete configuration ### Parameters @@ -21,7 +21,7 @@ _all ### Return type -[**_AllModel**](../Models/_AllModel.md) +null (empty response body) ### Authorization diff --git a/jira/Models/AbstractDirectoryModel.md b/jira/Models/AbstractDirectoryModel.md index cde79f6a..7ef166ee 100644 --- a/jira/Models/AbstractDirectoryModel.md +++ b/jira/Models/AbstractDirectoryModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **connector** | [**DirectoryDelegatingConnector**](DirectoryDelegatingConnector.md) | | [optional] [default to null] | | **configuration** | [**DirectoryDelegatingConfiguration**](DirectoryDelegatingConfiguration.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | diff --git a/jira/Models/AuthenticationModel.md b/jira/Models/AuthenticationModel.md new file mode 100644 index 00000000..b873bdc6 --- /dev/null +++ b/jira/Models/AuthenticationModel.md @@ -0,0 +1,10 @@ +# AuthenticationModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **idps** | [**Map**](AbstractAuthenticationIdpModel.md) | | [optional] [default to null] | +| **sso** | [**AuthenticationSsoModel**](AuthenticationSsoModel.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/jira/Models/DirectoryCrowdModel.md b/jira/Models/DirectoryCrowdModel.md index d58a9ad3..655455e4 100644 --- a/jira/Models/DirectoryCrowdModel.md +++ b/jira/Models/DirectoryCrowdModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryCrowdServer**](DirectoryCrowdServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryCrowdPermissions**](DirectoryCrowdPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryCrowdAdvanced**](DirectoryCrowdAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryDelegatingModel.md b/jira/Models/DirectoryDelegatingModel.md index 01c3480b..241e45d1 100644 --- a/jira/Models/DirectoryDelegatingModel.md +++ b/jira/Models/DirectoryDelegatingModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryGenericModel.md b/jira/Models/DirectoryGenericModel.md index 71c67548..ec59bab6 100644 --- a/jira/Models/DirectoryGenericModel.md +++ b/jira/Models/DirectoryGenericModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryInternalModel.md b/jira/Models/DirectoryInternalModel.md index 2ccbe759..472b0c05 100644 --- a/jira/Models/DirectoryInternalModel.md +++ b/jira/Models/DirectoryInternalModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryPermissions**](DirectoryPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/DirectoryLdapModel.md b/jira/Models/DirectoryLdapModel.md index 97eb576e..c5c48bfe 100644 --- a/jira/Models/DirectoryLdapModel.md +++ b/jira/Models/DirectoryLdapModel.md @@ -9,8 +9,8 @@ | **active** | **Boolean** | | [optional] [default to null] | | **createdDate** | **Date** | | [optional] [default to null] | | **updatedDate** | **Date** | | [optional] [default to null] | -| **testConnection** | **Boolean** | | [optional] [default to null] | | **type** | **String** | | [default to null] | +| **testConnection** | **Boolean** | | [optional] [default to null] | | **server** | [**DirectoryLdapServer**](DirectoryLdapServer.md) | | [optional] [default to null] | | **permissions** | [**DirectoryLdapPermissions**](DirectoryLdapPermissions.md) | | [optional] [default to null] | | **advanced** | [**DirectoryInternalAdvanced**](DirectoryInternalAdvanced.md) | | [optional] [default to null] | diff --git a/jira/Models/MailServerModel.md b/jira/Models/MailServerModel.md new file mode 100644 index 00000000..34c39bf7 --- /dev/null +++ b/jira/Models/MailServerModel.md @@ -0,0 +1,10 @@ +# MailServerModel +## Properties + +| Name | Type | Description | Notes | +|------------ | ------------- | ------------- | -------------| +| **smtp** | [**MailServerSmtpModel**](MailServerSmtpModel.md) | | [optional] [default to null] | +| **pop** | [**MailServerPopModel**](MailServerPopModel.md) | | [optional] [default to null] | + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/jira/README.md b/jira/README.md index 2f5bbfbd..82ce76d4 100644 --- a/jira/README.md +++ b/jira/README.md @@ -7,7 +7,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* | Class | Method | HTTP request | Description | |------------ | ------------- | ------------- | -------------| -| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | _all | +| *AllApi* | [**setAll**](Apis/AllApi.md#setAll) | **PUT** / | Apply a complete configuration | | *ApplicationLinkApi* | [**createApplicationLink**](Apis/ApplicationLinkApi.md#createApplicationLink) | **POST** /application-link | Create an application link | *ApplicationLinkApi* | [**deleteApplicationLink**](Apis/ApplicationLinkApi.md#deleteApplicationLink) | **DELETE** /application-link/{uuid} | Delete an application link | *ApplicationLinkApi* | [**getApplicationLink**](Apis/ApplicationLinkApi.md#getApplicationLink) | **GET** /application-link/{uuid} | Get an application link | @@ -52,6 +52,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* - [ApplicationLinkModel](./Models/ApplicationLinkModel.md) - [AuthenticationIdpOidcModel](./Models/AuthenticationIdpOidcModel.md) - [AuthenticationIdpSamlModel](./Models/AuthenticationIdpSamlModel.md) + - [AuthenticationModel](./Models/AuthenticationModel.md) - [AuthenticationSsoModel](./Models/AuthenticationSsoModel.md) - [DirectoryCrowdAdvanced](./Models/DirectoryCrowdAdvanced.md) - [DirectoryCrowdModel](./Models/DirectoryCrowdModel.md) @@ -73,6 +74,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* - [ErrorCollection](./Models/ErrorCollection.md) - [GroupModel](./Models/GroupModel.md) - [LicenseModel](./Models/LicenseModel.md) + - [MailServerModel](./Models/MailServerModel.md) - [MailServerPopModel](./Models/MailServerPopModel.md) - [MailServerSmtpModel](./Models/MailServerSmtpModel.md) - [PermissionsGlobalModel](./Models/PermissionsGlobalModel.md) diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index 71606181..d141f2e6 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -1,7 +1,13 @@ package com.deftdevs.bootstrapi.jira.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; +import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -9,6 +15,7 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; +import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import com.deftdevs.bootstrapi.jira.model.SettingsModel; import com.deftdevs.bootstrapi.jira.model._AllModel; import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; @@ -58,11 +65,11 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), + setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), + setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_BANNER, settingsInput.getBanner(), + setEntity(entityType(SettingsModel.class, SettingsBannerModel.class), settingsInput.getBanner(), settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); result.setSettings(settingsResult); } @@ -77,9 +84,9 @@ public _AllModel setAll( final AuthenticationModel authInput = allModel.getAuthentication(); if (authInput != null) { final AuthenticationModel authResult = new AuthenticationModel(); - setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), + setEntities(entityType(AuthenticationModel.class) + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), + setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } @@ -92,14 +99,14 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), + setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), + setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), + setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); From c53437fa29501df105acff97031823042b5c3aaa Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 19 May 2026 14:30:41 +0800 Subject: [PATCH 06/11] Implement _all endpoint with license redaction and exception sanitization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add map-based setLicenses overload (key → LicenseModel) to LicensesService API and all three product implementations; response keys are redacted via LicenseKeyRedactor (first4...last4#hash4 format) - Introduce LicenseKeyRedactor utility with SHA-1-based key redaction and tests - Refactor _AbstractAllServiceImpl: generalize setEntity to , sanitize exception details to only expose messages from mapped WebApplicationExceptions - Sweep all three _AllServiceImpl files to use static BootstrAPI constants exclusively (remove reflection-based entityType() helpers) - Add _AllResourceTest for Jira and Confluence mirroring Crowd's test Co-Authored-By: Claude Sonnet 4.6 --- .../service/_AbstractAllServiceImpl.java | 93 +++++-------------- .../commons/service/api/LicensesService.java | 14 +++ .../commons/util/LicenseKeyRedactor.java | 64 +++++++++++++ .../commons/util/LicenseKeyRedactorTest.java | 44 +++++++++ .../confluence/model/_AllModel.java | 4 +- .../service/LicensesServiceImpl.java | 14 +++ .../confluence/service/_AllServiceImpl.java | 51 +++++----- .../confluence/rest/_AllResourceTest.java | 60 ++++++++++++ .../bootstrapi/crowd/model/_AllModel.java | 3 +- .../crowd/service/LicensesServiceImpl.java | 14 +++ .../crowd/service/_AllServiceImpl.java | 39 ++++---- .../bootstrapi/jira/model/_AllModel.java | 4 +- .../jira/service/LicensesServiceImpl.java | 18 ++++ .../jira/service/_AllServiceImpl.java | 47 +++++----- .../jira/rest/_AllResourceTest.java | 60 ++++++++++++ 15 files changed, 389 insertions(+), 140 deletions(-) create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactor.java create mode 100644 commons/src/test/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactorTest.java create mode 100644 confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java create mode 100644 jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index 21d2c6bb..69bec241 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -4,84 +4,33 @@ import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service.api._AllService; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; -import javax.xml.bind.annotation.XmlRootElement; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { - /** - * Resolves the entity type identifier from the {@link XmlRootElement} annotation - * of the given model class. - * - * @param entityClass the model class - * @return the root element name - */ - protected static String entityType( - final Class entityClass) { - - final XmlRootElement rootElement = entityClass.getAnnotation(XmlRootElement.class); - if (rootElement == null || "##default".equals(rootElement.name())) { - throw new IllegalArgumentException( - entityClass.getName() + " must have @XmlRootElement with explicit name"); - } - return rootElement.name(); - } - - /** - * Resolves a hierarchical entity type identifier from the {@link XmlRootElement} annotations - * of the parent and child model classes by stripping the parent prefix from the child name. - *

- * For example, given parent {@code SettingsModel} with root element {@code "settings"} - * and child {@code SettingsGeneralModel} with root element {@code "settings-general"}, - * this returns {@code "settings/general"}. - * - * @param parentClass the wrapper model class - * @param childClass the child model class - * @return the hierarchical entity type (e.g. "settings/general") - */ - protected static String entityType( - final Class parentClass, - final Class childClass) { - - final String parentName = entityType(parentClass); - final String childName = entityType(childClass); - final String expectedPrefix = parentName + "-"; - - if (!childName.startsWith(expectedPrefix)) { - throw new IllegalArgumentException( - childClass.getName() + " root element '" + childName + - "' does not follow parent prefix convention '" + expectedPrefix + "'"); - } - - return parentName + "/" + childName.substring(expectedPrefix.length()); - } - - protected _AllModelStatus setEntity( + protected _AllModelStatus setEntity( final String entityType, - final T entity, - final Function updateFunction, - final Consumer resultConsumer, + final I input, + final Function updateFunction, + final Consumer resultConsumer, final Map statusMap) { - if (entity == null) { + if (input == null) { return null; } try { - final T updatedEntity = updateFunction.apply(entity); + final O updatedEntity = updateFunction.apply(input); resultConsumer.accept(updatedEntity); final _AllModelStatus status = _AllModelStatus.success(); statusMap.put(entityType, status); return status; } catch (Exception e) { - final _AllModelStatus status = _AllModelStatus.error( - resolveStatus(e), - String.format("Failed to apply %s configuration", entityType), - e.getMessage() - ); + final _AllModelStatus status = toErrorStatus(entityType, e); statusMap.put(entityType, status); return status; } @@ -106,24 +55,26 @@ protected _AllModelStatus setEntities( statusMap.put(entityType, status); return status; } catch (Exception e) { - final _AllModelStatus status = _AllModelStatus.error( - resolveStatus(e), - String.format("Failed to apply %s configuration", entityType), - e.getMessage() - ); + final _AllModelStatus status = toErrorStatus(entityType, e); statusMap.put(entityType, status); return status; } } - private static Response.Status resolveStatus(final Exception e) { - if (e instanceof com.deftdevs.bootstrapi.commons.exception.web.BadRequestException) { - return Response.Status.BAD_REQUEST; - } - if (e instanceof com.deftdevs.bootstrapi.commons.exception.web.NotFoundException) { - return Response.Status.NOT_FOUND; + private static _AllModelStatus toErrorStatus(final String entityType, final Exception e) { + if (e instanceof WebApplicationException) { + final Response response = ((WebApplicationException) e).getResponse(); + return _AllModelStatus.error( + Response.Status.fromStatusCode(response.getStatus()), + String.format("Failed to apply %s configuration", entityType), + e.getMessage() + ); } - return Response.Status.INTERNAL_SERVER_ERROR; + return _AllModelStatus.error( + Response.Status.INTERNAL_SERVER_ERROR, + String.format("Failed to apply %s configuration", entityType), + null + ); } } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/LicensesService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/LicensesService.java index 8f07d738..6c39a758 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/LicensesService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/LicensesService.java @@ -3,6 +3,7 @@ import com.deftdevs.bootstrapi.commons.model.LicenseModel; import java.util.List; +import java.util.Map; public interface LicensesService { @@ -21,6 +22,19 @@ public interface LicensesService { List setLicenses( List licenseKeys); + /** + * Set licenses from a map keyed by license key. + *

+ * Input values may be {@code null} (key-only entries are valid); the map keys are the + * license keys to apply. The returned map is keyed by a redacted form of each input + * key so that full license keys are not echoed in the response. + * + * @param licenseInputs map of license key to (optional) input model; values are ignored + * @return map of redacted-key to applied {@link LicenseModel} + */ + Map setLicenses( + Map licenseInputs); + /** * Add a single license * diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactor.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactor.java new file mode 100644 index 00000000..39d83ca3 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactor.java @@ -0,0 +1,64 @@ +package com.deftdevs.bootstrapi.commons.util; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +/** + * Redacts license keys for inclusion in HTTP responses. + *

+ * License keys are sensitive and should not be echoed back in full to clients, + * since responses may be captured by intermediaries (proxies, logs, etc.) that + * do not capture the original request body. Redacted keys allow a caller to + * correlate a response entry with the key they sent without leaking the full + * value. + *

+ * Format: {@code ...#}, where {@code hash4} is the first + * four hex characters of the SHA-1 digest of the full key. The hash suffix + * disambiguates keys that happen to share the same prefix and suffix (e.g. + * Atlassian license keys, which all start with the same product header). + *

+ * Keys shorter than nine characters are hashed entirely and emitted as + * {@code ***#} to avoid leaking the full key when redaction would be + * effectively a no-op. + */ +public final class LicenseKeyRedactor { + + private static final int VISIBLE_PREFIX_LENGTH = 4; + private static final int VISIBLE_SUFFIX_LENGTH = 4; + private static final int HASH_LENGTH = 4; + private static final int MIN_REDACTABLE_LENGTH = VISIBLE_PREFIX_LENGTH + VISIBLE_SUFFIX_LENGTH + 1; + + private LicenseKeyRedactor() { + } + + public static String redact(final String key) { + if (key == null) { + return null; + } + final String hash = shortSha1(key); + if (key.length() < MIN_REDACTABLE_LENGTH) { + return "***#" + hash; + } + return key.substring(0, VISIBLE_PREFIX_LENGTH) + + "..." + + key.substring(key.length() - VISIBLE_SUFFIX_LENGTH) + + "#" + + hash; + } + + private static String shortSha1(final String input) { + try { + final MessageDigest md = MessageDigest.getInstance("SHA-1"); + final byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8)); + final StringBuilder hex = new StringBuilder(HASH_LENGTH); + for (int i = 0; i < (HASH_LENGTH + 1) / 2; i++) { + hex.append(String.format("%02x", digest[i] & 0xff)); + } + return hex.substring(0, HASH_LENGTH); + } catch (NoSuchAlgorithmException e) { + throw new IllegalStateException("SHA-1 not available", e); + } + } + +} diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactorTest.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactorTest.java new file mode 100644 index 00000000..55cd1c81 --- /dev/null +++ b/commons/src/test/java/com/deftdevs/bootstrapi/commons/util/LicenseKeyRedactorTest.java @@ -0,0 +1,44 @@ +package com.deftdevs.bootstrapi.commons.util; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class LicenseKeyRedactorTest { + + @Test + void redactsNullAsNull() { + assertNull(LicenseKeyRedactor.redact(null)); + } + + @Test + void redactsShortKeyAsObfuscatedWithHash() { + final String redacted = LicenseKeyRedactor.redact("abc"); + assertEquals("***#a9993e36".substring(0, "***#".length() + 4), redacted); + } + + @Test + void redactsLongKeyShowingFirstAndLastFourPlusHash() { + final String key = "AAAA1234567890ZZZZ"; + final String redacted = LicenseKeyRedactor.redact(key); + assertEquals("AAAA...ZZZZ#", redacted.substring(0, "AAAA...ZZZZ#".length())); + assertEquals(4, redacted.length() - "AAAA...ZZZZ#".length()); + } + + @Test + void differentKeysWithSamePrefixAndSuffixGetDifferentHashes() { + final String a = LicenseKeyRedactor.redact("AAAA0000ZZZZ"); + final String b = LicenseKeyRedactor.redact("AAAA1111ZZZZ"); + assertEquals(a.substring(0, "AAAA...ZZZZ#".length()), b.substring(0, "AAAA...ZZZZ#".length())); + assertNotEquals(a, b); + } + + @Test + void redactionIsDeterministic() { + final String key = "AAAA-some-very-long-license-key-payload-ZZZZ"; + assertEquals(LicenseKeyRedactor.redact(key), LicenseKeyRedactor.redact(key)); + } + +} diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java index 230a91df..84a58c3b 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/model/_AllModel.java @@ -4,6 +4,7 @@ import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; import com.deftdevs.bootstrapi.commons.model.ApplicationLinkModel; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.LicenseModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; @@ -14,7 +15,6 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -import java.util.List; import java.util.Map; @Data @@ -36,7 +36,7 @@ public class _AllModel implements _AllModelAccessor { private AuthenticationModel authentication; @XmlElement - private List licenses; + private Map licenses; @XmlElement private MailServerModel mailServer; diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/LicensesServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/LicensesServiceImpl.java index f78cefe2..df4f5d16 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/LicensesServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/LicensesServiceImpl.java @@ -7,10 +7,13 @@ import com.deftdevs.bootstrapi.commons.exception.web.InternalServerErrorException; import com.deftdevs.bootstrapi.commons.model.LicenseModel; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; +import com.deftdevs.bootstrapi.commons.util.LicenseKeyRedactor; import com.deftdevs.bootstrapi.confluence.model.util.LicenseModelUtil; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import static com.atlassian.confluence.setup.ConfluenceBootstrapConstants.DEFAULT_LICENSE_REGISTRY_KEY; @@ -43,6 +46,17 @@ public List setLicenses( return getLicenses(); } + @Override + public Map setLicenses( + final Map licenseInputs) { + + final Map result = new LinkedHashMap<>(); + for (final String key : licenseInputs.keySet()) { + result.put(LicenseKeyRedactor.redact(key), addLicense(key)); + } + return result; + } + @Override public LicenseModel addLicense( final String licenseKey) { diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index a1858180..8d3bed3d 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -1,14 +1,7 @@ package com.deftdevs.bootstrapi.confluence.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; -import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; -import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; -import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; -import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; -import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; -import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; -import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -17,7 +10,6 @@ import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; -import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import com.deftdevs.bootstrapi.confluence.model.SettingsModel; import com.deftdevs.bootstrapi.confluence.model._AllModel; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; @@ -26,7 +18,22 @@ import java.util.HashMap; import java.util.Map; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_IDPS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_SSO; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_POP; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_SMTP; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS_GLOBAL; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BRANDING; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_CUSTOM_HTML; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_SECURITY; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -66,17 +73,16 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - // Settings wrapper final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), + setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), + setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(entityType(SettingsModel.class, SettingsBrandingColorSchemeModel.class), settingsInput.getBranding(), + setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); - setEntity(entityType(SettingsModel.class, SettingsCustomHtmlModel.class), settingsInput.getCustomHtml(), + setEntity(SETTINGS + "/" + SETTINGS_CUSTOM_HTML, settingsInput.getCustomHtml(), settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); result.setSettings(settingsResult); } @@ -87,33 +93,30 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - // Authentication wrapper final AuthenticationModel authInput = allModel.getAuthentication(); if (authInput != null) { final AuthenticationModel authResult = new AuthenticationModel(); - setEntities(entityType(AuthenticationModel.class) + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), + setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), + setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } - setEntity(LICENSES, allModel.getLicenses(), - keys -> { licensesService.setLicenses(keys); return keys; }, - result::setLicenses, statusMap); + setEntities(LICENSES, allModel.getLicenses(), + licensesService::setLicenses, result::setLicenses, statusMap); - // Mail server wrapper final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), + setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java b/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java new file mode 100644 index 00000000..e5734622 --- /dev/null +++ b/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java @@ -0,0 +1,60 @@ +package com.deftdevs.bootstrapi.confluence.rest; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service.api._AllService; +import com.deftdevs.bootstrapi.confluence.model.SettingsModel; +import com.deftdevs.bootstrapi.confluence.model._AllModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.ws.rs.core.Response; +import java.util.HashMap; +import java.util.Map; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class _AllResourceTest { + + @Mock + private _AllService<_AllModel> allService; + + private _AllResourceImpl allResource; + + private _AllModel allModel; + + @BeforeEach + public void setup() { + allResource = new _AllResourceImpl(allService); + + allModel = new _AllModel(); + final SettingsModel settings = new SettingsModel(); + settings.setGeneral(SettingsGeneralModel.EXAMPLE_1); + allModel.setSettings(settings); + + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, _AllModelStatus.success()); + status.put(APPLICATION_LINKS, _AllModelStatus.success()); + allModel.setStatus(status); + } + + @Test + public void testSetAll() { + doReturn(allModel).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(200, response.getStatus()); + + final _AllModel responseModel = (_AllModel) response.getEntity(); + assertEquals(allModel, responseModel); + + verify(allService).setAll(allModel); + } +} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java index d049c546..b9e63519 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/model/_AllModel.java @@ -3,6 +3,7 @@ import com.deftdevs.bootstrapi.commons.constants.BootstrAPI; import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; import com.deftdevs.bootstrapi.commons.model.ApplicationLinkModel; +import com.deftdevs.bootstrapi.commons.model.LicenseModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; @@ -34,7 +35,7 @@ public class _AllModel implements _AllModelAccessor { private Map applicationLinks; @XmlElement - private List licenses; + private Map licenses; @XmlElement private MailServerModel mailServer; diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/LicensesServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/LicensesServiceImpl.java index 31a0d9cc..3998434e 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/LicensesServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/LicensesServiceImpl.java @@ -6,9 +6,12 @@ import com.deftdevs.bootstrapi.commons.exception.web.InternalServerErrorException; import com.deftdevs.bootstrapi.commons.model.LicenseModel; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; +import com.deftdevs.bootstrapi.commons.util.LicenseKeyRedactor; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; public class LicensesServiceImpl implements LicensesService { @@ -40,6 +43,17 @@ public List setLicenses( ); } + @Override + public Map setLicenses( + final Map licenseInputs) { + + final Map result = new LinkedHashMap<>(); + for (final String key : licenseInputs.keySet()) { + result.put(LicenseKeyRedactor.redact(key), addLicense(key)); + } + return result; + } + public LicenseModel addLicense( final String licenseKey) { diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 52913ac8..9a916ab2 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,18 +1,12 @@ package com.deftdevs.bootstrapi.crowd.service; import com.deftdevs.bootstrapi.commons.model.MailServerModel; -import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; -import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; -import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; -import com.deftdevs.bootstrapi.crowd.model.MailTemplatesModel; -import com.deftdevs.bootstrapi.crowd.model.SessionConfigModel; -import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; @@ -25,7 +19,19 @@ import java.util.HashMap; import java.util.Map; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATIONS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_POP; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_SMTP; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_TEMPLATES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SESSION_CONFIG; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BRANDING; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.TRUSTED_PROXIES; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -71,13 +77,12 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - // Settings wrapper final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), + setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsModel.class, SettingsBrandingLoginPageModel.class), settingsInput.getBranding(), + setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), brandingService::setLoginPage, settingsResult::setBranding, statusMap); result.setSettings(settingsResult); } @@ -91,25 +96,23 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - setEntity(LICENSES, allModel.getLicenses(), - keys -> { licensesService.setLicenses(keys); return keys; }, - result::setLicenses, statusMap); + setEntities(LICENSES, allModel.getLicenses(), + licensesService::setLicenses, result::setLicenses, statusMap); - // Mail server wrapper final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(entityType(MailTemplatesModel.class), allModel.getMailTemplates(), + setEntity(MAIL_TEMPLATES, allModel.getMailTemplates(), mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); - setEntity(entityType(SessionConfigModel.class), allModel.getSessionConfig(), + setEntity(SESSION_CONFIG, allModel.getSessionConfig(), sessionConfigService::setSessionConfig, result::setSessionConfig, statusMap); setEntity(TRUSTED_PROXIES, allModel.getTrustedProxies(), diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java index daaa9b5f..76382da9 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/model/_AllModel.java @@ -4,6 +4,7 @@ import com.deftdevs.bootstrapi.commons.model.AbstractDirectoryModel; import com.deftdevs.bootstrapi.commons.model.ApplicationLinkModel; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.LicenseModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; @@ -14,7 +15,6 @@ import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -import java.util.List; import java.util.Map; @Data @@ -36,7 +36,7 @@ public class _AllModel implements _AllModelAccessor { private AuthenticationModel authentication; @XmlElement - private List licenses; + private Map licenses; @XmlElement private MailServerModel mailServer; diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java index bdf8badc..7ef8e6a1 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java @@ -3,9 +3,13 @@ import com.atlassian.jira.license.JiraLicenseManager; import com.deftdevs.bootstrapi.commons.model.LicenseModel; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; +import com.deftdevs.bootstrapi.commons.util.LicenseKeyRedactor; import com.deftdevs.bootstrapi.jira.model.util.LicenseModelUtil; +import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import java.util.stream.StreamSupport; @@ -36,6 +40,20 @@ public List setLicenses( return getLicenses(); } + @Override + public Map setLicenses( + final Map licenseInputs) { + + final List keys = new ArrayList<>(licenseInputs.keySet()); + final List applied = setLicenses(keys); + final Map result = new LinkedHashMap<>(); + for (int i = 0; i < keys.size(); i++) { + final LicenseModel model = i < applied.size() ? applied.get(i) : null; + result.put(LicenseKeyRedactor.redact(keys.get(i)), model); + } + return result; + } + @Override public LicenseModel addLicense( final String license) { diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index d141f2e6..8fae890b 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -1,13 +1,7 @@ package com.deftdevs.bootstrapi.jira.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; -import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; -import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; -import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; -import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; -import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; -import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -15,7 +9,6 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; -import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import com.deftdevs.bootstrapi.jira.model.SettingsModel; import com.deftdevs.bootstrapi.jira.model._AllModel; import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; @@ -24,7 +17,21 @@ import java.util.HashMap; import java.util.Map; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_IDPS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_SSO; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_POP; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_SMTP; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS_GLOBAL; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BANNER; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_SECURITY; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -61,15 +68,14 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - // Settings wrapper final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), + setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), + setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(entityType(SettingsModel.class, SettingsBannerModel.class), settingsInput.getBanner(), + setEntity(SETTINGS + "/" + SETTINGS_BANNER, settingsInput.getBanner(), settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); result.setSettings(settingsResult); } @@ -80,33 +86,30 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - // Authentication wrapper final AuthenticationModel authInput = allModel.getAuthentication(); if (authInput != null) { final AuthenticationModel authResult = new AuthenticationModel(); - setEntities(entityType(AuthenticationModel.class) + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), + setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), + setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } - setEntity(LICENSES, allModel.getLicenses(), - keys -> { licensesService.setLicenses(keys); return keys; }, - result::setLicenses, statusMap); + setEntities(LICENSES, allModel.getLicenses(), + licensesService::setLicenses, result::setLicenses, statusMap); - // Mail server wrapper final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), + setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), + setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java b/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java new file mode 100644 index 00000000..f6e1a035 --- /dev/null +++ b/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java @@ -0,0 +1,60 @@ +package com.deftdevs.bootstrapi.jira.rest; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.service.api._AllService; +import com.deftdevs.bootstrapi.jira.model.SettingsModel; +import com.deftdevs.bootstrapi.jira.model._AllModel; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import javax.ws.rs.core.Response; +import java.util.HashMap; +import java.util.Map; + +import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +public class _AllResourceTest { + + @Mock + private _AllService<_AllModel> allService; + + private _AllResourceImpl allResource; + + private _AllModel allModel; + + @BeforeEach + public void setup() { + allResource = new _AllResourceImpl(allService); + + allModel = new _AllModel(); + final SettingsModel settings = new SettingsModel(); + settings.setGeneral(SettingsGeneralModel.EXAMPLE_1); + allModel.setSettings(settings); + + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, _AllModelStatus.success()); + status.put(APPLICATION_LINKS, _AllModelStatus.success()); + allModel.setStatus(status); + } + + @Test + public void testSetAll() { + doReturn(allModel).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(200, response.getStatus()); + + final _AllModel responseModel = (_AllModel) response.getEntity(); + assertEquals(allModel, responseModel); + + verify(allService).setAll(allModel); + } +} From 257e4517c4b9c02c2f662318840b4da918d9b8f7 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 19 May 2026 14:43:35 +0800 Subject: [PATCH 07/11] WIP_UNIFY --- .../service/_AbstractAllServiceImpl.java | 29 +++++++++++++++ .../confluence/service/_AllServiceImpl.java | 35 +++++++++---------- .../crowd/service/_AllServiceImpl.java | 26 +++++++------- .../jira/service/_AllServiceImpl.java | 31 ++++++++-------- 4 files changed, 71 insertions(+), 50 deletions(-) diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index 69bec241..8860ebec 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -6,12 +6,41 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; +import javax.xml.bind.annotation.XmlRootElement; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { + protected static String entityType( + final Class entityClass) { + + final XmlRootElement rootElement = entityClass.getAnnotation(XmlRootElement.class); + if (rootElement == null || "##default".equals(rootElement.name())) { + throw new IllegalArgumentException( + entityClass.getName() + " must have @XmlRootElement with explicit name"); + } + return rootElement.name(); + } + + protected static String entityType( + final Class parentClass, + final Class childClass) { + + final String parentName = entityType(parentClass); + final String childName = entityType(childClass); + final String expectedPrefix = parentName + "-"; + + if (!childName.startsWith(expectedPrefix)) { + throw new IllegalArgumentException( + childClass.getName() + " root element '" + childName + + "' does not follow parent prefix convention '" + expectedPrefix + "'"); + } + + return parentName + "/" + childName.substring(expectedPrefix.length()); + } + protected _AllModelStatus setEntity( final String entityType, final I input, diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index 8d3bed3d..1b00709d 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -1,7 +1,14 @@ package com.deftdevs.bootstrapi.confluence.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; +import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; +import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -10,6 +17,7 @@ import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; +import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import com.deftdevs.bootstrapi.confluence.model.SettingsModel; import com.deftdevs.bootstrapi.confluence.model._AllModel; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; @@ -21,19 +29,8 @@ import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_IDPS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_SSO; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_POP; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_SMTP; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS_GLOBAL; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BRANDING; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_CUSTOM_HTML; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_SECURITY; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -76,13 +73,13 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), + setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), + setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), + setEntity(entityType(SettingsModel.class, SettingsBrandingColorSchemeModel.class), settingsInput.getBranding(), settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_CUSTOM_HTML, settingsInput.getCustomHtml(), + setEntity(entityType(SettingsModel.class, SettingsCustomHtmlModel.class), settingsInput.getCustomHtml(), settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); result.setSettings(settingsResult); } @@ -98,7 +95,7 @@ public _AllModel setAll( final AuthenticationModel authResult = new AuthenticationModel(); setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), + setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } @@ -109,14 +106,14 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), + setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), + setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), + setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 9a916ab2..3572c68b 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,12 +1,18 @@ package com.deftdevs.bootstrapi.crowd.service; import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; +import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; +import com.deftdevs.bootstrapi.crowd.model.MailTemplatesModel; +import com.deftdevs.bootstrapi.crowd.model.SessionConfigModel; +import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; @@ -23,14 +29,6 @@ import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_POP; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_SMTP; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_TEMPLATES; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SESSION_CONFIG; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BRANDING; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.TRUSTED_PROXIES; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -80,9 +78,9 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), + setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_BRANDING, settingsInput.getBranding(), + setEntity(entityType(SettingsModel.class, SettingsBrandingLoginPageModel.class), settingsInput.getBranding(), brandingService::setLoginPage, settingsResult::setBranding, statusMap); result.setSettings(settingsResult); } @@ -102,17 +100,17 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), + setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), + setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(MAIL_TEMPLATES, allModel.getMailTemplates(), + setEntity(entityType(MailTemplatesModel.class), allModel.getMailTemplates(), mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); - setEntity(SESSION_CONFIG, allModel.getSessionConfig(), + setEntity(entityType(SessionConfigModel.class), allModel.getSessionConfig(), sessionConfigService::setSessionConfig, result::setSessionConfig, statusMap); setEntity(TRUSTED_PROXIES, allModel.getTrustedProxies(), diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index 8fae890b..e783f5c7 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -1,7 +1,13 @@ package com.deftdevs.bootstrapi.jira.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; +import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; +import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -9,6 +15,7 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; +import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import com.deftdevs.bootstrapi.jira.model.SettingsModel; import com.deftdevs.bootstrapi.jira.model._AllModel; import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; @@ -20,18 +27,8 @@ import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_IDPS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_SSO; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_POP; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.MAIL_SERVER_SMTP; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.PERMISSIONS_GLOBAL; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_BANNER; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_GENERAL; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.SETTINGS_SECURITY; public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { @@ -71,11 +68,11 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(SETTINGS + "/" + SETTINGS_GENERAL, settingsInput.getGeneral(), + setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_SECURITY, settingsInput.getSecurity(), + setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(SETTINGS + "/" + SETTINGS_BANNER, settingsInput.getBanner(), + setEntity(entityType(SettingsModel.class, SettingsBannerModel.class), settingsInput.getBanner(), settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); result.setSettings(settingsResult); } @@ -91,7 +88,7 @@ public _AllModel setAll( final AuthenticationModel authResult = new AuthenticationModel(); setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(AUTHENTICATION + "/" + AUTHENTICATION_SSO, authInput.getSso(), + setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } @@ -102,14 +99,14 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_SMTP, mailServerInput.getSmtp(), + setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(MAIL_SERVER + "/" + MAIL_SERVER_POP, mailServerInput.getPop(), + setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } - setEntity(PERMISSIONS + "/" + PERMISSIONS_GLOBAL, allModel.getPermissionsGlobal(), + setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); From 0016cca2f955e93c4381a3013aa8cf35f3faaee1 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 19 May 2026 15:07:24 +0800 Subject: [PATCH 08/11] WIP_MORE_DYNAMIC --- .../service/_AbstractAllServiceImpl.java | 20 ++----------------- .../confluence/service/_AllServiceImpl.java | 14 ++++++------- .../crowd/service/_AllServiceImpl.java | 8 ++++---- .../jira/service/_AllServiceImpl.java | 12 +++++------ 4 files changed, 19 insertions(+), 35 deletions(-) diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index 8860ebec..101ec15c 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -13,6 +13,7 @@ public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { + // Derives the status-map key from @XmlRootElement: "parent-child" → "parent/child" protected static String entityType( final Class entityClass) { @@ -21,24 +22,7 @@ protected static String entityType( throw new IllegalArgumentException( entityClass.getName() + " must have @XmlRootElement with explicit name"); } - return rootElement.name(); - } - - protected static String entityType( - final Class parentClass, - final Class childClass) { - - final String parentName = entityType(parentClass); - final String childName = entityType(childClass); - final String expectedPrefix = parentName + "-"; - - if (!childName.startsWith(expectedPrefix)) { - throw new IllegalArgumentException( - childClass.getName() + " root element '" + childName + - "' does not follow parent prefix convention '" + expectedPrefix + "'"); - } - - return parentName + "/" + childName.substring(expectedPrefix.length()); + return rootElement.name().replaceFirst("-", "/"); } protected _AllModelStatus setEntity( diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index 1b00709d..4fe306d9 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -73,13 +73,13 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), + setEntity(entityType(SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), + setEntity(entityType(SettingsSecurityModel.class), settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(entityType(SettingsModel.class, SettingsBrandingColorSchemeModel.class), settingsInput.getBranding(), + setEntity(entityType(SettingsBrandingColorSchemeModel.class), settingsInput.getBranding(), settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); - setEntity(entityType(SettingsModel.class, SettingsCustomHtmlModel.class), settingsInput.getCustomHtml(), + setEntity(entityType(SettingsCustomHtmlModel.class), settingsInput.getCustomHtml(), settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); result.setSettings(settingsResult); } @@ -95,7 +95,7 @@ public _AllModel setAll( final AuthenticationModel authResult = new AuthenticationModel(); setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), + setEntity(entityType(AuthenticationSsoModel.class), authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } @@ -106,9 +106,9 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), + setEntity(entityType(MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), + setEntity(entityType(MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 3572c68b..43287790 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -78,9 +78,9 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), + setEntity(entityType(SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsModel.class, SettingsBrandingLoginPageModel.class), settingsInput.getBranding(), + setEntity(entityType(SettingsBrandingLoginPageModel.class), settingsInput.getBranding(), brandingService::setLoginPage, settingsResult::setBranding, statusMap); result.setSettings(settingsResult); } @@ -100,9 +100,9 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), + setEntity(entityType(MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), + setEntity(entityType(MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index e783f5c7..40de2635 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -68,11 +68,11 @@ public _AllModel setAll( final SettingsModel settingsInput = allModel.getSettings(); if (settingsInput != null) { final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsModel.class, SettingsGeneralModel.class), settingsInput.getGeneral(), + setEntity(entityType(SettingsGeneralModel.class), settingsInput.getGeneral(), settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsModel.class, SettingsSecurityModel.class), settingsInput.getSecurity(), + setEntity(entityType(SettingsSecurityModel.class), settingsInput.getSecurity(), settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(entityType(SettingsModel.class, SettingsBannerModel.class), settingsInput.getBanner(), + setEntity(entityType(SettingsBannerModel.class), settingsInput.getBanner(), settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); result.setSettings(settingsResult); } @@ -88,7 +88,7 @@ public _AllModel setAll( final AuthenticationModel authResult = new AuthenticationModel(); setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(entityType(AuthenticationModel.class, AuthenticationSsoModel.class), authInput.getSso(), + setEntity(entityType(AuthenticationSsoModel.class), authInput.getSso(), authenticationService::setAuthenticationSso, authResult::setSso, statusMap); result.setAuthentication(authResult); } @@ -99,9 +99,9 @@ public _AllModel setAll( final MailServerModel mailServerInput = allModel.getMailServer(); if (mailServerInput != null) { final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerModel.class, MailServerSmtpModel.class), mailServerInput.getSmtp(), + setEntity(entityType(MailServerSmtpModel.class), mailServerInput.getSmtp(), mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerModel.class, MailServerPopModel.class), mailServerInput.getPop(), + setEntity(entityType(MailServerPopModel.class), mailServerInput.getPop(), mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); result.setMailServer(mailServerResult); } From f9902a65dd8ea48eea4efe192a91fe8ca3e0deb5 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 19 May 2026 15:49:52 +0800 Subject: [PATCH 09/11] Consolidate _AllServiceImpl to call composite setSettings/setMailServer/setAuthentication - Add default setMailServer/getMailServer to MailServerService delegating to smtp/pop - Add default setAuthentication/getAuthentication to AuthenticationService delegating to idps/sso - Add setSettings/getSettings to JiraSettingsService as default methods - Extend ConfluenceSettingsService to also include SettingsBrandingService; introduce ConfluenceSettingsServiceImpl composing SettingsServiceImpl + SettingsBrandingServiceImpl - Introduce CrowdSettingsService unifying CrowdSettingsGeneralService + CrowdSettingsBrandingService; introduce CrowdSettingsServiceImpl composing both - Reduce _AllServiceImpl in all three products to flat single setEntity calls per top-level section Co-Authored-By: Claude Sonnet 4.6 --- .../service/api/AuthenticationService.java | 21 +++++ .../service/api/MailServerService.java | 16 ++++ .../confluence/config/ServiceConfig.java | 8 +- .../ConfluenceSettingsServiceImpl.java | 84 +++++++++++++++++++ .../service/SettingsServiceImpl.java | 16 ++-- .../confluence/service/_AllServiceImpl.java | 50 ++--------- .../api/ConfluenceSettingsService.java | 30 ++++++- .../crowd/config/ServiceConfig.java | 10 ++- .../service/CrowdSettingsServiceImpl.java | 47 +++++++++++ .../crowd/service/_AllServiceImpl.java | 36 ++------ .../service/api/CrowdSettingsService.java | 24 ++++++ .../jira/service/_AllServiceImpl.java | 41 ++------- .../jira/service/api/JiraSettingsService.java | 21 ++++- 13 files changed, 279 insertions(+), 125 deletions(-) create mode 100644 confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java create mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java create mode 100644 crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java index 871806a1..af80606e 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java @@ -1,12 +1,33 @@ package com.deftdevs.bootstrapi.commons.service.api; import com.deftdevs.bootstrapi.commons.model.AbstractAuthenticationIdpModel; +import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import java.util.Map; public interface AuthenticationService { + @SuppressWarnings("unchecked") + default AuthenticationModel getAuthentication() { + return new AuthenticationModel( + (Map) getAuthenticationIdps(), + getAuthenticationSso()); + } + + @SuppressWarnings("unchecked") + default AuthenticationModel setAuthentication(final AuthenticationModel authenticationModel) { + final AuthenticationModel result = new AuthenticationModel(); + if (authenticationModel.getIdps() != null) { + result.setIdps((Map) setAuthenticationIdps( + (Map) authenticationModel.getIdps())); + } + if (authenticationModel.getSso() != null) { + result.setSso(setAuthenticationSso((SB) authenticationModel.getSso())); + } + return result; + } + Map getAuthenticationIdps(); Map setAuthenticationIdps( diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java index ed1bcfcd..464c6262 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java @@ -1,11 +1,27 @@ package com.deftdevs.bootstrapi.commons.service.api; +import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; public interface MailServerService { + default MailServerModel getMailServer() { + return new MailServerModel(getMailServerSmtp(), getMailServerPop()); + } + + default MailServerModel setMailServer(final MailServerModel mailServerModel) { + final MailServerModel result = new MailServerModel(); + if (mailServerModel.getSmtp() != null) { + result.setSmtp(setMailServerSmtp(mailServerModel.getSmtp())); + } + if (mailServerModel.getPop() != null) { + result.setPop(setMailServerPop(mailServerModel.getPop())); + } + return result; + } + /** * Get the smtp mailserver settings. * diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java index c9e079ea..15bc479e 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java @@ -28,8 +28,7 @@ public _AllService<_AllModel> _allService() { confluenceAuthenticationService(), licensesService(), mailServerService(), - permissionsService(), - settingsBrandingService()); + permissionsService()); } @Bean @@ -56,8 +55,9 @@ public ConfluenceAuthenticationService confluenceAuthenticationService() { @Bean public ConfluenceSettingsService confluenceSettingsService() { - return new SettingsServiceImpl( - atlassianConfig.globalSettingsManager()); + return new ConfluenceSettingsServiceImpl( + new SettingsServiceImpl(atlassianConfig.globalSettingsManager()), + settingsBrandingService()); } @Bean diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java new file mode 100644 index 00000000..940d1e6e --- /dev/null +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java @@ -0,0 +1,84 @@ +package com.deftdevs.bootstrapi.confluence.service; + +import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; +import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; +import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; +import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceSettingsService; + +import java.io.InputStream; + +public class ConfluenceSettingsServiceImpl implements ConfluenceSettingsService { + + private final SettingsServiceImpl settingsService; + private final SettingsBrandingService settingsBrandingService; + + public ConfluenceSettingsServiceImpl( + final SettingsServiceImpl settingsService, + final SettingsBrandingService settingsBrandingService) { + + this.settingsService = settingsService; + this.settingsBrandingService = settingsBrandingService; + } + + @Override + public SettingsGeneralModel getSettingsGeneral() { + return settingsService.getSettingsGeneral(); + } + + @Override + public SettingsGeneralModel setSettingsGeneral(final SettingsGeneralModel settingsGeneralModel) { + return settingsService.setSettingsGeneral(settingsGeneralModel); + } + + @Override + public SettingsSecurityModel getSettingsSecurity() { + return settingsService.getSettingsSecurity(); + } + + @Override + public SettingsSecurityModel setSettingsSecurity(final SettingsSecurityModel settingsSecurityModel) { + return settingsService.setSettingsSecurity(settingsSecurityModel); + } + + @Override + public SettingsCustomHtmlModel getCustomHtml() { + return settingsService.getCustomHtml(); + } + + @Override + public SettingsCustomHtmlModel setCustomHtml(final SettingsCustomHtmlModel settingsCustomHtmlModel) { + return settingsService.setCustomHtml(settingsCustomHtmlModel); + } + + @Override + public SettingsBrandingColorSchemeModel getColourScheme() { + return settingsBrandingService.getColourScheme(); + } + + @Override + public SettingsBrandingColorSchemeModel setColourScheme(final SettingsBrandingColorSchemeModel colourSchemeModel) { + return settingsBrandingService.setColourScheme(colourSchemeModel); + } + + @Override + public InputStream getLogo() { + return settingsBrandingService.getLogo(); + } + + @Override + public void setLogo(final InputStream inputStream) { + settingsBrandingService.setLogo(inputStream); + } + + @Override + public InputStream getFavicon() { + return settingsBrandingService.getFavicon(); + } + + @Override + public void setFavicon(final InputStream inputStream) { + settingsBrandingService.setFavicon(inputStream); + } +} diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java index 438a4d42..faf17d1a 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java @@ -6,11 +6,9 @@ import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; -import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceSettingsService; - import java.net.URI; -public class SettingsServiceImpl implements ConfluenceSettingsService { +public class SettingsServiceImpl { private final GlobalSettingsManager globalSettingsManager; @@ -20,7 +18,7 @@ public SettingsServiceImpl( this.globalSettingsManager = globalSettingsManager; } - @Override + public SettingsGeneralModel getSettingsGeneral() { final Settings settings = globalSettingsManager.getGlobalSettings(); @@ -32,7 +30,7 @@ public SettingsGeneralModel getSettingsGeneral() { .build(); } - @Override + public SettingsGeneralModel setSettingsGeneral(SettingsGeneralModel settingsModel) { final Settings settings = globalSettingsManager.getGlobalSettings(); @@ -57,7 +55,7 @@ public SettingsGeneralModel setSettingsGeneral(SettingsGeneralModel settingsMode return getSettingsGeneral(); } - @Override + public SettingsCustomHtmlModel getCustomHtml() { final CustomHtmlSettings customHtmlSettings = globalSettingsManager.getGlobalSettings().getCustomHtmlSettings(); @@ -68,7 +66,7 @@ public SettingsCustomHtmlModel getCustomHtml() { .build(); } - @Override + public SettingsCustomHtmlModel setCustomHtml( final SettingsCustomHtmlModel settingsCustomHtmlModel) { @@ -92,7 +90,7 @@ public SettingsCustomHtmlModel setCustomHtml( return getCustomHtml(); } - @Override + public SettingsSecurityModel getSettingsSecurity() { final Settings settings = globalSettingsManager.getGlobalSettings(); @@ -102,7 +100,7 @@ public SettingsSecurityModel getSettingsSecurity() { .build(); } - @Override + public SettingsSecurityModel setSettingsSecurity( final SettingsSecurityModel settingsSecurityModel) { diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index 4fe306d9..f68eb240 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -1,14 +1,8 @@ package com.deftdevs.bootstrapi.confluence.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; -import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; -import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; -import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; -import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; -import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; -import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -16,8 +10,6 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; -import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; -import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import com.deftdevs.bootstrapi.confluence.model.SettingsModel; import com.deftdevs.bootstrapi.confluence.model._AllModel; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; @@ -41,7 +33,6 @@ public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { private final LicensesService licensesService; private final MailServerService mailServerService; private final PermissionsService permissionsService; - private final SettingsBrandingService settingsBrandingService; public _AllServiceImpl( final ConfluenceSettingsService settingsService, @@ -50,8 +41,7 @@ public _AllServiceImpl( final ConfluenceAuthenticationService authenticationService, final LicensesService licensesService, final MailServerService mailServerService, - final PermissionsService permissionsService, - final SettingsBrandingService settingsBrandingService) { + final PermissionsService permissionsService) { this.settingsService = settingsService; this.directoriesService = directoriesService; @@ -60,7 +50,6 @@ public _AllServiceImpl( this.licensesService = licensesService; this.mailServerService = mailServerService; this.permissionsService = permissionsService; - this.settingsBrandingService = settingsBrandingService; } @Override @@ -70,19 +59,8 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - final SettingsModel settingsInput = allModel.getSettings(); - if (settingsInput != null) { - final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsGeneralModel.class), settingsInput.getGeneral(), - settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsSecurityModel.class), settingsInput.getSecurity(), - settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(entityType(SettingsBrandingColorSchemeModel.class), settingsInput.getBranding(), - settingsBrandingService::setColourScheme, settingsResult::setBranding, statusMap); - setEntity(entityType(SettingsCustomHtmlModel.class), settingsInput.getCustomHtml(), - settingsService::setCustomHtml, settingsResult::setCustomHtml, statusMap); - result.setSettings(settingsResult); - } + setEntity(entityType(SettingsModel.class), allModel.getSettings(), + settingsService::setSettings, result::setSettings, statusMap); setEntities(DIRECTORIES, allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); @@ -90,28 +68,14 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - final AuthenticationModel authInput = allModel.getAuthentication(); - if (authInput != null) { - final AuthenticationModel authResult = new AuthenticationModel(); - setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), - authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(entityType(AuthenticationSsoModel.class), authInput.getSso(), - authenticationService::setAuthenticationSso, authResult::setSso, statusMap); - result.setAuthentication(authResult); - } + setEntity(entityType(AuthenticationModel.class), allModel.getAuthentication(), + authenticationService::setAuthentication, result::setAuthentication, statusMap); setEntities(LICENSES, allModel.getLicenses(), licensesService::setLicenses, result::setLicenses, statusMap); - final MailServerModel mailServerInput = allModel.getMailServer(); - if (mailServerInput != null) { - final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerSmtpModel.class), mailServerInput.getSmtp(), - mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerPopModel.class), mailServerInput.getPop(), - mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); - result.setMailServer(mailServerResult); - } + setEntity(entityType(MailServerModel.class), allModel.getMailServer(), + mailServerService::setMailServer, result::setMailServer, statusMap); setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java index a820dea6..c7e0742e 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java @@ -1,18 +1,44 @@ package com.deftdevs.bootstrapi.confluence.service.api; +import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; -import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; +import com.deftdevs.bootstrapi.confluence.model.SettingsModel; public interface ConfluenceSettingsService extends SettingsGeneralService, - SettingsSecurityService { + SettingsSecurityService, + SettingsBrandingService { SettingsCustomHtmlModel getCustomHtml(); SettingsCustomHtmlModel setCustomHtml( SettingsCustomHtmlModel settingsCustomHtmlModel); + default SettingsModel getSettings() { + return new SettingsModel(getSettingsGeneral(), getSettingsSecurity(), + getColourScheme(), getCustomHtml()); + } + + default SettingsModel setSettings(final SettingsModel settingsModel) { + final SettingsModel result = new SettingsModel(); + if (settingsModel.getGeneral() != null) { + result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + } + if (settingsModel.getSecurity() != null) { + result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); + } + if (settingsModel.getBranding() != null) { + result.setBranding(setColourScheme(settingsModel.getBranding())); + } + if (settingsModel.getCustomHtml() != null) { + result.setCustomHtml(setCustomHtml(settingsModel.getCustomHtml())); + } + return result; + } + } diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java index 454bb481..a20bcb01 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java @@ -20,8 +20,7 @@ public class ServiceConfig { @Bean public _AllService<_AllModel> _allService() { return new _AllServiceImpl( - crowdSettingsGeneralService(), - settingsBrandingService(), + crowdSettingsService(), directoriesService(), applicationsService(), applicationLinksService(), @@ -61,6 +60,13 @@ public CrowdSettingsGeneralService crowdSettingsGeneralService() { atlassianConfig.propertyManager()); } + @Bean + public CrowdSettingsService crowdSettingsService() { + return new CrowdSettingsServiceImpl( + new SettingsServiceImpl(atlassianConfig.propertyManager()), + new SettingsBrandingServiceImpl(atlassianConfig.propertyManager())); + } + @Bean public DirectoriesService directoriesService() { return new DirectoriesServiceImpl( diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java new file mode 100644 index 00000000..004f0dc2 --- /dev/null +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java @@ -0,0 +1,47 @@ +package com.deftdevs.bootstrapi.crowd.service; + +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; +import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsService; + +import java.io.InputStream; + +public class CrowdSettingsServiceImpl implements CrowdSettingsService { + + private final SettingsServiceImpl settingsService; + private final SettingsBrandingServiceImpl settingsBrandingService; + + public CrowdSettingsServiceImpl( + final SettingsServiceImpl settingsService, + final SettingsBrandingServiceImpl settingsBrandingService) { + + this.settingsService = settingsService; + this.settingsBrandingService = settingsBrandingService; + } + + @Override + public SettingsGeneralModel getSettingsGeneral() { + return settingsService.getSettingsGeneral(); + } + + @Override + public SettingsGeneralModel setSettingsGeneral(final SettingsGeneralModel settingsGeneralModel) { + return settingsService.setSettingsGeneral(settingsGeneralModel); + } + + @Override + public SettingsBrandingLoginPageModel getLoginPage() { + return settingsBrandingService.getLoginPage(); + } + + @Override + public SettingsBrandingLoginPageModel setLoginPage(final SettingsBrandingLoginPageModel settingsBrandingLoginPageModel) { + return settingsBrandingService.setLoginPage(settingsBrandingLoginPageModel); + } + + @Override + public void setLogo(final InputStream inputStream) { + settingsBrandingService.setLogo(inputStream); + } + +} diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 43287790..d61cbe2e 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,9 +1,6 @@ package com.deftdevs.bootstrapi.crowd.service; import com.deftdevs.bootstrapi.commons.model.MailServerModel; -import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; -import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; -import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -12,12 +9,10 @@ import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.crowd.model.MailTemplatesModel; import com.deftdevs.bootstrapi.crowd.model.SessionConfigModel; -import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; -import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsBrandingService; -import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; +import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsService; import com.deftdevs.bootstrapi.crowd.service.api.MailTemplatesService; import com.deftdevs.bootstrapi.crowd.service.api.SessionConfigService; import com.deftdevs.bootstrapi.crowd.service.api.TrustedProxiesService; @@ -33,8 +28,7 @@ public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { - private final CrowdSettingsGeneralService settingsService; - private final CrowdSettingsBrandingService brandingService; + private final CrowdSettingsService settingsService; private final DirectoriesService directoriesService; private final ApplicationsService applicationsService; private final ApplicationLinksService applicationLinksService; @@ -45,8 +39,7 @@ public class _AllServiceImpl extends _AbstractAllServiceImpl<_AllModel> { private final TrustedProxiesService trustedProxiesService; public _AllServiceImpl( - final CrowdSettingsGeneralService settingsService, - final CrowdSettingsBrandingService brandingService, + final CrowdSettingsService settingsService, final DirectoriesService directoriesService, final ApplicationsService applicationsService, final ApplicationLinksService applicationLinksService, @@ -57,7 +50,6 @@ public _AllServiceImpl( final TrustedProxiesService trustedProxiesService) { this.settingsService = settingsService; - this.brandingService = brandingService; this.directoriesService = directoriesService; this.applicationsService = applicationsService; this.applicationLinksService = applicationLinksService; @@ -75,15 +67,8 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - final SettingsModel settingsInput = allModel.getSettings(); - if (settingsInput != null) { - final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsGeneralModel.class), settingsInput.getGeneral(), - settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsBrandingLoginPageModel.class), settingsInput.getBranding(), - brandingService::setLoginPage, settingsResult::setBranding, statusMap); - result.setSettings(settingsResult); - } + setEntity(entityType(SettingsModel.class), allModel.getSettings(), + settingsService::setSettings, result::setSettings, statusMap); setEntities(DIRECTORIES, allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); @@ -97,15 +82,8 @@ public _AllModel setAll( setEntities(LICENSES, allModel.getLicenses(), licensesService::setLicenses, result::setLicenses, statusMap); - final MailServerModel mailServerInput = allModel.getMailServer(); - if (mailServerInput != null) { - final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerSmtpModel.class), mailServerInput.getSmtp(), - mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerPopModel.class), mailServerInput.getPop(), - mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); - result.setMailServer(mailServerResult); - } + setEntity(entityType(MailServerModel.class), allModel.getMailServer(), + mailServerService::setMailServer, result::setMailServer, statusMap); setEntity(entityType(MailTemplatesModel.class), allModel.getMailTemplates(), mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java new file mode 100644 index 00000000..62afd96f --- /dev/null +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java @@ -0,0 +1,24 @@ +package com.deftdevs.bootstrapi.crowd.service.api; + +import com.deftdevs.bootstrapi.crowd.model.SettingsModel; + +public interface CrowdSettingsService extends + CrowdSettingsGeneralService, + CrowdSettingsBrandingService { + + default SettingsModel getSettings() { + return new SettingsModel(getSettingsGeneral(), getLoginPage()); + } + + default SettingsModel setSettings(final SettingsModel settingsModel) { + final SettingsModel result = new SettingsModel(); + if (settingsModel.getGeneral() != null) { + result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + } + if (settingsModel.getBranding() != null) { + result.setBranding(setLoginPage(settingsModel.getBranding())); + } + return result; + } + +} diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index 40de2635..5e54ceda 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -1,13 +1,8 @@ package com.deftdevs.bootstrapi.jira.service; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; -import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; import com.deftdevs.bootstrapi.commons.model.MailServerModel; -import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; -import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; -import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; -import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; @@ -15,7 +10,6 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; -import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import com.deftdevs.bootstrapi.jira.model.SettingsModel; import com.deftdevs.bootstrapi.jira.model._AllModel; import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; @@ -65,17 +59,8 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - final SettingsModel settingsInput = allModel.getSettings(); - if (settingsInput != null) { - final SettingsModel settingsResult = new SettingsModel(); - setEntity(entityType(SettingsGeneralModel.class), settingsInput.getGeneral(), - settingsService::setSettingsGeneral, settingsResult::setGeneral, statusMap); - setEntity(entityType(SettingsSecurityModel.class), settingsInput.getSecurity(), - settingsService::setSettingsSecurity, settingsResult::setSecurity, statusMap); - setEntity(entityType(SettingsBannerModel.class), settingsInput.getBanner(), - settingsService::setSettingsBanner, settingsResult::setBanner, statusMap); - result.setSettings(settingsResult); - } + setEntity(entityType(SettingsModel.class), allModel.getSettings(), + settingsService::setSettings, result::setSettings, statusMap); setEntities(DIRECTORIES, allModel.getDirectories(), directoriesService::setDirectories, result::setDirectories, statusMap); @@ -83,28 +68,14 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - final AuthenticationModel authInput = allModel.getAuthentication(); - if (authInput != null) { - final AuthenticationModel authResult = new AuthenticationModel(); - setEntities(AUTHENTICATION + "/" + AUTHENTICATION_IDPS, authInput.getIdps(), - authenticationService::setAuthenticationIdps, authResult::setIdps, statusMap); - setEntity(entityType(AuthenticationSsoModel.class), authInput.getSso(), - authenticationService::setAuthenticationSso, authResult::setSso, statusMap); - result.setAuthentication(authResult); - } + setEntity(entityType(AuthenticationModel.class), allModel.getAuthentication(), + authenticationService::setAuthentication, result::setAuthentication, statusMap); setEntities(LICENSES, allModel.getLicenses(), licensesService::setLicenses, result::setLicenses, statusMap); - final MailServerModel mailServerInput = allModel.getMailServer(); - if (mailServerInput != null) { - final MailServerModel mailServerResult = new MailServerModel(); - setEntity(entityType(MailServerSmtpModel.class), mailServerInput.getSmtp(), - mailServerService::setMailServerSmtp, mailServerResult::setSmtp, statusMap); - setEntity(entityType(MailServerPopModel.class), mailServerInput.getPop(), - mailServerService::setMailServerPop, mailServerResult::setPop, statusMap); - result.setMailServer(mailServerResult); - } + setEntity(entityType(MailServerModel.class), allModel.getMailServer(), + mailServerService::setMailServer, result::setMailServer, statusMap); setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java index 8242bb3a..5f2874e1 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java @@ -2,9 +2,10 @@ import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; -import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; +import com.deftdevs.bootstrapi.jira.model.SettingsModel; public interface JiraSettingsService extends SettingsGeneralService, @@ -15,4 +16,22 @@ public interface JiraSettingsService extends SettingsBannerModel setSettingsBanner( SettingsBannerModel settingsBannerModel); + default SettingsModel getSettings() { + return new SettingsModel(getSettingsGeneral(), getSettingsSecurity(), getSettingsBanner()); + } + + default SettingsModel setSettings(final SettingsModel settingsModel) { + final SettingsModel result = new SettingsModel(); + if (settingsModel.getGeneral() != null) { + result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + } + if (settingsModel.getSecurity() != null) { + result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); + } + if (settingsModel.getBanner() != null) { + result.setBanner(setSettingsBanner(settingsModel.getBanner())); + } + return result; + } + } From d20e886d63d8b540891849b0ad62c7a0fc4baa43 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 19 May 2026 15:59:51 +0800 Subject: [PATCH 10/11] Introduce ServiceResult for per-sub-field status granularity in PUT / Composite service methods (setSettings, setMailServer, setAuthentication) now return ServiceResult carrying both the result model and a sub-map of per-field status entries. _AbstractAllServiceImpl.setEntityWithStatus merges these sub-maps into the top-level status map, so the PUT / response exposes fine-grained keys like settings/general, mail-server/smtp, and authentication/idps rather than a single coarse entry per composite. ServiceResultUtil extracts entityType() and toErrorStatus() as public statics so service interfaces can use them without depending on the abstract class. AbstractAuthenticationIdpModel gains an explicit @XmlRootElement name to enable the same key derivation for the idps entry. Co-Authored-By: Claude Sonnet 4.6 --- .../model/AbstractAuthenticationIdpModel.java | 2 +- .../commons/model/type/ServiceResult.java | 26 +++++++++++ .../service/_AbstractAllServiceImpl.java | 42 ++++++++---------- .../service/api/AuthenticationService.java | 28 +++++++++--- .../service/api/MailServerService.java | 27 ++++++++++-- .../commons/util/ServiceResultUtil.java | 39 ++++++++++++++++ .../confluence/service/_AllServiceImpl.java | 6 +-- .../api/ConfluenceSettingsService.java | 44 ++++++++++++++++--- .../crowd/service/_AllServiceImpl.java | 4 +- .../service/api/CrowdSettingsService.java | 30 +++++++++++-- .../jira/service/_AllServiceImpl.java | 6 +-- .../jira/service/api/JiraSettingsService.java | 36 ++++++++++++--- 12 files changed, 233 insertions(+), 57 deletions(-) create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/ServiceResult.java create mode 100644 commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractAuthenticationIdpModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractAuthenticationIdpModel.java index ba5828d8..86ee05b1 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractAuthenticationIdpModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/AbstractAuthenticationIdpModel.java @@ -17,7 +17,7 @@ @SuperBuilder @NoArgsConstructor @AllArgsConstructor -@XmlRootElement +@XmlRootElement(name = "authentication-idps") @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/ServiceResult.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/ServiceResult.java new file mode 100644 index 00000000..53b0f1fb --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/ServiceResult.java @@ -0,0 +1,26 @@ +package com.deftdevs.bootstrapi.commons.model.type; + +import java.util.Map; + +public class ServiceResult { + + private final T model; + private final Map status; + + public ServiceResult( + final T model, + final Map status) { + + this.model = model; + this.status = status; + } + + public T getModel() { + return model; + } + + public Map getStatus() { + return status; + } + +} diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index 101ec15c..09197675 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -2,27 +2,33 @@ import com.deftdevs.bootstrapi.commons.model.type._AllModelAccessor; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.model.type.ServiceResult; import com.deftdevs.bootstrapi.commons.service.api._AllService; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; -import javax.xml.bind.annotation.XmlRootElement; import java.util.Map; import java.util.function.Consumer; import java.util.function.Function; public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { - // Derives the status-map key from @XmlRootElement: "parent-child" → "parent/child" - protected static String entityType( - final Class entityClass) { + protected static String entityType(final Class entityClass) { + return ServiceResultUtil.entityType(entityClass); + } + + protected void setEntityWithStatus( + final I input, + final Function> updateFunction, + final Consumer resultConsumer, + final Map statusMap) { - final XmlRootElement rootElement = entityClass.getAnnotation(XmlRootElement.class); - if (rootElement == null || "##default".equals(rootElement.name())) { - throw new IllegalArgumentException( - entityClass.getName() + " must have @XmlRootElement with explicit name"); + if (input == null) { + return; } - return rootElement.name().replaceFirst("-", "/"); + + final ServiceResult serviceResult = updateFunction.apply(input); + resultConsumer.accept(serviceResult.getModel()); + statusMap.putAll(serviceResult.getStatus()); } protected _AllModelStatus setEntity( @@ -75,19 +81,7 @@ protected _AllModelStatus setEntities( } private static _AllModelStatus toErrorStatus(final String entityType, final Exception e) { - if (e instanceof WebApplicationException) { - final Response response = ((WebApplicationException) e).getResponse(); - return _AllModelStatus.error( - Response.Status.fromStatusCode(response.getStatus()), - String.format("Failed to apply %s configuration", entityType), - e.getMessage() - ); - } - return _AllModelStatus.error( - Response.Status.INTERNAL_SERVER_ERROR, - String.format("Failed to apply %s configuration", entityType), - null - ); + return ServiceResultUtil.toErrorStatus(entityType, e); } } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java index af80606e..45c11545 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java @@ -3,7 +3,11 @@ import com.deftdevs.bootstrapi.commons.model.AbstractAuthenticationIdpModel; import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; import com.deftdevs.bootstrapi.commons.model.AuthenticationSsoModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.model.type.ServiceResult; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; +import java.util.LinkedHashMap; import java.util.Map; public interface AuthenticationService { @@ -16,16 +20,30 @@ default AuthenticationModel getAuthentication() { } @SuppressWarnings("unchecked") - default AuthenticationModel setAuthentication(final AuthenticationModel authenticationModel) { + default ServiceResult setAuthentication(final AuthenticationModel authenticationModel) { final AuthenticationModel result = new AuthenticationModel(); + final Map status = new LinkedHashMap<>(); + if (authenticationModel.getIdps() != null) { - result.setIdps((Map) setAuthenticationIdps( - (Map) authenticationModel.getIdps())); + final String key = ServiceResultUtil.entityType(AbstractAuthenticationIdpModel.class); + try { + result.setIdps((Map) setAuthenticationIdps( + (Map) authenticationModel.getIdps())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (authenticationModel.getSso() != null) { - result.setSso(setAuthenticationSso((SB) authenticationModel.getSso())); + final String key = ServiceResultUtil.entityType(AuthenticationSsoModel.class); + try { + result.setSso(setAuthenticationSso((SB) authenticationModel.getSso())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } - return result; + return new ServiceResult<>(result, status); } Map getAuthenticationIdps(); diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java index 464c6262..84ec98c9 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java @@ -3,7 +3,12 @@ import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.MailServerPopModel; import com.deftdevs.bootstrapi.commons.model.MailServerSmtpModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.model.type.ServiceResult; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; +import java.util.LinkedHashMap; +import java.util.Map; public interface MailServerService { @@ -11,15 +16,29 @@ default MailServerModel getMailServer() { return new MailServerModel(getMailServerSmtp(), getMailServerPop()); } - default MailServerModel setMailServer(final MailServerModel mailServerModel) { + default ServiceResult setMailServer(final MailServerModel mailServerModel) { final MailServerModel result = new MailServerModel(); + final Map status = new LinkedHashMap<>(); + if (mailServerModel.getSmtp() != null) { - result.setSmtp(setMailServerSmtp(mailServerModel.getSmtp())); + final String key = ServiceResultUtil.entityType(MailServerSmtpModel.class); + try { + result.setSmtp(setMailServerSmtp(mailServerModel.getSmtp())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (mailServerModel.getPop() != null) { - result.setPop(setMailServerPop(mailServerModel.getPop())); + final String key = ServiceResultUtil.entityType(MailServerPopModel.class); + try { + result.setPop(setMailServerPop(mailServerModel.getPop())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } - return result; + return new ServiceResult<>(result, status); } /** diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java new file mode 100644 index 00000000..a22787c0 --- /dev/null +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java @@ -0,0 +1,39 @@ +package com.deftdevs.bootstrapi.commons.util; + +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.xml.bind.annotation.XmlRootElement; + +public class ServiceResultUtil { + + public static String entityType(final Class entityClass) { + final XmlRootElement rootElement = entityClass.getAnnotation(XmlRootElement.class); + if (rootElement == null || "##default".equals(rootElement.name())) { + throw new IllegalArgumentException( + entityClass.getName() + " must have @XmlRootElement with explicit name"); + } + return rootElement.name().replaceFirst("-", "/"); + } + + public static _AllModelStatus toErrorStatus(final String entityType, final Exception e) { + if (e instanceof WebApplicationException) { + final Response response = ((WebApplicationException) e).getResponse(); + return _AllModelStatus.error( + Response.Status.fromStatusCode(response.getStatus()), + String.format("Failed to apply %s configuration", entityType), + e.getMessage() + ); + } + return _AllModelStatus.error( + Response.Status.INTERNAL_SERVER_ERROR, + String.format("Failed to apply %s configuration", entityType), + null + ); + } + + private ServiceResultUtil() { + } + +} diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index f68eb240..ec12cfeb 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -59,7 +59,7 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - setEntity(entityType(SettingsModel.class), allModel.getSettings(), + setEntityWithStatus(allModel.getSettings(), settingsService::setSettings, result::setSettings, statusMap); setEntities(DIRECTORIES, allModel.getDirectories(), @@ -68,13 +68,13 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - setEntity(entityType(AuthenticationModel.class), allModel.getAuthentication(), + setEntityWithStatus(allModel.getAuthentication(), authenticationService::setAuthentication, result::setAuthentication, statusMap); setEntities(LICENSES, allModel.getLicenses(), licensesService::setLicenses, result::setLicenses, statusMap); - setEntity(entityType(MailServerModel.class), allModel.getMailServer(), + setEntityWithStatus(allModel.getMailServer(), mailServerService::setMailServer, result::setMailServer, statusMap); setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java index c7e0742e..7261b5c3 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java @@ -3,12 +3,18 @@ import com.deftdevs.bootstrapi.commons.model.SettingsBrandingColorSchemeModel; import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.model.type.ServiceResult; import com.deftdevs.bootstrapi.commons.service.api.SettingsBrandingService; import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import com.deftdevs.bootstrapi.confluence.model.SettingsModel; +import java.util.LinkedHashMap; +import java.util.Map; + public interface ConfluenceSettingsService extends SettingsGeneralService, SettingsSecurityService, @@ -24,21 +30,47 @@ default SettingsModel getSettings() { getColourScheme(), getCustomHtml()); } - default SettingsModel setSettings(final SettingsModel settingsModel) { + default ServiceResult setSettings(final SettingsModel settingsModel) { final SettingsModel result = new SettingsModel(); + final Map status = new LinkedHashMap<>(); + if (settingsModel.getGeneral() != null) { - result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + final String key = ServiceResultUtil.entityType(SettingsGeneralModel.class); + try { + result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (settingsModel.getSecurity() != null) { - result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); + final String key = ServiceResultUtil.entityType(SettingsSecurityModel.class); + try { + result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (settingsModel.getBranding() != null) { - result.setBranding(setColourScheme(settingsModel.getBranding())); + final String key = ServiceResultUtil.entityType(SettingsBrandingColorSchemeModel.class); + try { + result.setBranding(setColourScheme(settingsModel.getBranding())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (settingsModel.getCustomHtml() != null) { - result.setCustomHtml(setCustomHtml(settingsModel.getCustomHtml())); + final String key = ServiceResultUtil.entityType(SettingsCustomHtmlModel.class); + try { + result.setCustomHtml(setCustomHtml(settingsModel.getCustomHtml())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } - return result; + return new ServiceResult<>(result, status); } } diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index d61cbe2e..7310cbdf 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -67,7 +67,7 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - setEntity(entityType(SettingsModel.class), allModel.getSettings(), + setEntityWithStatus(allModel.getSettings(), settingsService::setSettings, result::setSettings, statusMap); setEntities(DIRECTORIES, allModel.getDirectories(), @@ -82,7 +82,7 @@ public _AllModel setAll( setEntities(LICENSES, allModel.getLicenses(), licensesService::setLicenses, result::setLicenses, statusMap); - setEntity(entityType(MailServerModel.class), allModel.getMailServer(), + setEntityWithStatus(allModel.getMailServer(), mailServerService::setMailServer, result::setMailServer, statusMap); setEntity(entityType(MailTemplatesModel.class), allModel.getMailTemplates(), diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java index 62afd96f..c6ad1cc3 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java @@ -1,7 +1,15 @@ package com.deftdevs.bootstrapi.crowd.service.api; +import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.model.type.ServiceResult; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; +import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; import com.deftdevs.bootstrapi.crowd.model.SettingsModel; +import java.util.LinkedHashMap; +import java.util.Map; + public interface CrowdSettingsService extends CrowdSettingsGeneralService, CrowdSettingsBrandingService { @@ -10,15 +18,29 @@ default SettingsModel getSettings() { return new SettingsModel(getSettingsGeneral(), getLoginPage()); } - default SettingsModel setSettings(final SettingsModel settingsModel) { + default ServiceResult setSettings(final SettingsModel settingsModel) { final SettingsModel result = new SettingsModel(); + final Map status = new LinkedHashMap<>(); + if (settingsModel.getGeneral() != null) { - result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + final String key = ServiceResultUtil.entityType(SettingsGeneralModel.class); + try { + result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (settingsModel.getBranding() != null) { - result.setBranding(setLoginPage(settingsModel.getBranding())); + final String key = ServiceResultUtil.entityType(SettingsBrandingLoginPageModel.class); + try { + result.setBranding(setLoginPage(settingsModel.getBranding())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } - return result; + return new ServiceResult<>(result, status); } } diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index 5e54ceda..a1f6d3c2 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -59,7 +59,7 @@ public _AllModel setAll( final _AllModel result = new _AllModel(); final Map statusMap = new HashMap<>(); - setEntity(entityType(SettingsModel.class), allModel.getSettings(), + setEntityWithStatus(allModel.getSettings(), settingsService::setSettings, result::setSettings, statusMap); setEntities(DIRECTORIES, allModel.getDirectories(), @@ -68,13 +68,13 @@ public _AllModel setAll( setEntities(APPLICATION_LINKS, allModel.getApplicationLinks(), applicationLinksService::setApplicationLinks, result::setApplicationLinks, statusMap); - setEntity(entityType(AuthenticationModel.class), allModel.getAuthentication(), + setEntityWithStatus(allModel.getAuthentication(), authenticationService::setAuthentication, result::setAuthentication, statusMap); setEntities(LICENSES, allModel.getLicenses(), licensesService::setLicenses, result::setLicenses, statusMap); - setEntity(entityType(MailServerModel.class), allModel.getMailServer(), + setEntityWithStatus(allModel.getMailServer(), mailServerService::setMailServer, result::setMailServer, statusMap); setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java index 5f2874e1..8f14a030 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java @@ -2,11 +2,17 @@ import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import com.deftdevs.bootstrapi.commons.model.type.ServiceResult; import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; import com.deftdevs.bootstrapi.jira.model.SettingsBannerModel; import com.deftdevs.bootstrapi.jira.model.SettingsModel; +import java.util.LinkedHashMap; +import java.util.Map; + public interface JiraSettingsService extends SettingsGeneralService, SettingsSecurityService { @@ -20,18 +26,38 @@ default SettingsModel getSettings() { return new SettingsModel(getSettingsGeneral(), getSettingsSecurity(), getSettingsBanner()); } - default SettingsModel setSettings(final SettingsModel settingsModel) { + default ServiceResult setSettings(final SettingsModel settingsModel) { final SettingsModel result = new SettingsModel(); + final Map status = new LinkedHashMap<>(); + if (settingsModel.getGeneral() != null) { - result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + final String key = ServiceResultUtil.entityType(SettingsGeneralModel.class); + try { + result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (settingsModel.getSecurity() != null) { - result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); + final String key = ServiceResultUtil.entityType(SettingsSecurityModel.class); + try { + result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } if (settingsModel.getBanner() != null) { - result.setBanner(setSettingsBanner(settingsModel.getBanner())); + final String key = ServiceResultUtil.entityType(SettingsBannerModel.class); + try { + result.setBanner(setSettingsBanner(settingsModel.getBanner())); + status.put(key, _AllModelStatus.success()); + } catch (Exception e) { + status.put(key, ServiceResultUtil.toErrorStatus(key, e)); + } } - return result; + return new ServiceResult<>(result, status); } } From 01c955883c4bba3c1146c7a930e08d984b673450 Mon Sep 17 00:00:00 2001 From: Patrick Hobusch Date: Tue, 19 May 2026 16:51:18 +0800 Subject: [PATCH 11/11] Address review feedback on _all endpoint Bug fixes - Fix NPE in ServiceResultUtil.toErrorStatus for non-standard HTTP codes (e.g. 422, 429) by accepting an int status code on _AllModelStatus.error. - Wrap the composite call in _AbstractAllServiceImpl.setEntityWithStatus so a thrown exception inside setSettings/setMailServer/setAuthentication no longer kills the entire setAll; the failure is attributed to the top-level group derived from the input's @XmlRootElement. - Log non-WAE exceptions server-side before sanitizing them out of the client response. - Fix Jira LicensesServiceImpl.setLicenses(Map) to call addLicense per-key like Confluence/Crowd. The previous implementation paired input keys with JiraLicenseManager.getLicenses() entries by index, but the API makes no ordering guarantee. - Fix Crowd and Confluence ServiceConfig to call existing bean methods instead of `new`-ing duplicate instances for the composite settings service (CGLIB caching was being bypassed). - Fix copy-paste in BootstrAPI.SETTINGS_GENERAL_PUT_RESPONSE_DESCRIPTION. Status-key convention - Split the formerly-overloaded entityType() into two named operations: entityType(Class) returns the raw @XmlRootElement.name (used for top-level keys like mail-templates, session-config) and subEntityKey(Class) splits on the last dash for sub-field keys like settings/general, mail-server/smtp, permissions/global. This removes the silent transform that was incorrectly mapping mail-templates to mail/templates. - Rewrite _AbstractAllResourceImpl.computeOverallStatus to use 207 Multi-Status for mixed outcomes, 500 for any 5xx, the common 4xx when all client errors agree, and 200 otherwise. Design cleanup - Have Confluence's SettingsServiceImpl implement SettingsGeneralService and SettingsSecurityService (it had no interface before). - Have Crowd's CrowdSettingsServiceImpl take interfaces, not concrete impl types, in its constructor. - Remove the unused MailServerModel.EXAMPLE_1 and stale imports across the three _AllServiceImpl files. Docs - Fix _AllModel.md in all three products: licenses is a Map, not a List. - Fix AllApi.md in all three products: the response body is _AllModel (with the status map and redacted license keys), not empty. Tests (+22, all passing) - New ServiceResultUtilTest covers entityType, subEntityKey edge cases, the NPE fix, and exception sanitization. - New _AbstractAllResourceImplTest covers the new aggregation logic. - LicensesServiceTest gets a Jira-specific test verifying redaction and per-key pairing for the new setLicenses(Map) overload. - Rename Crowd AllResourceTest -> _AllResourceTest for naming parity with Jira/Confluence; add status-aggregation tests to all three. Co-Authored-By: Claude Opus 4.7 --- .../commons/constants/BootstrAPI.java | 2 +- .../commons/model/MailServerModel.java | 7 -- .../commons/model/type/_AllModelStatus.java | 9 +- .../rest/_AbstractAllResourceImpl.java | 53 +++++++++-- .../service/_AbstractAllServiceImpl.java | 28 +++--- .../service/api/AuthenticationService.java | 4 +- .../service/api/MailServerService.java | 4 +- .../commons/util/ServiceResultUtil.java | 55 +++++++++--- .../rest/_AbstractAllResourceImplTest.java | 65 ++++++++++++++ .../commons/util/ServiceResultUtilTest.java | 89 +++++++++++++++++++ confluence/Apis/AllApi.md | 8 +- confluence/Models/_AllModel.md | 2 +- .../confluence/config/ServiceConfig.java | 7 +- .../ConfluenceSettingsServiceImpl.java | 6 ++ .../service/SettingsServiceImpl.java | 9 +- .../confluence/service/_AllServiceImpl.java | 8 +- .../api/ConfluenceSettingsService.java | 8 +- .../confluence/rest/_AllResourceTest.java | 28 ++++++ crowd/Apis/AllApi.md | 8 +- crowd/Models/_AllModel.md | 2 +- .../crowd/config/ServiceConfig.java | 4 +- .../service/CrowdSettingsServiceImpl.java | 10 ++- .../crowd/service/_AllServiceImpl.java | 7 +- .../service/api/CrowdSettingsService.java | 4 +- ...esourceTest.java => _AllResourceTest.java} | 46 +++++++--- jira/Apis/AllApi.md | 8 +- jira/Models/_AllModel.md | 2 +- .../jira/service/LicensesServiceImpl.java | 8 +- .../jira/service/_AllServiceImpl.java | 8 +- .../jira/service/api/JiraSettingsService.java | 6 +- .../jira/rest/_AllResourceTest.java | 28 ++++++ .../jira/service/LicensesServiceTest.java | 35 ++++++++ 32 files changed, 468 insertions(+), 100 deletions(-) create mode 100644 commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImplTest.java create mode 100644 commons/src/test/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtilTest.java rename crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/{AllResourceTest.java => _AllResourceTest.java} (52%) diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java index ed6fbc8d..b25e179d 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/constants/BootstrAPI.java @@ -66,7 +66,7 @@ public class BootstrAPI { public static final String SETTINGS_GENERAL_GET_SUMMARY = "Get the general settings"; public static final String SETTINGS_GENERAL_GET_RESPONSE_DESCRIPTION = "Returns the general settings"; public static final String SETTINGS_GENERAL_PUT_SUMMARY = "Set the general settings"; - public static final String SETTINGS_GENERAL_PUT_RESPONSE_DESCRIPTION = "Returns the general security settings"; + public static final String SETTINGS_GENERAL_PUT_RESPONSE_DESCRIPTION = "Returns the updated general settings"; public static final String SETTINGS_SECURITY_GET_SUMMARY = "Get the security settings"; public static final String SETTINGS_SECURITY_GET_RESPONSE_DESCRIPTION = "Returns the security settings"; public static final String SETTINGS_SECURITY_PUT_SUMMARY = "Set the security settings"; diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java index 0b75d942..b49c2efe 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/MailServerModel.java @@ -21,11 +21,4 @@ public class MailServerModel { @XmlElement private MailServerPopModel pop; - // Example instances for documentation and tests - - public static final MailServerModel EXAMPLE_1 = new MailServerModel( - MailServerSmtpModel.EXAMPLE_1, - MailServerPopModel.EXAMPLE_1 - ); - } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java index 8dfcc8f0..42d73b65 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/model/type/_AllModelStatus.java @@ -28,6 +28,13 @@ public static _AllModelStatus success() { } public static _AllModelStatus error(Response.Status status, String message, String details) { - return new _AllModelStatus(status.getStatusCode(), message, details); + final int code = status != null + ? status.getStatusCode() + : Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); + return new _AllModelStatus(code, message, details); + } + + public static _AllModelStatus error(int statusCode, String message, String details) { + return new _AllModelStatus(statusCode, message, details); } } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java index 423ce4f7..45a5febf 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImpl.java @@ -11,6 +11,8 @@ public abstract class _AbstractAllResourceImpl<_AllModel extends _AllModelAccessor> implements _AllResource<_AllModel> { + static final int MULTI_STATUS = 207; + private final _AllService<_AllModel> allService; public _AbstractAllResourceImpl( @@ -19,6 +21,7 @@ public _AbstractAllResourceImpl( this.allService = allService; } + @Override public Response setAll( final _AllModel allModel) { @@ -27,16 +30,56 @@ public Response setAll( return Response.status(overallStatus).entity(result).build(); } - private static int computeOverallStatus( + /** + * Aggregates per-sub-field statuses into a single HTTP response code: + *

    + *
  • All successful (or empty) → 200 OK.
  • + *
  • All entries share the same status code → that code.
  • + *
  • Any 5xx → 500 Internal Server Error.
  • + *
  • Mixed 2xx/4xx (or multiple distinct 4xx) → 207 Multi-Status.
  • + *
+ * 207 is used to signal "partial success" — callers must inspect the + * per-field {@code status} map in the response body to see which + * fields succeeded and which failed. + */ + static int computeOverallStatus( final Map statusMap) { if (statusMap == null || statusMap.isEmpty()) { return Response.Status.OK.getStatusCode(); } - return statusMap.values().stream() - .mapToInt(_AllModelStatus::getStatus) - .max() - .orElse(Response.Status.OK.getStatusCode()); + boolean anyServerError = false; + boolean anyClientError = false; + boolean anySuccess = false; + Integer firstClientErrorCode = null; + boolean clientErrorCodesDiffer = false; + + for (_AllModelStatus entry : statusMap.values()) { + final int code = entry.getStatus(); + if (code >= 500) { + anyServerError = true; + } else if (code >= 400) { + anyClientError = true; + if (firstClientErrorCode == null) { + firstClientErrorCode = code; + } else if (firstClientErrorCode != code) { + clientErrorCodesDiffer = true; + } + } else if (code >= 200 && code < 300) { + anySuccess = true; + } + } + + if (anyServerError) { + return Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); + } + if (anyClientError) { + if (anySuccess || clientErrorCodesDiffer) { + return MULTI_STATUS; + } + return firstClientErrorCode; + } + return Response.Status.OK.getStatusCode(); } } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java index 09197675..1f6c938c 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/_AbstractAllServiceImpl.java @@ -12,10 +12,6 @@ public abstract class _AbstractAllServiceImpl<_AllModel extends _AllModelAccessor> implements _AllService<_AllModel> { - protected static String entityType(final Class entityClass) { - return ServiceResultUtil.entityType(entityClass); - } - protected void setEntityWithStatus( final I input, final Function> updateFunction, @@ -26,9 +22,19 @@ protected void setEntityWithStatus( return; } - final ServiceResult serviceResult = updateFunction.apply(input); - resultConsumer.accept(serviceResult.getModel()); - statusMap.putAll(serviceResult.getStatus()); + try { + final ServiceResult serviceResult = updateFunction.apply(input); + resultConsumer.accept(serviceResult.getModel()); + statusMap.putAll(serviceResult.getStatus()); + } catch (Exception e) { + // The composite updateFunction normally produces fine-grained + // sub-field status entries itself. If it threw before doing so + // (e.g. NPE on a sub-field accessor, or a cast failure on a + // generic parameter), attribute the failure to the top-level + // group derived from the input model's @XmlRootElement name. + final String fallbackKey = ServiceResultUtil.entityType(input.getClass()); + statusMap.put(fallbackKey, ServiceResultUtil.toErrorStatus(fallbackKey, e)); + } } protected _AllModelStatus setEntity( @@ -49,7 +55,7 @@ protected _AllModelStatus setEntity( statusMap.put(entityType, status); return status; } catch (Exception e) { - final _AllModelStatus status = toErrorStatus(entityType, e); + final _AllModelStatus status = ServiceResultUtil.toErrorStatus(entityType, e); statusMap.put(entityType, status); return status; } @@ -74,14 +80,10 @@ protected _AllModelStatus setEntities( statusMap.put(entityType, status); return status; } catch (Exception e) { - final _AllModelStatus status = toErrorStatus(entityType, e); + final _AllModelStatus status = ServiceResultUtil.toErrorStatus(entityType, e); statusMap.put(entityType, status); return status; } } - private static _AllModelStatus toErrorStatus(final String entityType, final Exception e) { - return ServiceResultUtil.toErrorStatus(entityType, e); - } - } diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java index 45c11545..a248a904 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/AuthenticationService.java @@ -25,7 +25,7 @@ default ServiceResult setAuthentication(final Authenticatio final Map status = new LinkedHashMap<>(); if (authenticationModel.getIdps() != null) { - final String key = ServiceResultUtil.entityType(AbstractAuthenticationIdpModel.class); + final String key = ServiceResultUtil.subEntityKey(AbstractAuthenticationIdpModel.class); try { result.setIdps((Map) setAuthenticationIdps( (Map) authenticationModel.getIdps())); @@ -35,7 +35,7 @@ default ServiceResult setAuthentication(final Authenticatio } } if (authenticationModel.getSso() != null) { - final String key = ServiceResultUtil.entityType(AuthenticationSsoModel.class); + final String key = ServiceResultUtil.subEntityKey(AuthenticationSsoModel.class); try { result.setSso(setAuthenticationSso((SB) authenticationModel.getSso())); status.put(key, _AllModelStatus.success()); diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java index 84ec98c9..213a70f0 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/service/api/MailServerService.java @@ -21,7 +21,7 @@ default ServiceResult setMailServer(final MailServerModel mailS final Map status = new LinkedHashMap<>(); if (mailServerModel.getSmtp() != null) { - final String key = ServiceResultUtil.entityType(MailServerSmtpModel.class); + final String key = ServiceResultUtil.subEntityKey(MailServerSmtpModel.class); try { result.setSmtp(setMailServerSmtp(mailServerModel.getSmtp())); status.put(key, _AllModelStatus.success()); @@ -30,7 +30,7 @@ default ServiceResult setMailServer(final MailServerModel mailS } } if (mailServerModel.getPop() != null) { - final String key = ServiceResultUtil.entityType(MailServerPopModel.class); + final String key = ServiceResultUtil.subEntityKey(MailServerPopModel.class); try { result.setPop(setMailServerPop(mailServerModel.getPop())); status.put(key, _AllModelStatus.success()); diff --git a/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java b/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java index a22787c0..2f99e340 100644 --- a/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java +++ b/commons/src/main/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtil.java @@ -1,6 +1,8 @@ package com.deftdevs.bootstrapi.commons.util; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; @@ -8,29 +10,60 @@ public class ServiceResultUtil { + private static final Logger log = LoggerFactory.getLogger(ServiceResultUtil.class); + + /** + * Returns the raw {@code @XmlRootElement(name = ...)} of a model class. + * Used as the top-level status-map key for non-composite entries + * (e.g. {@code mail-templates}, {@code session-config}). Dashes in the + * name are preserved — composite "group/sub" keys are produced by the + * {@link #subEntityKey(Class)} overload instead. + */ public static String entityType(final Class entityClass) { final XmlRootElement rootElement = entityClass.getAnnotation(XmlRootElement.class); if (rootElement == null || "##default".equals(rootElement.name())) { throw new IllegalArgumentException( entityClass.getName() + " must have @XmlRootElement with explicit name"); } - return rootElement.name().replaceFirst("-", "/"); + return rootElement.name(); + } + + /** + * Returns the status-map key for a sub-field of a composite group, + * derived from the leaf model's {@code @XmlRootElement(name = ...)} + * by replacing the last dash with a slash. The convention assumes + * sub-field models are named {@code -}, where the group + * itself may contain dashes (e.g. {@code mail-server-smtp} → + * {@code mail-server/smtp}). Single-dash names map straightforwardly + * (e.g. {@code settings-general} → {@code settings/general}, + * {@code authentication-idps} → {@code authentication/idps}, + * {@code permissions-global} → {@code permissions/global}). + * + * @throws IllegalArgumentException if the model name contains no dash + * (i.e. the model is not a sub-field model — use {@link #entityType(Class)} instead) + */ + public static String subEntityKey(final Class entityClass) { + final String name = entityType(entityClass); + final int dash = name.lastIndexOf('-'); + if (dash < 0) { + throw new IllegalArgumentException( + entityClass.getName() + " is not a sub-field model: name '" + name + + "' has no dash separator"); + } + return name.substring(0, dash) + "/" + name.substring(dash + 1); } public static _AllModelStatus toErrorStatus(final String entityType, final Exception e) { + final String message = String.format("Failed to apply %s configuration", entityType); if (e instanceof WebApplicationException) { final Response response = ((WebApplicationException) e).getResponse(); - return _AllModelStatus.error( - Response.Status.fromStatusCode(response.getStatus()), - String.format("Failed to apply %s configuration", entityType), - e.getMessage() - ); + final int statusCode = response != null + ? response.getStatus() + : Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); + return _AllModelStatus.error(statusCode, message, e.getMessage()); } - return _AllModelStatus.error( - Response.Status.INTERNAL_SERVER_ERROR, - String.format("Failed to apply %s configuration", entityType), - null - ); + log.warn("Unexpected error applying {} configuration", entityType, e); + return _AllModelStatus.error(Response.Status.INTERNAL_SERVER_ERROR, message, null); } private ServiceResultUtil() { diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImplTest.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImplTest.java new file mode 100644 index 00000000..f7742bb9 --- /dev/null +++ b/commons/src/test/java/com/deftdevs/bootstrapi/commons/rest/_AbstractAllResourceImplTest.java @@ -0,0 +1,65 @@ +package com.deftdevs.bootstrapi.commons.rest; + +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import org.junit.jupiter.api.Test; + +import javax.ws.rs.core.Response; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class _AbstractAllResourceImplTest { + + @Test + void emptyMapYieldsOk() { + assertEquals(200, _AbstractAllResourceImpl.computeOverallStatus(Collections.emptyMap())); + } + + @Test + void nullMapYieldsOk() { + assertEquals(200, _AbstractAllResourceImpl.computeOverallStatus(null)); + } + + @Test + void allSuccessYieldsOk() { + final Map map = new LinkedHashMap<>(); + map.put("a", _AllModelStatus.success()); + map.put("b", _AllModelStatus.success()); + assertEquals(200, _AbstractAllResourceImpl.computeOverallStatus(map)); + } + + @Test + void anyServerErrorYields500() { + final Map map = new LinkedHashMap<>(); + map.put("a", _AllModelStatus.success()); + map.put("b", _AllModelStatus.error(Response.Status.BAD_REQUEST, "x", null)); + map.put("c", _AllModelStatus.error(Response.Status.INTERNAL_SERVER_ERROR, "x", null)); + assertEquals(500, _AbstractAllResourceImpl.computeOverallStatus(map)); + } + + @Test + void mixedSuccessAndClientErrorYields207() { + final Map map = new LinkedHashMap<>(); + map.put("a", _AllModelStatus.success()); + map.put("b", _AllModelStatus.error(Response.Status.BAD_REQUEST, "x", null)); + assertEquals(_AbstractAllResourceImpl.MULTI_STATUS, _AbstractAllResourceImpl.computeOverallStatus(map)); + } + + @Test + void allSameClientErrorBubblesThat() { + final Map map = new LinkedHashMap<>(); + map.put("a", _AllModelStatus.error(Response.Status.BAD_REQUEST, "x", null)); + map.put("b", _AllModelStatus.error(Response.Status.BAD_REQUEST, "y", null)); + assertEquals(400, _AbstractAllResourceImpl.computeOverallStatus(map)); + } + + @Test + void differentClientErrorsYield207() { + final Map map = new LinkedHashMap<>(); + map.put("a", _AllModelStatus.error(Response.Status.BAD_REQUEST, "x", null)); + map.put("b", _AllModelStatus.error(Response.Status.CONFLICT, "y", null)); + assertEquals(_AbstractAllResourceImpl.MULTI_STATUS, _AbstractAllResourceImpl.computeOverallStatus(map)); + } +} diff --git a/commons/src/test/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtilTest.java b/commons/src/test/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtilTest.java new file mode 100644 index 00000000..77ff9f3b --- /dev/null +++ b/commons/src/test/java/com/deftdevs/bootstrapi/commons/util/ServiceResultUtilTest.java @@ -0,0 +1,89 @@ +package com.deftdevs.bootstrapi.commons.util; + +import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; +import org.junit.jupiter.api.Test; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.xml.bind.annotation.XmlRootElement; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ServiceResultUtilTest { + + @XmlRootElement(name = "leaf") + private static class LeafModel { + } + + @XmlRootElement(name = "settings-general") + private static class SubFieldSingleDash { + } + + @XmlRootElement(name = "mail-server-smtp") + private static class SubFieldMultiDash { + } + + @XmlRootElement + private static class UnnamedModel { + } + + private static class UnannotatedModel { + } + + @Test + void entityTypeReturnsRawName() { + assertEquals("leaf", ServiceResultUtil.entityType(LeafModel.class)); + } + + @Test + void entityTypeRejectsMissingAnnotation() { + assertThrows(IllegalArgumentException.class, + () -> ServiceResultUtil.entityType(UnannotatedModel.class)); + } + + @Test + void entityTypeRejectsDefaultName() { + assertThrows(IllegalArgumentException.class, + () -> ServiceResultUtil.entityType(UnnamedModel.class)); + } + + @Test + void subEntityKeySplitsOnLastDash() { + assertEquals("settings/general", ServiceResultUtil.subEntityKey(SubFieldSingleDash.class)); + assertEquals("mail-server/smtp", ServiceResultUtil.subEntityKey(SubFieldMultiDash.class)); + } + + @Test + void subEntityKeyRejectsNonCompositeName() { + assertThrows(IllegalArgumentException.class, + () -> ServiceResultUtil.subEntityKey(LeafModel.class)); + } + + @Test + void toErrorStatusWithStandardWaeUsesItsStatusCode() { + final WebApplicationException e = new WebApplicationException("bad input", 400); + final _AllModelStatus status = ServiceResultUtil.toErrorStatus("settings", e); + assertEquals(400, status.getStatus()); + assertEquals("bad input", status.getDetails()); + assertTrue(status.getMessage().contains("settings")); + } + + @Test + void toErrorStatusWithNonStandardCodeDoesNotNpe() { + final WebApplicationException e = new WebApplicationException("rate limited", + Response.status(429).build()); + final _AllModelStatus status = ServiceResultUtil.toErrorStatus("settings", e); + assertEquals(429, status.getStatus()); + } + + @Test + void toErrorStatusForNonWaeIsGenericAndDropsDetails() { + final _AllModelStatus status = ServiceResultUtil.toErrorStatus("settings", + new RuntimeException("internal secret")); + assertEquals(500, status.getStatus()); + assertNull(status.getDetails()); + } +} diff --git a/confluence/Apis/AllApi.md b/confluence/Apis/AllApi.md index 4636a333..1cb57839 100644 --- a/confluence/Apis/AllApi.md +++ b/confluence/Apis/AllApi.md @@ -9,7 +9,7 @@ All URIs are relative to *https://CONFLUENCE_URL/rest/bootstrapi/1* # **setAll** -> setAll(\_AllModel) +> _AllModel setAll(\_AllModel) Apply a complete configuration @@ -21,7 +21,11 @@ Apply a complete configuration ### Return type -null (empty response body) +[**_AllModel**](../Models/_AllModel.md) + +The updated configuration. The per-sub-field outcome is reported in the `status` map +(2xx for success, 4xx/5xx for failure with a human-readable `message` and optional +`details`). License keys in the response are redacted (e.g. `AAAB...wxyz#a1b2`). ### Authorization diff --git a/confluence/Models/_AllModel.md b/confluence/Models/_AllModel.md index cd6000f3..3a2e4dee 100644 --- a/confluence/Models/_AllModel.md +++ b/confluence/Models/_AllModel.md @@ -7,7 +7,7 @@ | **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | | **applicationLinks** | [**Map**](ApplicationLinkModel.md) | | [optional] [default to null] | | **authentication** | [**AuthenticationModel**](AuthenticationModel.md) | | [optional] [default to null] | -| **licenses** | **List** | | [optional] [default to null] | +| **licenses** | [**Map**](LicenseModel.md) | | [optional] [default to null] | | **mailServer** | [**MailServerModel**](MailServerModel.md) | | [optional] [default to null] | | **permissionsGlobal** | [**PermissionsGlobalModel**](PermissionsGlobalModel.md) | | [optional] [default to null] | | **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java index 15bc479e..bc5af7e1 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/config/ServiceConfig.java @@ -56,10 +56,15 @@ public ConfluenceAuthenticationService confluenceAuthenticationService() { @Bean public ConfluenceSettingsService confluenceSettingsService() { return new ConfluenceSettingsServiceImpl( - new SettingsServiceImpl(atlassianConfig.globalSettingsManager()), + settingsService(), settingsBrandingService()); } + @Bean + public SettingsServiceImpl settingsService() { + return new SettingsServiceImpl(atlassianConfig.globalSettingsManager()); + } + @Bean public DirectoriesService directoriesService() { return new DirectoriesServiceImpl( diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java index 940d1e6e..b3e7e586 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/ConfluenceSettingsServiceImpl.java @@ -14,6 +14,12 @@ public class ConfluenceSettingsServiceImpl implements ConfluenceSettingsService private final SettingsServiceImpl settingsService; private final SettingsBrandingService settingsBrandingService; + /** + * The general/security/custom-html operations are provided by {@link SettingsServiceImpl}, + * which intentionally exposes {@code getCustomHtml}/{@code setCustomHtml} as + * non-interface methods (there is no Confluence-shared interface for them). + * That forces the concrete type here. + */ public ConfluenceSettingsServiceImpl( final SettingsServiceImpl settingsService, final SettingsBrandingService settingsBrandingService) { diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java index faf17d1a..cedaaaab 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/SettingsServiceImpl.java @@ -5,10 +5,13 @@ import com.atlassian.confluence.setup.settings.Settings; import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.commons.model.SettingsSecurityModel; +import com.deftdevs.bootstrapi.commons.service.api.SettingsGeneralService; +import com.deftdevs.bootstrapi.commons.service.api.SettingsSecurityService; import com.deftdevs.bootstrapi.confluence.model.SettingsCustomHtmlModel; import java.net.URI; -public class SettingsServiceImpl { +public class SettingsServiceImpl + implements SettingsGeneralService, SettingsSecurityService { private final GlobalSettingsManager globalSettingsManager; @@ -19,6 +22,7 @@ public SettingsServiceImpl( } + @Override public SettingsGeneralModel getSettingsGeneral() { final Settings settings = globalSettingsManager.getGlobalSettings(); @@ -31,6 +35,7 @@ public SettingsGeneralModel getSettingsGeneral() { } + @Override public SettingsGeneralModel setSettingsGeneral(SettingsGeneralModel settingsModel) { final Settings settings = globalSettingsManager.getGlobalSettings(); @@ -91,6 +96,7 @@ public SettingsCustomHtmlModel setCustomHtml( } + @Override public SettingsSecurityModel getSettingsSecurity() { final Settings settings = globalSettingsManager.getGlobalSettings(); @@ -101,6 +107,7 @@ public SettingsSecurityModel getSettingsSecurity() { } + @Override public SettingsSecurityModel setSettingsSecurity( final SettingsSecurityModel settingsSecurityModel) { diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java index ec12cfeb..91d3ea1d 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/_AllServiceImpl.java @@ -1,7 +1,5 @@ package com.deftdevs.bootstrapi.confluence.service; -import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; -import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; @@ -10,7 +8,7 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; -import com.deftdevs.bootstrapi.confluence.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; import com.deftdevs.bootstrapi.confluence.model._AllModel; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceAuthenticationService; import com.deftdevs.bootstrapi.confluence.service.api.ConfluenceSettingsService; @@ -19,8 +17,6 @@ import java.util.Map; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_IDPS; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; @@ -77,7 +73,7 @@ public _AllModel setAll( setEntityWithStatus(allModel.getMailServer(), mailServerService::setMailServer, result::setMailServer, statusMap); - setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), + setEntity(ServiceResultUtil.subEntityKey(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java index 7261b5c3..52f85c77 100644 --- a/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java +++ b/confluence/src/main/java/com/deftdevs/bootstrapi/confluence/service/api/ConfluenceSettingsService.java @@ -35,7 +35,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod final Map status = new LinkedHashMap<>(); if (settingsModel.getGeneral() != null) { - final String key = ServiceResultUtil.entityType(SettingsGeneralModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsGeneralModel.class); try { result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); status.put(key, _AllModelStatus.success()); @@ -44,7 +44,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod } } if (settingsModel.getSecurity() != null) { - final String key = ServiceResultUtil.entityType(SettingsSecurityModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsSecurityModel.class); try { result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); status.put(key, _AllModelStatus.success()); @@ -53,7 +53,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod } } if (settingsModel.getBranding() != null) { - final String key = ServiceResultUtil.entityType(SettingsBrandingColorSchemeModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsBrandingColorSchemeModel.class); try { result.setBranding(setColourScheme(settingsModel.getBranding())); status.put(key, _AllModelStatus.success()); @@ -62,7 +62,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod } } if (settingsModel.getCustomHtml() != null) { - final String key = ServiceResultUtil.entityType(SettingsCustomHtmlModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsCustomHtmlModel.class); try { result.setCustomHtml(setCustomHtml(settingsModel.getCustomHtml())); status.put(key, _AllModelStatus.success()); diff --git a/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java b/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java index e5734622..021f9c48 100644 --- a/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java +++ b/confluence/src/test/java/com/deftdevs/bootstrapi/confluence/rest/_AllResourceTest.java @@ -57,4 +57,32 @@ public void testSetAll() { verify(allService).setAll(allModel); } + + @Test + public void testSetAllReturns500WhenAnySubFieldFailedWithServerError() { + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, + _AllModelStatus.error(Response.Status.INTERNAL_SERVER_ERROR, "boom", null)); + result.setStatus(status); + doReturn(result).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(500, response.getStatus()); + } + + @Test + public void testSetAllReturns207OnMixedSuccessAndClientError() { + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, + _AllModelStatus.error(Response.Status.BAD_REQUEST, "bad", null)); + result.setStatus(status); + doReturn(result).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(207, response.getStatus()); + } } diff --git a/crowd/Apis/AllApi.md b/crowd/Apis/AllApi.md index 2e3d15cd..849afb3e 100644 --- a/crowd/Apis/AllApi.md +++ b/crowd/Apis/AllApi.md @@ -9,7 +9,7 @@ All URIs are relative to *https://CROWD_URL/rest/bootstrapi/1* # **setAll** -> setAll(\_AllModel) +> _AllModel setAll(\_AllModel) Apply a complete configuration @@ -21,7 +21,11 @@ Apply a complete configuration ### Return type -null (empty response body) +[**_AllModel**](../Models/_AllModel.md) + +The updated configuration. The per-sub-field outcome is reported in the `status` map +(2xx for success, 4xx/5xx for failure with a human-readable `message` and optional +`details`). License keys in the response are redacted (e.g. `AAAB...wxyz#a1b2`). ### Authorization diff --git a/crowd/Models/_AllModel.md b/crowd/Models/_AllModel.md index 32538708..5f85397e 100644 --- a/crowd/Models/_AllModel.md +++ b/crowd/Models/_AllModel.md @@ -7,7 +7,7 @@ | **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | | **applications** | [**Map**](ApplicationModel.md) | | [optional] [default to null] | | **applicationLinks** | [**Map**](ApplicationLinkModel.md) | | [optional] [default to null] | -| **licenses** | **List** | | [optional] [default to null] | +| **licenses** | [**Map**](LicenseModel.md) | | [optional] [default to null] | | **mailServer** | [**MailServerModel**](MailServerModel.md) | | [optional] [default to null] | | **mailTemplates** | [**MailTemplatesModel**](MailTemplatesModel.md) | | [optional] [default to null] | | **sessionConfig** | [**SessionConfigModel**](SessionConfigModel.md) | | [optional] [default to null] | diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java index a20bcb01..ec7cb8da 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/config/ServiceConfig.java @@ -63,8 +63,8 @@ public CrowdSettingsGeneralService crowdSettingsGeneralService() { @Bean public CrowdSettingsService crowdSettingsService() { return new CrowdSettingsServiceImpl( - new SettingsServiceImpl(atlassianConfig.propertyManager()), - new SettingsBrandingServiceImpl(atlassianConfig.propertyManager())); + crowdSettingsGeneralService(), + settingsBrandingService()); } @Bean diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java index 004f0dc2..477e9f9b 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/CrowdSettingsServiceImpl.java @@ -2,18 +2,20 @@ import com.deftdevs.bootstrapi.commons.model.SettingsGeneralModel; import com.deftdevs.bootstrapi.crowd.model.SettingsBrandingLoginPageModel; +import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsBrandingService; +import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsGeneralService; import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsService; import java.io.InputStream; public class CrowdSettingsServiceImpl implements CrowdSettingsService { - private final SettingsServiceImpl settingsService; - private final SettingsBrandingServiceImpl settingsBrandingService; + private final CrowdSettingsGeneralService settingsService; + private final CrowdSettingsBrandingService settingsBrandingService; public CrowdSettingsServiceImpl( - final SettingsServiceImpl settingsService, - final SettingsBrandingServiceImpl settingsBrandingService) { + final CrowdSettingsGeneralService settingsService, + final CrowdSettingsBrandingService settingsBrandingService) { this.settingsService = settingsService; this.settingsBrandingService = settingsBrandingService; diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java index 7310cbdf..f2aec961 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/_AllServiceImpl.java @@ -1,15 +1,14 @@ package com.deftdevs.bootstrapi.crowd.service; -import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; import com.deftdevs.bootstrapi.commons.service.api.ApplicationLinksService; import com.deftdevs.bootstrapi.commons.service.api.DirectoriesService; import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; import com.deftdevs.bootstrapi.crowd.model.MailTemplatesModel; import com.deftdevs.bootstrapi.crowd.model.SessionConfigModel; -import com.deftdevs.bootstrapi.crowd.model.SettingsModel; import com.deftdevs.bootstrapi.crowd.model._AllModel; import com.deftdevs.bootstrapi.crowd.service.api.ApplicationsService; import com.deftdevs.bootstrapi.crowd.service.api.CrowdSettingsService; @@ -85,10 +84,10 @@ public _AllModel setAll( setEntityWithStatus(allModel.getMailServer(), mailServerService::setMailServer, result::setMailServer, statusMap); - setEntity(entityType(MailTemplatesModel.class), allModel.getMailTemplates(), + setEntity(ServiceResultUtil.entityType(MailTemplatesModel.class), allModel.getMailTemplates(), mailTemplatesService::setMailTemplates, result::setMailTemplates, statusMap); - setEntity(entityType(SessionConfigModel.class), allModel.getSessionConfig(), + setEntity(ServiceResultUtil.entityType(SessionConfigModel.class), allModel.getSessionConfig(), sessionConfigService::setSessionConfig, result::setSessionConfig, statusMap); setEntity(TRUSTED_PROXIES, allModel.getTrustedProxies(), diff --git a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java index c6ad1cc3..1bea779f 100644 --- a/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java +++ b/crowd/src/main/java/com/deftdevs/bootstrapi/crowd/service/api/CrowdSettingsService.java @@ -23,7 +23,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod final Map status = new LinkedHashMap<>(); if (settingsModel.getGeneral() != null) { - final String key = ServiceResultUtil.entityType(SettingsGeneralModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsGeneralModel.class); try { result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); status.put(key, _AllModelStatus.success()); @@ -32,7 +32,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod } } if (settingsModel.getBranding() != null) { - final String key = ServiceResultUtil.entityType(SettingsBrandingLoginPageModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsBrandingLoginPageModel.class); try { result.setBranding(setLoginPage(settingsModel.getBranding())); status.put(key, _AllModelStatus.success()); diff --git a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceTest.java similarity index 52% rename from crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java rename to crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceTest.java index 144762eb..826e0d3a 100644 --- a/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/AllResourceTest.java +++ b/crowd/src/test/java/com/deftdevs/bootstrapi/crowd/rest/_AllResourceTest.java @@ -21,31 +21,29 @@ import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) -public class AllResourceTest { +public class _AllResourceTest { @Mock private _AllService<_AllModel> allService; - private _AllResourceImpl configurationResource; + private _AllResourceImpl allResource; private _AllModel allModel; @BeforeEach public void setup() { - configurationResource = new _AllResourceImpl(allService); + allResource = new _AllResourceImpl(allService); - // Setup test data allModel = new _AllModel(); final SettingsModel settings = new SettingsModel(); settings.setGeneral(SettingsGeneralModel.EXAMPLE_1); allModel.setSettings(settings); - // Setup applications map - Map applications = new HashMap<>(); + final Map applications = new HashMap<>(); applications.put(ApplicationModel.EXAMPLE_1.getName(), ApplicationModel.EXAMPLE_1); allModel.setApplications(applications); - Map status = new HashMap<>(); + final Map status = new HashMap<>(); status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); status.put(DIRECTORIES, _AllModelStatus.success()); status.put(APPLICATIONS, _AllModelStatus.success()); @@ -53,15 +51,43 @@ public void setup() { } @Test - public void testSetConfiguration() { + public void testSetAll() { doReturn(allModel).when(allService).setAll(any()); - Response response = configurationResource.setAll(allModel); + final Response response = allResource.setAll(allModel); assertEquals(200, response.getStatus()); - _AllModel responseModel = (_AllModel) response.getEntity(); + final _AllModel responseModel = (_AllModel) response.getEntity(); assertEquals(allModel, responseModel); verify(allService).setAll(allModel); } + + @Test + public void testSetAllReturns500WhenAnySubFieldFailedWithServerError() { + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, + _AllModelStatus.error(Response.Status.INTERNAL_SERVER_ERROR, "boom", null)); + result.setStatus(status); + doReturn(result).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(500, response.getStatus()); + } + + @Test + public void testSetAllReturns207OnMixedSuccessAndClientError() { + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, + _AllModelStatus.error(Response.Status.BAD_REQUEST, "bad", null)); + result.setStatus(status); + doReturn(result).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(207, response.getStatus()); + } } diff --git a/jira/Apis/AllApi.md b/jira/Apis/AllApi.md index 3a239341..f190f05c 100644 --- a/jira/Apis/AllApi.md +++ b/jira/Apis/AllApi.md @@ -9,7 +9,7 @@ All URIs are relative to *https://JIRA_URL/rest/bootstrapi/1* # **setAll** -> setAll(\_AllModel) +> _AllModel setAll(\_AllModel) Apply a complete configuration @@ -21,7 +21,11 @@ Apply a complete configuration ### Return type -null (empty response body) +[**_AllModel**](../Models/_AllModel.md) + +The updated configuration. The per-sub-field outcome is reported in the `status` map +(2xx for success, 4xx/5xx for failure with a human-readable `message` and optional +`details`). License keys in the response are redacted (e.g. `AAAB...wxyz#a1b2`). ### Authorization diff --git a/jira/Models/_AllModel.md b/jira/Models/_AllModel.md index cd6000f3..3a2e4dee 100644 --- a/jira/Models/_AllModel.md +++ b/jira/Models/_AllModel.md @@ -7,7 +7,7 @@ | **directories** | [**Map**](AbstractDirectoryModel.md) | | [optional] [default to null] | | **applicationLinks** | [**Map**](ApplicationLinkModel.md) | | [optional] [default to null] | | **authentication** | [**AuthenticationModel**](AuthenticationModel.md) | | [optional] [default to null] | -| **licenses** | **List** | | [optional] [default to null] | +| **licenses** | [**Map**](LicenseModel.md) | | [optional] [default to null] | | **mailServer** | [**MailServerModel**](MailServerModel.md) | | [optional] [default to null] | | **permissionsGlobal** | [**PermissionsGlobalModel**](PermissionsGlobalModel.md) | | [optional] [default to null] | | **status** | [**Map**](_AllModelStatus.md) | | [optional] [default to null] | diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java index 7ef8e6a1..6f50abfb 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceImpl.java @@ -6,7 +6,6 @@ import com.deftdevs.bootstrapi.commons.util.LicenseKeyRedactor; import com.deftdevs.bootstrapi.jira.model.util.LicenseModelUtil; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -44,12 +43,9 @@ public List setLicenses( public Map setLicenses( final Map licenseInputs) { - final List keys = new ArrayList<>(licenseInputs.keySet()); - final List applied = setLicenses(keys); final Map result = new LinkedHashMap<>(); - for (int i = 0; i < keys.size(); i++) { - final LicenseModel model = i < applied.size() ? applied.get(i) : null; - result.put(LicenseKeyRedactor.redact(keys.get(i)), model); + for (final String key : licenseInputs.keySet()) { + result.put(LicenseKeyRedactor.redact(key), addLicense(key)); } return result; } diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java index a1f6d3c2..3b154105 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/_AllServiceImpl.java @@ -1,7 +1,5 @@ package com.deftdevs.bootstrapi.jira.service; -import com.deftdevs.bootstrapi.commons.model.AuthenticationModel; -import com.deftdevs.bootstrapi.commons.model.MailServerModel; import com.deftdevs.bootstrapi.commons.model.PermissionsGlobalModel; import com.deftdevs.bootstrapi.commons.model.type._AllModelStatus; import com.deftdevs.bootstrapi.commons.service._AbstractAllServiceImpl; @@ -10,7 +8,7 @@ import com.deftdevs.bootstrapi.commons.service.api.LicensesService; import com.deftdevs.bootstrapi.commons.service.api.MailServerService; import com.deftdevs.bootstrapi.commons.service.api.PermissionsService; -import com.deftdevs.bootstrapi.jira.model.SettingsModel; +import com.deftdevs.bootstrapi.commons.util.ServiceResultUtil; import com.deftdevs.bootstrapi.jira.model._AllModel; import com.deftdevs.bootstrapi.jira.service.api.JiraAuthenticationService; import com.deftdevs.bootstrapi.jira.service.api.JiraSettingsService; @@ -19,8 +17,6 @@ import java.util.Map; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.APPLICATION_LINKS; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION; -import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.AUTHENTICATION_IDPS; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.DIRECTORIES; import static com.deftdevs.bootstrapi.commons.constants.BootstrAPI.LICENSES; @@ -77,7 +73,7 @@ public _AllModel setAll( setEntityWithStatus(allModel.getMailServer(), mailServerService::setMailServer, result::setMailServer, statusMap); - setEntity(entityType(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), + setEntity(ServiceResultUtil.subEntityKey(PermissionsGlobalModel.class), allModel.getPermissionsGlobal(), permissionsService::setPermissionsGlobal, result::setPermissionsGlobal, statusMap); result.setStatus(statusMap); diff --git a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java index 8f14a030..ed439921 100644 --- a/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java +++ b/jira/src/main/java/com/deftdevs/bootstrapi/jira/service/api/JiraSettingsService.java @@ -31,7 +31,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod final Map status = new LinkedHashMap<>(); if (settingsModel.getGeneral() != null) { - final String key = ServiceResultUtil.entityType(SettingsGeneralModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsGeneralModel.class); try { result.setGeneral(setSettingsGeneral(settingsModel.getGeneral())); status.put(key, _AllModelStatus.success()); @@ -40,7 +40,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod } } if (settingsModel.getSecurity() != null) { - final String key = ServiceResultUtil.entityType(SettingsSecurityModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsSecurityModel.class); try { result.setSecurity(setSettingsSecurity(settingsModel.getSecurity())); status.put(key, _AllModelStatus.success()); @@ -49,7 +49,7 @@ default ServiceResult setSettings(final SettingsModel settingsMod } } if (settingsModel.getBanner() != null) { - final String key = ServiceResultUtil.entityType(SettingsBannerModel.class); + final String key = ServiceResultUtil.subEntityKey(SettingsBannerModel.class); try { result.setBanner(setSettingsBanner(settingsModel.getBanner())); status.put(key, _AllModelStatus.success()); diff --git a/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java b/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java index f6e1a035..c5fe65f0 100644 --- a/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java +++ b/jira/src/test/java/com/deftdevs/bootstrapi/jira/rest/_AllResourceTest.java @@ -57,4 +57,32 @@ public void testSetAll() { verify(allService).setAll(allModel); } + + @Test + public void testSetAllReturns500WhenAnySubFieldFailedWithServerError() { + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, + _AllModelStatus.error(Response.Status.INTERNAL_SERVER_ERROR, "boom", null)); + result.setStatus(status); + doReturn(result).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(500, response.getStatus()); + } + + @Test + public void testSetAllReturns207OnMixedSuccessAndClientError() { + final _AllModel result = new _AllModel(); + final Map status = new HashMap<>(); + status.put(SETTINGS + "/" + SETTINGS_GENERAL, _AllModelStatus.success()); + status.put(DIRECTORIES, + _AllModelStatus.error(Response.Status.BAD_REQUEST, "bad", null)); + result.setStatus(status); + doReturn(result).when(allService).setAll(any()); + + final Response response = allResource.setAll(allModel); + assertEquals(207, response.getStatus()); + } } diff --git a/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceTest.java b/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceTest.java index 6fb05576..44327650 100644 --- a/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceTest.java +++ b/jira/src/test/java/com/deftdevs/bootstrapi/jira/service/LicensesServiceTest.java @@ -12,11 +12,14 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import static com.atlassian.extras.api.LicenseType.TESTING; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -64,6 +67,38 @@ void testSetLicenses() { verify(spy).getLicenses(); } + @Test + void testSetLicensesMapRedactsKeysAndPairsPerKey() { + // Set up two distinct LicenseDetails so we can verify each map entry's + // value comes from that key's own addLicense call (not from index-into-getLicenses). + final LicensedApplications apps = mock(LicensedApplications.class); + doReturn(Collections.singleton(ApplicationKey.valueOf("jira"))).when(apps).getKeys(); + final LicenseDetails detailsA = mock(LicenseDetails.class); + doReturn(apps).when(detailsA).getLicensedApplications(); + doReturn(TESTING).when(detailsA).getLicenseType(); + final LicenseDetails detailsB = mock(LicenseDetails.class); + doReturn(apps).when(detailsB).getLicensedApplications(); + doReturn(TESTING).when(detailsB).getLicenseType(); + + doReturn(detailsA).when(licenseManager).setLicense("KEY_A_payload_aaaa"); + doReturn(detailsB).when(licenseManager).setLicense("KEY_B_payload_bbbb"); + + final Map input = new LinkedHashMap<>(); + input.put("KEY_A_payload_aaaa", null); + input.put("KEY_B_payload_bbbb", null); + + final Map result = licensesService.setLicenses(input); + + assertEquals(2, result.size()); + // Keys in the response must be redacted (not the original keys). + assertTrue(result.keySet().stream().allMatch(k -> k.contains("...") && k.contains("#"))); + assertTrue(result.keySet().stream().noneMatch(k -> k.contains("payload"))); + // Each addLicense was called per input key (verifies we aren't relying + // on JiraLicenseManager.getLicenses() ordering). + verify(licenseManager).setLicense("KEY_A_payload_aaaa"); + verify(licenseManager).setLicense("KEY_B_payload_bbbb"); + } + @Test void testAddLicense() { final LicensedApplications licensedApplications = mock(LicensedApplications.class);