mirror of
https://github.com/Athou/commafeed.git
synced 2026-03-21 21:37:29 +00:00
session support
This commit is contained in:
@@ -72,7 +72,10 @@ gulp.task('serve', function() {
|
|||||||
root : BUILD_DIR,
|
root : BUILD_DIR,
|
||||||
port : 8082,
|
port : 8082,
|
||||||
middleware : function() {
|
middleware : function() {
|
||||||
return [modRewrite(['^/rest/(.*)$ http://localhost:8083/rest/$1 [P]'])];
|
var rest = '^/rest/(.*)$ http://localhost:8083/rest/$1 [P]';
|
||||||
|
var next = '^/next(.*)$ http://localhost:8083/next$1 [P]';
|
||||||
|
var logout = '^/logout(.*)$ http://localhost:8083/logout$1 [P]';
|
||||||
|
return [modRewrite([rest, next, logout])];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ app.config(['$routeProvider', '$stateProvider', '$urlRouterProvider', '$httpProv
|
|||||||
cfpLoadingBarProvider.includeSpinner = false;
|
cfpLoadingBarProvider.includeSpinner = false;
|
||||||
|
|
||||||
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|javascript):/);
|
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|javascript):/);
|
||||||
var interceptor = ['$rootScope', '$q', function(scope, $q) {
|
var interceptor = ['$rootScope', '$q', '$injector', function(scope, $q, $injector) {
|
||||||
|
|
||||||
var success = function(response) {
|
var success = function(response) {
|
||||||
return response;
|
return response;
|
||||||
@@ -16,7 +16,7 @@ app.config(['$routeProvider', '$stateProvider', '$urlRouterProvider', '$httpProv
|
|||||||
var error = function(response) {
|
var error = function(response) {
|
||||||
var status = response.status;
|
var status = response.status;
|
||||||
if (status == 401) {
|
if (status == 401) {
|
||||||
window.location = 'logout';
|
$injector.get('$state').transitionTo('welcome');
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return $q.reject(response);
|
return $q.reject(response);
|
||||||
@@ -123,6 +123,12 @@ app.config(['$routeProvider', '$stateProvider', '$urlRouterProvider', '$httpProv
|
|||||||
templateUrl : 'templates/admin.metrics.html',
|
templateUrl : 'templates/admin.metrics.html',
|
||||||
controller : 'MetricsCtrl'
|
controller : 'MetricsCtrl'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$stateProvider.state('welcome', {
|
||||||
|
url : '/welcome',
|
||||||
|
templateUrl : 'templates/welcome.html',
|
||||||
|
controller : 'WelcomeCtrl'
|
||||||
|
});
|
||||||
|
|
||||||
$urlRouterProvider.when('/', '/feeds/view/category/all');
|
$urlRouterProvider.when('/', '/feeds/view/category/all');
|
||||||
$urlRouterProvider.when('/admin', '/admin/settings');
|
$urlRouterProvider.when('/admin', '/admin/settings');
|
||||||
|
|||||||
3
src/main/app/templates/welcome.html
Normal file
3
src/main/app/templates/welcome.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="container">
|
||||||
|
<div class="admin" ui-view></div>
|
||||||
|
</div>
|
||||||
@@ -4,6 +4,7 @@ import io.dropwizard.Application;
|
|||||||
import io.dropwizard.assets.AssetsBundle;
|
import io.dropwizard.assets.AssetsBundle;
|
||||||
import io.dropwizard.db.DataSourceFactory;
|
import io.dropwizard.db.DataSourceFactory;
|
||||||
import io.dropwizard.hibernate.HibernateBundle;
|
import io.dropwizard.hibernate.HibernateBundle;
|
||||||
|
import io.dropwizard.jersey.sessions.HttpSessionProvider;
|
||||||
import io.dropwizard.migrations.MigrationsBundle;
|
import io.dropwizard.migrations.MigrationsBundle;
|
||||||
import io.dropwizard.setup.Bootstrap;
|
import io.dropwizard.setup.Bootstrap;
|
||||||
import io.dropwizard.setup.Environment;
|
import io.dropwizard.setup.Environment;
|
||||||
@@ -12,6 +13,7 @@ import java.util.Date;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.session.SessionHandler;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
|
|
||||||
import com.codahale.metrics.MetricRegistry;
|
import com.codahale.metrics.MetricRegistry;
|
||||||
@@ -63,6 +65,7 @@ import com.commafeed.backend.service.PubSubService;
|
|||||||
import com.commafeed.backend.service.StartupService;
|
import com.commafeed.backend.service.StartupService;
|
||||||
import com.commafeed.backend.service.UserService;
|
import com.commafeed.backend.service.UserService;
|
||||||
import com.commafeed.frontend.auth.SecurityCheckProvider;
|
import com.commafeed.frontend.auth.SecurityCheckProvider;
|
||||||
|
import com.commafeed.frontend.auth.SecurityCheckProvider.SecurityCheckUserServiceProvider;
|
||||||
import com.commafeed.frontend.resource.AdminREST;
|
import com.commafeed.frontend.resource.AdminREST;
|
||||||
import com.commafeed.frontend.resource.CategoryREST;
|
import com.commafeed.frontend.resource.CategoryREST;
|
||||||
import com.commafeed.frontend.resource.EntryREST;
|
import com.commafeed.frontend.resource.EntryREST;
|
||||||
@@ -70,6 +73,7 @@ import com.commafeed.frontend.resource.FeedREST;
|
|||||||
import com.commafeed.frontend.resource.PubSubHubbubCallbackREST;
|
import com.commafeed.frontend.resource.PubSubHubbubCallbackREST;
|
||||||
import com.commafeed.frontend.resource.ServerREST;
|
import com.commafeed.frontend.resource.ServerREST;
|
||||||
import com.commafeed.frontend.resource.UserREST;
|
import com.commafeed.frontend.resource.UserREST;
|
||||||
|
import com.commafeed.frontend.servlet.LogoutServlet;
|
||||||
import com.commafeed.frontend.servlet.NextUnreadServlet;
|
import com.commafeed.frontend.servlet.NextUnreadServlet;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -78,6 +82,8 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
public static final String USERNAME_ADMIN = "admin";
|
public static final String USERNAME_ADMIN = "admin";
|
||||||
public static final String USERNAME_DEMO = "demo";
|
public static final String USERNAME_DEMO = "demo";
|
||||||
|
|
||||||
|
public static final String SESSION_USER = "user";
|
||||||
|
|
||||||
public static final Date STARTUP_TIME = new Date();
|
public static final Date STARTUP_TIME = new Date();
|
||||||
|
|
||||||
private HibernateBundle<CommaFeedConfiguration> hibernateBundle;
|
private HibernateBundle<CommaFeedConfiguration> hibernateBundle;
|
||||||
@@ -115,6 +121,7 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
: new RedisCacheService();
|
: new RedisCacheService();
|
||||||
log.info("using cache {}", cacheService.getClass());
|
log.info("using cache {}", cacheService.getClass());
|
||||||
|
|
||||||
|
// DAOs
|
||||||
FeedCategoryDAO feedCategoryDAO = new FeedCategoryDAO(sessionFactory);
|
FeedCategoryDAO feedCategoryDAO = new FeedCategoryDAO(sessionFactory);
|
||||||
FeedDAO feedDAO = new FeedDAO(sessionFactory);
|
FeedDAO feedDAO = new FeedDAO(sessionFactory);
|
||||||
FeedEntryContentDAO feedEntryContentDAO = new FeedEntryContentDAO(sessionFactory);
|
FeedEntryContentDAO feedEntryContentDAO = new FeedEntryContentDAO(sessionFactory);
|
||||||
@@ -128,6 +135,7 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
|
|
||||||
FeedQueues queues = new FeedQueues(feedDAO, config, metrics);
|
FeedQueues queues = new FeedQueues(feedDAO, config, metrics);
|
||||||
|
|
||||||
|
// Services
|
||||||
ApplicationPropertiesService applicationPropertiesService = new ApplicationPropertiesService();
|
ApplicationPropertiesService applicationPropertiesService = new ApplicationPropertiesService();
|
||||||
DatabaseCleaningService cleaningService = new DatabaseCleaningService(feedDAO, feedEntryDAO, feedEntryContentDAO,
|
DatabaseCleaningService cleaningService = new DatabaseCleaningService(feedDAO, feedEntryDAO, feedEntryContentDAO,
|
||||||
feedEntryStatusDAO, feedSubscriptionDAO);
|
feedEntryStatusDAO, feedSubscriptionDAO);
|
||||||
@@ -144,22 +152,28 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
config);
|
config);
|
||||||
StartupService startupService = new StartupService(sessionFactory, userDAO, userService);
|
StartupService startupService = new StartupService(sessionFactory, userDAO, userService);
|
||||||
|
|
||||||
|
// OPML
|
||||||
OPMLImporter opmlImporter = new OPMLImporter(feedCategoryDAO, feedSubscriptionService, cacheService);
|
OPMLImporter opmlImporter = new OPMLImporter(feedCategoryDAO, feedSubscriptionService, cacheService);
|
||||||
OPMLExporter opmlExporter = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO);
|
OPMLExporter opmlExporter = new OPMLExporter(feedCategoryDAO, feedSubscriptionDAO);
|
||||||
|
|
||||||
|
// Feed fetching/parsing
|
||||||
HttpGetter httpGetter = new HttpGetter();
|
HttpGetter httpGetter = new HttpGetter();
|
||||||
FeedParser feedParser = new FeedParser();
|
FeedParser feedParser = new FeedParser();
|
||||||
FaviconFetcher faviconFetcher = new FaviconFetcher(httpGetter);
|
FaviconFetcher faviconFetcher = new FaviconFetcher(httpGetter);
|
||||||
|
|
||||||
FeedFetcher feedFetcher = new FeedFetcher(feedParser, httpGetter);
|
FeedFetcher feedFetcher = new FeedFetcher(feedParser, httpGetter);
|
||||||
FeedRefreshUpdater feedUpdater = new FeedRefreshUpdater(sessionFactory, feedUpdateService, pubSubService, queues, config, metrics,
|
FeedRefreshUpdater feedUpdater = new FeedRefreshUpdater(sessionFactory, feedUpdateService, pubSubService, queues, config, metrics,
|
||||||
feedSubscriptionDAO, cacheService);
|
feedSubscriptionDAO, cacheService);
|
||||||
FeedRefreshWorker feedWorker = new FeedRefreshWorker(feedUpdater, feedFetcher, queues, config, metrics);
|
FeedRefreshWorker feedWorker = new FeedRefreshWorker(feedUpdater, feedFetcher, queues, config, metrics);
|
||||||
FeedRefreshTaskGiver taskGiver = new FeedRefreshTaskGiver(sessionFactory, queues, feedDAO, feedWorker, config, metrics);
|
FeedRefreshTaskGiver taskGiver = new FeedRefreshTaskGiver(sessionFactory, queues, feedDAO, feedWorker, config, metrics);
|
||||||
|
|
||||||
// TODO add caching of credentials somehow
|
// Auth/session management
|
||||||
environment.jersey().register(new SecurityCheckProvider(userService));
|
|
||||||
|
|
||||||
|
environment.servlets().setSessionHandler(new SessionHandler());
|
||||||
|
environment.jersey().register(new SecurityCheckUserServiceProvider(userService));
|
||||||
|
environment.jersey().register(SecurityCheckProvider.class);
|
||||||
|
environment.jersey().register(HttpSessionProvider.class);
|
||||||
|
|
||||||
|
// REST resources
|
||||||
environment.jersey().setUrlPattern("/rest/*");
|
environment.jersey().setUrlPattern("/rest/*");
|
||||||
environment.jersey()
|
environment.jersey()
|
||||||
.register(new AdminREST(userDAO, userRoleDAO, userService, encryptionService, cleaningService, config, metrics));
|
.register(new AdminREST(userDAO, userRoleDAO, userService, encryptionService, cleaningService, config, metrics));
|
||||||
@@ -174,18 +188,20 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
|
|||||||
environment.jersey().register(new ServerREST(httpGetter, config, applicationPropertiesService));
|
environment.jersey().register(new ServerREST(httpGetter, config, applicationPropertiesService));
|
||||||
environment.jersey().register(new UserREST(userDAO, userRoleDAO, userSettingsDAO, userService, encryptionService));
|
environment.jersey().register(new UserREST(userDAO, userRoleDAO, userSettingsDAO, userService, encryptionService));
|
||||||
|
|
||||||
|
// Servlets
|
||||||
NextUnreadServlet nextUnreadServlet = new NextUnreadServlet(feedSubscriptionDAO, feedEntryStatusDAO, feedCategoryDAO, userService,
|
NextUnreadServlet nextUnreadServlet = new NextUnreadServlet(feedSubscriptionDAO, feedEntryStatusDAO, feedCategoryDAO, userService,
|
||||||
config);
|
config);
|
||||||
|
LogoutServlet logoutServlet = new LogoutServlet(config);
|
||||||
environment.servlets().addServlet("next", nextUnreadServlet).addMapping("/next");
|
environment.servlets().addServlet("next", nextUnreadServlet).addMapping("/next");
|
||||||
|
environment.servlets().addServlet("logout", logoutServlet).addMapping("/logout");
|
||||||
|
|
||||||
|
// Managed objects
|
||||||
environment.lifecycle().manage(startupService);
|
environment.lifecycle().manage(startupService);
|
||||||
environment.lifecycle().manage(taskGiver);
|
environment.lifecycle().manage(taskGiver);
|
||||||
environment.lifecycle().manage(feedWorker);
|
environment.lifecycle().manage(feedWorker);
|
||||||
environment.lifecycle().manage(feedUpdater);
|
environment.lifecycle().manage(feedUpdater);
|
||||||
|
|
||||||
// TODO user registration
|
// TODO user login + registration page
|
||||||
// TODO user login page
|
|
||||||
// TODO cookie support ?
|
|
||||||
// TODO translations
|
// TODO translations
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.commafeed.backend.dao.UserSettingsDAO;
|
|||||||
import com.commafeed.backend.model.User;
|
import com.commafeed.backend.model.User;
|
||||||
import com.commafeed.backend.model.UserRole;
|
import com.commafeed.backend.model.UserRole;
|
||||||
import com.commafeed.backend.model.UserRole.Role;
|
import com.commafeed.backend.model.UserRole.Role;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@@ -30,7 +31,7 @@ public class UserService {
|
|||||||
private final PasswordEncryptionService encryptionService;
|
private final PasswordEncryptionService encryptionService;
|
||||||
private final CommaFeedConfiguration config;
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
public User login(String name, String password) {
|
public Optional<User> login(String name, String password) {
|
||||||
if (name == null || password == null) {
|
if (name == null || password == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -58,22 +59,22 @@ public class UserService {
|
|||||||
if (saveUser) {
|
if (saveUser) {
|
||||||
userDAO.saveOrUpdate(user);
|
userDAO.saveOrUpdate(user);
|
||||||
}
|
}
|
||||||
return user;
|
return Optional.fromNullable(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User login(String apiKey) {
|
public Optional<User> login(String apiKey) {
|
||||||
if (apiKey == null) {
|
if (apiKey == null) {
|
||||||
return null;
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
|
||||||
User user = userDAO.findByApiKey(apiKey);
|
User user = userDAO.findByApiKey(apiKey);
|
||||||
if (user != null && !user.isDisabled()) {
|
if (user != null && !user.isDisabled()) {
|
||||||
return user;
|
return Optional.fromNullable(user);
|
||||||
}
|
}
|
||||||
return null;
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User register(String name, String password, String email, Collection<Role> roles) {
|
public User register(String name, String password, String email, Collection<Role> roles) {
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
package com.commafeed.frontend.auth;
|
package com.commafeed.frontend.auth;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
import javax.ws.rs.WebApplicationException;
|
import javax.ws.rs.WebApplicationException;
|
||||||
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.HttpHeaders;
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.B64Code;
|
import org.eclipse.jetty.util.B64Code;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
|
||||||
|
import com.commafeed.CommaFeedApplication;
|
||||||
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;
|
||||||
import com.commafeed.backend.service.UserService;
|
import com.commafeed.backend.service.UserService;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.sun.jersey.api.core.HttpContext;
|
import com.sun.jersey.api.core.HttpContext;
|
||||||
import com.sun.jersey.api.model.Parameter;
|
import com.sun.jersey.api.model.Parameter;
|
||||||
import com.sun.jersey.core.spi.component.ComponentContext;
|
import com.sun.jersey.core.spi.component.ComponentContext;
|
||||||
@@ -20,66 +25,93 @@ import com.sun.jersey.core.spi.component.ComponentScope;
|
|||||||
import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
|
import com.sun.jersey.server.impl.inject.AbstractHttpContextInjectable;
|
||||||
import com.sun.jersey.spi.inject.Injectable;
|
import com.sun.jersey.spi.inject.Injectable;
|
||||||
import com.sun.jersey.spi.inject.InjectableProvider;
|
import com.sun.jersey.spi.inject.InjectableProvider;
|
||||||
|
import com.sun.jersey.spi.inject.SingletonTypeInjectableProvider;
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SecurityCheckProvider implements InjectableProvider<SecurityCheck, Parameter> {
|
public class SecurityCheckProvider implements InjectableProvider<SecurityCheck, Parameter> {
|
||||||
|
|
||||||
private static class SecurityCheckInjectable<T> extends AbstractHttpContextInjectable<User> {
|
public static class SecurityCheckUserServiceProvider extends SingletonTypeInjectableProvider<Context, UserService> {
|
||||||
private static final String PREFIX = "Basic";
|
|
||||||
|
|
||||||
private final UserService userService;
|
public SecurityCheckUserServiceProvider(UserService userService) {
|
||||||
private Role role;
|
super(UserService.class, userService);
|
||||||
private final boolean apiKeyAllowed;
|
|
||||||
|
|
||||||
private SecurityCheckInjectable(UserService userService, Role role, boolean apiKeyAllowed) {
|
|
||||||
this.userService = userService;
|
|
||||||
this.role = role;
|
|
||||||
this.apiKeyAllowed = apiKeyAllowed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public User getValue(HttpContext c) {
|
|
||||||
final String header = c.getRequest().getHeaderValue(HttpHeaders.AUTHORIZATION);
|
|
||||||
try {
|
|
||||||
if (header != null) {
|
|
||||||
final int space = header.indexOf(' ');
|
|
||||||
if (space > 0) {
|
|
||||||
final String method = header.substring(0, space);
|
|
||||||
if (PREFIX.equalsIgnoreCase(method)) {
|
|
||||||
final String decoded = B64Code.decode(header.substring(space + 1), StringUtil.__ISO_8859_1);
|
|
||||||
final int i = decoded.indexOf(':');
|
|
||||||
if (i > 0) {
|
|
||||||
final String username = decoded.substring(0, i);
|
|
||||||
final String password = decoded.substring(i + 1);
|
|
||||||
final User user = userService.login(username, password);
|
|
||||||
if (user != null && user.hasRole(role)) {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
String apiKey = c.getUriInfo().getPathParameters().getFirst("apiKey");
|
|
||||||
if (apiKey != null && apiKeyAllowed) {
|
|
||||||
User user = userService.login(apiKey);
|
|
||||||
if (user != null && user.hasRole(role)) {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
log.debug("Error decoding credentials", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
|
|
||||||
.header(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"CommaFeed\"")
|
|
||||||
.entity("Credentials are required to access this resource.").type(MediaType.TEXT_PLAIN_TYPE).build());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
private static class SecurityCheckInjectable<T> extends AbstractHttpContextInjectable<User> {
|
||||||
|
private static final String PREFIX = "Basic";
|
||||||
|
|
||||||
|
private final HttpServletRequest request;
|
||||||
|
private final UserService userService;
|
||||||
|
private final Role role;
|
||||||
|
private final boolean apiKeyAllowed;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public User getValue(HttpContext c) {
|
||||||
|
Optional<User> user = cookieSessionLogin();
|
||||||
|
if (!user.isPresent()) {
|
||||||
|
user = basicAuthenticationLogin(c);
|
||||||
|
}
|
||||||
|
if (!user.isPresent()) {
|
||||||
|
user = apiKeyLogin(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.isPresent()) {
|
||||||
|
return user.get();
|
||||||
|
} else {
|
||||||
|
throw new WebApplicationException(Response.status(Response.Status.UNAUTHORIZED)
|
||||||
|
.entity("Credentials are required to access this resource.").type(MediaType.TEXT_PLAIN_TYPE).build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<User> cookieSessionLogin() {
|
||||||
|
HttpSession session = request.getSession(false);
|
||||||
|
if (session != null) {
|
||||||
|
User user = (User) session.getAttribute(CommaFeedApplication.SESSION_USER);
|
||||||
|
return Optional.fromNullable(user);
|
||||||
|
}
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<User> basicAuthenticationLogin(HttpContext c) {
|
||||||
|
String header = c.getRequest().getHeaderValue(HttpHeaders.AUTHORIZATION);
|
||||||
|
if (header != null) {
|
||||||
|
int space = header.indexOf(' ');
|
||||||
|
if (space > 0) {
|
||||||
|
String method = header.substring(0, space);
|
||||||
|
if (PREFIX.equalsIgnoreCase(method)) {
|
||||||
|
String decoded = B64Code.decode(header.substring(space + 1), StringUtil.__ISO_8859_1);
|
||||||
|
int i = decoded.indexOf(':');
|
||||||
|
if (i > 0) {
|
||||||
|
String username = decoded.substring(0, i);
|
||||||
|
String password = decoded.substring(i + 1);
|
||||||
|
Optional<User> user = userService.login(username, password);
|
||||||
|
if (user.isPresent() && user.get().hasRole(role)) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<User> apiKeyLogin(HttpContext c) {
|
||||||
|
String apiKey = c.getUriInfo().getPathParameters().getFirst("apiKey");
|
||||||
|
if (apiKey != null && apiKeyAllowed) {
|
||||||
|
Optional<User> user = userService.login(apiKey);
|
||||||
|
if (user.isPresent() && user.get().hasRole(role)) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.absent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpServletRequest request;
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
|
||||||
public SecurityCheckProvider(UserService userService) {
|
public SecurityCheckProvider(@Context HttpServletRequest request, @Context UserService userService) {
|
||||||
|
this.request = request;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,6 +122,6 @@ public class SecurityCheckProvider implements InjectableProvider<SecurityCheck,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Injectable<?> getInjectable(ComponentContext ic, SecurityCheck sc, Parameter c) {
|
public Injectable<?> getInjectable(ComponentContext ic, SecurityCheck sc, Parameter c) {
|
||||||
return new SecurityCheckInjectable<>(userService, sc.value(), sc.apiKeyAllowed());
|
return new SecurityCheckInjectable<>(request, userService, sc.value(), sc.apiKeyAllowed());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.commafeed.frontend.model.request;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import com.wordnik.swagger.annotations.ApiModel;
|
||||||
|
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@Data
|
||||||
|
@ApiModel
|
||||||
|
public class LoginRequest implements Serializable {
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "username", required = true)
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "password", required = true)
|
||||||
|
private String password;
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.commafeed.frontend.resource;
|
package com.commafeed.frontend.resource;
|
||||||
|
|
||||||
import io.dropwizard.hibernate.UnitOfWork;
|
import io.dropwizard.hibernate.UnitOfWork;
|
||||||
|
import io.dropwizard.jersey.sessions.Session;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
@@ -33,8 +35,10 @@ import com.commafeed.backend.service.UserService;
|
|||||||
import com.commafeed.frontend.auth.SecurityCheck;
|
import com.commafeed.frontend.auth.SecurityCheck;
|
||||||
import com.commafeed.frontend.model.Settings;
|
import com.commafeed.frontend.model.Settings;
|
||||||
import com.commafeed.frontend.model.UserModel;
|
import com.commafeed.frontend.model.UserModel;
|
||||||
|
import com.commafeed.frontend.model.request.LoginRequest;
|
||||||
import com.commafeed.frontend.model.request.ProfileModificationRequest;
|
import com.commafeed.frontend.model.request.ProfileModificationRequest;
|
||||||
import com.commafeed.frontend.model.request.RegistrationRequest;
|
import com.commafeed.frontend.model.request.RegistrationRequest;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.wordnik.swagger.annotations.Api;
|
import com.wordnik.swagger.annotations.Api;
|
||||||
import com.wordnik.swagger.annotations.ApiOperation;
|
import com.wordnik.swagger.annotations.ApiOperation;
|
||||||
@@ -203,7 +207,20 @@ public class UserREST {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
|
return Response.status(Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Path("/login")
|
||||||
|
@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());
|
||||||
|
if (user.isPresent()) {
|
||||||
|
session.setAttribute(CommaFeedApplication.SESSION_USER, user);
|
||||||
|
return Response.ok().build();
|
||||||
|
} else {
|
||||||
|
return Response.status(Response.Status.UNAUTHORIZED).build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Path("/profile/deleteAccount")
|
@Path("/profile/deleteAccount")
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.commafeed.frontend.servlet;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import com.commafeed.CommaFeedConfiguration;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class LogoutServlet extends HttpServlet {
|
||||||
|
|
||||||
|
private final CommaFeedConfiguration config;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||||
|
req.getSession().invalidate();
|
||||||
|
resp.sendRedirect(resp.encodeRedirectURL(config.getApplicationSettings().getPublicUrl()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import com.commafeed.backend.model.User;
|
|||||||
import com.commafeed.backend.model.UserSettings.ReadingOrder;
|
import com.commafeed.backend.model.UserSettings.ReadingOrder;
|
||||||
import com.commafeed.backend.service.UserService;
|
import com.commafeed.backend.service.UserService;
|
||||||
import com.commafeed.frontend.resource.CategoryREST;
|
import com.commafeed.frontend.resource.CategoryREST;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@@ -51,8 +52,8 @@ public class NextUnreadServlet extends HttpServlet {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
User user = userService.login(apiKey);
|
Optional<User> user = userService.login(apiKey);
|
||||||
if (user == null) {
|
if (!user.isPresent()) {
|
||||||
resp.getWriter().write("unknown user or api key not found");
|
resp.getWriter().write("unknown user or api key not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -65,14 +66,15 @@ public class NextUnreadServlet extends HttpServlet {
|
|||||||
|
|
||||||
List<FeedEntryStatus> statuses = null;
|
List<FeedEntryStatus> statuses = null;
|
||||||
if (StringUtils.isBlank(categoryId) || CategoryREST.ALL.equals(categoryId)) {
|
if (StringUtils.isBlank(categoryId) || CategoryREST.ALL.equals(categoryId)) {
|
||||||
List<FeedSubscription> subs = feedSubscriptionDAO.findAll(user);
|
List<FeedSubscription> subs = feedSubscriptionDAO.findAll(user.get());
|
||||||
statuses = feedEntryStatusDAO.findBySubscriptions(user, subs, true, null, null, 0, 1, order, true, false, null);
|
statuses = feedEntryStatusDAO.findBySubscriptions(user.get(), subs, true, null, null, 0, 1, order, true, false, null);
|
||||||
} else {
|
} else {
|
||||||
FeedCategory category = feedCategoryDAO.findById(user, Long.valueOf(categoryId));
|
FeedCategory category = feedCategoryDAO.findById(user.get(), Long.valueOf(categoryId));
|
||||||
if (category != null) {
|
if (category != null) {
|
||||||
List<FeedCategory> children = feedCategoryDAO.findAllChildrenCategories(user, category);
|
List<FeedCategory> children = feedCategoryDAO.findAllChildrenCategories(user.get(), category);
|
||||||
List<FeedSubscription> subscriptions = feedSubscriptionDAO.findByCategories(user, children);
|
List<FeedSubscription> subscriptions = feedSubscriptionDAO.findByCategories(user.get(), children);
|
||||||
statuses = feedEntryStatusDAO.findBySubscriptions(user, subscriptions, true, null, null, 0, 1, order, true, false, null);
|
statuses = feedEntryStatusDAO.findBySubscriptions(user.get(), subscriptions, true, null, null, 0, 1, order, true, false,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user