DaanHoogland commented on a change in pull request #3694: Ldap fixes
URL: https://github.com/apache/cloudstack/pull/3694#discussion_r360403041
 
 

 ##########
 File path: 
plugins/user-authenticators/ldap/src/main/java/org/apache/cloudstack/api/command/LdapListUsersCmd.java
 ##########
 @@ -104,20 +241,251 @@ public long getEntityOwnerId() {
         return Account.ACCOUNT_ID_SYSTEM;
     }
 
-    private String getListType() {
+    String getListTypeString() {
         return listType == null ? "all" : listType;
     }
 
-    private boolean isACloudstackUser(final LdapUser ldapUser) {
-        final ListResponse<UserResponse> response = 
_queryService.searchForUsers(new ListUsersCmd());
-        final List<UserResponse> cloudstackUsers = response.getResponses();
+    String getUserFilterString() {
+        return userFilter == null ? getListTypeString() == null ? "NoFilter" : 
getListTypeString().equals("all") ? "NoFilter" : "AnyDomain" : userFilter;
+    }
+
+    UserFilter getUserFilter() {
+        return UserFilter.fromString(getUserFilterString());
+    }
+
+    boolean isACloudstackUser(final LdapUser ldapUser) {
+        boolean rc = false;
+        final List<UserResponse> cloudstackUsers = getCloudstackUsers();
+        if (cloudstackUsers != null) {
+            for (final UserResponse cloudstackUser : cloudstackUsers) {
+                if 
(ldapUser.getUsername().equals(cloudstackUser.getUsername())) {
+                    if(s_logger.isTraceEnabled()) {
+                        s_logger.trace(String.format("found user %s in 
cloudstack", ldapUser.getUsername()));
+                    }
+
+                    rc = true;
+                } else {
+                    if(s_logger.isTraceEnabled()) {
+                        s_logger.trace(String.format("ldap user %s does not 
match cloudstack user", ldapUser.getUsername(), cloudstackUser.getUsername()));
+                    }
+                }
+            }
+        }
+        return rc;
+    }
+
+    boolean isACloudstackUser(final LdapUserResponse ldapUser) {
+        if(s_logger.isTraceEnabled()) {
+            s_logger.trace("checking response : " + ldapUser.toString());
+        }
+        final List<UserResponse> cloudstackUsers = getCloudstackUsers();
         if (cloudstackUsers != null && cloudstackUsers.size() != 0) {
-            for (final UserResponse cloudstackUser : response.getResponses()) {
+            for (final UserResponse cloudstackUser : cloudstackUsers) {
                 if 
(ldapUser.getUsername().equals(cloudstackUser.getUsername())) {
+                    if(s_logger.isTraceEnabled()) {
+                        s_logger.trace(String.format("found user %s in 
cloudstack", ldapUser.getUsername()));
+                    }
                     return true;
+                } else {
+                    if(s_logger.isTraceEnabled()) {
+                        s_logger.trace(String.format("ldap user %s does not 
match cloudstack user", ldapUser.getUsername(), cloudstackUser.getUsername()));
+                    }
                 }
             }
         }
         return false;
     }
+    /**
+     * typecheck for userfilter values
+     */
+    enum UserFilter {
+        NO_FILTER("NoFilter"),
+        LOCAL_DOMAIN("LocalDomain"),
+        ANY_DOMAIN("AnyDomain"),
+        POTENTIAL_IMPORT("PotentialImport");
+
+        private final String value;
+
+        UserFilter(String val) {
+            this.value = val;
+        }
+
+        static UserFilter fromString(String val) {
+            if(NO_FILTER.toString().equalsIgnoreCase(val)) {
+                return NO_FILTER;
+            } else if (LOCAL_DOMAIN.toString().equalsIgnoreCase(val)) {
+                return LOCAL_DOMAIN;
+            } else if(ANY_DOMAIN.toString().equalsIgnoreCase(val)) {
+                return ANY_DOMAIN;
+            } else if(POTENTIAL_IMPORT.toString().equalsIgnoreCase(val)) {
+                return POTENTIAL_IMPORT;
+            } else {
+                throw new IllegalArgumentException(String.format("%s is not a 
legal 'UserFilter' value", val));
+            }
+        }
+
+        @Override public String toString() {
+            return value;
+        }
+    }
+
+    /**
+     * no filtering but improve with annotation of source for existing ACS 
users
+     * @param input ldap response list of users
+     * @return unfiltered list of the input list of ldap users
+     */
+    public List<LdapUserResponse> filterNoFilter(List<LdapUserResponse> input) 
{
+        if(s_logger.isTraceEnabled()) {
+            s_logger.trace("returning unfiltered list of ldap users");
+        }
+        annotateUserListWithSources(input);
+        return input;
+    }
+
+    /**
+     * filter the list of ldap users. no users visible to the caller should be 
in the returned list
+     * @param input ldap response list of users
+     * @return a list of ldap users not already in ACS
+     */
+    public List<LdapUserResponse> filterAnyDomain(List<LdapUserResponse> 
input) {
+        if(s_logger.isTraceEnabled()) {
+            s_logger.trace("filtering existing users");
+        }
+        final List<LdapUserResponse> ldapResponses = new 
ArrayList<LdapUserResponse>();
+        for (final LdapUserResponse user : input) {
+
+            if (isNotAlreadyImportedInTheCurrentDomain(user)) {
+                ldapResponses.add(user);
+            }
+        }
+        annotateUserListWithSources(ldapResponses);
+
+        return ldapResponses;
+    }
+
+    private boolean isNotAlreadyImportedInTheCurrentDomain(LdapUserResponse 
user) {
+        UserResponse cloudstackUser = getCloudstackUser(user);
+        String domainId = getCurrentDomainId();
+
+        return cloudstackUser == null /*doesn't exist in cloudstack*/
+                || ! (
+                        
cloudstackUser.getUserSource().equalsIgnoreCase(User.Source.LDAP.toString())
+                                && 
domainId.equals(cloudstackUser.getDomainId())); /* is from another source */
+    }
+
+    /**
+     * filter the list of ldap users. no users visible to the caller already 
in the domain specified should be in the returned list
+     * @param input ldap response list of users
+     * @return a list of ldap users not already in ACS
+     */
+    public List<LdapUserResponse> filterLocalDomain(List<LdapUserResponse> 
input) {
+        if(s_logger.isTraceEnabled()) {
+            s_logger.trace("filtering local domain users");
+        }
+        final List<LdapUserResponse> ldapResponses = new 
ArrayList<LdapUserResponse>();
+        String domainId = getCurrentDomainId();
+        for (final LdapUserResponse user : input) {
+            UserResponse cloudstackUser = getCloudstackUser(user);
+            if (cloudstackUser == null /*doesn't exist in cloudstack*/
+                    || !domainId.equals(cloudstackUser.getDomainId()) /* 
doesn't exist in this domain */
+                    || 
!cloudstackUser.getUserSource().equalsIgnoreCase(User.Source.LDAP.toString()) 
/* is from another source */
+            ) {
+                ldapResponses.add(user);
+            }
+        }
+        annotateUserListWithSources(ldapResponses);
+        return ldapResponses;
+    }
+
+    private String getCurrentDomainId() {
+        String domainId = null;
+        if (this.domainId != null) {
+            Domain domain = _domainService.getDomain(this.domainId);
+            domainId = domain.getUuid();
+        } else {
+            final CallContext callContext = CallContext.current();
+            domainId = 
_domainService.getDomain(callContext.getCallingAccount().getDomainId()).getUuid();
+        }
+        return domainId;
+    }
+
+    /**
+     *
+     * @param input a list of ldap users
+     * @return annotated list of the users of the input list, that will be 
automatically imported or synchronised
+     */
+    public List<LdapUserResponse> filterPotentialImport(List<LdapUserResponse> 
input) {
+        if(s_logger.isTraceEnabled()) {
+            s_logger.trace("should be filtering potential imports!!!");
+        }
+        // functional possibility do not add only users not yet in cloudstack 
but include users that would be moved if they are so in ldap?
+        // this means if they are part of a account linked to an ldap group/ou
+        input.removeIf(ldapUser ->
+                (
+                        (isACloudstackUser(ldapUser))
+                        && 
(getCloudstackUser(ldapUser).getUserSource().equalsIgnoreCase(User.Source.LDAP.toString()))
+                )
+        );
+        annotateUserListWithSources(input);
+        return input;
+    }
+
+    private void annotateUserListWithSources(List<LdapUserResponse> input) {
+        for (final LdapUserResponse user : input) {
+            annotateCloudstackSource(user);
+        }
+    }
+
+    private void annotateCloudstackSource(LdapUserResponse user) {
+        final UserResponse cloudstackUser = getCloudstackUser(user);
+        if (cloudstackUser != null) {
+            user.setUserSource(cloudstackUser.getUserSource());
+        } else {
+            // it makes more sense to make it User.Source.UNKNOWN.toString()
+            user.setUserSource("");
 
 Review comment:
   this is a stale comment, FR specifies that it will be empty if the LDAP user 
does not exist yet.
   removing

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to