1
0
mirror of https://github.com/sismics/docs.git synced 2025-12-21 05:31:42 +00:00

Initial commit

This commit is contained in:
jendib
2013-07-27 18:33:20 +02:00
parent 41cb6dd9ae
commit 9b74bd8194
156 changed files with 72879 additions and 0 deletions

View File

@@ -0,0 +1,151 @@
package com.sismics.util.filter;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Locale;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sismics.docs.core.constant.Constants;
import com.sismics.docs.core.model.context.AppContext;
import com.sismics.docs.core.util.DirectoryUtil;
import com.sismics.docs.core.util.TransactionUtil;
import com.sismics.util.EnvironmentUtil;
import com.sismics.util.context.ThreadLocalContext;
import com.sismics.util.jpa.EMF;
/**
* Filter used to process a couple things in the request context.
*
* @author jtremeaux
*/
public class RequestContextFilter implements Filter {
/**
* Logger.
*/
private static final Logger log = LoggerFactory.getLogger(RequestContextFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Force the locale in order to not depend on the execution environment
Locale.setDefault(new Locale(Constants.DEFAULT_LOCALE_ID));
// Injects the webapp root
String webappRoot = filterConfig.getServletContext().getRealPath("/");
EnvironmentUtil.setWebappRoot(webappRoot);
// Initialize the app directory
File baseDataDirectory = null;
try {
baseDataDirectory = DirectoryUtil.getBaseDataDirectory();
} catch (Exception e) {
log.error("Error initializing base data directory", e);
}
if (log.isInfoEnabled()) {
log.info(MessageFormat.format("Using base data directory: {0}", baseDataDirectory.toString()));
}
// Initialize file logger
RollingFileAppender fileAppender = new RollingFileAppender();
fileAppender.setName("FILE");
fileAppender.setFile(DirectoryUtil.getLogDirectory() + File.separator + "docs.log");
fileAppender.setLayout(new PatternLayout("%d{DATE} %p %l %m %n"));
fileAppender.setThreshold(Level.INFO);
fileAppender.setAppend(true);
fileAppender.setMaxFileSize("5MB");
fileAppender.setMaxBackupIndex(5);
fileAppender.activateOptions();
org.apache.log4j.Logger.getRootLogger().addAppender(fileAppender);
// Initialize the application context
TransactionUtil.handle(new Runnable() {
@Override
public void run() {
AppContext.getInstance();
}
});
}
@Override
public void destroy() {
// NOP
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
EntityManager em = null;
try {
em = EMF.get().createEntityManager();
} catch (Exception e) {
throw new ServletException("Cannot create entity manager", e);
}
ThreadLocalContext context = ThreadLocalContext.get();
context.setEntityManager(em);
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
filterChain.doFilter(request, response);
} catch (Exception e) {
ThreadLocalContext.cleanup();
log.error("An exception occured, rolling back current transaction", e);
// If an unprocessed error comes up from the application layers (Jersey...), rollback the transaction (should not happen)
if (em.isOpen()) {
if (em.getTransaction() != null && em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
try {
em.close();
} catch (Exception ce) {
log.error("Error closing entity manager", ce);
}
}
throw new ServletException(e);
}
ThreadLocalContext.cleanup();
// No error processing the request : commit / rollback the current transaction depending on the HTTP code
if (em.isOpen()) {
if (em.getTransaction() != null && em.getTransaction().isActive()) {
HttpServletResponse r = (HttpServletResponse) response;
int statusClass = r.getStatus() / 100;
if (statusClass == 2 || statusClass == 3) {
try {
em.getTransaction().commit();
} catch (Exception e) {
log.error("Error during commit", e);
r.sendError(500);
}
} else {
em.getTransaction().rollback();
}
try {
em.close();
} catch (Exception e) {
log.error("Error closing entity manager", e);
}
}
}
}
}

View File

@@ -0,0 +1,180 @@
package com.sismics.util.filter;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTimeZone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sismics.docs.core.constant.Constants;
import com.sismics.docs.core.dao.jpa.AuthenticationTokenDao;
import com.sismics.docs.core.dao.jpa.RoleBaseFunctionDao;
import com.sismics.docs.core.dao.jpa.UserDao;
import com.sismics.docs.core.model.jpa.AuthenticationToken;
import com.sismics.docs.core.model.jpa.User;
import com.sismics.security.AnonymousPrincipal;
import com.sismics.security.UserPrincipal;
import com.sismics.util.LocaleUtil;
/**
* This filter is used to authenticate the user having an active session via an authentication token stored in database.
* The filter extracts the authentication token stored in a cookie.
* If the ocokie exists and the token is valid, the filter injects a UserPrincipal into a request attribute.
* If not, the user is anonymous, and the filter injects a AnonymousPrincipal into the request attribute.
*
* @author jtremeaux
*/
public class TokenBasedSecurityFilter implements Filter {
/**
* Logger.
*/
private static final Logger log = LoggerFactory.getLogger(TokenBasedSecurityFilter.class);
/**
* Name of the cookie used to store the authentication token.
*/
public static final String COOKIE_NAME = "auth_token";
/**
* Name of the attribute containing the principal.
*/
public static final String PRINCIPAL_ATTRIBUTE = "principal";
/**
* Lifetime of the authentication token in seconds, since login.
*/
public static final int TOKEN_LONG_LIFETIME = 3600 * 24 * 365 * 20;
/**
* Lifetime of the authentication token in seconds, since last connection.
*/
public static final int TOKEN_SESSION_LIFETIME = 3600 * 24;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// NOP
}
@Override
public void destroy() {
// NOP
}
@Override
public void doFilter(ServletRequest req, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
// Get the value of the client authentication token
HttpServletRequest request = (HttpServletRequest) req;
String authToken = null;
if (request.getCookies() != null) {
for (Cookie cookie : request.getCookies()) {
if (COOKIE_NAME.equals(cookie.getName())) {
authToken = cookie.getValue();
}
}
}
// Get the corresponding server token
AuthenticationTokenDao authenticationTokenDao = new AuthenticationTokenDao();
AuthenticationToken authenticationToken = null;
if (authToken != null) {
authenticationToken = authenticationTokenDao.get(authToken);
}
if (authenticationToken == null) {
injectAnonymousUser(request);
} else {
// Check if the token is still valid
if (isTokenExpired(authenticationToken)) {
try {
injectAnonymousUser(request);
// Destroy the expired token
authenticationTokenDao.delete(authToken);
} catch (Exception e) {
if (log.isErrorEnabled()) {
log.error(MessageFormat.format("Error deleting authentication token {0} ", authToken), e);
}
}
} else {
// Check if the user is still valid
UserDao userDao = new UserDao();
User user = userDao.getById(authenticationToken.getUserId());
if (user != null && user.getDeleteDate() == null) {
injectAuthenticatedUser(request, user);
// Update the last connection date
authenticationTokenDao.updateLastConnectionDate(authenticationToken.getId());
} else {
injectAnonymousUser(request);
}
}
}
filterChain.doFilter(request, response);
}
/**
* Returns true if the token is expired.
*
* @param authenticationToken Authentication token
* @return Token expired
*/
private boolean isTokenExpired(AuthenticationToken authenticationToken) {
final long now = new Date().getTime();
final long creationDate = authenticationToken.getCreationDate().getTime();
if (authenticationToken.isLongLasted()) {
return now >= creationDate + ((long) TOKEN_LONG_LIFETIME) * 1000L;
} else {
long date = authenticationToken.getLastConnectionDate() != null ?
authenticationToken.getLastConnectionDate().getTime() : creationDate;
return now >= date + ((long) TOKEN_SESSION_LIFETIME) * 1000L;
}
}
/**
* Inject an authenticated user into the request attributes.
*
* @param request HTTP request
* @param user User to inject
*/
private void injectAuthenticatedUser(HttpServletRequest request, User user) {
UserPrincipal userPrincipal = new UserPrincipal(user.getId(), user.getUsername());
// Add locale
Locale locale = LocaleUtil.getLocale(user.getLocaleId());
userPrincipal.setLocale(locale);
// Add base functions
RoleBaseFunctionDao userBaseFuction = new RoleBaseFunctionDao();
Set<String> baseFunctionSet = userBaseFuction.findByRoleId(user.getRoleId());
userPrincipal.setBaseFunctionSet(baseFunctionSet);
request.setAttribute(PRINCIPAL_ATTRIBUTE, userPrincipal);
}
/**
* Inject an anonymous user into the request attributes.
*
* @param request HTTP request
*/
private void injectAnonymousUser(HttpServletRequest request) {
AnonymousPrincipal anonymousPrincipal = new AnonymousPrincipal();
anonymousPrincipal.setLocale(request.getLocale());
anonymousPrincipal.setDateTimeZone(DateTimeZone.forID(Constants.DEFAULT_TIMEZONE_ID));
request.setAttribute(PRINCIPAL_ATTRIBUTE, anonymousPrincipal);
}
}