package pl.net.bluesoft.rnd.processtool.plugins; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.model.Role; import com.liferay.portal.model.User; import com.liferay.portal.service.UserLocalServiceUtil; import com.liferay.portal.util.PortalUtil; import pl.net.bluesoft.rnd.pt.utils.lang.Lang2; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * <p> * This servlet authorizes user by screen name using Liferay API. Of course no SSO (CAS for example) is available * at this moment. Still, if such need arises, SSO could also be implemented. * </p> * We use basic authentication, therefore use of SSL is required in production environment. */ public class PermissionFilter implements Filter { private static final Logger logger = Logger.getLogger(PermissionFilter.class.getName()); public static final String AUTHORIZED = "Aperte_Authorized"; private static final Collection<String> ROLE_NAMES = Arrays.asList("ADMINISTRATOR", "MODELER_USER"); @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = Lang2.assumeType(request, HttpServletRequest.class); HttpServletResponse res = Lang2.assumeType(response, HttpServletResponse.class); HttpSession session = req.getSession(); if (session.getAttribute(AUTHORIZED) != null) { chain.doFilter(request, response); return; } try { //check for user session User userByScreenName = null; //try to authorize user using Liferay API long basicAuthUserId = PortalUtil.getBasicAuthUserId(req); if (basicAuthUserId != 0) userByScreenName = UserLocalServiceUtil.getUserById(basicAuthUserId); if (userByScreenName != null) { String username = userByScreenName.getScreenName(); logger.info("Successfully authorized user: " + username); List<Role> roles = userByScreenName.getRoles(); boolean found = false; for (Role role : roles) { if (!role.isTeam() && ROLE_NAMES.contains(role.getName().toUpperCase())) { found = true; logger.info("Matched role " + role.getName() + " for user " + username); break; } } if (!found) { logger.info("User " + username + " has insufficient privileges."); } else { session.setAttribute(AUTHORIZED, username); chain.doFilter(request, response); return; } } else { logger.warning("Failed to authorize user"); } } catch (PortalException e) { logger.log(Level.SEVERE, e.getMessage(), e); throw new ServletException(e); } catch (SystemException e) { logger.log(Level.SEVERE, e.getMessage(), e); throw new ServletException(e); } //if we are here, then authentication has failed or no username/password has been supplied res.setHeader("WWW-Authenticate", "Basic realm=\"Aperte Modeler\""); res.setStatus(401); } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }