diff --git a/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java b/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java index d267160a..b19a8ba6 100644 --- a/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java +++ b/commafeed-server/src/main/java/com/commafeed/CommaFeedApplication.java @@ -10,6 +10,7 @@ import java.util.concurrent.TimeUnit; import org.hibernate.cfg.AvailableSettings; import com.codahale.metrics.json.MetricsModule; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.feed.FeedRefreshEngine; import com.commafeed.backend.model.AbstractModel; import com.commafeed.backend.model.Feed; @@ -166,7 +167,9 @@ public class CommaFeedApplication extends Application { environment.servlets().setSessionHandler(config.getSessionHandlerFactory().build(config.getDataSourceFactory())); // support for "@SecurityCheck User user" injection - environment.jersey().register(new SecurityCheckFactoryProvider.Binder(injector.getInstance(UserService.class))); + environment.jersey() + .register(new SecurityCheckFactoryProvider.Binder(injector.getInstance(UserDAO.class), + injector.getInstance(UserService.class))); // 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 58fcc7a4..ac2bdf2a 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 @@ -8,6 +8,7 @@ import java.util.function.Function; import org.glassfish.jersey.server.ContainerRequest; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserRole.Role; import com.commafeed.backend.service.UserService; @@ -25,6 +26,7 @@ public class SecurityCheckFactory implements Function { private static final String PREFIX = "Basic"; + private final UserDAO userDAO; private final UserService userService; private final HttpServletRequest request; private final Role role; @@ -59,7 +61,7 @@ public class SecurityCheckFactory implements Function { } Optional cookieSessionLogin(SessionHelper sessionHelper) { - Optional loggedInUser = sessionHelper.getLoggedInUser(); + Optional loggedInUser = sessionHelper.getLoggedInUserId().map(userDAO::findById); loggedInUser.ifPresent(userService::performPostLoginActivities); return loggedInUser; } 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 7ccfbc64..ca9ee1fd 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.backend.dao.UserDAO; import com.commafeed.backend.model.User; import com.commafeed.backend.service.UserService; @@ -21,12 +22,14 @@ import lombok.RequiredArgsConstructor; public class SecurityCheckFactoryProvider extends AbstractValueParamProvider { private final UserService userService; + private final UserDAO userDAO; private final HttpServletRequest request; @Inject - public SecurityCheckFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider, UserService userService, - HttpServletRequest request) { + public SecurityCheckFactoryProvider(final MultivaluedParameterExtractorProvider extractorProvider, UserDAO userDAO, + UserService userService, HttpServletRequest request) { super(() -> extractorProvider, Parameter.Source.UNKNOWN); + this.userDAO = userDAO; this.userService = userService; this.request = request; } @@ -44,17 +47,19 @@ public class SecurityCheckFactoryProvider extends AbstractValueParamProvider { return null; } - return new SecurityCheckFactory(userService, request, securityCheck.value(), securityCheck.apiKeyAllowed()); + return new SecurityCheckFactory(userDAO, userService, request, securityCheck.value(), securityCheck.apiKeyAllowed()); } @RequiredArgsConstructor public static class Binder extends AbstractBinder { + private final UserDAO userDAO; private final UserService userService; @Override protected void configure() { bind(SecurityCheckFactoryProvider.class).to(ValueParamProvider.class).in(Singleton.class); + bind(userDAO).to(UserDAO.class); bind(userService).to(UserService.class); } } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/AbstractCustomCodeServlet.java b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/AbstractCustomCodeServlet.java index 9f3b83e2..c71b1632 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/AbstractCustomCodeServlet.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/AbstractCustomCodeServlet.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.util.Optional; import com.commafeed.backend.dao.UnitOfWork; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserSettingsDAO; import com.commafeed.backend.model.User; import com.commafeed.backend.model.UserSettings; @@ -20,13 +21,16 @@ abstract class AbstractCustomCodeServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final UnitOfWork unitOfWork; + private final UserDAO userDAO; private final UserSettingsDAO userSettingsDAO; @Override protected final void doGet(final HttpServletRequest req, HttpServletResponse resp) throws IOException { resp.setContentType(getMimeType()); - final Optional user = new SessionHelper(req).getLoggedInUser(); + SessionHelper sessionHelper = new SessionHelper(req); + Optional userId = sessionHelper.getLoggedInUserId(); + final Optional user = unitOfWork.call(() -> userId.map(userDAO::findById)); if (user.isEmpty()) { return; } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java index 2cc74fe2..7bcc1f91 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomCssServlet.java @@ -1,6 +1,7 @@ package com.commafeed.frontend.servlet; import com.commafeed.backend.dao.UnitOfWork; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserSettingsDAO; import com.commafeed.backend.model.UserSettings; @@ -11,8 +12,8 @@ public class CustomCssServlet extends AbstractCustomCodeServlet { private static final long serialVersionUID = 1L; @Inject - public CustomCssServlet(UnitOfWork unitOfWork, UserSettingsDAO userSettingsDAO) { - super(unitOfWork, userSettingsDAO); + public CustomCssServlet(UnitOfWork unitOfWork, UserDAO userDAO, UserSettingsDAO userSettingsDAO) { + super(unitOfWork, userDAO, userSettingsDAO); } @Override diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomJsServlet.java b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomJsServlet.java index e0b86468..0c29b7a9 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomJsServlet.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/CustomJsServlet.java @@ -1,6 +1,7 @@ package com.commafeed.frontend.servlet; import com.commafeed.backend.dao.UnitOfWork; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.dao.UserSettingsDAO; import com.commafeed.backend.model.UserSettings; @@ -13,8 +14,8 @@ public class CustomJsServlet extends AbstractCustomCodeServlet { private static final long serialVersionUID = 1L; @Inject - public CustomJsServlet(UnitOfWork unitOfWork, UserSettingsDAO userSettingsDAO) { - super(unitOfWork, userSettingsDAO); + public CustomJsServlet(UnitOfWork unitOfWork, UserDAO userDAO, UserSettingsDAO userSettingsDAO) { + super(unitOfWork, userDAO, userSettingsDAO); } @Override diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java index dbd598c0..13355bd7 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/servlet/NextUnreadServlet.java @@ -11,6 +11,7 @@ import com.commafeed.backend.dao.FeedCategoryDAO; import com.commafeed.backend.dao.FeedEntryStatusDAO; import com.commafeed.backend.dao.FeedSubscriptionDAO; import com.commafeed.backend.dao.UnitOfWork; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.model.FeedCategory; import com.commafeed.backend.model.FeedEntryStatus; import com.commafeed.backend.model.FeedSubscription; @@ -41,6 +42,7 @@ public class NextUnreadServlet extends HttpServlet { private final FeedSubscriptionDAO feedSubscriptionDAO; private final FeedEntryStatusDAO feedEntryStatusDAO; private final FeedCategoryDAO feedCategoryDAO; + private final UserDAO userDAO; private final UserService userService; private final FeedEntryService feedEntryService; private final CommaFeedConfiguration config; @@ -51,7 +53,8 @@ public class NextUnreadServlet extends HttpServlet { String orderParam = req.getParameter(PARAM_READINGORDER); SessionHelper sessionHelper = new SessionHelper(req); - Optional user = sessionHelper.getLoggedInUser(); + Optional userId = sessionHelper.getLoggedInUserId(); + Optional user = unitOfWork.call(() -> userId.map(userDAO::findById)); user.ifPresent(value -> unitOfWork.run(() -> userService.performPostLoginActivities(value))); if (user.isEmpty()) { resp.sendRedirect(resp.encodeRedirectURL(config.getApplicationSettings().getPublicUrl())); diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/session/SessionHelper.java b/commafeed-server/src/main/java/com/commafeed/frontend/session/SessionHelper.java index 3d2c1353..97341ea3 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/session/SessionHelper.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/session/SessionHelper.java @@ -11,32 +11,25 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class SessionHelper { - private static final String SESSION_KEY_USER = "user"; + public static final String SESSION_KEY_USER_ID = "user-id"; private final HttpServletRequest request; - public Optional getLoggedInUser() { - Optional session = getSession(false); - if (session.isPresent()) { - return getLoggedInUser(session.get()); - } - - return Optional.empty(); + public Optional getLoggedInUserId() { + HttpSession session = request.getSession(false); + return getLoggedInUserId(session); } - public static Optional getLoggedInUser(HttpSession session) { - User user = (User) session.getAttribute(SESSION_KEY_USER); - return Optional.ofNullable(user); + public static Optional getLoggedInUserId(HttpSession session) { + if (session == null) { + return Optional.empty(); + } + Long userId = (Long) session.getAttribute(SESSION_KEY_USER_ID); + return Optional.ofNullable(userId); } public void setLoggedInUser(User user) { - Optional session = getSession(true); - session.get().setAttribute(SESSION_KEY_USER, user); - } - - private Optional getSession(boolean force) { - HttpSession session = request.getSession(force); - return Optional.ofNullable(session); + request.getSession(true).setAttribute(SESSION_KEY_USER_ID, user.getId()); } } diff --git a/commafeed-server/src/main/java/com/commafeed/frontend/ws/WebSocketConfigurator.java b/commafeed-server/src/main/java/com/commafeed/frontend/ws/WebSocketConfigurator.java index 54dd8407..70d6a903 100644 --- a/commafeed-server/src/main/java/com/commafeed/frontend/ws/WebSocketConfigurator.java +++ b/commafeed-server/src/main/java/com/commafeed/frontend/ws/WebSocketConfigurator.java @@ -2,7 +2,6 @@ package com.commafeed.frontend.ws; import java.util.Optional; -import com.commafeed.backend.model.User; import com.commafeed.frontend.session.SessionHelper; import jakarta.inject.Inject; @@ -26,8 +25,8 @@ public class WebSocketConfigurator extends Configurator { public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) { HttpSession httpSession = (HttpSession) request.getHttpSession(); if (httpSession != null) { - Optional user = SessionHelper.getLoggedInUser(httpSession); - user.ifPresent(value -> config.getUserProperties().put(SESSIONKEY_USERID, value.getId())); + Optional userId = SessionHelper.getLoggedInUserId(httpSession); + userId.ifPresent(value -> config.getUserProperties().put(SESSIONKEY_USERID, value)); } } 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 1afccf8c..e227530a 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 @@ -5,6 +5,7 @@ import java.util.Optional; import org.junit.jupiter.api.Test; import org.mockito.Mockito; +import com.commafeed.backend.dao.UserDAO; import com.commafeed.backend.model.User; import com.commafeed.backend.service.UserService; import com.commafeed.backend.service.internal.PostLoginActivities; @@ -15,15 +16,17 @@ class SecurityCheckFactoryTest { @Test void cookieLoginShouldPerformPostLoginActivities() { User userInSession = new User(); + UserDAO userDAO = Mockito.mock(UserDAO.class); + Mockito.when(userDAO.findById(1L)).thenReturn(userInSession); SessionHelper sessionHelper = Mockito.mock(SessionHelper.class); - Mockito.when(sessionHelper.getLoggedInUser()).thenReturn(Optional.of(userInSession)); + Mockito.when(sessionHelper.getLoggedInUserId()).thenReturn(Optional.of(1L)); PostLoginActivities postLoginActivities = Mockito.mock(PostLoginActivities.class); UserService service = new UserService(null, null, null, null, null, null, null, postLoginActivities); - SecurityCheckFactory factory = new SecurityCheckFactory(service, null, null, false); + SecurityCheckFactory factory = new SecurityCheckFactory(userDAO, service, null, null, false); factory.cookieSessionLogin(sessionHelper); Mockito.verify(postLoginActivities).executeFor(userInSession); diff --git a/commafeed-server/src/test/java/com/commafeed/frontend/session/SessionHelperTest.java b/commafeed-server/src/test/java/com/commafeed/frontend/session/SessionHelperTest.java index 54a1d6d3..47d0fd5d 100644 --- a/commafeed-server/src/test/java/com/commafeed/frontend/session/SessionHelperTest.java +++ b/commafeed-server/src/test/java/com/commafeed/frontend/session/SessionHelperTest.java @@ -13,14 +13,12 @@ import jakarta.servlet.http.HttpSession; class SessionHelperTest { - private static final String SESSION_KEY_USER = "user"; - @Test void gettingUserDoesNotCreateSession() { HttpServletRequest request = Mockito.mock(HttpServletRequest.class); SessionHelper sessionHelper = new SessionHelper(request); - sessionHelper.getLoggedInUser(); + sessionHelper.getLoggedInUserId(); Mockito.verify(request).getSession(false); } @@ -31,23 +29,23 @@ class SessionHelperTest { Mockito.when(request.getSession(false)).thenReturn(null); SessionHelper sessionHelper = new SessionHelper(request); - Optional user = sessionHelper.getLoggedInUser(); + Optional userId = sessionHelper.getLoggedInUserId(); - Assertions.assertFalse(user.isPresent()); + Assertions.assertFalse(userId.isPresent()); } @Test void gettingUserShouldNotReturnUserIfUserNotPresentInHttpSession() { HttpSession session = Mockito.mock(HttpSession.class); - Mockito.when(session.getAttribute(SESSION_KEY_USER)).thenReturn(null); + Mockito.when(session.getAttribute(SessionHelper.SESSION_KEY_USER_ID)).thenReturn(null); HttpServletRequest request = Mockito.mock(HttpServletRequest.class); Mockito.when(request.getSession(false)).thenReturn(session); SessionHelper sessionHelper = new SessionHelper(request); - Optional user = sessionHelper.getLoggedInUser(); + Optional userId = sessionHelper.getLoggedInUserId(); - Assertions.assertFalse(user.isPresent()); + Assertions.assertFalse(userId.isPresent()); } @Test @@ -55,16 +53,15 @@ class SessionHelperTest { User userInSession = new User(); HttpSession session = Mockito.mock(HttpSession.class); - Mockito.when(session.getAttribute(SESSION_KEY_USER)).thenReturn(userInSession); + Mockito.when(session.getAttribute(SessionHelper.SESSION_KEY_USER_ID)).thenReturn(1L); HttpServletRequest request = Mockito.mock(HttpServletRequest.class); Mockito.when(request.getSession(false)).thenReturn(session); SessionHelper sessionHelper = new SessionHelper(request); - Optional user = sessionHelper.getLoggedInUser(); + Optional userId = sessionHelper.getLoggedInUserId(); - Assertions.assertTrue(user.isPresent()); - Assertions.assertEquals(userInSession, user.get()); + Assertions.assertTrue(userId.isPresent()); } }