From f518d03e889410287053299fa630c2db59c1ac4b Mon Sep 17 00:00:00 2001 From: Dustin Jenkins <Dustin.Jenkins@nrc-cnrc.gc.ca> Date: Fri, 17 Jul 2015 16:38:46 -0700 Subject: [PATCH] Story 1734: Accommodate 409 (Already exists). --- .../cadc/ac/UserAlreadyExistsException.java | 85 +++++++ .../nrc/cadc/ac/server/UserPersistence.java | 4 +- .../ca/nrc/cadc/ac/server/ldap/LdapDAO.java | 11 +- .../nrc/cadc/ac/server/ldap/LdapUserDAO.java | 227 +++++++++++------- .../ac/server/ldap/LdapUserPersistence.java | 5 +- .../ac/server/web/users/CreateUserAction.java | 17 +- .../ac/server/web/users/UsersServlet.java | 1 + 7 files changed, 247 insertions(+), 103 deletions(-) create mode 100644 projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java new file mode 100644 index 00000000..a8bd0a27 --- /dev/null +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/UserAlreadyExistsException.java @@ -0,0 +1,85 @@ +/* + ************************************************************************ + ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* + ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** + * + * (c) 2015. (c) 2015. + * Government of Canada Gouvernement du Canada + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits réservés + * + * NRC disclaims any warranties, Le CNRC dénie toute garantie + * expressed, implied, or énoncée, implicite ou légale, + * statutory, of any kind with de quelque nature que ce + * respect to the software, soit, concernant le logiciel, + * including without limitation y compris sans restriction + * any warranty of merchantability toute garantie de valeur + * or fitness for a particular marchande ou de pertinence + * purpose. NRC shall not be pour un usage particulier. + * liable in any event for any Le CNRC ne pourra en aucun cas + * damages, whether direct or être tenu responsable de tout + * indirect, special or general, dommage, direct ou indirect, + * consequential or incidental, particulier ou général, + * arising from the use of the accessoire ou fortuit, résultant + * software. Neither the name de l'utilisation du logiciel. Ni + * of the National Research le nom du Conseil National de + * Council of Canada nor the Recherches du Canada ni les noms + * names of its contributors may de ses participants ne peuvent + * be used to endorse or promote être utilisés pour approuver ou + * products derived from this promouvoir les produits dérivés + * software without specific prior de ce logiciel sans autorisation + * written permission. préalable et particulière + * par écrit. + * + * This file is part of the Ce fichier fait partie du projet + * OpenCADC project. OpenCADC. + * + * OpenCADC is free software: OpenCADC est un logiciel libre ; + * you can redistribute it and/or vous pouvez le redistribuer ou le + * modify it under the terms of modifier suivant les termes de + * the GNU Affero General Public la “GNU Affero General Public + * License as published by the License” telle que publiée + * Free Software Foundation, par la Free Software Foundation + * either version 3 of the : soit la version 3 de cette + * License, or (at your option) licence, soit (à votre gré) + * any later version. toute version ultérieure. + * + * OpenCADC is distributed in the OpenCADC est distribué + * hope that it will be useful, dans l’espoir qu’il vous + * but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE + * without even the implied GARANTIE : sans même la garantie + * warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ + * or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF + * PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence + * General Public License for Générale Publique GNU Affero + * more details. pour plus de détails. + * + * You should have received Vous devriez avoir reçu une + * a copy of the GNU Affero copie de la Licence Générale + * General Public License along Publique GNU Affero avec + * with OpenCADC. If not, see OpenCADC ; si ce n’est + * <http://www.gnu.org/licenses/>. pas le cas, consultez : + * <http://www.gnu.org/licenses/>. + * + * + ************************************************************************ + */ + +package ca.nrc.cadc.ac; + +public class UserAlreadyExistsException extends Exception +{ + /** + * Constructs a new exception with the specified detail message. The + * cause is not initialized, and may subsequently be initialized by + * a call to {@link #initCause}. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link #getMessage()} method. + */ + public UserAlreadyExistsException(String message) + { + super(message); + } +} diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java index af5a6c53..599f9858 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java @@ -73,6 +73,7 @@ import java.security.Principal; import java.util.Collection; import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.UserAlreadyExistsException; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.net.TransientException; @@ -102,7 +103,8 @@ public interface UserPersistence<T extends Principal> * @throws AccessControlException If the operation is not permitted. */ User<T> addUser(UserRequest<T> user) - throws TransientException, AccessControlException; + throws TransientException, AccessControlException, + UserAlreadyExistsException; /** * Get the user specified by userID. diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java index 90005ee0..1b85d39d 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapDAO.java @@ -68,6 +68,7 @@ */ package ca.nrc.cadc.ac.server.ldap; +import ca.nrc.cadc.ac.UserAlreadyExistsException; import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.auth.OpenIdPrincipal; @@ -78,6 +79,8 @@ import com.unboundid.ldap.sdk.LDAPException; import com.unboundid.ldap.sdk.ResultCode; import com.unboundid.ldap.sdk.SearchResult; import com.unboundid.ldap.sdk.SearchScope; + +import java.nio.file.FileAlreadyExistsException; import java.security.AccessControlException; import java.security.AccessController; import java.security.GeneralSecurityException; @@ -233,7 +236,7 @@ public abstract class LdapDAO throws TransientException { logger.debug("Ldap result: " + code); - + if (code == ResultCode.INSUFFICIENT_ACCESS_RIGHTS) { throw new AccessControlException("Not authorized "); @@ -242,8 +245,7 @@ public abstract class LdapDAO { throw new AccessControlException("Invalid credentials "); } - else if ((code == ResultCode.SUCCESS) || (code - == ResultCode.NO_SUCH_OBJECT)) + else if ((code == ResultCode.SUCCESS) || (code == ResultCode.NO_SUCH_OBJECT)) { // all good. nothing to do } @@ -251,8 +253,7 @@ public abstract class LdapDAO { throw new IllegalArgumentException("Error in Ldap parameters "); } - else if (code == ResultCode.BUSY || - code == ResultCode.CONNECT_ERROR) + else if (code == ResultCode.BUSY || code == ResultCode.CONNECT_ERROR) { throw new TransientException("Connection problems "); } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java index 956661a4..835fa9a9 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java @@ -96,6 +96,7 @@ import java.util.Map; import javax.security.auth.x500.X500Principal; import org.apache.log4j.Logger; + public class LdapUserDAO<T extends Principal> extends LdapDAO { private static final Logger logger = Logger.getLogger(LdapUserDAO.class); @@ -126,17 +127,19 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO protected static final String LDAP_GID_NUMBER = "gidNumber"; protected static final String LDAP_HOME_DIRECTORY = "homeDirectory"; protected static final String LDAP_LOGIN_SHELL = "loginShell"; - + private String[] userAttribs = new String[] - { - LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY, LDAP_COUNTRY, - LDAP_EMAIL, LDAP_INSTITUTE, LDAP_UID, LDAP_UID_NUMBER, LDAP_GID_NUMBER, - LDAP_HOME_DIRECTORY, LDAP_LOGIN_SHELL - }; + { + LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY, + LDAP_COUNTRY, + LDAP_EMAIL, LDAP_INSTITUTE, LDAP_UID, LDAP_UID_NUMBER, + LDAP_GID_NUMBER, + LDAP_HOME_DIRECTORY, LDAP_LOGIN_SHELL + }; private String[] memberAttribs = new String[] - { - LDAP_FIRST_NAME, LDAP_LAST_NAME - }; + { + LDAP_FIRST_NAME, LDAP_LAST_NAME + }; public LdapUserDAO(LdapConfig config) { @@ -159,23 +162,22 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO memberAttribs.length); memberAttribs = tmp; } - + /** - * * @return - * @throws TransientException + * @throws TransientException */ public Collection<HttpPrincipal> getCadcIDs() throws TransientException { try { Filter filter = Filter.createPresenceFilter("uid"); - String [] attributes = new String[] {"uid"}; - - SearchRequest searchRequest = - new SearchRequest(config.getUsersDN(), + String[] attributes = new String[]{"uid"}; + + SearchRequest searchRequest = + new SearchRequest(config.getUsersDN(), SearchScope.SUB, filter, attributes); - + SearchResult searchResult = null; try { @@ -189,24 +191,24 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO throw new IllegalStateException("Could not find users root"); } } - + LdapDAO.checkLdapResult(searchResult.getResultCode()); Collection<HttpPrincipal> userIDs = new HashSet<HttpPrincipal>(); for (SearchResultEntry next : searchResult.getSearchEntries()) { userIDs.add(new HttpPrincipal(next.getAttributeValue("uid"))); } - + return userIDs; } catch (LDAPException e1) { logger.debug("getCadcIDs Exception: " + e1, e1); LdapDAO.checkLdapResult(e1.getResultCode()); - throw new IllegalStateException("Unexpected exception: " + - e1.getMatchedDN(), e1); + throw new IllegalStateException("Unexpected exception: " + + e1.getMatchedDN(), e1); } - + } @@ -215,20 +217,22 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO * * @param userRequest The user to add. * @return User instance. - * @throws TransientException If an temporary, unexpected problem occurred. - * @throws AccessControlException If the operation is not permitted. + * @throws TransientException If an temporary, unexpected problem occurred. + * @throws AccessControlException If the operation is not permitted. + * @throws UserAlreadyExistsException If the user already exists. */ public User<T> addUser(final UserRequest<T> userRequest) - throws TransientException + throws TransientException, UserAlreadyExistsException { final User<T> user = userRequest.getUser(); final Class userType = user.getUserID().getClass(); - String searchField = userLdapAttrib.get(userType); + final String searchField = userLdapAttrib.get(userType); + if (searchField == null) { throw new IllegalArgumentException("Unsupported principal type " + userType); } - + try { // add new user @@ -236,16 +240,20 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO List<Attribute> attributes = new ArrayList<Attribute>(); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_ORG_PERSON); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_CADC_ACCOUNT); - addAttribute(attributes, LDAP_COMMON_NAME, user.getUserID().getName()); - addAttribute(attributes, LDAP_DISTINGUISHED_NAME, userDN.toNormalizedString()); - addAttribute(attributes, LADP_USER_PASSWORD, userRequest.getPassword()); + addAttribute(attributes, LDAP_COMMON_NAME, user.getUserID() + .getName()); + addAttribute(attributes, LDAP_DISTINGUISHED_NAME, userDN + .toNormalizedString()); + addAttribute(attributes, LADP_USER_PASSWORD, userRequest + .getPassword()); for (UserDetails details : user.details) { if (details.getClass() == PersonalDetails.class) { PersonalDetails pd = (PersonalDetails) details; - addAttribute(attributes, LDAP_FIRST_NAME, pd.getFirstName()); + addAttribute(attributes, LDAP_FIRST_NAME, pd + .getFirstName()); addAttribute(attributes, LDAP_LAST_NAME, pd.getLastName()); addAttribute(attributes, LDAP_ADDRESS, pd.address); addAttribute(attributes, LDAP_CITY, pd.city); @@ -257,14 +265,18 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO { PosixDetails pd = (PosixDetails) details; addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_POSIX_ACCOUNT); - addAttribute(attributes, LDAP_UID, Long.toString(pd.getUid())); - addAttribute(attributes, LDAP_UID_NUMBER, Long.toString(pd.getUid())); - addAttribute(attributes, LDAP_GID_NUMBER, Long.toString(pd.getGid())); - addAttribute(attributes, LDAP_HOME_DIRECTORY, pd.getHomeDirectory()); + addAttribute(attributes, LDAP_UID, Long + .toString(pd.getUid())); + addAttribute(attributes, LDAP_UID_NUMBER, Long + .toString(pd.getUid())); + addAttribute(attributes, LDAP_GID_NUMBER, Long + .toString(pd.getGid())); + addAttribute(attributes, LDAP_HOME_DIRECTORY, pd + .getHomeDirectory()); addAttribute(attributes, LDAP_LOGIN_SHELL, pd.loginShell); } } - + AddRequest addRequest = new AddRequest(userDN, attributes); LDAPResult result = getConnection().add(addRequest); LdapDAO.checkLdapResult(result.getResultCode()); @@ -274,12 +286,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO getConnection().reconnect(); try { - return getUser(user.getUserID(), config.getUserRequestsDN()); + return getUser(user.getUserID(), config.getUserRequestsDN()); } catch (UserNotFoundException e) { - throw new RuntimeException("BUG: new user " + userDN.toNormalizedString() + - " not found, result " + result.getResultCode()); + throw new RuntimeException("BUG: new user " + userDN + .toNormalizedString() + + " not found, result " + result + .getResultCode()); } } catch (LDAPException e) @@ -287,7 +301,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO System.out.println("LDAPe: " + e); System.out.println("LDAPrc: " + e.getResultCode()); logger.debug("addUser Exception: " + e, e); - LdapDAO.checkLdapResult(e.getResultCode()); + LdapUserDAO.checkUserLDAPResult(e.getResultCode()); throw new RuntimeException("Unexpected LDAP exception", e); } } @@ -302,17 +316,17 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO * @throws AccessControlException If the operation is not permitted. */ public User<T> getUser(final T userID) - throws UserNotFoundException, TransientException, AccessControlException + throws UserNotFoundException, TransientException, + AccessControlException { return getUser(userID, config.getUsersDN()); } - /** * Get the user specified by userID. * - * @param userID The userID. + * @param userID The userID. * @param usersDN The LDAP tree to search. * @return User instance. * @throws UserNotFoundException when the user is not found. @@ -320,7 +334,8 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO * @throws AccessControlException If the operation is not permitted. */ private User<T> getUser(final T userID, final String usersDN) - throws UserNotFoundException, TransientException, AccessControlException + throws UserNotFoundException, TransientException, + AccessControlException { String searchField = userLdapAttrib.get(userID.getClass()); if (searchField == null) @@ -329,16 +344,16 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO "Unsupported principal type " + userID.getClass()); } - searchField = "(&(objectclass=inetorgperson)(" + + searchField = "(&(objectclass=inetorgperson)(" + searchField + "=" + userID.getName() + "))"; logger.debug(searchField); SearchResultEntry searchResult = null; try { - SearchRequest searchRequest = + SearchRequest searchRequest = new SearchRequest(usersDN, SearchScope.SUB, - searchField, userAttribs); + searchField, userAttribs); if (isSecure(usersDN)) { @@ -362,7 +377,8 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } User<T> user = new User<T>(userID); user.getIdentities().add(new HttpPrincipal(searchResult - .getAttributeValue(userLdapAttrib.get(HttpPrincipal.class)))); + .getAttributeValue(userLdapAttrib + .get(HttpPrincipal.class)))); String fname = searchResult.getAttributeValue(LDAP_FIRST_NAME); String lname = searchResult.getAttributeValue(LDAP_LAST_NAME); @@ -371,27 +387,30 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO personaDetails.city = searchResult.getAttributeValue(LDAP_CITY); personaDetails.country = searchResult.getAttributeValue(LDAP_COUNTRY); personaDetails.email = searchResult.getAttributeValue(LDAP_EMAIL); - personaDetails.institute = searchResult.getAttributeValue(LDAP_INSTITUTE); + personaDetails.institute = searchResult + .getAttributeValue(LDAP_INSTITUTE); user.details.add(personaDetails); - + Long uid = searchResult.getAttributeValueAsLong(LDAP_UID_NUMBER); Long gid = searchResult.getAttributeValueAsLong(LDAP_GID_NUMBER); - String homeDirectory = searchResult.getAttributeValue(LDAP_HOME_DIRECTORY); + String homeDirectory = searchResult + .getAttributeValue(LDAP_HOME_DIRECTORY); if (uid != null && gid != null && homeDirectory != null) { PosixDetails posixDetails = new PosixDetails(uid, gid, homeDirectory); - posixDetails.loginShell = searchResult.getAttributeValue(LDAP_LOGIN_SHELL); + posixDetails.loginShell = searchResult + .getAttributeValue(LDAP_LOGIN_SHELL); user.details.add(posixDetails); } - + return user; } /** * Obtain whether the given DN tree requires authentication. * - * @param usersDN The usersDN to check. - * @return True if requires authentication, False otherwise. + * @param usersDN The usersDN to check. + * @return True if requires authentication, False otherwise. */ private boolean isSecure(final String usersDN) { @@ -400,23 +419,23 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO /** * Get all group names. - * + * * @return A collection of strings - * * @throws TransientException If an temporary, unexpected problem occurred. */ public Collection<String> getUserNames() - throws TransientException + throws TransientException { try { Filter filter = Filter.createPresenceFilter(LDAP_COMMON_NAME); - String [] attributes = new String[] {LDAP_COMMON_NAME, LDAP_NSACCOUNTLOCK}; - - SearchRequest searchRequest = - new SearchRequest(config.getGroupsDN(), + String[] attributes = new String[]{LDAP_COMMON_NAME, + LDAP_NSACCOUNTLOCK}; + + SearchRequest searchRequest = + new SearchRequest(config.getGroupsDN(), SearchScope.SUB, filter, attributes); - + SearchResult searchResult = null; try { @@ -430,7 +449,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO throw new IllegalStateException("Could not find groups root"); } } - + LdapDAO.checkLdapResult(searchResult.getResultCode()); List<String> groupNames = new ArrayList<String>(); for (SearchResultEntry next : searchResult.getSearchEntries()) @@ -440,49 +459,47 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO groupNames.add(next.getAttributeValue(LDAP_COMMON_NAME)); } } - + return groupNames; } catch (LDAPException e1) { - logger.debug("getGroupNames Exception: " + e1, e1); + logger.debug("getGroupNames Exception: " + e1, e1); LdapDAO.checkLdapResult(e1.getResultCode()); - throw new IllegalStateException("Unexpected exception: " + e1.getMatchedDN(), e1); + throw new IllegalStateException("Unexpected exception: " + e1 + .getMatchedDN(), e1); } } - + /** * Updated the user specified by User. * * @param user - * * @return User instance. - * - * @throws UserNotFoundException when the user is not found. - * @throws TransientException If an temporary, unexpected problem occurred. + * @throws UserNotFoundException when the user is not found. + * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ public User<T> modifyUser(User<T> user) - throws UserNotFoundException, TransientException, - AccessControlException + throws UserNotFoundException, TransientException, + AccessControlException { return null; } - + /** * Delete the user specified by userID. * * @param userID The userID. - * - * @throws UserNotFoundException when the user is not found. - * @throws TransientException If an temporary, unexpected problem occurred. + * @throws UserNotFoundException when the user is not found. + * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ public void deleteUser(final T userID) - throws UserNotFoundException, TransientException, - AccessControlException + throws UserNotFoundException, TransientException, + AccessControlException { - + } /** @@ -539,7 +556,8 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO if (searchResult != null) { - String[] members = searchResult.getAttributeValues(LDAP_MEMBEROF); + String[] members = searchResult + .getAttributeValues(LDAP_MEMBEROF); if (members != null) { for (String member : members) @@ -668,20 +686,21 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO "Unsupported principal type " + user.getUserID() .getClass()); } - + // change the DN to be in the 'java' format if (user.getUserID() instanceof X500Principal) { X500Principal orderedPrincipal = AuthenticationUtil.getOrderedForm( - (X500Principal) user.getUserID()); - searchField = "(" + searchField + "=" + orderedPrincipal.toString() + ")"; + (X500Principal) user.getUserID()); + searchField = "(" + searchField + "=" + orderedPrincipal + .toString() + ")"; } else { searchField = "(" + searchField + "=" + user.getUserID().getName() - + ")"; + + ")"; } - + logger.debug("Search field is: " + searchField); SearchResultEntry searchResult = null; @@ -709,9 +728,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } return searchResult.getAttributeValueAsDN(LDAP_ENTRYDN); } - + protected DN getUserDN(final String userID) - throws LDAPException, TransientException + throws LDAPException, TransientException { try { @@ -719,18 +738,19 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } catch (LDAPException e) { - logger.debug("getUserDN Exception: " + e, e); + logger.debug("getUserDN Exception: " + e, e); LdapDAO.checkLdapResult(e.getResultCode()); } throw new IllegalArgumentException(userID + " not a valid user ID"); } protected DN getUserRequestsDN(final String userID) - throws LDAPException, TransientException + throws LDAPException, TransientException { try { - return new DN(LDAP_UID + "=" + userID + "," + config.getUserRequestsDN()); + return new DN(LDAP_UID + "=" + userID + "," + config + .getUserRequestsDN()); } catch (LDAPException e) { @@ -739,7 +759,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } throw new IllegalArgumentException(userID + " not a valid user ID"); } - + void addAttribute(List<Attribute> attributes, final String name, final String value) { if (value != null && !value.isEmpty()) @@ -748,4 +768,25 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } } + /** + * Checks the Ldap result code, and if the result is not SUCCESS, + * throws an appropriate exception. This is the place to decide on + * mapping between ldap errors and exception types + * + * @param code The code returned from an LDAP request. + * @throws TransientException + * @throws UserAlreadyExistsException + */ + protected static void checkUserLDAPResult(final ResultCode code) + throws TransientException, UserAlreadyExistsException + { + if (code == ResultCode.ENTRY_ALREADY_EXISTS) + { + throw new UserAlreadyExistsException("User already exists."); + } + else + { + LdapDAO.checkLdapResult(code); + } + } } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java index 24ed9de3..ef57b6d4 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java @@ -69,6 +69,7 @@ package ca.nrc.cadc.ac.server.ldap; import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.UserAlreadyExistsException; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.server.UserPersistence; @@ -127,8 +128,10 @@ public class LdapUserPersistence<T extends Principal> * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ + @Override public User<T> addUser(UserRequest<T> user) - throws TransientException, AccessControlException + throws TransientException, AccessControlException, + UserAlreadyExistsException { LdapUserDAO<T> userDAO = null; try diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java index 81d25f43..e7c0cda3 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/CreateUserAction.java @@ -70,11 +70,13 @@ package ca.nrc.cadc.ac.server.web.users; import java.io.InputStream; import ca.nrc.cadc.ac.User; +import ca.nrc.cadc.ac.UserAlreadyExistsException; import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.server.UserPersistence; import ca.nrc.cadc.ac.xml.UserRequestReader; import ca.nrc.cadc.ac.xml.UserWriter; +import javax.servlet.http.HttpServletResponse; import java.security.Principal; public class CreateUserAction<T extends Principal> extends UsersAction @@ -92,9 +94,18 @@ public class CreateUserAction<T extends Principal> extends UsersAction { UserPersistence<Principal> userPersistence = getUserPersistence(); UserRequest<Principal> userRequest = readUserRequest(this.inputStream); - User<Principal> newUser = userPersistence.addUser(userRequest); - writeUser(newUser); - logUserInfo(newUser.getUserID().getName()); + try + { + User<Principal> newUser = userPersistence.addUser(userRequest); + writeUser(newUser); + logUserInfo(newUser.getUserID().getName()); + } + catch (UserAlreadyExistsException e) + { + response.setStatus(HttpServletResponse.SC_CONFLICT); + response.getWriter().write("User already exists"); + } + return null; } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java index 260bc47f..2a6ec56c 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java @@ -75,6 +75,7 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import ca.nrc.cadc.ac.UserAlreadyExistsException; import ca.nrc.cadc.util.StringUtil; import org.apache.log4j.Logger; -- GitLab