Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions spring/ConfigurationProperties.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ spring boot starter web site for more details.
can be `true` or `false`. `true` will tell FLuentForms to log in with https, `false` will result in an http connection. This
property is optional, and it defaults to `false` if it is not supplied.

`fluentforms.aem.sslBundle` - This is the name used to locate a Spring Security SSL Bundle that will be used as a trust store
for SSL HTTPS connections to AEM. This property is optional, and it defaults to `aem` if it is not supplied.

### Adaptive Forms

`fluentforms.rproxy.enabled` - This is used to enable/disable the reverse proxying of secondary resources to AEM. If it is
Expand Down
2 changes: 1 addition & 1 deletion spring/fluentforms-sample-cli-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<version>3.3.5</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com._4point.aem.fluentforms</groupId>
Expand Down
2 changes: 1 addition & 1 deletion spring/fluentforms-sample-web-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<version>3.3.5</version>
</parent>
<groupId>com._4point.aem.fluentforms</groupId>
<artifactId>fluentforms-sample-web-app</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion spring/fluentforms-spring-boot-autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<version>3.3.5</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com._4point.aem.fluentforms</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public record AemConfiguration(
Integer port, // "aem.port"
String user, // "aem.user"
String password, // "aem.password"
@DefaultValue("false") Boolean useSsl // "aem.useSsl"
@DefaultValue("false") Boolean useSsl, // "aem.useSsl"
@DefaultValue("aem") String sslBundle // "aem.sslBundle" - Spring SSL Bundle for trust store
) {

public String url() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@

import org.glassfish.jersey.client.ChunkedInput;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.media.multipart.BodyPartEntity;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.util.MultiValueMap;
import org.springframework.util.MultiValueMapAdapter;

Expand All @@ -34,7 +33,6 @@
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Context;
Expand Down Expand Up @@ -176,9 +174,9 @@ static class AfSubmitAemProxyProcessor implements AfSubmitProcessor {
private final AemConfiguration aemConfig;
private final Client httpClient;

public AfSubmitAemProxyProcessor(AemConfiguration aemConfig) {
public AfSubmitAemProxyProcessor(AemConfiguration aemConfig, SslBundles sslBundles) {
this.aemConfig = aemConfig;
this.httpClient = ClientBuilder.newClient().register(HttpAuthenticationFeature.basic(aemConfig.user(), aemConfig.password())).register(MultiPartFeature.class);
this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
Expand All @@ -10,6 +11,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.jersey.ResourceConfigCustomizer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;

import com._4point.aem.fluentforms.spring.AemProxyAfSubmission.AfSubmissionHandler;
Expand Down Expand Up @@ -43,8 +45,8 @@ public class AemProxyAutoConfiguration {
* JAX-RS Resources (i.e. endpoints)
*/
@Bean
public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig) {
return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig))
public ResourceConfigCustomizer afProxyConfigurer(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles) {
return config->config.register(new AemProxyEndpoint(aemConfig, aemProxyConfig, sslBundles))
.register(new AemProxyAfSubmission())
;
}
Expand Down Expand Up @@ -85,8 +87,8 @@ public AfSubmitProcessor localSubmitProcessor(List<AfSubmissionHandler> submissi
*/
@ConditionalOnMissingBean({AfSubmitProcessor.class, AfSubmissionHandler.class})
@Bean()
public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig) {
return new AfSubmitAemProxyProcessor(aemConfig);
public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
return new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
}

/**
Expand All @@ -105,7 +107,7 @@ public AfSubmitProcessor aemSubmitProcessor(AemConfiguration aemConfig) {
@ConditionalOnMissingBean(InternalAfSubmitAemProxyProcessor.class)
@ConditionalOnBean(AfSubmissionHandler.class)
@Bean
public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig) {
return ()->new AfSubmitAemProxyProcessor(aemConfig);
public InternalAfSubmitAemProxyProcessor aemProxyProcessor(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
return ()->new AfSubmitAemProxyProcessor(aemConfig, sslBundles);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,27 @@
import java.util.stream.Collectors;

import javax.naming.ConfigurationException;

import org.glassfish.jersey.client.ChunkedInput;
import org.glassfish.jersey.server.ChunkedOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ssl.SslBundles;

import com._4point.aem.docservices.rest_services.client.helpers.ReplacingInputStream;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.HeaderParam;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import jakarta.ws.rs.client.Entity;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.GenericType;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

import org.glassfish.jersey.client.ChunkedInput;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ChunkedOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com._4point.aem.docservices.rest_services.client.helpers.ReplacingInputStream;

/**
* Reverse Proxy Code which reverse proxies secondary resources (.css, .js, etc.) that the browser will request.
* These requests are forwarded to AEM.
Expand All @@ -55,10 +54,10 @@ public class AemProxyEndpoint {
/**
*
*/
public AemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig) {
public AemProxyEndpoint(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, SslBundles sslBundles) {
this.aemProxyConfig = aemProxyConfig;
this.aemConfig = aemConfig;
this.httpClient = ClientBuilder.newClient().register(HttpAuthenticationFeature.basic(aemConfig.user(), aemConfig.password())).register(MultiPartFeature.class);
this.httpClient = JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle(), aemConfig.user(), aemConfig.password());
}

@Path("libs/granite/csrf/token.json")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import java.io.InputStream;
import java.util.function.Function;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.ssl.SslBundles;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;

Expand Down Expand Up @@ -52,18 +54,19 @@
public class FluentFormsAutoConfiguration {

@SuppressWarnings("unchecked")
private <T extends Builder> T setAemFields(T builder, AemConfiguration aemConfig) {
private <T extends Builder> T setAemFields(T builder, AemConfiguration aemConfig, SslBundles sslBundles) {
return (T)(builder.machineName(aemConfig.servername())
.port(aemConfig.port())
.basicAuthentication(aemConfig.user(), aemConfig.password())
.useSsl(aemConfig.useSsl())
.clientFactory(()->JerseyClientFactory.createClient(sslBundles, aemConfig.sslBundle()))
);
}

@ConditionalOnMissingBean
@Bean
public AdaptiveFormsService adaptiveFormsService(AemConfiguration aemConfig, Function<InputStream, InputStream> afInputStreamFilter) {
return setAemFields(AdaptiveFormsService.builder(), aemConfig)
public AdaptiveFormsService adaptiveFormsService(AemConfiguration aemConfig, Function<InputStream, InputStream> afInputStreamFilter, @Autowired(required = false) SslBundles sslBundles) {
return setAemFields(AdaptiveFormsService.builder(), aemConfig, sslBundles)
.addRenderResultFilter(afInputStreamFilter)
.build();
}
Expand All @@ -83,58 +86,58 @@ private Function<InputStream, InputStream> buildInputFilter(String aemPrefix, St

@ConditionalOnMissingBean
@Bean
public AssemblerService assemblerService(AemConfiguration aemConfig) {
RestServicesDocAssemblerServiceAdapter adapter = setAemFields(RestServicesDocAssemblerServiceAdapter.builder(), aemConfig).build();
public AssemblerService assemblerService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesDocAssemblerServiceAdapter adapter = setAemFields(RestServicesDocAssemblerServiceAdapter.builder(), aemConfig, sslBundles).build();
return new AssemblerServiceImpl(adapter, UsageContext.CLIENT_SIDE);
}

@ConditionalOnMissingBean
@Bean
public DocAssuranceService docAssuranceService(AemConfiguration aemConfig) {
RestServicesDocAssuranceServiceAdapter adapter = setAemFields(RestServicesDocAssuranceServiceAdapter.builder(), aemConfig).build();
public DocAssuranceService docAssuranceService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesDocAssuranceServiceAdapter adapter = setAemFields(RestServicesDocAssuranceServiceAdapter.builder(), aemConfig, sslBundles).build();
return new DocAssuranceServiceImpl(adapter);
}

@ConditionalOnMissingBean
@Bean
public FormsService formsService(AemConfiguration aemConfig) {
RestServicesFormsServiceAdapter adapter = setAemFields(RestServicesFormsServiceAdapter.builder(), aemConfig).build();
public FormsService formsService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesFormsServiceAdapter adapter = setAemFields(RestServicesFormsServiceAdapter.builder(), aemConfig, sslBundles).build();
return new FormsServiceImpl(adapter, UsageContext.CLIENT_SIDE);
}

@ConditionalOnMissingBean
@Bean
public GeneratePDFService generatePDFService(AemConfiguration aemConfig) {
RestServicesGeneratePDFServiceAdapter adapter = setAemFields(RestServicesGeneratePDFServiceAdapter.builder(), aemConfig).build();
public GeneratePDFService generatePDFService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesGeneratePDFServiceAdapter adapter = setAemFields(RestServicesGeneratePDFServiceAdapter.builder(), aemConfig, sslBundles).build();
return new GeneratePDFServiceImpl(adapter);
}

@ConditionalOnMissingBean
@Bean
public Html5FormsService html5FormsService(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig) {
return setAemFields(Html5FormsService.builder(), aemConfig)
public Html5FormsService html5FormsService(AemConfiguration aemConfig, AemProxyConfiguration aemProxyConfig, @Autowired(required = false) SslBundles sslBundles) {
return setAemFields(Html5FormsService.builder(), aemConfig, sslBundles)
.addRenderResultFilter(afInputStreamFilter(aemProxyConfig))
.build();
}

@ConditionalOnMissingBean
@Bean
public OutputService outputService(AemConfiguration aemConfig) {
RestServicesOutputServiceAdapter adapter = setAemFields(RestServicesOutputServiceAdapter.builder(), aemConfig).build();
public OutputService outputService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesOutputServiceAdapter adapter = setAemFields(RestServicesOutputServiceAdapter.builder(), aemConfig, sslBundles).build();
return new OutputServiceImpl(adapter, UsageContext.CLIENT_SIDE);
}

@ConditionalOnMissingBean
@Bean
public PdfUtilityService pdfUtilityService(AemConfiguration aemConfig) {
RestServicesPdfUtilityServiceAdapter adapter = setAemFields(RestServicesPdfUtilityServiceAdapter.builder(), aemConfig).build();
public PdfUtilityService pdfUtilityService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesPdfUtilityServiceAdapter adapter = setAemFields(RestServicesPdfUtilityServiceAdapter.builder(), aemConfig, sslBundles).build();
return new PdfUtilityServiceImpl(adapter);
}

@ConditionalOnMissingBean
@Bean
public ConvertPdfService convertPdfService(AemConfiguration aemConfig) {
RestServicesConvertPdfServiceAdapter adapter = setAemFields(RestServicesConvertPdfServiceAdapter.builder(), aemConfig).build();
public ConvertPdfService convertPdfService(AemConfiguration aemConfig, @Autowired(required = false) SslBundles sslBundles) {
RestServicesConvertPdfServiceAdapter adapter = setAemFields(RestServicesConvertPdfServiceAdapter.builder(), aemConfig, sslBundles).build();
return new ConvertPdfServiceImpl(adapter);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com._4point.aem.fluentforms.spring;

import javax.net.ssl.SSLContext;

import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ssl.NoSuchSslBundleException;
import org.springframework.boot.ssl.SslBundle;
import org.springframework.boot.ssl.SslBundles;

import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;

/**
*
*/
public class JerseyClientFactory {
private final static Logger logger = LoggerFactory.getLogger(JerseyClientFactory.class);

public static Client createClient(SslBundles sslBundles, String bundleName, String username, String password) {
return createClient(sslBundles, bundleName)
.register(HttpAuthenticationFeature.basic(username, password))
.register(MultiPartFeature.class);
}

public static Client createClient(SslBundles sslBundles, String bundleName) {
if (sslBundles != null) {
logger.info("SslBundles is not null");
try {
SslBundle bundle = sslBundles.getBundle(bundleName);
logger.info("Client sslBundle is not null");
SSLContext sslContext = bundle.createSslContext();
return ClientBuilder.newBuilder().sslContext(sslContext).build();
} catch (NoSuchSslBundleException e) {
// Eat the exception and fall through to the default client
}
}
logger.info("Creating default client");
return ClientBuilder.newClient();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,19 @@ void testGetUrl() {
assertEquals("http://" + EXPECTED_SERVERNAME + ":" + EXPECTED_PORT + "/", underTest.url());
}

@Test
void testGetSslBundle() {
assertEquals("aem", underTest.sslBundle());
}

@SpringBootTest(classes = {com._4point.aem.fluentforms.spring.AemConfigurationTest.TestApplication.class},
properties = {
"fluentforms.aem.servername=" + EXPECTED_SERVERNAME,
"fluentforms.aem.port=" + AemConfigurationTests2.EXPECTED_PORT,
"fluentforms.aem.user=" + EXPECTED_USER,
"fluentforms.aem.password=" + EXPECTED_PASSWORD,
"fluentforms.aem.useSsl=true",
"fluentforms.aem.sslBundle=notAem"
})
static class AemConfigurationTests2 {
protected static final int EXPECTED_PORT = 80;
Expand All @@ -98,7 +104,10 @@ void testGetUrl() {
assertEquals("https://" + EXPECTED_SERVERNAME + "/", underTest.url());
}


@Test
void testGetSslBundle() {
assertEquals("notAem", underTest.sslBundle());
}
}

@SpringBootApplication
Expand Down
Loading