diff --git a/commafeed-client/src/app/client.ts b/commafeed-client/src/app/client.ts index db34c9d6..e765923a 100644 --- a/commafeed-client/src/app/client.ts +++ b/commafeed-client/src/app/client.ts @@ -31,11 +31,12 @@ const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true }) axiosInstance.interceptors.response.use( response => response, error => { + const { status, data } = error.response if ( - (error.response.status === 401 && error.response.data === "Credentials are required to access this resource.") || - (error.response.status === 403 && error.response.data === "You don't have the required role to access this resource.") + (status === 401 && data?.message === "Credentials are required to access this resource.") || + (status === 403 && data?.message === "You don't have the required role to access this resource.") ) { - window.location.hash = "/welcome" + window.location.hash = data?.allowRegistrations ? "/welcome" : "/login" } throw error } diff --git a/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java b/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java index a07a1480..46d6e91b 100644 --- a/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java +++ b/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java @@ -169,7 +169,7 @@ public class CommaFeedApplication extends Application { // support for "@SecurityCheck User user" injection environment.jersey() .register(new SecurityCheckFactoryProvider.Binder(injector.getInstance(UserDAO.class), - injector.getInstance(UserService.class))); + injector.getInstance(UserService.class), config)); // support for "@Context SessionHelper sessionHelper" injection environment.jersey().register(new SessionHelperFactoryProvider.Binder()); diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactory.java b/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactory.java index ac2bdf2a..2e14bd7a 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactory.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactory.java @@ -2,12 +2,15 @@ package com.commafeed.frontend.auth; import java.nio.charset.StandardCharsets; import java.util.Base64; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Function; import org.glassfish.jersey.server.ContainerRequest; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole.Role; @@ -28,6 +31,7 @@ public class SecurityCheckFactory implements Function { private final UserDAO userDAO; private final UserService userService; + private final CommaFeedConfiguration config; private final HttpServletRequest request; private final Role role; private final boolean apiKeyAllowed; @@ -47,16 +51,10 @@ public class SecurityCheckFactory implements Function { if (roles.contains(role)) { return user.get(); } else { - throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN) - .entity("You don't have the required role to access this resource.") - .type(MediaType.TEXT_PLAIN_TYPE) - .build()); + throw buildWebApplicationException(Response.Status.FORBIDDEN, "You don't have the required role to access this resource."); } } else { - throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED) - .entity("Credentials are required to access this resource.") - .type(MediaType.TEXT_PLAIN_TYPE) - .build()); + throw buildWebApplicationException(Response.Status.UNAUTHORIZED, "Credentials are required to access this resource."); } } @@ -95,4 +93,11 @@ public class SecurityCheckFactory implements Function { return Optional.empty(); } + private WebApplicationException buildWebApplicationException(Response.Status status, String message) { + Map response = new HashMap<>(); + response.put("message", message); + response.put("allowRegistrations", config.getApplicationSettings().getAllowRegistrations()); + return new WebApplicationException(Response.status(status).entity(response).type(MediaType.APPLICATION_JSON).build()); + } + } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactoryProvider.java b/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactoryProvider.java index ca9ee1fd..4e70d479 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactoryProvider.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/auth/SecurityCheckFactoryProvider.java @@ -9,6 +9,7 @@ import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractor import org.glassfish.jersey.server.model.Parameter; import org.glassfish.jersey.server.spi.internal.ValueParamProvider; +import com.commafeed.CommaFeedConfiguration; import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.model.User; import com.commafeed.backend.service.UserService; @@ -23,14 +24,16 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider { private final UserService userService; private final UserDAO userDAO; + private final CommaFeedConfiguration config; private final HttpServletRequest request; @Inject public SecurityCheckFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider, UserDAO userDAO, - UserService userService, HttpServletRequest request) { + UserService userService, CommaFeedConfiguration config, HttpServletRequest request) { super(() -> extractorProvider, Parameter.Source.UNKNOWN); this.userDAO = userDAO; this.userService = userService; + this.config = config; this.request = request; } @@ -47,7 +50,7 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider { return null; } - return new SecurityCheckFactory(userDAO, userService, request, securityCheck.value(), securityCheck.apiKeyAllowed()); + return new SecurityCheckFactory(userDAO, userService, config, request, securityCheck.value(), securityCheck.apiKeyAllowed()); } @RequiredArgsConstructor @@ -55,12 +58,14 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider { private final UserDAO userDAO; private final UserService userService; + private final CommaFeedConfiguration config; @Override protected void configure() { bind(SecurityCheckFactoryProvider.class).to(ValueParamProvider.class).in(Singleton.class); bind(userDAO).to(UserDAO.class); bind(userService).to(UserService.class); + bind(config).to(CommaFeedConfiguration.class); } } diff --git a/commafeed-server/src/test/java/com/commafeed/frontend/auth/SecurityCheckFactoryTest.java b/commafeed-server/src/test/java/com/commafeed/frontend/auth/SecurityCheckFactoryTest.java index e227530a..1069ef8f 100644 --- a/commafeed-server/src/test/java/com/commafeed/frontend/auth/SecurityCheckFactoryTest.java +++ b/commafeed-server/src/test/java/com/commafeed/frontend/auth/SecurityCheckFactoryTest.java @@ -26,7 +26,7 @@ class SecurityCheckFactoryTest { UserService service = new UserService(null, null, null, null, null, null, null, postLoginActivities); - SecurityCheckFactory factory = new SecurityCheckFactory(userDAO, service, null, null, false); + SecurityCheckFactory factory = new SecurityCheckFactory(userDAO, service, null, null, null, false); factory.cookieSessionLogin(sessionHelper); Mockito.verify(postLoginActivities).executeFor(userInSession);