diff --git a/src/main/java/jp/sf/fess/filter/AdLoginInfoFilter.java b/src/main/java/jp/sf/fess/filter/AdLoginInfoFilter.java new file mode 100644 index 000000000..1d4cf3584 --- /dev/null +++ b/src/main/java/jp/sf/fess/filter/AdLoginInfoFilter.java @@ -0,0 +1,115 @@ +package jp.sf.fess.filter; + +import java.io.IOException; +import java.util.HashSet; +import java.util.List; +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.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import jp.sf.fess.entity.LoginInfo; +import jp.sf.fess.helper.AdRoleHelper; +import jp.sf.fess.util.ComponentUtil; + +import org.codelibs.sastruts.core.SSCConstants; +import org.seasar.framework.util.StringUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdLoginInfoFilter implements Filter { + private static final Logger logger = LoggerFactory + .getLogger(AdLoginInfoFilter.class); + + private long updateInterval = 60 * 60 * 1000L; // 1h + + private boolean redirectLoginError; + + private boolean useTestUser; + + private String testUserName; + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + redirectLoginError = "true".equalsIgnoreCase(filterConfig + .getInitParameter("redirectLoginError")); + + final String value = filterConfig.getInitParameter("updateInterval"); + if (value != null) { + updateInterval = Long.parseLong(value); + } + + useTestUser = "true".equalsIgnoreCase(filterConfig + .getInitParameter("useTestUser")); + + testUserName = filterConfig.getInitParameter("testUserName"); + } + + @Override + public void doFilter(final ServletRequest request, + final ServletResponse response, final FilterChain chain) + throws IOException, ServletException { + if (request instanceof HttpServletRequest) { + final HttpServletRequest httpRequest = (HttpServletRequest) request; + final HttpSession session = httpRequest.getSession(); + + String userId = httpRequest.getRemoteUser(); + if (useTestUser) { + userId = testUserName; + } + + if (StringUtil.isEmpty(userId)) { + final String servletPath = ((HttpServletRequest) request) + .getServletPath(); + if (redirectLoginError + && ("/index.do".equals(servletPath) || "/mobile.do" + .equals(servletPath))) { + ((HttpServletResponse) response) + .sendRedirect("/n2search/error/badRequest"); + return; + } + } + + LoginInfo loginInfo = (LoginInfo) session + .getAttribute(SSCConstants.USER_INFO); + if (loginInfo == null) { + loginInfo = new LoginInfo(); + loginInfo.setUsername(userId); + updateRoleList(userId, loginInfo); + session.setAttribute(SSCConstants.USER_INFO, loginInfo); + } else { + final long now = System.currentTimeMillis(); + if (now - loginInfo.getUpdatedTime() > updateInterval) { + loginInfo.setUsername(userId); + updateRoleList(userId, loginInfo); + loginInfo.setUpdatedTime(now); + } + } + } + chain.doFilter(request, response); + } + + @Override + public void destroy() { + } + + private void updateRoleList(final String userId, final LoginInfo loginInfo) { + final AdRoleHelper adRoleHelper = ComponentUtil.getAdRoleHelper(); + final List roleList = adRoleHelper.getRoleList(userId); + final Set roleSet = new HashSet<>(); + for (final String role : roleList) { + roleSet.add(role); + } + loginInfo.setRoleSet(roleSet); + if (logger.isDebugEnabled()) { + logger.debug(loginInfo.toString()); + } + } +} diff --git a/src/main/java/jp/sf/fess/filter/AdminAuthFilter.java b/src/main/java/jp/sf/fess/filter/AdminAuthFilter.java new file mode 100644 index 000000000..f4f7a7654 --- /dev/null +++ b/src/main/java/jp/sf/fess/filter/AdminAuthFilter.java @@ -0,0 +1,24 @@ +package jp.sf.fess.filter; + +import javax.servlet.http.HttpServletRequest; + +import jp.sf.fess.entity.LoginInfo; + +import org.codelibs.sastruts.core.SSCConstants; +import org.codelibs.sastruts.core.entity.UserInfo; +import org.codelibs.sastruts.core.filter.AuthFilter; + +public class AdminAuthFilter extends AuthFilter { + @Override + protected UserInfo getUserInfo(final HttpServletRequest req) { + final Object obj = req.getSession() + .getAttribute(SSCConstants.USER_INFO); + if (obj instanceof LoginInfo) { + final LoginInfo loginInfo = (LoginInfo) obj; + if (loginInfo.isAdministrator()) { + return loginInfo; + } + } + return null; + } +} diff --git a/src/main/java/jp/sf/fess/helper/AdRoleHelper.java b/src/main/java/jp/sf/fess/helper/AdRoleHelper.java new file mode 100644 index 000000000..d50a82660 --- /dev/null +++ b/src/main/java/jp/sf/fess/helper/AdRoleHelper.java @@ -0,0 +1,92 @@ +package jp.sf.fess.helper; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import javax.naming.directory.SearchControls; +import javax.naming.directory.SearchResult; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class AdRoleHelper { + private static final Logger logger = LoggerFactory + .getLogger(AdRoleHelper.class); + + public String domain; + + public Properties adProperties; + + public void setAdProperties(final Properties adProperties) { + this.adProperties = adProperties; + } + + public List getRoleList(final String userId) { + final List rolelist = new ArrayList(); + + DirContext ctx = null; + try { + ctx = new InitialDirContext(adProperties); + + //set search conditions + final String filter = "cn=" + userId; + final SearchControls controls = new SearchControls(); + controls.setSearchScope(SearchControls.SUBTREE_SCOPE); + + String name = domain; + name = "dc=" + name; + name = name.replace(".", ",dc="); + + //search + final NamingEnumeration rslt = ctx.search(name, + filter, controls); + while (rslt.hasMoreElements()) { + final SearchResult srcrslt = rslt.next(); + final Attributes attrs = srcrslt.getAttributes(); + + //get group attr + final Attribute attr = attrs.get("memberOf"); + if (attr == null) { + continue; + } + + for (int i = 0; i < attr.size(); i++) { + String strTmp = (String) attr.get(i); + + int strStart = 0; + int strEnd = 0; + + strStart = strTmp.indexOf("CN="); + strStart += "CN=".length(); + strEnd = strTmp.indexOf(','); + + strTmp = strTmp.substring(strStart, strEnd); + + rolelist.add(strTmp); + } + } + + } catch (final Exception e) { + logger.warn("Failed to resolve roles: " + userId, e); + } finally { + if (ctx != null) { + try { + ctx.close(); + } catch (final NamingException e) { + // ignored + logger.warn("Failed to close: " + userId, e); + } + } + } + + logger.debug("ADGroup:" + rolelist.toString()); + return rolelist; + } +} diff --git a/src/main/java/jp/sf/fess/util/ComponentUtil.java b/src/main/java/jp/sf/fess/util/ComponentUtil.java index 1e7e58ba8..6af43d282 100644 --- a/src/main/java/jp/sf/fess/util/ComponentUtil.java +++ b/src/main/java/jp/sf/fess/util/ComponentUtil.java @@ -18,6 +18,7 @@ package jp.sf.fess.util; import jp.sf.fess.api.WebApiManagerFactory; import jp.sf.fess.ds.DataStoreFactory; +import jp.sf.fess.helper.AdRoleHelper; import jp.sf.fess.helper.CrawlingConfigHelper; import jp.sf.fess.helper.CrawlingSessionHelper; import jp.sf.fess.helper.DatabaseHelper; @@ -92,6 +93,8 @@ public final class ComponentUtil { private static final String SYSTEM_HELPER = "systemHelper"; + private static final String AD_ROLE_HELPER = "adRoleHelper"; + private static final String SOLR_GROUP_MANAGER = "solrGroupManager"; private static final String CRAWLER_PROPERTIES = "crawlerProperties"; @@ -214,6 +217,10 @@ public final class ComponentUtil { return SingletonS2Container.getComponent(DATABASE_HELPER); } + public static AdRoleHelper getAdRoleHelper() { + return SingletonS2Container.getComponent(AD_ROLE_HELPER); + } + public static IndexUpdater getIndexUpdater() { return SingletonS2Container.getComponent(INDEX_UPDATER); } diff --git a/src/main/resources/app.dicon b/src/main/resources/app.dicon index cbfafc251..a0a780e7a 100644 --- a/src/main/resources/app.dicon +++ b/src/main/resources/app.dicon @@ -249,4 +249,46 @@ "Mozilla/5.0 (compatible; Fess/" + @jp.sf.fess.Constants@FESS_VERSION + "; +http://fess.codelibs.org/bot.html)" + + + + @javax.naming.Context@INITIAL_CONTEXT_FACTORY + "com.sun.jndi.ldap.LdapCtxFactory" + + + @javax.naming.directory.DirContext@PROVIDER_URL + "ldap://[host]:[port]" + + + @javax.naming.directory.DirContext@SECURITY_PRINCIPAL + "[loginId]@[domain]" + + + @javax.naming.directory.DirContext@SECURITY_CREDENTIALS + "password" + + + "com.sun.jndi.ldap.connect.timeout" + "10000" + + + "com.sun.jndi.ldap.connect.pool" + "true" + + + "com.sun.jndi.connect.pool.timeout" + "30000" + + + "com.sun.jndi.connect.pool.debug" + "all" + + + + + + adProperties + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index 34a054f73..7bb9ef974 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -60,7 +60,7 @@ authenticationFilter - org.codelibs.sastruts.core.filter.AuthFilter + jp.sf.fess.filter.AdminAuthFilter urlPatterns /fess/admin.* @@ -89,6 +89,89 @@ + + + + + + + action org.codelibs.sastruts.core.servlet.SSCActionServlet