redirect to login page instead of welcome page if allowRegistrations is false (#1185)

This commit is contained in:
Athou
2024-01-11 16:21:54 +01:00
parent 9e4e629a1a
commit 8297edaf71
5 changed files with 26 additions and 15 deletions

View File

@@ -31,11 +31,12 @@ const axiosInstance = axios.create({ baseURL: "./rest", withCredentials: true })
axiosInstance.interceptors.response.use( axiosInstance.interceptors.response.use(
response => response, response => response,
error => { error => {
const { status, data } = error.response
if ( if (
(error.response.status === 401 && error.response.data === "Credentials are required to access this resource.") || (status === 401 && data?.message === "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 === 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 throw error
} }

View File

@@ -169,7 +169,7 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
// support for "@SecurityCheck User user" injection // support for "@SecurityCheck User user" injection
environment.jersey() environment.jersey()
.register(new SecurityCheckFactoryProvider.Binder(injector.getInstance(UserDAO.class), .register(new SecurityCheckFactoryProvider.Binder(injector.getInstance(UserDAO.class),
injector.getInstance(UserService.class))); injector.getInstance(UserService.class), config));
// support for "@Context SessionHelper sessionHelper" injection // support for "@Context SessionHelper sessionHelper" injection
environment.jersey().register(new SessionHelperFactoryProvider.Binder()); environment.jersey().register(new SessionHelperFactoryProvider.Binder());

View File

@@ -2,12 +2,15 @@ package com.commafeed.frontend.auth;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import org.glassfish.jersey.server.ContainerRequest; import org.glassfish.jersey.server.ContainerRequest;
import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.model.UserRole.Role;
@@ -28,6 +31,7 @@ public class SecurityCheckFactory implements Function<ContainerRequest, User> {
private final UserDAO userDAO; private final UserDAO userDAO;
private final UserService userService; private final UserService userService;
private final CommaFeedConfiguration config;
private final HttpServletRequest request; private final HttpServletRequest request;
private final Role role; private final Role role;
private final boolean apiKeyAllowed; private final boolean apiKeyAllowed;
@@ -47,16 +51,10 @@ public class SecurityCheckFactory implements Function<ContainerRequest, User> {
if (roles.contains(role)) { if (roles.contains(role)) {
return user.get(); return user.get();
} else { } else {
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN) throw buildWebApplicationException(Response.Status.FORBIDDEN, "You don't have the required role to access this resource.");
.entity("You don't have the required role to access this resource.")
.type(MediaType.TEXT_PLAIN_TYPE)
.build());
} }
} else { } else {
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED) throw buildWebApplicationException(Response.Status.UNAUTHORIZED, "Credentials are required to access this resource.");
.entity("Credentials are required to access this resource.")
.type(MediaType.TEXT_PLAIN_TYPE)
.build());
} }
} }
@@ -95,4 +93,11 @@ public class SecurityCheckFactory implements Function<ContainerRequest, User> {
return Optional.empty(); return Optional.empty();
} }
private WebApplicationException buildWebApplicationException(Response.Status status, String message) {
Map<String, Object> 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());
}
} }

View File

@@ -9,6 +9,7 @@ import org.glassfish.jersey.server.internal.inject.MultivaluedParameterExtractor
import org.glassfish.jersey.server.model.Parameter; import org.glassfish.jersey.server.model.Parameter;
import org.glassfish.jersey.server.spi.internal.ValueParamProvider; import org.glassfish.jersey.server.spi.internal.ValueParamProvider;
import com.commafeed.CommaFeedConfiguration;
import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserDAO;
import com.commafeed.backend.model.User; import com.commafeed.backend.model.User;
import com.commafeed.backend.service.UserService; import com.commafeed.backend.service.UserService;
@@ -23,14 +24,16 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider {
private final UserService userService; private final UserService userService;
private final UserDAO userDAO; private final UserDAO userDAO;
private final CommaFeedConfiguration config;
private final HttpServletRequest request; private final HttpServletRequest request;
@Inject @Inject
public SecurityCheckFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider, UserDAO userDAO, public SecurityCheckFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider, UserDAO userDAO,
UserService userService, HttpServletRequest request) { UserService userService, CommaFeedConfiguration config, HttpServletRequest request) {
super(() -> extractorProvider, Parameter.Source.UNKNOWN); super(() -> extractorProvider, Parameter.Source.UNKNOWN);
this.userDAO = userDAO; this.userDAO = userDAO;
this.userService = userService; this.userService = userService;
this.config = config;
this.request = request; this.request = request;
} }
@@ -47,7 +50,7 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider {
return null; return null;
} }
return new SecurityCheckFactory(userDAO, userService, request, securityCheck.value(), securityCheck.apiKeyAllowed()); return new SecurityCheckFactory(userDAO, userService, config, request, securityCheck.value(), securityCheck.apiKeyAllowed());
} }
@RequiredArgsConstructor @RequiredArgsConstructor
@@ -55,12 +58,14 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider {
private final UserDAO userDAO; private final UserDAO userDAO;
private final UserService userService; private final UserService userService;
private final CommaFeedConfiguration config;
@Override @Override
protected void configure() { protected void configure() {
bind(SecurityCheckFactoryProvider.class).to(ValueParamProvider.class).in(Singleton.class); bind(SecurityCheckFactoryProvider.class).to(ValueParamProvider.class).in(Singleton.class);
bind(userDAO).to(UserDAO.class); bind(userDAO).to(UserDAO.class);
bind(userService).to(UserService.class); bind(userService).to(UserService.class);
bind(config).to(CommaFeedConfiguration.class);
} }
} }

View File

@@ -26,7 +26,7 @@ class SecurityCheckFactoryTest {
UserService service = new UserService(null, null, null, null, null, null, null, postLoginActivities); 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); factory.cookieSessionLogin(sessionHelper);
Mockito.verify(postLoginActivities).executeFor(userInSession); Mockito.verify(postLoginActivities).executeFor(userInSession);