Index: sitestats/sitestats-impl/src/test/org/sakaiproject/sitestats/test/mocks/FakeUserDirectoryService.java =================================================================== --- new-workspace/sakai-trunk/sitestats/sitestats-impl/src/test/org/sakaiproject/sitestats/test/mocks/FakeUserDirectoryService.java (revision 313788) +++ new-workspace/sakai-trunk/sitestats/sitestats-impl/src/test/org/sakaiproject/sitestats/test/mocks/FakeUserDirectoryService.java (working copy) @@ -36,6 +36,7 @@ import org.sakaiproject.user.api.UserIdInvalidException; import org.sakaiproject.user.api.UserLockedException; import org.sakaiproject.user.api.UserNotDefinedException; import org.sakaiproject.user.api.UserPermissionException; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -158,6 +159,10 @@ return (new FakeUser()).getId(); } + public boolean checkDuplicatedEmail(User user) { + //TODO Not used in the tests + return false; + } + public List getUsers() { // TODO Auto-generated method stub return null; Index: kernel/api/src/main/java/org/sakaiproject/user/api/UserDirectoryService.java =================================================================== --- new-workspace/sakai-trunk/kernel/api/src/main/java/org/sakaiproject/user/api/UserDirectoryService.java (revision 313856) +++ new-workspace/sakai-trunk/kernel/api/src/main/java/org/sakaiproject/user/api/UserDirectoryService.java (working copy) @@ -304,6 +304,15 @@ User getCurrentUser(); /** + * Check if the email is used by an user + * @param user + * The UserEdit to check the email + * @return true if email is duplicated false in other case + * + */ + public boolean checkDuplicatedEmail(User user); + + /** * Access a user object. * * @param id Index: kernel/api/src/main/java/org/sakaiproject/user/cover/UserDirectoryService.java =================================================================== --- new-workspace/sakai-trunk/kernel/api/src/main/java/org/sakaiproject/user/cover/UserDirectoryService.java (revision 313856) +++ new-workspace/sakai-trunk/kernel/api/src/main/java/org/sakaiproject/user/cover/UserDirectoryService.java (working copy) @@ -220,7 +220,16 @@ return service.allowAddUser(); } + + public static boolean checkDuplicatedEmail(org.sakaiproject.user.api.User param0) + { + org.sakaiproject.user.api.UserDirectoryService service = getInstance(); + if (service == null) return false; + + return service.checkDuplicatedEmail(param0); + } + public static org.sakaiproject.user.api.UserEdit addUser(java.lang.String param0, java.lang.String param1) throws org.sakaiproject.user.api.UserIdInvalidException, org.sakaiproject.user.api.UserAlreadyDefinedException, org.sakaiproject.user.api.UserPermissionException Index: kernel/kernel-impl/src/main/java/org/sakaiproject/user/impl/BaseUserDirectoryService.java =================================================================== --- new-workspace/sakai-trunk/kernel/kernel-impl/src/main/java/org/sakaiproject/user/impl/BaseUserDirectoryService.java (revision 313856) +++ new-workspace/sakai-trunk/kernel/kernel-impl/src/main/java/org/sakaiproject/user/impl/BaseUserDirectoryService.java (working copy) @@ -761,6 +761,28 @@ ensureMappedIdForProvidedUser(user); } } + + public boolean checkDuplicatedEmail (User user) + { + //Check if another user has the same email + String email = StringUtils.trimToNull (user.getEmail()); + + M_log.debug("commitEdit(): Check for mail " + email); + + if (email!=null) + { + Collection usersByMail = findUsersByEmail(email); + for (User userToCheck : usersByMail) + { + if (!StringUtils.equals(userToCheck.getId(),user.getId())) + { + return true; + } + } + } + + return false; + } /** * @inheritDoc Index: sakai-mock/src/main/java/org/sakaiproject/mock/service/UserDirectoryService.java =================================================================== --- new-workspace/sakai-trunk/sakai-mock/src/main/java/org/sakaiproject/mock/service/UserDirectoryService.java (revision 313856) +++ new-workspace/sakai-trunk/sakai-mock/src/main/java/org/sakaiproject/mock/service/UserDirectoryService.java (working copy) @@ -154,6 +154,10 @@ return users.get(eid); } + public boolean checkDuplicatedEmail (User user){ + return false; + } + @Override public User getUserByAid(String aid) throws UserNotDefinedException { throw new UserNotDefinedException(aid); Index: user/user-tool/tool/src/bundle/admin.properties =================================================================== --- new-workspace/sakai-trunk/user/user-tool/tool/src/bundle/admin.properties (revision 313856) +++ new-workspace/sakai-trunk/user/user-tool/tool/src/bundle/admin.properties (working copy) @@ -5,6 +5,7 @@ useact.remuse = Remove User useact.remuse.list.summary = List of users to be removed. First column: user ID. Second column: user name. Third column: user email. useact.theuseid1 = The user id is already in use +useact.theuseemail1 = The user email is already in use useact.theuseid2 = The user id is invalid useact.use_notfou = User {0} not found useact.youdonot1 = You do not have permission to edit User {0} Index: user/user-tool/tool/src/bundle/admin_ca.properties =================================================================== --- new-workspace/sakai-trunk/user/user-tool/tool/src/bundle/admin_ca.properties (revision 313856) +++ new-workspace/sakai-trunk/user/user-tool/tool/src/bundle/admin_ca.properties (working copy) @@ -52,6 +52,7 @@ useact.somels = Alg\u00FA altre est\u00E0 editant aquest usuari actualment: {0} useact.theuseid1 = L'identificador d'usuari ja est\u00E0 en \u00FAs useact.theuseid2 = L'identificador d'usuari no \u00E9s v\u00E0lid +useact.theuseemail1 = L'adre\u00e7a de correu ja est\u00e0 en \u00fas useact.tryloginagain = S'ha creat el compte, per\u00F2 no es pot processar l'inici de sessi\u00F3. Torneu a provar d'iniciar la sessi\u00F3. useact.use_notfou = L''usuari {0} no s''ha trobat useact.youdonot1 = No teniu autoritzaci\u00F3 per editar l''usuari {0} Index: user/user-tool/tool/src/bundle/admin_es.properties =================================================================== --- new-workspace/sakai-trunk/user/user-tool/tool/src/bundle/admin_es.properties (revision 313856) +++ new-workspace/sakai-trunk/user/user-tool/tool/src/bundle/admin_es.properties (working copy) @@ -7,6 +7,7 @@ useact.remuse.list.summary=Lista de usuarios que se borrar\u00e1n. Primera columna\: ID de usuario. Segunda columna\: nombre de usuario. Tercera columna\: correo electr\u00f3nico del usuario. useact.theuseid1=El ID de usuario est\u00e1 actualmente en uso useact.theuseid2=El ID de usuario no es v\u00e1lido +useact.theuseemail1 = La direcci\u00f3n de correo electr\u00f3nico est\u00e1 actualmente en uso useact.use_notfou=El usuario {0} no se encuentra. useact.youdonot1=No tiene permiso para editar el usuario {0} useact.youdonot2=No tiene permisos para borrar al usuario {0} Index: user/user-tool/tool/src/java/org/sakaiproject/user/tool/PasswordPolicyHelper.java =================================================================== --- new-workspace/sakai-trunk/user/user-tool/tool/src/java/org/sakaiproject/user/tool/PasswordPolicyHelper.java (revision 313856) +++ new-workspace/sakai-trunk/user/user-tool/tool/src/java/org/sakaiproject/user/tool/PasswordPolicyHelper.java (working copy) @@ -137,7 +137,6 @@ @Override public String getDisplayId() { return null; } @Override public String getDisplayName() { return null; } @Override public String getEid() { return null; } - @Override public String getEmail() { return null; } @Override public String getFirstName() { return null; } @Override public String getLastName() { return null; } @Override public String getReference() { return null; } Index: user/user-tool/tool/src/java/org/sakaiproject/user/tool/UsersAction.java =================================================================== --- new-workspace/sakai-trunk/user/user-tool/tool/src/java/org/sakaiproject/user/tool/UsersAction.java (revision 313856) +++ new-workspace/sakai-trunk/user/user-tool/tool/src/java/org/sakaiproject/user/tool/UsersAction.java (working copy) @@ -650,10 +650,25 @@ List users = (List)state.getAttribute("importedUsers"); if(users !=null && users.size() > 0) { - + //Check if the email is duplicated + boolean allowEmailDuplicates = ServerConfigurationService.getBoolean("user.email.allowduplicates",true); + + for(ImportedUser user: users) { try { + + TempUser tempUser = new TempUser(user.getEid(), user.getEmail(), null, null, user.getEid(), user.getPassword(), null); + + if (!allowEmailDuplicates && UserDirectoryService.checkDuplicatedEmail(tempUser)){ + addAlert(state, rb.getString("useact.theuseemail1") + ":" + tempUser.getEmail()); + + //Try to import the rest + continue; + } + User newUser = UserDirectoryService.addUser(null, user.getEid(), user.getFirstName(), user.getLastName(), user.getEmail(), user.getPassword(), user.getType(), user.getProperties()); + + } catch (UserAlreadyDefinedException e){ //ok, just skip @@ -807,10 +822,21 @@ // read the form - if rejected, leave things as they are if (!readUserForm(data, state)) return; + + // commit the change UserEdit edit = (UserEdit) state.getAttribute("user"); if (edit != null) { + + //Check if the email is duplicated + boolean allowEmailDuplicates = ServerConfigurationService.getBoolean("user.email.allowduplicates",true); + + if (!allowEmailDuplicates && UserDirectoryService.checkDuplicatedEmail(edit)){ + addAlert(state, rb.getString("useact.theuseemail1")); + return; + } + try { UserDirectoryService.commitEdit(edit); @@ -1211,11 +1237,20 @@ } // SAK-23568 - make sure password meets policy requirements - TempUser tempUser = new TempUser(eid, null, null, null, eid, pw, null); + TempUser tempUser = new TempUser(eid, email, null, null, eid, pw, null); if (!validatePassword(pw, tempUser, state)) { return false; } + //Check if the email is duplicated + boolean allowEmailDuplicates = ServerConfigurationService.getBoolean("user.email.allowduplicates",true); + + if (!allowEmailDuplicates && UserDirectoryService.checkDuplicatedEmail(tempUser)){ + addAlert(state, rb.getString("useact.theuseemail1")); + return false; + } + + try { // add the user in one step so that all you need is add not update permission