Shinsuke Sugaya 7 лет назад
Родитель
Сommit
e17850568b

+ 2 - 0
src/main/java/org/codelibs/fess/Constants.java

@@ -380,6 +380,8 @@ public class Constants extends CoreLibConstants {
 
     public static final String LDAP_ACCOUNT_FILTER = "ldap.account.filter";
 
+    public static final String LDAP_GROUP_FILTER = "ldap.group.filter";
+
     public static final String LDAP_MEMBEROF_ATTRIBUTE = "ldap.memberof.attribute";
 
     public static final String NOTIFICATION_LOGIN = "notification.login";

+ 2 - 0
src/main/java/org/codelibs/fess/app/web/admin/general/AdminGeneralAction.java

@@ -160,6 +160,7 @@ public class AdminGeneralAction extends FessAdminAction {
         }
         fessConfig.setLdapBaseDn(form.ldapBaseDn);
         fessConfig.setLdapAccountFilter(form.ldapAccountFilter);
+        fessConfig.setLdapGroupFilter(form.ldapGroupFilter);
         fessConfig.setLdapMemberofAttribute(form.ldapMemberofAttribute);
         fessConfig.setNotificationLogin(form.notificationLogin);
         fessConfig.setNotificationSearchTop(form.notificationSearchTop);
@@ -204,6 +205,7 @@ public class AdminGeneralAction extends FessAdminAction {
                 StringUtil.isNotBlank(fessConfig.getLdapAdminSecurityCredentials()) ? DUMMY_PASSWORD : StringUtil.EMPTY;
         form.ldapBaseDn = fessConfig.getLdapBaseDn();
         form.ldapAccountFilter = fessConfig.getLdapAccountFilter();
+        form.ldapGroupFilter = fessConfig.getLdapGroupFilter();
         form.ldapMemberofAttribute = fessConfig.getLdapMemberofAttribute();
         form.notificationLogin = fessConfig.getNotificationLogin();
         form.notificationSearchTop = fessConfig.getNotificationSearchTop();

+ 3 - 0
src/main/java/org/codelibs/fess/app/web/admin/general/EditForm.java

@@ -145,6 +145,9 @@ public class EditForm {
     @Size(max = 1000)
     public String ldapAccountFilter;
 
+    @Size(max = 1000)
+    public String ldapGroupFilter;
+
     @Size(max = 100)
     public String ldapMemberofAttribute;
 

+ 58 - 18
src/main/java/org/codelibs/fess/ldap/LdapManager.java

@@ -20,9 +20,11 @@ import static org.codelibs.core.stream.StreamUtil.stream;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Locale;
+import java.util.Set;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
@@ -169,40 +171,81 @@ public class LdapManager {
         return new LdapUser(env, username);
     }
 
-    public String[] getRoles(final LdapUser ldapUser, final String bindDn, final String accountFilter) {
+    public String[] getRoles(final LdapUser ldapUser, final String bindDn, final String accountFilter, final String groupFilter) {
         final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
-        final List<String> roleList = new ArrayList<>();
+        final Set<String> roleSet = new HashSet<>();
 
         if (fessConfig.isLdapRoleSearchUserEnabled()) {
-            roleList.add(systemHelper.getSearchRoleByUser(ldapUser.getName()));
+            roleSet.add(systemHelper.getSearchRoleByUser(ldapUser.getName()));
         }
 
         // LDAP: cn=%s
         // AD: (&(objectClass=user)(sAMAccountName=%s))
         final String filter = String.format(accountFilter, ldapUser.getName());
         if (logger.isDebugEnabled()) {
-            logger.debug("filter: " + filter);
+            logger.debug("Account Filter: " + filter);
         }
         search(bindDn, filter, new String[] { fessConfig.getLdapMemberofAttribute() }, () -> ldapUser.getEnvironment(), result -> {
-            processSearchRoles(result, (entryDn, name) -> {
-                final boolean isRole = entryDn.toLowerCase(Locale.ROOT).indexOf("ou=role") != -1;
-                if (isRole) {
-                    if (fessConfig.isLdapRoleSearchRoleEnabled()) {
-                        roleList.add(systemHelper.getSearchRoleByRole(name));
-                    }
-                } else if (fessConfig.isLdapRoleSearchGroupEnabled()) {
-                    roleList.add(systemHelper.getSearchRoleByGroup(name));
+            processSearchRoles(result, entryDn -> {
+                updateSearchRoles(roleSet, entryDn);
+
+                if (StringUtil.isNotBlank(groupFilter)) {
+                    processSubRoles(ldapUser, bindDn, entryDn, groupFilter, roleSet);
                 }
             });
         });
 
         if (logger.isDebugEnabled()) {
-            logger.debug("roleList: " + roleList);
+            logger.debug("role: " + roleSet);
+        }
+        return roleSet.toArray(new String[roleSet.size()]);
+    }
+
+    protected void processSubRoles(final LdapUser ldapUser, final String bindDn, final String dn, final String groupFilter,
+            final Set<String> roleSet) {
+        // (member:1.2.840.113556.1.4.1941:=%s)
+        final String filter = String.format(groupFilter, dn);
+        if (logger.isDebugEnabled()) {
+            logger.debug("Group Filter: " + filter);
+        }
+        search(bindDn, filter, null, () -> ldapUser.getEnvironment(), result -> {
+            for (final SearchResult srcrslt : result) {
+                String groupDn = srcrslt.getNameInNamespace();
+                if (logger.isDebugEnabled()) {
+                    logger.debug("groupDn: " + groupDn);
+                }
+                updateSearchRoles(roleSet, groupDn);
+            }
+        });
+    }
+
+    protected void updateSearchRoles(final Set<String> roleSet, String entryDn) {
+        final String name = getSearchRoleName(entryDn);
+        if (StringUtil.isBlank(name)) {
+            return;
+        }
+
+        final SystemHelper systemHelper = ComponentUtil.getSystemHelper();
+        final boolean isRole = entryDn.toLowerCase(Locale.ROOT).indexOf("ou=role") != -1;
+        if (isRole) {
+            if (fessConfig.isLdapRoleSearchRoleEnabled()) {
+                roleSet.add(systemHelper.getSearchRoleByRole(name));
+            }
+        } else if (fessConfig.isLdapRoleSearchGroupEnabled()) {
+            roleSet.add(systemHelper.getSearchRoleByGroup(name));
         }
-        return roleList.toArray(new String[roleList.size()]);
     }
 
     protected void processSearchRoles(final List<SearchResult> result, final BiConsumer<String, String> consumer) throws NamingException {
+        processSearchRoles(result, entryDn -> {
+            final String name = getSearchRoleName(entryDn);
+            if (name != null) {
+                consumer.accept(entryDn, name);
+            }
+        });
+    }
+
+    protected void processSearchRoles(final List<SearchResult> result, final Consumer<String> consumer) throws NamingException {
         for (final SearchResult srcrslt : result) {
             final Attributes attrs = srcrslt.getAttributes();
 
@@ -220,10 +263,7 @@ public class LdapManager {
                     if (logger.isDebugEnabled()) {
                         logger.debug("entryDn: " + entryDn);
                     }
-                    final String name = getSearchRoleName(entryDn);
-                    if (name != null) {
-                        consumer.accept(entryDn, name);
-                    }
+                    consumer.accept(entryDn);
                 }
             }
         }

+ 4 - 3
src/main/java/org/codelibs/fess/ldap/LdapUser.java

@@ -49,11 +49,12 @@ public class LdapUser implements FessUser {
     public String[] getPermissions() {
         if (permissions == null) {
             final FessConfig fessConfig = ComponentUtil.getFessConfig();
-            final String baseDn = ComponentUtil.getFessConfig().getLdapBaseDn();
-            final String accountFilter = ComponentUtil.getFessConfig().getLdapAccountFilter();
+            final String baseDn = fessConfig.getLdapBaseDn();
+            final String accountFilter = fessConfig.getLdapAccountFilter();
+            final String groupFilter = fessConfig.getLdapGroupFilter();
             if (StringUtil.isNotBlank(baseDn) && StringUtil.isNotBlank(accountFilter)) {
                 permissions =
-                        ArrayUtils.addAll(ComponentUtil.getLdapManager().getRoles(this, baseDn, accountFilter),
+                        ArrayUtils.addAll(ComponentUtil.getLdapManager().getRoles(this, baseDn, accountFilter, groupFilter),
                                 fessConfig.getRoleSearchUserPrefix() + getName());
             } else {
                 permissions = StringUtil.EMPTY_STRINGS;

+ 8 - 0
src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java

@@ -603,6 +603,14 @@ public interface FessProp {
         return getSystemProperty(Constants.LDAP_ACCOUNT_FILTER);
     }
 
+    public default void setLdapGroupFilter(final String value) {
+        setSystemProperty(Constants.LDAP_GROUP_FILTER, value);
+    }
+
+    public default String getLdapGroupFilter() {
+        return getSystemProperty(Constants.LDAP_GROUP_FILTER, StringUtil.EMPTY);
+    }
+
     public default void setNotificationLogin(final String value) {
         setSystemProperty(Constants.NOTIFICATION_LOGIN, value);
     }

+ 2 - 0
src/main/resources/fess_label.properties

@@ -141,6 +141,7 @@ labels.ldapAdminSecurityPrincipal=Bind DN
 labels.ldapAdminSecurityCredentials=Password
 labels.ldapBaseDn=Base DN
 labels.ldapAccountFilter=Account Filter
+labels.ldapGroupFilter=Group Filter
 labels.ldapMemberofAttribute=memberOf Attribute
 labels.oldPassword=Current Password
 labels.newPassword=New Password
@@ -786,6 +787,7 @@ labels.ldap_admin_security_principal=Bind DN
 labels.ldap_admin_security_credentials=Password
 labels.ldap_base_dn=Base DN
 labels.ldap_account_filter=Account Filter
+labels.ldap_group_filter=Group Filter
 labels.ldap_memberof_attribute=memberOf Attribute
 labels.notification_login=Login page
 labels.notification_search_top=Search top page

+ 2 - 0
src/main/resources/fess_label_en.properties

@@ -141,6 +141,7 @@ labels.ldapAdminSecurityPrincipal=Bind DN
 labels.ldapAdminSecurityCredentials=Password
 labels.ldapBaseDn=Base DN
 labels.ldapAccountFilter=Account Filter
+labels.ldapGroupFilter=Group Filter
 labels.ldapMemberofAttribute=memberOf Attribute
 labels.oldPassword=Current Password
 labels.newPassword=New Password
@@ -786,6 +787,7 @@ labels.ldap_admin_security_principal=Bind DN
 labels.ldap_admin_security_credentials=Password
 labels.ldap_base_dn=Base DN
 labels.ldap_account_filter=Account Filter
+labels.ldap_group_filter=Group Filter
 labels.ldap_memberof_attribute=memberOf Attribute
 labels.notification_login=Login page
 labels.notification_search_top=Search top page

+ 2 - 0
src/main/resources/fess_label_ja.properties

@@ -786,8 +786,10 @@ labels.ldap_admin_security_principal=Bind DN
 labels.ldap_admin_security_credentials=パスワード
 labels.ldap_base_dn=Base DN
 labels.ldapAccountFilter=アカウントフィルタ
+labels.ldapGroupFilter=グループフィルタ
 labels.ldapMemberofAttribute=memberOf属性
 labels.ldap_account_filter=アカウントフィルタ
+labels.ldap_group_filter=グループフィルタ
 labels.ldap_memberof_attribute=memberOf属性
 labels.notification_login=ログインページ
 labels.notification_search_top=検索トップページ

+ 10 - 0
src/main/webapp/WEB-INF/view/admin/general/admin_general.jsp

@@ -403,6 +403,16 @@
 												styleClass="form-control" autocomplete="off" />
 										</div>
 									</div>
+									<div class="form-group">
+										<label for="ldapGroupFilter"
+											class="col-sm-3 control-label"><la:message
+												key="labels.ldap_group_filter" /></label>
+										<div class="col-sm-9">
+											<la:errors property="ldapGroupFilter" />
+											<la:text styleId="ldapGroupFilter" property="ldapGroupFilter"
+												styleClass="form-control" autocomplete="off" />
+										</div>
+									</div>
 									<div class="form-group">
 										<label for="ldapMemberofAttribute"
 											class="col-sm-3 control-label"><la:message