cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From GitBox <...@apache.org>
Subject [GitHub] [cloudstack] DaanHoogland commented on a change in pull request #3694: Ldap fixes
Date Fri, 20 Dec 2019 14:46:54 GMT
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:
users@infra.apache.org


With regards,
Apache Git Services

Mime
View raw message