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
77 changes: 57 additions & 20 deletions wrappercommon/src/main/java/com/genexus/cors/CORSHelper.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,71 @@
package com.genexus.cors;

import com.genexus.common.interfaces.SpecificImplementation;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CORSHelper {
private static String CORS_ALLOWED_ORIGINS_ENV_VAR_NAME = "GX_CORS_ALLOW_ORIGIN";
public static String REQUEST_METHOD_HEADER_NAME = "Access-Control-Request-Method";
public static String REQUEST_HEADERS_HEADER_NAME = "Access-Control-Request-Headers";

private static String CORS_ALLOWED_ORIGIN = "CORS_ALLOW_ORIGIN";
private static String CORS_MAX_AGE_SECONDS = "86400";
private static String CORS_ALLOWED_METHODS = "GET, POST, PUT, DELETE, HEAD";
private static String CORS_ALLOWED_HEADERS = "*";

public static HashMap<String, String> getCORSHeaders(String requestRequiredHeaders) {
String corsAllowedOrigin = System.getenv(CORS_ALLOWED_ORIGINS_ENV_VAR_NAME);

public static boolean corsSupportEnabled() {
return getAllowedOrigin() != null;
}

public static HashMap<String, String> getCORSHeaders(Map<String, List<String>> headers) {
String corsAllowedOrigin = getAllowedOrigin();
if (corsAllowedOrigin == null) return null;

String requestedMethod = getHeaderValue(REQUEST_METHOD_HEADER_NAME, headers);
String requestedHeaders = getHeaderValue(REQUEST_HEADERS_HEADER_NAME, headers);
if (requestedMethod == null) {
return null;
}

return corsHeaders(corsAllowedOrigin, requestedMethod, requestedHeaders);
}

public static HashMap<String, String> getCORSHeaders(String requestedMethod, String requestedHeaders) {
String corsAllowedOrigin = getAllowedOrigin();

if (corsAllowedOrigin == null || requestedMethod == null) {
return null;
}

return corsHeaders(corsAllowedOrigin, requestedMethod, requestedHeaders);
}

private static String getAllowedOrigin() {
String corsAllowedOrigin = SpecificImplementation.Application.getClientPreferences().getProperty(CORS_ALLOWED_ORIGIN, "");
if (corsAllowedOrigin == null || corsAllowedOrigin.isEmpty()) {
return null;
}
return corsAllowedOrigin;
}

private static HashMap<String, String> corsHeaders(String corsAllowedOrigin, String requestedMethod, String requestedHeaders) {
HashMap<String, String> corsHeaders = new HashMap<>();
corsHeaders.put(
"Access-Control-Allow-Origin", corsAllowedOrigin);
corsHeaders.put(
"Access-Control-Allow-Credentials", "true");

corsHeaders.put(
"Access-Control-Allow-Headers",
requestRequiredHeaders == null || requestRequiredHeaders.isEmpty() ? CORS_ALLOWED_HEADERS : requestRequiredHeaders);

corsHeaders.put(
"Access-Control-Allow-Methods",
CORS_ALLOWED_METHODS);
corsHeaders.put(
"Access-Control-Max-Age",
CORS_MAX_AGE_SECONDS);
corsHeaders.put("Access-Control-Allow-Origin", corsAllowedOrigin);
corsHeaders.put("Access-Control-Allow-Credentials", "true");
if (requestedHeaders != null && !requestedHeaders.isEmpty()) {
corsHeaders.put("Access-Control-Allow-Headers", requestedHeaders);
}
corsHeaders.put("Access-Control-Allow-Methods", requestedMethod);
corsHeaders.put("Access-Control-Max-Age", CORS_MAX_AGE_SECONDS);
return corsHeaders;
}

private static String getHeaderValue(String headerName, Map<String, List<String>> headers) {
List<String> value = headers.get(headerName);
if (value != null && value.size() > 0) {
return value.get(0);
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package com.genexus.servlet;


import com.genexus.cors.CORSHelper;
import jakarta.servlet.*;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
Expand All @@ -25,7 +23,7 @@ public void init(FilterConfig filterConfig) throws ServletException {
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;

HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(request.getHeader("Access-Control-Request-Headers"));
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(request.getHeader(CORSHelper.REQUEST_METHOD_HEADER_NAME), request.getHeader(CORSHelper.REQUEST_HEADERS_HEADER_NAME));
if (corsHeaders != null) {
HttpServletResponse response = (HttpServletResponse) servletResponse;
for (String headerName : corsHeaders.keySet()) {
Expand All @@ -34,9 +32,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
}
}
}
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {
filterChain.doFilter(servletRequest, servletResponse);
}
filterChain.doFilter(servletRequest, servletResponse);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class JAXRSCorsFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaderString("Access-Control-Request-Headers"));
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaders());
if (corsHeaders == null) {
return;
}
Expand Down
26 changes: 21 additions & 5 deletions wrapperjakarta/src/main/java/com/genexus/ws/rs/core/Response.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.genexus.ws.rs.core;

public abstract class Response extends jakarta.ws.rs.core.Response{
public abstract class Response extends jakarta.ws.rs.core.Response {

public static Response.ResponseBuilder notModifiedWrapped() {
return new Response.ResponseBuilder(jakarta.ws.rs.core.Response.notModified());
Expand All @@ -14,6 +14,12 @@ public static Response.ResponseBuilder okWrapped() {
return new Response.ResponseBuilder(jakarta.ws.rs.core.Response.ok());
}

public static Response.ResponseBuilder options(String allowedMethods) {
Response.ResponseBuilder builder = okWrapped();
builder.header("Allow", allowedMethods);
return builder;
}

public static Response.ResponseBuilder notFound() {
return new Response.ResponseBuilder(jakarta.ws.rs.core.Response.status(Status.NOT_FOUND));
}
Expand Down Expand Up @@ -41,7 +47,8 @@ public static Response.ResponseBuilder createdWrapped(java.net.URI uri) {
public static Response.ResponseBuilder statusWrapped(int status) {
return new Response.ResponseBuilder(jakarta.ws.rs.core.Response.status(status));
}
public static class ResponseBuilder implements IResponseBuilder{

public static class ResponseBuilder implements IResponseBuilder {
jakarta.ws.rs.core.Response.ResponseBuilder rb;

ResponseBuilder(jakarta.ws.rs.core.Response.ResponseBuilder rb) {
Expand All @@ -51,13 +58,22 @@ public static class ResponseBuilder implements IResponseBuilder{
public jakarta.ws.rs.core.Response build() {
return rb.build();
}

public void type(String type) {
rb.type(type);
}
public void entity(Object entity) { rb.entity(entity); }

public IResponseBuilder status(short i) { return new ResponseBuilder(rb.status(i)); }
public IResponseBuilder entityWrapped(Object entity) { return new ResponseBuilder(rb.entity(entity)); }
public void entity(Object entity) {
rb.entity(entity);
}

public IResponseBuilder status(short i) {
return new ResponseBuilder(rb.status(i));
}

public IResponseBuilder entityWrapped(Object entity) {
return new ResponseBuilder(rb.entity(entity));
}

public void header(String header, Object object) {
rb.header(header, object);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.*;

public class CorsFilter implements Filter {
@Override
Expand All @@ -22,7 +22,7 @@ public void init(FilterConfig filterConfig) throws ServletException {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(request.getHeader("Access-Control-Request-Headers"));
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(request.getHeader(CORSHelper.REQUEST_METHOD_HEADER_NAME), request.getHeader(CORSHelper.REQUEST_HEADERS_HEADER_NAME));
if (corsHeaders != null) {
HttpServletResponse response = (HttpServletResponse) servletResponse;
for (String headerName : corsHeaders.keySet()) {
Expand All @@ -31,9 +31,7 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo
}
}
}
if (!request.getMethod().equalsIgnoreCase("OPTIONS")) {
filterChain.doFilter(servletRequest, servletResponse);
}
filterChain.doFilter(servletRequest, servletResponse);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.util.Collections;
import java.util.HashMap;

@Provider
Expand All @@ -15,7 +14,7 @@ public class JAXRSCorsFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) {
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaderString("Access-Control-Request-Headers"));
HashMap<String, String> corsHeaders = CORSHelper.getCORSHeaders(requestContext.getHeaders());
if (corsHeaders == null) {
return;
}
Expand Down
26 changes: 21 additions & 5 deletions wrapperjavax/src/main/java/com/genexus/ws/rs/core/Response.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.genexus.ws.rs.core;

public abstract class Response extends javax.ws.rs.core.Response{
public abstract class Response extends javax.ws.rs.core.Response {

public static Response.ResponseBuilder notModifiedWrapped() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.notModified());
Expand All @@ -13,19 +13,29 @@ public static Response.ResponseBuilder okWrapped(Object entity) {
public static Response.ResponseBuilder okWrapped() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.ok());
}

public static Response.ResponseBuilder options(String allowedMethods) {
Response.ResponseBuilder builder = okWrapped();
builder.header("Allow", allowedMethods);
return builder;
}

public static Response.ResponseBuilder notFound() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.status(Status.NOT_FOUND));
}

public static Response.ResponseBuilder conflict() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.status(Status.CONFLICT));
}

public static Response.ResponseBuilder forbidden() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.status(Status.FORBIDDEN));
}

public static Response.ResponseBuilder unauthorized() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.status(Status.UNAUTHORIZED));
}

public static Response.ResponseBuilder noContentWrapped() {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.noContent());
}
Expand All @@ -38,7 +48,7 @@ public static Response.ResponseBuilder statusWrapped(int status) {
return new Response.ResponseBuilder(javax.ws.rs.core.Response.status(status));
}

public static class ResponseBuilder implements IResponseBuilder{
public static class ResponseBuilder implements IResponseBuilder {
javax.ws.rs.core.Response.ResponseBuilder rb;

ResponseBuilder(javax.ws.rs.core.Response.ResponseBuilder rb) {
Expand All @@ -53,11 +63,17 @@ public void type(String type) {
rb.type(type);
}

public void entity(Object entity) { rb.entity(entity); }
public void entity(Object entity) {
rb.entity(entity);
}

public IResponseBuilder status(short i) { return new ResponseBuilder(rb.status(i)); }
public IResponseBuilder status(short i) {
return new ResponseBuilder(rb.status(i));
}

public IResponseBuilder entityWrapped(Object entity) { return new ResponseBuilder(rb.entity(entity)); }
public IResponseBuilder entityWrapped(Object entity) {
return new ResponseBuilder(rb.entity(entity));
}

public void header(String header, Object object) {
rb.header(header, object);
Expand Down