cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aprat...@apache.org
Subject [7/7] git commit: updated refs/heads/ldapplugin to 25e8e9b
Date Fri, 02 Aug 2013 10:42:19 GMT
Disable password changing when ldap is enabled

Signed-off-by: Abhinandan Prateek <aprateek@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/532e04db
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/532e04db
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/532e04db

Branch: refs/heads/ldapplugin
Commit: 532e04db1a66f1f89bb940917928dfa97dd8748a
Parents: ec1e695
Author: Ian Duffy <ian@ianduffy.ie>
Authored: Fri Aug 2 09:27:38 2013 +0100
Committer: Abhinandan Prateek <aprateek@apache.org>
Committed: Fri Aug 2 14:20:47 2013 +0530

----------------------------------------------------------------------
 .../apache/cloudstack/api/LdapValidator.java    |   5 +
 .../command/admin/account/UpdateAccountCmd.java |   5 +-
 .../api/command/admin/user/UpdateUserCmd.java   |  15 +-
 .../classes/resources/messages.properties       |   1 +
 client/tomcatconf/commands.properties.in        |   2 +-
 .../api/command/LdapCreateAccount.java          |  29 +-
 .../api/command/LdapListAllUsersCmd.java        |  11 +-
 .../apache/cloudstack/ldap/LdapManagerImpl.java |   8 +-
 .../cloudstack/ldap/LdapConfigurationVO.groovy  |  36 ---
 .../ldap/LdapConfigurationVOSpec.groovy         |  36 +++
 .../ldap/LdapCreateAccountCmdSpec.groovy        | 154 ++++++++++
 .../ldap/LdapDeleteConfigurationCmdSpec.groovy  |   2 +-
 .../ldap/LdapListAllUsersCmdSpec.groovy         |   2 +-
 .../apache/cloudstack/ldap/LdapUserSpec.groovy  |  22 ++
 .../ldap/test/resources/cloudstack.org.ldif     |  13 +
 ui/dictionary.jsp                               |   1 +
 ui/scripts/accounts.js                          | 298 +++----------------
 ui/scripts/ui-custom/accountsWizard.js          |  18 +-
 18 files changed, 341 insertions(+), 317 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/api/src/org/apache/cloudstack/api/LdapValidator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/LdapValidator.java b/api/src/org/apache/cloudstack/api/LdapValidator.java
new file mode 100644
index 0000000..4619a58
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/LdapValidator.java
@@ -0,0 +1,5 @@
+package org.apache.cloudstack.api;
+
+public interface LdapValidator {
+    boolean isLdapEnabled();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
index 60d1a97..f4f1dc0 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/account/UpdateAccountCmd.java
@@ -21,6 +21,8 @@ import java.util.Map;
 
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -30,7 +32,6 @@ import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.AccountResponse;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.region.RegionService;
-import org.apache.log4j.Logger;
 
 import com.cloud.user.Account;
 
@@ -128,7 +129,7 @@ public class UpdateAccountCmd extends BaseCmd{
         if (result != null){
             AccountResponse response = _responseGenerator.createAccountResponse(result);
             response.setResponseName(getCommandName());
-            this.setResponseObject(response);
+	    setResponseObject(response);
         } else {
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update account");
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
index 52ec2ab..415a9fb 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/user/UpdateUserCmd.java
@@ -18,24 +18,29 @@ package org.apache.cloudstack.api.command.admin.user;
 
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.LdapValidator;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.UserResponse;
 import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.region.RegionService;
 
-import org.apache.log4j.Logger;
-
 import com.cloud.user.Account;
 import com.cloud.user.User;
 import com.cloud.user.UserAccount;
 
 @APICommand(name = "updateUser", description="Updates a user account", responseObject=UserResponse.class)
 public class UpdateUserCmd extends BaseCmd {
+
+    @Inject
+    private LdapValidator _ldapValidator;
+
     public static final Logger s_logger = Logger.getLogger(UpdateUserCmd.class.getName());
 
     private static final String s_name = "updateuserresponse";
@@ -137,11 +142,13 @@ public class UpdateUserCmd extends BaseCmd {
     public void execute(){
         CallContext.current().setEventDetails("UserId: "+getId());
         UserAccount user = _regionService.updateUser(this);
-
+	if (_ldapValidator.isLdapEnabled()) {
+	    throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Password cannot be changed when LDAP is enabled");
+	}
         if (user != null){
             UserResponse response = _responseGenerator.createUserResponse(user);
             response.setResponseName(getCommandName());
-            this.setResponseObject(response);
+	    setResponseObject(response);
         } else {
             throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update user");
         }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/client/WEB-INF/classes/resources/messages.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index 3e775e0..e806192 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -31,6 +31,7 @@ message.action.delete.nic=Please confirm that want to remove this NIC, which wil
 changed.item.properties=Changed item properties
 confirm.enable.s3=Please fill in the following information to enable support for S3-backed Secondary Storage
 confirm.enable.swift=Please fill in the following information to enable support for Swift
+error.could.not.change.your.password.because.ldap.is.enabled=Error cloud not change your password because LDAP is enabled.
 error.could.not.enable.zone=Could not enable zone
 error.installWizard.message=Something went wrong; you may go back and correct any errors
 error.invalid.username.password=Invalid username or password

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index b275017..0e00e3c 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -667,7 +667,7 @@ listDedicatedHosts=1
 
 ### LDAP
 searchLdap=3
-listLdapConfigurations=3
+listLdapConfigurations=15
 addLdapConfiguration=3
 deleteLdapConfiguration=3
 listAllLdapUsers=3

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccount.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccount.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccount.java
index 01aebce..82c6e4a 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccount.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapCreateAccount.java
@@ -39,6 +39,7 @@ import org.apache.cloudstack.ldap.LdapManager;
 import org.apache.cloudstack.ldap.LdapUser;
 
 import com.cloud.user.Account;
+import com.cloud.user.AccountService;
 import com.cloud.user.UserAccount;
 
 @APICommand(name = "ldapCreateAccount", description = "Creates an account from an LDAP user", responseObject = AccountResponse.class, since = "4.2.0")
@@ -60,10 +61,10 @@ public class LdapCreateAccount extends BaseCmd {
     private Long domainId;
 
     @Parameter(name = ApiConstants.TIMEZONE, type = CommandType.STRING, description = "Specifies a timezone for this command. For more information on the timezone parameter, see Time Zone Format.")
-    private String timeZone;
+    private String timezone;
 
     @Parameter(name = ApiConstants.USERNAME, type = CommandType.STRING, required = true, description = "Unique username.")
-    private String userName;
+    private String username;
 
     @Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING, description = "Network domain for the account's networks")
     private String networkDomain;
@@ -81,18 +82,19 @@ public class LdapCreateAccount extends BaseCmd {
         super();
     }
 
-    public LdapCreateAccount(final LdapManager ldapManager) {
+    public LdapCreateAccount(final LdapManager ldapManager, final AccountService accountService) {
         super();
         _ldapManager = ldapManager;
+	_accountService = accountService;
     }
 
     @Override
     public void execute() throws ServerApiException {
-        CallContext.current().setEventDetails("Account Name: " + accountName + ", Domain Id:" + domainId);
+	updateCallContext();
         try {
-            LdapUser user = _ldapManager.getUser(userName);
+	    LdapUser user = _ldapManager.getUser(username);
             validateUser(user);
-            UserAccount userAccount = _accountService.createUserAccount(userName, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timeZone,
+	    UserAccount userAccount = _accountService.createUserAccount(username, generatePassword(), user.getFirstname(), user.getLastname(), user.getEmail(), timezone,
                     accountName, accountType, domainId, networkDomain, details, accountUUID, userUUID);
             if (userAccount != null) {
                 AccountResponse response = _responseGenerator.createUserAccountResponse(userAccount);
@@ -102,10 +104,14 @@ public class LdapCreateAccount extends BaseCmd {
                 throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create a user account");
             }
         } catch (NamingException e) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "No LDAP user exists with the username of " + userName);
+	    throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, "No LDAP user exists with the username of " + username);
         }
     }
 
+    private void updateCallContext() {
+	CallContext.current().setEventDetails("Account Name: " + accountName + ", Domain Id:" + domainId);
+    }
+
     private String generatePassword() throws ServerApiException {
         try {
             SecureRandom randomGen = SecureRandom.getInstance("SHA1PRNG");
@@ -127,15 +133,16 @@ public class LdapCreateAccount extends BaseCmd {
         return Account.ACCOUNT_ID_SYSTEM;
     }
 
-    private void validateUser(LdapUser user) throws ServerApiException {
+    private boolean validateUser(LdapUser user) throws ServerApiException {
         if (user.getEmail() == null) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, userName + " has no email address set within LDAP");
+	    throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, username + " has no email address set within LDAP");
         }
         if (user.getFirstname() == null) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, userName + " has no firstname set within LDAP");
+	    throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, username + " has no firstname set within LDAP");
         }
         if (user.getLastname() == null) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, userName + " has no lastname set within LDAP");
+	    throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, username + " has no lastname set within LDAP");
         }
+	return true;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListAllUsersCmd.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListAllUsersCmd.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListAllUsersCmd.java
index 98c9fcf..c5d6b40 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListAllUsersCmd.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/api/command/LdapListAllUsersCmd.java
@@ -24,7 +24,6 @@ import javax.inject.Inject;
 import org.apache.log4j.Logger;
 
 import org.apache.cloudstack.api.APICommand;
-import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseListCmd;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.LdapUserResponse;
@@ -64,15 +63,17 @@ public class LdapListAllUsersCmd extends BaseListCmd {
 
     @Override
     public void execute() throws ServerApiException {
+	List<LdapUserResponse> ldapResponses = null;
+	final ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
         try {
             final List<LdapUser> users = _ldapManager.getUsers();
-            final ListResponse<LdapUserResponse> response = new ListResponse<LdapUserResponse>();
-            final List<LdapUserResponse> ldapResponses = createLdapUserResponse(users);
+	    ldapResponses = createLdapUserResponse(users);
+	} catch (final NoLdapUserMatchingQueryException ex) {
+	    ldapResponses = new ArrayList<LdapUserResponse>();
+	} finally {
             response.setResponses(ldapResponses);
             response.setResponseName(getCommandName());
             setResponseObject(response);
-        } catch (final NoLdapUserMatchingQueryException ex) {
-            throw new ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
index b6fb3e8..5d73ce9 100644
--- a/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
+++ b/plugins/user-authenticators/ldap/src/org/apache/cloudstack/ldap/LdapManagerImpl.java
@@ -27,6 +27,7 @@ import javax.naming.directory.DirContext;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
+import org.apache.cloudstack.api.LdapValidator;
 import org.apache.cloudstack.api.command.LdapAddConfigurationCmd;
 import org.apache.cloudstack.api.command.LdapCreateAccount;
 import org.apache.cloudstack.api.command.LdapDeleteConfigurationCmd;
@@ -42,7 +43,7 @@ import com.cloud.utils.Pair;
 
 @Component
 @Local(value = LdapManager.class)
-public class LdapManagerImpl implements LdapManager {
+public class LdapManagerImpl implements LdapManager, LdapValidator {
     private static final Logger s_logger = Logger.getLogger(LdapManagerImpl.class.getName());
 
     @Inject
@@ -202,4 +203,9 @@ public class LdapManagerImpl implements LdapManager {
             closeContext(context);
         }
     }
+
+    @Override
+    public boolean isLdapEnabled() {
+	return listConfigurations(new LdapListConfigurationCmd(this)).second() > 0;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy
deleted file mode 100644
index 27f3dfc..0000000
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVO.groovy
+++ /dev/null
@@ -1,36 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-package groovy.org.apache.cloudstack.ldap
-
-import org.apache.cloudstack.ldap.LdapConfigurationVO
-
-
-class LdapConfigurationVOSpec extends spock.lang.Specification {
-    def "Testing that the ID hostname and port is correctly set within the LDAP configuration VO"() {
-        given: "You have created an LDAP Configuration VO"
-        def configuration = new LdapConfigurationVO(hostname, port)
-        configuration.setId(id)
-        expect: "The id hostname and port is equal to the given data source"
-        configuration.getId() == id
-        configuration.getHostname() == hostname
-        configuration.getPort() == port
-        where: "The id, hostname and port is set to "
-        hostname << ["", null, "localhost"]
-        id << [0, 1000, -1000]
-        port << [0, 1000, -1000]
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy
new file mode 100644
index 0000000..66b3f44
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapConfigurationVOSpec.groovy
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package groovy.org.apache.cloudstack.ldap
+
+import org.apache.cloudstack.ldap.LdapConfigurationVO
+
+
+class LdapConfigurationVOSpec extends spock.lang.Specification {
+    def "Testing that the ID hostname and port is correctly set within the LDAP configuration VO"() {
+	given: "You have created an LDAP Configuration VO"
+	def configuration = new LdapConfigurationVO(hostname, port)
+	configuration.setId(id)
+	expect: "The id hostname and port is equal to the given data source"
+	configuration.getId() == id
+	configuration.getHostname() == hostname
+	configuration.getPort() == port
+	where: "The id, hostname and port is set to "
+	hostname << ["", null, "localhost"]
+	id << [0, 1000, -1000]
+	port << [0, 1000, -1000]
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
new file mode 100644
index 0000000..07056b0
--- /dev/null
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapCreateAccountCmdSpec.groovy
@@ -0,0 +1,154 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package groovy.org.apache.cloudstack.ldap
+
+import com.cloud.exception.InvalidParameterValueException
+import org.apache.cloudstack.api.ServerApiException
+import org.apache.cloudstack.api.command.LdapAddConfigurationCmd
+import org.apache.cloudstack.api.response.LdapConfigurationResponse
+
+import org.apache.cloudstack.ldap.LdapUser;
+import org.apache.cloudstack.ldap.LdapManager;
+
+import org.apache.cloudstack.api.command.LdapCreateAccount
+
+import com.cloud.user.AccountService;
+import com.cloud.user.UserAccountVO;
+
+import javax.naming.NamingException
+
+class LdapCreateAccountCmdSpec extends spock.lang.Specification {
+/*
+    def "Test failure to retrive LDAP user"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	ldapManager.getUser(_) >> { throw new NamingException() }
+	AccountService accountService = Mock(AccountService)
+
+	def ldapCreateAccount = Spy(LdapCreateAccount, constructorArgs: [ldapManager, accountService])
+	ldapCreateAccount.updateCallContext() >> System.out.println("Hello World");
+	when:
+	ldapCreateAccount.execute()
+	then:
+	thrown ServerApiException
+    } */
+
+    def "Test validation of a user"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+
+	def ldapCreateAccount = Spy(LdapCreateAccount, constructorArgs: [ldapManager, accountService])
+
+	when:
+	def commandName = ldapCreateAccount.getCommandName()
+
+	then:
+	commandName == "createaccountresponse"
+    }
+
+    def "Test getEntityOwnerId is 1"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+
+	def ldapCreateAccount = Spy(LdapCreateAccount, constructorArgs: [ldapManager, accountService])
+	when:
+	long ownerId = ldapCreateAccount.getEntityOwnerId()
+	then:
+	ownerId == 1
+    }
+
+    def "Test validate User"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService);
+	when:
+	def result = ldapCreateAccount.validateUser(new LdapUser("username","email","firstname","lastname","principal"))
+	then:
+	result == true
+   }
+
+    def "Test validate User empty email"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService)
+	when:
+	ldapCreateAccount.validateUser(new LdapUser("username",null,"firstname","lastname","principal"))
+	then:
+	thrown Exception
+   }
+
+    def "Test validate User empty firstname"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService)
+	when:
+	ldapCreateAccount.validateUser(new LdapUser("username","email",null,"lastname","principal"))
+	then:
+	thrown Exception
+   }
+
+    def "Test validate User empty lastname"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService)
+	when:
+	ldapCreateAccount.validateUser(new LdapUser("username","email","firstname",null,"principal"))
+	then:
+	thrown Exception
+   }
+
+    def "Test failed password generation"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService)
+	when:
+	def result = ldapCreateAccount.generatePassword()
+	then:
+	result != ""
+	result != null
+    }
+
+    def "Test password generation"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService)
+	when:
+	def result = ldapCreateAccount.generatePassword()
+	then:
+	result != ""
+	result != null
+    }
+
+    def "Test command name"() {
+	given:
+	LdapManager ldapManager = Mock(LdapManager)
+	AccountService accountService = Mock(AccountService)
+	def ldapCreateAccount = new LdapCreateAccount(ldapManager, accountService)
+	when:
+	def result = ldapCreateAccount.getCommandName()
+	then:
+	result == "createaccountresponse"
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
index f4d185b..b702689 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapDeleteConfigurationCmdSpec.groovy
@@ -46,7 +46,7 @@ class LdapDeleteConfigurationCmdSpec extends spock.lang.Specification {
         thrown ServerApiException
     }
 
-    def "Test getEntityOwnerId is 0"() {
+    def "Test getEntityOwnerId is 1"() {
         given:
         def ldapManager = Mock(LdapManager)
         def ldapDeleteConfigurationCmd = new LdapDeleteConfigurationCmd(ldapManager)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy
index 2756e92..f6ade31 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapListAllUsersCmdSpec.groovy
@@ -47,7 +47,7 @@ class LdapListAllUsersCmdSpec extends spock.lang.Specification {
         when:
         ldapListAllUsersCmd.execute()
         then:
-        thrown ServerApiException
+	ldapListAllUsersCmd.responseObject.getResponses().size() == 0
     }
 
     def "Test getEntityOwnerId is 1"() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
index cf2f9ec..5519d7f 100644
--- a/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
+++ b/plugins/user-authenticators/ldap/test/groovy/org/apache/cloudstack/ldap/LdapUserSpec.groovy
@@ -76,4 +76,26 @@ class LdapUserSpec extends spock.lang.Specification {
         "A"       | "B"
         "A"       | "A"
     }
+
+    def "Testing that LdapUsers equality"() {
+	given:
+	def userA = new LdapUser(usernameA, "", "", "", "")
+	def userB = new LdapUser(usernameB, "", "", "", "")
+	expect:
+	userA.equals(userA) == true
+	userA.equals(new Object()) == false
+	userA.equals(userB) == false
+	where:
+	usernameA | usernameB
+	"A"       | "B"
+    }
+
+    def "Testing LdapUsers hashCode generation"() {
+	given:
+	def userA = new LdapUser(usernameA, "", "", "", "")
+	expect:
+	userA.hashCode() == usernameA.hashCode()
+	where:
+	usernameA = "A"
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
----------------------------------------------------------------------
diff --git a/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif b/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
index f46a383..d5f5c24 100644
--- a/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
+++ b/plugins/user-authenticators/ldap/test/resources/cloudstack.org.ldif
@@ -268,6 +268,19 @@ mail: acasson@cloudstack.org
 uid: acasson
 userpassword:: cGFzc3dvcmQ=
 
+dn: cn=Noel King,dc=cloudstack,dc=org
+objectClass: inetOrgPerson
+objectClass: organizationalPerson
+objectClass: person
+objectClass: top
+cn: Noel King
+sn: King
+givenName: Noel
+mail: nking@cloudstack.org
+uid: nking
+userpassword:: cGFzc3dvcmQ=
+
+
 dn: cn=Cammy Petri,dc=cloudstack,dc=org
 objectClass: inetOrgPerson
 objectClass: organizationalPerson

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/ui/dictionary.jsp
----------------------------------------------------------------------
diff --git a/ui/dictionary.jsp b/ui/dictionary.jsp
index eec0264..24c7e5e 100644
--- a/ui/dictionary.jsp
+++ b/ui/dictionary.jsp
@@ -42,6 +42,7 @@ dictionary = {
 'changed.item.properties': '<fmt:message key="changed.item.properties" />',
 'confirm.enable.s3': '<fmt:message key="confirm.enable.s3" />',
 'confirm.enable.swift': '<fmt:message key="confirm.enable.swift" />',
+'error.could.not.change.your.password.because.ldap.is.enabled': '<fmt:message key="error.could.not.change.your.password.because.ldap.is.enabled" />',
 'error.could.not.enable.zone': '<fmt:message key="error.could.not.enable.zone" />',
 'error.installWizard.message': '<fmt:message key="error.installWizard.message" />',
 'error.invalid.username.password': '<fmt:message key="error.invalid.username.password" />',

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/ui/scripts/accounts.js
----------------------------------------------------------------------
diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js
index 43b242d..3a7f44a 100644
--- a/ui/scripts/accounts.js
+++ b/ui/scripts/accounts.js
@@ -76,215 +76,6 @@
                                     return 'label.add.account';
                                 }
                             },
-                            /*
-                            createForm: {
-                                title: 'label.add.account',
-                                desc: 'label.add.account',
-                                fields: {
-                                    username: {
-                                        label: 'label.username',
-                                        validation: {
-                                            required: true
-                                        },
-                                        docID: 'helpAccountUsername'
-                                    },
-                                    password: {
-                                        label: 'label.password',
-                                        validation: {
-                                            required: true
-                                        },
-                                        isPassword: true,
-                                        id: 'password',
-                                        docID: 'helpAccountPassword'
-                                    },
-                                    'password-confirm': {
-                                        label: 'label.confirm.password',
-                                        validation: {
-                                            required: true,
-                                            equalTo: '#password'
-                                        },
-                                        isPassword: true,
-                                        docID: 'helpAccountConfirmPassword'
-                                    },
-                                    email: {
-                                        label: 'label.email',
-                                        validation: {
-                                            required: true,
-                                            email: true
-                                        },
-                                        docID: 'helpAccountEmail'
-                                    },
-                                    firstname: {
-                                        label: 'label.first.name',
-                                        validation: {
-                                            required: true
-                                        },
-                                        docID: 'helpAccountFirstName'
-                                    },
-                                    lastname: {
-                                        label: 'label.last.name',
-                                        validation: {
-                                            required: true
-                                        },
-                                        docID: 'helpAccountLastName'
-                                    },
-                                    domainid: {
-                                        label: 'label.domain',
-                                        docID: 'helpAccountDomain',
-                                        validation: {
-                                            required: true
-                                        },
-                                        select: function(args) {
-                                            var data = {};
-
-                                            if (args.context.users) { // In accounts section
-                                                data.listAll = true;
-                                            } else if (args.context.domains) { // In domain section (use specific domain)
-                                                data.id = args.context.domains[0].id;
-                                            }
-
-                                            $.ajax({
-                                                url: createURL("listDomains"),
-                                                data: data,
-                                                dataType: "json",
-                                                async: false,
-                                                success: function(json) {
-                                                    var items = [];
-                                                    domainObjs = json.listdomainsresponse.domain;
-                                                    $(domainObjs).each(function() {
-                                                        items.push({
-                                                            id: this.id,
-                                                            description: this.path
-                                                        });
-
-                                                        if (this.level == 0)
-                                                            rootDomainId = this.id;
-                                                    });
-                                                    args.response.success({
-                                                        data: items
-                                                    });
-                                                }
-                                            });
-                                        }
-                                    },
-                                    account: {
-                                        label: 'label.account',
-                                        docID: 'helpAccountAccount'
-                                    },
-                                    accounttype: {
-                                        label: 'label.type',
-                                        docID: 'helpAccountType',
-                                        validation: {
-                                            required: true
-                                        },
-                                        select: function(args) {
-                                            var items = [];
-                                            items.push({
-                                                id: 0,
-                                                description: "User"
-                                            }); //regular-user
-                                            items.push({
-                                                id: 1,
-                                                description: "Admin"
-                                            }); //root-admin
-                                            args.response.success({
-                                                data: items
-                                            });
-                                        }
-                                    },
-                                    timezone: {
-                                        label: 'label.timezone',
-                                        docID: 'helpAccountTimezone',
-                                        select: function(args) {
-                                            var items = [];
-                                            items.push({
-                                                id: "",
-                                                description: ""
-                                            });
-                                            for (var p in timezoneMap)
-                                                items.push({
-                                                    id: p,
-                                                    description: timezoneMap[p]
-                                                });
-                                            args.response.success({
-                                                data: items
-                                            });
-                                        }
-                                    },
-                                    networkdomain: {
-                                        label: 'label.network.domain',
-                                        docID: 'helpAccountNetworkDomain',
-                                        validation: {
-                                            required: false
-                                        }
-                                    }
-                                }
-                            },
-
-                            action: function(args) {
-                                var data = {
-                                    username: args.data.username,
-                                };
-
-                                var password = args.data.password;
-                                if (md5Hashed) {
-                                    password = $.md5(password);
-                                }
-                                $.extend(data, {
-                                    password: password
-                                });
-
-                                $.extend(data, {
-                                    email: args.data.email,
-                                    firstname: args.data.firstname,
-                                    lastname: args.data.lastname,
-                                    domainid: args.data.domainid
-                                });
-
-                                var account = args.data.account;
-                                if (account == null || account.length == 0) {
-                                    account = args.data.username;
-                                }
-                                $.extend(data, {
-                                    account: account
-                                });
-
-                                var accountType = args.data.accounttype;
-                                if (args.data.accounttype == "1" && args.data.domainid != rootDomainId) { //if account type is admin, but domain is not Root domain
-                                    accountType = "2"; // Change accounttype from root-domain("1") to domain-admin("2")
-                                }
-                                $.extend(data, {
-                                    accounttype: accountType
-                                });
-
-                                if (args.data.timezone != null && args.data.timezone.length > 0) {
-                                    $.extend(data, {
-                                        timezone: args.data.timezone
-                                    });
-                                }
-
-                                if (args.data.networkdomain != null && args.data.networkdomain.length > 0) {
-                                    $.extend(data, {
-                                        networkdomain: args.data.networkdomain
-                                    });
-                                }
-
-                                $.ajax({
-                                    url: createURL('createAccount'),
-                                    type: "POST",
-                                    data: data,
-                                    success: function(json) {
-                                        var item = json.createaccountresponse.account;
-                                        args.response.success({
-                                            data: item
-                                        });
-                                    },
-                                    error: function(XMLHttpResponse) {
-                                        args.response.error(parseXMLHttpResponse(XMLHttpResponse));
-                                    }
-                                });
-                            },
-                            */
                             notification: {
                                 poll: function(args) {
                                     args.complete({
@@ -1253,47 +1044,56 @@
                                         return 'label.action.change.password';
                                     }
                                 },
-                                createForm: {
-                                    title: 'label.action.change.password',
-                                    fields: {
-                                        newPassword: {
-                                            label: 'label.new.password',
-                                            isPassword: true,
-                                            validation: {
-                                                required: true
-                                            },
-                                            id: 'newPassword'
-                                        },
-                                        'password-confirm': {
-                                            label: 'label.confirm.password',
-                                            validation: {
-                                                required: true,
-                                                equalTo: '#newPassword'
-                                            },
-                                            isPassword: true
-                                        }
-                                    }
-                                },
-                                action: function(args) {
-                                    var password = args.data.newPassword;
-                                    if (md5Hashed)
-                                        password = $.md5(password);
 
-                                    var data = {
-                                        id: args.context.users[0].id,
-                                        password: password
-                                    };
-
-                                    $.ajax({
-                                        url: createURL('updateUser'),
-                                        data: data,
-                                        type: "POST",
-                                        success: function(json) {
-                                            args.response.success({
-                                                data: json.updateuserresponse.user
-                                            });
-                                        }
-                                    });
+				action: function(args) {
+				    if (isLdapEnabled()) {
+					alert(dictionary["error.could.not.change.your.password.because.ldap.is.enabled"]);
+					args.response.error({});
+				    } else {
+					cloudStack.dialog.createForm({
+					    noDialog: false,
+					    form: {
+						title: 'label.action.change.password',
+						fields: {
+						    newPassword: {
+							label: 'label.new.password',
+							isPassword: true,
+							validation: {
+							    required: true
+							},
+							id: 'newPassword'
+						    },
+						    'password-confirm': {
+							label: 'label.confirm.password',
+							validation: {
+							    required: true,
+							    equalTo: '#newPassword'
+							},
+							isPassword: true
+						    }
+						}
+					    }
+					})
+					var password = args.data.newPassword;
+					if (md5Hashed)
+					    password = $.md5(password);
+
+					var data = {
+					    id: args.context.users[0].id,
+					    password: password
+					};
+					$.ajax({
+					    url: createURL('updateUser'),
+					    data: data,
+					    type: "POST",
+					    success: function(json) {
+						args.response.success({
+						    data: json.updateuserresponse.user
+						});
+					    }
+					});
+
+				    }
                                 },
                                 notification: {
                                     poll: function(args) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/532e04db/ui/scripts/ui-custom/accountsWizard.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui-custom/accountsWizard.js b/ui/scripts/ui-custom/accountsWizard.js
index 7951553..628cc34 100644
--- a/ui/scripts/ui-custom/accountsWizard.js
+++ b/ui/scripts/ui-custom/accountsWizard.js
@@ -97,14 +97,20 @@
                         dataType: "json",
                         async: false,
                         success: function(json) {
-                            $(json.ldapuserresponse.LdapUser).each(function() {
+			    if(json.ldapuserresponse.count > 0) {
+				$(json.ldapuserresponse.LdapUser).each(function() {
+				    var result = $("<tr>");
+				    result.append("<td><input type=\"checkbox\" class=\"required\" name=\"username\" value=\"" + this.username + "\"></td>");
+				    result.append("<td>" + this.firstname + " " + this.lastname + "</td>");
+				    result.append("<td>" + this.username + "</td>");
+				    result.append("<td>" + this.email + "</td>");
+				    $table.append(result);
+				});
+			    } else {
                                 var result = $("<tr>");
-                                result.append("<td><input type=\"checkbox\" class=\"required\" name=\"username\" value=\"" + this.username + "\"></td>");
-                                result.append("<td>" + this.firstname + " " + this.lastname + "</td>");
-                                result.append("<td>" + this.username + "</td>");
-                                result.append("<td>" + this.email + "</td>");
+				result.append("<td colspan=\"4\">No data to show</td>");
                                 $table.append(result);
-                            });
+			    }
                         }
                     });
                 } else {


Mime
View raw message