mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
Merge pull request #647 from rationalrevolt/userservice-tests
Remove dependency on HttpSession in UserService
This commit is contained in:
@@ -4,7 +4,6 @@ import io.dropwizard.Application;
|
||||
import io.dropwizard.assets.AssetsBundle;
|
||||
import io.dropwizard.db.DataSourceFactory;
|
||||
import io.dropwizard.hibernate.HibernateBundle;
|
||||
import io.dropwizard.jersey.sessions.HttpSessionProvider;
|
||||
import io.dropwizard.migrations.MigrationsBundle;
|
||||
import io.dropwizard.servlets.CacheBustingFilter;
|
||||
import io.dropwizard.setup.Bootstrap;
|
||||
@@ -36,6 +35,7 @@ import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.backend.task.OldStatusesCleanupTask;
|
||||
import com.commafeed.backend.task.OrphansCleanupTask;
|
||||
import com.commafeed.backend.task.SchedulingService;
|
||||
import com.commafeed.frontend.SessionHelperProvider;
|
||||
import com.commafeed.frontend.auth.SecurityCheckProvider;
|
||||
import com.commafeed.frontend.auth.SecurityCheckProvider.SecurityCheckUserServiceProvider;
|
||||
import com.commafeed.frontend.resource.AdminREST;
|
||||
@@ -108,7 +108,7 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
||||
environment.servlets().setSessionHandler(new SessionHandler(config.getSessionManagerFactory().build()));
|
||||
environment.jersey().register(new SecurityCheckUserServiceProvider(injector.getInstance(UserService.class)));
|
||||
environment.jersey().register(SecurityCheckProvider.class);
|
||||
environment.jersey().register(HttpSessionProvider.class);
|
||||
environment.jersey().register(SessionHelperProvider.class);
|
||||
|
||||
// REST resources
|
||||
environment.jersey().setUrlPattern("/rest/*");
|
||||
|
||||
@@ -15,6 +15,7 @@ import javax.persistence.TemporalType;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import org.apache.commons.lang.time.DateUtils;
|
||||
import org.hibernate.annotations.Cascade;
|
||||
|
||||
import com.commafeed.backend.model.UserRole.Role;
|
||||
@@ -77,5 +78,13 @@ public class User extends AbstractModel {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldRefreshFeedsAt(Date when) {
|
||||
return (lastFullRefresh == null || lastFullRefreshMoreThan30MinutesBefore(when));
|
||||
}
|
||||
|
||||
private boolean lastFullRefreshMoreThan30MinutesBefore(Date when) {
|
||||
return lastFullRefresh.before(DateUtils.addMinutes(when, -30));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@@ -28,8 +27,6 @@ import com.google.common.base.Preconditions;
|
||||
@Singleton
|
||||
public class UserService {
|
||||
|
||||
private static final String SESSION_KEY_USER = "user";
|
||||
|
||||
private final FeedCategoryDAO feedCategoryDAO;
|
||||
private final UserDAO userDAO;
|
||||
private final UserSettingsDAO userSettingsDAO;
|
||||
@@ -54,37 +51,12 @@ public class UserService {
|
||||
if (user != null && !user.isDisabled()) {
|
||||
boolean authenticated = encryptionService.authenticate(password, user.getPassword(), user.getSalt());
|
||||
if (authenticated) {
|
||||
afterLogin(user);
|
||||
return Optional.fromNullable(user);
|
||||
}
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
/**
|
||||
* try to log in with given credentials and create a session for the user
|
||||
*/
|
||||
public Optional<User> login(String nameOrEmail, String password, HttpSession sessionToFill) {
|
||||
Optional<User> user = login(nameOrEmail, password);
|
||||
if (user.isPresent()) {
|
||||
sessionToFill.setAttribute(SESSION_KEY_USER, user.get());
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* try to log in by checking if the user has an active session
|
||||
*/
|
||||
public Optional<User> login(HttpSession session) {
|
||||
if (session != null) {
|
||||
User user = (User) session.getAttribute(SESSION_KEY_USER);
|
||||
if (user != null) {
|
||||
afterLogin(user);
|
||||
performPostLoginActivities(user);
|
||||
return Optional.of(user);
|
||||
}
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* try to log in with given api key
|
||||
@@ -96,8 +68,8 @@ public class UserService {
|
||||
|
||||
User user = userDAO.findByApiKey(apiKey);
|
||||
if (user != null && !user.isDisabled()) {
|
||||
afterLogin(user);
|
||||
return Optional.fromNullable(user);
|
||||
performPostLoginActivities(user);
|
||||
return Optional.of(user);
|
||||
}
|
||||
return Optional.absent();
|
||||
}
|
||||
@@ -105,7 +77,7 @@ public class UserService {
|
||||
/**
|
||||
* should triggers after successful login
|
||||
*/
|
||||
private void afterLogin(User user) {
|
||||
public void performPostLoginActivities(User user) {
|
||||
postLoginActivities.executeFor(user);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,16 +28,15 @@ public class PostLoginActivities {
|
||||
|
||||
boolean saveUser = false;
|
||||
// only update lastLogin field every hour in order to not
|
||||
// invalidate the cache everytime someone logs in
|
||||
// invalidate the cache every time someone logs in
|
||||
if (lastLogin == null || lastLogin.before(DateUtils.addHours(now, -1))) {
|
||||
user.setLastLogin(now);
|
||||
saveUser = true;
|
||||
}
|
||||
if (config.getApplicationSettings().isHeavyLoad()
|
||||
&& (user.getLastFullRefresh() == null || user.getLastFullRefresh().before(DateUtils.addMinutes(now, -30)))) {
|
||||
if (config.getApplicationSettings().isHeavyLoad() && user.shouldRefreshFeedsAt(now)) {
|
||||
feedSubscriptionService.refreshAll(user);
|
||||
user.setLastFullRefresh(now);
|
||||
saveUser = true;
|
||||
feedSubscriptionService.refreshAll(user);
|
||||
}
|
||||
if (saveUser) {
|
||||
userDAO.merge(user);
|
||||
|
||||
39
src/main/java/com/commafeed/frontend/SessionHelper.java
Normal file
39
src/main/java/com/commafeed/frontend/SessionHelper.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package com.commafeed.frontend;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
@RequiredArgsConstructor()
|
||||
public class SessionHelper {
|
||||
|
||||
private static final String SESSION_KEY_USER = "user";
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
public Optional<User> getLoggedInUser() {
|
||||
Optional<HttpSession> session = getSession(false);
|
||||
|
||||
if (session.isPresent()) {
|
||||
User user = (User) session.get().getAttribute(SESSION_KEY_USER);
|
||||
return Optional.fromNullable(user);
|
||||
}
|
||||
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
public void setLoggedInUser(User user) {
|
||||
Optional<HttpSession> session = getSession(true);
|
||||
session.get().setAttribute(SESSION_KEY_USER, user);
|
||||
}
|
||||
|
||||
private Optional<HttpSession> getSession(boolean force) {
|
||||
HttpSession session = request.getSession(force);
|
||||
return Optional.fromNullable(session);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.commafeed.frontend;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.ext.Provider;
|
||||
|
||||
import com.sun.jersey.core.spi.component.ComponentContext;
|
||||
import com.sun.jersey.core.spi.component.ComponentScope;
|
||||
import com.sun.jersey.spi.inject.Injectable;
|
||||
import com.sun.jersey.spi.inject.InjectableProvider;
|
||||
|
||||
@Provider
|
||||
public class SessionHelperProvider implements InjectableProvider<Context, Type> {
|
||||
|
||||
private final ThreadLocal<HttpServletRequest> request;
|
||||
|
||||
public SessionHelperProvider(@Context ThreadLocal<HttpServletRequest> request) {
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentScope getScope() {
|
||||
return ComponentScope.PerRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Injectable<?> getInjectable(ComponentContext ic, final Context session, Type type) {
|
||||
if (type.equals(SessionHelper.class)) {
|
||||
return new Injectable<SessionHelper>() {
|
||||
@Override
|
||||
public SessionHelper getValue() {
|
||||
final HttpServletRequest req = request.get();
|
||||
if (req != null) {
|
||||
return new SessionHelper(req);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import org.eclipse.jetty.util.StringUtil;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserRole.Role;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.frontend.SessionHelper;
|
||||
import com.google.common.base.Optional;
|
||||
import com.sun.jersey.api.core.HttpContext;
|
||||
import com.sun.jersey.api.model.Parameter;
|
||||
@@ -35,7 +36,7 @@ public class SecurityCheckProvider implements InjectableProvider<SecurityCheck,
|
||||
}
|
||||
|
||||
@RequiredArgsConstructor
|
||||
private static class SecurityCheckInjectable<T> extends AbstractHttpContextInjectable<User> {
|
||||
static class SecurityCheckInjectable<T> extends AbstractHttpContextInjectable<User> {
|
||||
private static final String PREFIX = "Basic";
|
||||
|
||||
private final HttpServletRequest request;
|
||||
@@ -66,8 +67,13 @@ public class SecurityCheckProvider implements InjectableProvider<SecurityCheck,
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<User> cookieSessionLogin() {
|
||||
return userService.login(request.getSession(false));
|
||||
Optional<User> cookieSessionLogin() {
|
||||
SessionHelper sessionHelper = new SessionHelper(request);
|
||||
Optional<User> loggedInUser = sessionHelper.getLoggedInUser();
|
||||
if (loggedInUser.isPresent()) {
|
||||
userService.performPostLoginActivities(loggedInUser.get());
|
||||
}
|
||||
return loggedInUser;
|
||||
}
|
||||
|
||||
private Optional<User> basicAuthenticationLogin(HttpContext c) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.commafeed.frontend.resource;
|
||||
|
||||
import io.dropwizard.hibernate.UnitOfWork;
|
||||
import io.dropwizard.jersey.sessions.Session;
|
||||
import io.dropwizard.jersey.validation.ValidationErrorMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -11,7 +10,6 @@ import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
@@ -20,6 +18,7 @@ import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
@@ -49,6 +48,7 @@ import com.commafeed.backend.model.UserSettings.ViewMode;
|
||||
import com.commafeed.backend.service.MailService;
|
||||
import com.commafeed.backend.service.PasswordEncryptionService;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.frontend.SessionHelper;
|
||||
import com.commafeed.frontend.auth.SecurityCheck;
|
||||
import com.commafeed.frontend.model.Settings;
|
||||
import com.commafeed.frontend.model.UserModel;
|
||||
@@ -223,10 +223,11 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Register a new account")
|
||||
public Response register(@Valid @ApiParam(required = true) RegistrationRequest req, @Session HttpSession session) {
|
||||
public Response register(@Valid @ApiParam(required = true) RegistrationRequest req, @Context SessionHelper sessionHelper) {
|
||||
try {
|
||||
userService.register(req.getName(), req.getPassword(), req.getEmail(), Arrays.asList(Role.USER));
|
||||
userService.login(req.getName(), req.getPassword(), session);
|
||||
User registeredUser = userService.register(req.getName(), req.getPassword(), req.getEmail(), Arrays.asList(Role.USER));
|
||||
userService.login(req.getName(), req.getPassword());
|
||||
sessionHelper.setLoggedInUser(registeredUser);
|
||||
return Response.ok().build();
|
||||
} catch (final IllegalArgumentException e) {
|
||||
return Response.status(422).entity(new ValidationErrorMessage(Collections.<ConstraintViolation<?>> emptySet()) {
|
||||
@@ -242,9 +243,10 @@ public class UserREST {
|
||||
@POST
|
||||
@UnitOfWork
|
||||
@ApiOperation(value = "Login and create a session")
|
||||
public Response login(@ApiParam(required = true) LoginRequest req, @Session HttpSession session) {
|
||||
Optional<User> user = userService.login(req.getName(), req.getPassword(), session);
|
||||
public Response login(@ApiParam(required = true) LoginRequest req, @Context SessionHelper sessionHelper) {
|
||||
Optional<User> user = userService.login(req.getName(), req.getPassword());
|
||||
if (user.isPresent()) {
|
||||
sessionHelper.setLoggedInUser(user.get());
|
||||
return Response.ok().build();
|
||||
} else {
|
||||
return Response.status(Response.Status.UNAUTHORIZED).entity("wrong username or password").build();
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.commafeed.backend.dao.UserSettingsDAO;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserSettings;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.frontend.SessionHelper;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
@@ -36,7 +37,12 @@ public class CustomCssServlet extends HttpServlet {
|
||||
final Optional<User> user = new UnitOfWork<Optional<User>>(sessionFactory) {
|
||||
@Override
|
||||
protected Optional<User> runInSession() throws Exception {
|
||||
return userService.login(req.getSession(false));
|
||||
SessionHelper sessionHelper = new SessionHelper(req);
|
||||
Optional<User> loggedInUser = sessionHelper.getLoggedInUser();
|
||||
if (loggedInUser.isPresent()) {
|
||||
userService.performPostLoginActivities(loggedInUser.get());
|
||||
}
|
||||
return loggedInUser;
|
||||
}
|
||||
}.run();
|
||||
if (!user.isPresent()) {
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.commafeed.backend.model.FeedSubscription;
|
||||
import com.commafeed.backend.model.User;
|
||||
import com.commafeed.backend.model.UserSettings.ReadingOrder;
|
||||
import com.commafeed.backend.service.UserService;
|
||||
import com.commafeed.frontend.SessionHelper;
|
||||
import com.commafeed.frontend.resource.CategoryREST;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Iterables;
|
||||
@@ -53,7 +54,12 @@ public class NextUnreadServlet extends HttpServlet {
|
||||
final Optional<User> user = new UnitOfWork<Optional<User>>(sessionFactory) {
|
||||
@Override
|
||||
protected Optional<User> runInSession() throws Exception {
|
||||
return userService.login(req.getSession(false));
|
||||
SessionHelper sessionHelper = new SessionHelper(req);
|
||||
Optional<User> loggedInUser = sessionHelper.getLoggedInUser();
|
||||
if (loggedInUser.isPresent()) {
|
||||
userService.performPostLoginActivities(loggedInUser.get());
|
||||
}
|
||||
return loggedInUser;
|
||||
}
|
||||
}.run();
|
||||
if (!user.isPresent()) {
|
||||
|
||||
Reference in New Issue
Block a user