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 d4049e2fb3363bce96b81fff1ae46b3366cff508..dae9d245d651331b3a0994cbbfa5d63141c60eaf 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 @@ -260,6 +260,10 @@ public abstract class LdapDAO { throw new TransientException("ldap timeout"); } + else if (code == ResultCode.INVALID_DN_SYNTAX) + { + throw new IllegalArgumentException("Invalid DN syntax"); + } throw new RuntimeException("Ldap error (" + code.getName() + ")"); } 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 dc10edb015acfe5960c7d0f834ef4b92bbda7123..5108b0828c2c1618262d3aa22e63eedc69057829 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 @@ -285,7 +285,16 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO DN userDN; try { - userDN = getUserRequestsDN(userRequest.getUser().getUserID().getName()); + T userID = userRequest.getUser().getUserID(); + try + { + getUser(userID, config.getUsersDN(), false); + throw new UserAlreadyExistsException(userID.getName() + " found in " + + config.getUsersDN()); + } + catch (UserNotFoundException ignore) {} + + userDN = getUserRequestsDN(userID.getName()); addUser(userRequest, userDN); // AD: Search results sometimes come incomplete if @@ -293,7 +302,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO getConnection().reconnect(); try { - return getUser(userRequest.getUser().getUserID(), config.getUserRequestsDN()); + return getUser(userID, config.getUserRequestsDN()); } catch (UserNotFoundException e) { @@ -443,7 +452,6 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO return getUser(userID, config.getUserRequestsDN()); } - /** * Get the user specified by userID. * @@ -455,6 +463,24 @@ 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 + { + return getUser(userID, usersDN, true); + } + + /** + * Get the user specified by userID. + * + * @param userID The userID. + * @param usersDN The LDAP tree to search. + * @param proxy If true proxy the request as the calling user. + * @return User instance. + * @throws UserNotFoundException when the user is not found. + * @throws TransientException If an temporary, unexpected problem occurred. + * @throws AccessControlException If the operation is not permitted. + */ + private User<T> getUser(final T userID, final String usersDN, boolean proxy) throws UserNotFoundException, TransientException, AccessControlException { @@ -474,7 +500,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO SearchRequest searchRequest = new SearchRequest(usersDN, SearchScope.SUB, searchField, userAttribs); - if (isSecure(usersDN)) + if (proxy && isSecure(usersDN)) { searchRequest.addControl( new ProxiedAuthorizationV2RequestControl( diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/SyncOutput.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/SyncOutput.java index 9ebd42f75c00d63f1ccc05a6cee320bb8e3b6d7f..1f67b9bf613c852c294515d673c4247b75c42dad 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/SyncOutput.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/SyncOutput.java @@ -97,16 +97,18 @@ public class SyncOutput public void setCode(int code) { + log.debug("setting code"); if (writer != null) - return; + throw new IllegalStateException("attempted to set code after writer has been opened"); response.setStatus(code); + log.debug("set code " + code); } public void setHeader(String key, Object value) { if (writer != null) - return; + throw new IllegalStateException("attempted to set header after writer has been opened"); if (value == null) response.setHeader(key, null); diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java index 0a7266ca4ac83cee0232619b1ef5500b7d99051e..af79d45ffa72d6f8adcbe4db50a154d006aca303 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/AbstractUserAction.java @@ -69,7 +69,9 @@ package ca.nrc.cadc.ac.server.web.users; import ca.nrc.cadc.ac.PersonalDetails; +import ca.nrc.cadc.ac.ReaderException; 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.json.JsonUserListWriter; @@ -158,6 +160,13 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob this.logInfo.setMessage(message); sendError(400, message); } + catch (ReaderException e) + { + log.debug(e.getMessage(), e); + String message = e.getMessage(); + this.logInfo.setMessage(message); + sendError(400, message); + } catch (UserNotFoundException e) { log.debug(e.getMessage(), e); @@ -165,6 +174,13 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob this.logInfo.setMessage(message); sendError(404, message); } + catch (UserAlreadyExistsException e) + { + log.debug(e.getMessage(), e); + String message = "User not found: " + e.getMessage(); + this.logInfo.setMessage(message); + sendError(409, message); + } catch (UnsupportedOperationException e) { log.debug(e.getMessage(), e); @@ -198,19 +214,19 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob private void sendError(int responseCode, String message) { + syncOut.setCode(responseCode); syncOut.setHeader("Content-Type", "text/plain"); if (message != null) { try { - syncOut.getWriter() .write(message); + syncOut.getWriter().write(message); } catch (IOException e) { log.warn("Could not write error message to output stream"); } } - syncOut.setCode(responseCode); } @SuppressWarnings("unchecked") @@ -344,28 +360,4 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob } } - void redirectGet(User<?> user) throws Exception - { - final Set<Principal> httpPrincipals = user.getIdentities(); - - String id = null; - String idType = null; - Iterator<Principal> i = httpPrincipals.iterator(); - Principal next = null; - while (idType == null && i.hasNext()) - { - next = i.next(); - idType = AuthenticationUtil.getPrincipalType(next); - id = next.getName(); - } - - if (idType == null) - { - throw new IllegalStateException("No identities found."); - } - - final String redirectURL = "/" + id + "?idType=" + idType; - syncOut.setHeader("Location", redirectURL); - syncOut.setCode(303); - } } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java index 4e7ebe372ba2a3c0feb149274bf8bbfcbb38b58f..51777edcdfc1e20d793a15bc9bf74e8c510a963c 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/ModifyUserAction.java @@ -84,13 +84,15 @@ import java.util.Set; public class ModifyUserAction extends AbstractUserAction { private final InputStream inputStream; + private final String request; - ModifyUserAction(final InputStream inputStream) + ModifyUserAction(final InputStream inputStream, final String request) { super(); this.inputStream = inputStream; + this.request = request; } @@ -100,7 +102,8 @@ public class ModifyUserAction extends AbstractUserAction final User<Principal> modifiedUser = modifyUser(user); logUserInfo(modifiedUser.getUserID().getName()); - redirectGet(modifiedUser); + syncOut.setHeader("Location", request); + syncOut.setCode(303); } /** diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java index 6c7b0c33338c075c71e3688f65d068f0bb6c2773..457dd4b1b686ef42092abd6378945affbf82ed05 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserActionFactory.java @@ -77,6 +77,7 @@ import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.auth.OpenIdPrincipal; import java.io.IOException; +import java.net.URL; import java.security.Principal; import javax.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; @@ -169,7 +170,23 @@ public abstract class UserActionFactory if (segments.length == 1) { - action = new ModifyUserAction(request.getInputStream()); + final URL requestURL = new URL(request.getRequestURL().toString()); + final StringBuilder sb = new StringBuilder(); + sb.append(requestURL.getProtocol()); + sb.append("://"); + sb.append(requestURL.getHost()); + if (requestURL.getPort() > 0) + { + sb.append(":"); + sb.append(requestURL.getPort()); + } + sb.append(request.getContextPath()); + sb.append(request.getServletPath()); + sb.append(path); + sb.append("?"); + sb.append(request.getQueryString()); + + action = new ModifyUserAction(request.getInputStream(), sb.toString()); } if (action != null) @@ -242,7 +259,7 @@ public abstract class UserActionFactory { return new User<X500Principal>(new X500Principal(userName)); } - else if (idType.equalsIgnoreCase(IdentityType.UID.getValue())) + else if (idType.equalsIgnoreCase(IdentityType.CADC.getValue())) { return new User<NumericPrincipal>(new NumericPrincipal( Long.parseLong(userName))); diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java index 69a5c20a786b9cf364713c9555fd13a2b195cb60..6fbb19c354a93371a55156836e135a8394784f0f 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserServlet.java @@ -192,7 +192,7 @@ public class UserServlet extends HttpServlet public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { - doAction(UserActionFactory.httpGetFactory(), request, response); + doAction(UserActionFactory.httpPostFactory(), request, response); } @Override diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java index ff4538b29c58b0c6a33548b1907f78077309a866..861403fac3f2c3d8e3808c0210fe439935e53ebc 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/ModifyUserActionTest.java @@ -108,6 +108,7 @@ public class ModifyUserActionTest final byte[] input = sb.toString().getBytes(); final InputStream inputStream = new ByteArrayInputStream(input); + final String request = "/CADCtest?idType=http"; // Should match the JSON above, without the e-mail modification. Principal principal = new HttpPrincipal("CADCtest"); @@ -119,8 +120,6 @@ public class ModifyUserActionTest personalDetail.email = "CADC.Test@nrc-cnrc.gc.ca"; userObject.details.add(personalDetail); - final HttpServletRequest mockRequest = - createMock(HttpServletRequest.class); final SyncOutput mockSyncOut = createMock(SyncOutput.class); @@ -130,11 +129,9 @@ public class ModifyUserActionTest expect(mockUserPersistence.modifyUser(userObject)).andReturn( userObject).once(); -// -// expect(mockRequest.getRemoteAddr()).andReturn(requestURL). -// once(); - mockSyncOut.setHeader("Location", "/CADCtest?idType=http"); + + mockSyncOut.setHeader("Location", request); expectLastCall().once(); mockSyncOut.setCode(303); @@ -143,9 +140,9 @@ public class ModifyUserActionTest mockSyncOut.setHeader("Content-Type", "application/json"); expectLastCall().once(); - replay(mockRequest, mockSyncOut, mockUserPersistence); + replay(mockSyncOut, mockUserPersistence); - final ModifyUserAction testSubject = new ModifyUserAction(inputStream) + final ModifyUserAction testSubject = new ModifyUserAction(inputStream, request) { @Override @SuppressWarnings("unchecked") @@ -161,6 +158,6 @@ public class ModifyUserActionTest testSubject.setLogInfo(logInfo); testSubject.doAction(); - verify(mockRequest, mockSyncOut, mockUserPersistence); + verify(mockSyncOut, mockUserPersistence); } } diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java index 93aa2a541fdc96f9b2ba2f2057ab37becf347c8c..54db0b92985648da2304dadf29e42e63fcbaaa62 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/UserActionFactoryTest.java @@ -175,11 +175,12 @@ public class UserActionFactoryTest HttpServletRequest request = EasyMock.createMock(HttpServletRequest.class); EasyMock.expect(request.getPathInfo()).andReturn("userName"); - //EasyMock.expect(request.getRequestURL()).andReturn(sb); - //EasyMock.expect(request.getContextPath()).andReturn(""); - //EasyMock.expect(request.getServletPath()).andReturn(""); + EasyMock.expect(request.getRequestURL()).andReturn(sb); + EasyMock.expect(request.getContextPath()).andReturn(""); + EasyMock.expect(request.getServletPath()).andReturn(""); + EasyMock.expect(request.getQueryString()).andReturn(""); EasyMock.expect(request.getInputStream()).andReturn(null); - //EasyMock.expect(request.getParameter("idType")).andReturn("sessionID"); +// EasyMock.expect(request.getParameter("idType")).andReturn("sessionID"); EasyMock.replay(request); AbstractUserAction action = UserActionFactory.httpPostFactory().createAction(request); EasyMock.verify(request); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java index 97a63b6bb2827991999266e3e547cdf4bd31f42d..70ec423820e5bac0c3878dda8cb7a7469279e151 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/User.java @@ -152,6 +152,18 @@ public class User<T extends Principal> return getClass().getSimpleName() + "[" + userID.getName() + "]"; } + public <S extends UserDetails>S getUserDetail(final Class<S> userDetailsClass) + { + for (final UserDetails ud : details) + { + if (ud.getClass() == userDetailsClass) + { + return (S) ud; + } + } + return null; + } + public <S extends UserDetails> Set<S> getDetails( final Class<S> userDetailsClass) { diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java index be5ce05a46b28437ecce9e5bc2b91df2a7a906b7..3f0a4f954a61d5ec56ca98e4773e3ab842f2c401 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java @@ -83,7 +83,6 @@ import java.security.AccessControlException; import java.security.AccessController; import java.security.Principal; import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -239,7 +238,7 @@ public class GMSClient implements TransferListener { final URL usersListURL = new URL(this.baseURL + "/users"); return new HttpDownload(usersListURL, - new JSONUserListInputStreamWrapper(webUsers)); + new JsonUserListInputStreamWrapper(webUsers)); } /** diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java deleted file mode 100644 index 8e3a47447965467f2f822dc5a532fff1ab0571a0..0000000000000000000000000000000000000000 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JSONUserListInputStreamWrapper.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - ************************************************************************ - ******************* 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.client; - -import ca.nrc.cadc.ac.PersonalDetails; -import ca.nrc.cadc.ac.User; -import ca.nrc.cadc.auth.HttpPrincipal; -import ca.nrc.cadc.net.InputStreamWrapper; -import ca.nrc.cadc.util.StringUtil; -import org.apache.log4j.Logger; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.List; - -public class JSONUserListInputStreamWrapper implements InputStreamWrapper -{ - private static final Logger LOGGER = Logger - .getLogger(JSONUserListInputStreamWrapper.class); - private final List<User<HttpPrincipal>> output; - - - public JSONUserListInputStreamWrapper( - final List<User<HttpPrincipal>> output) - { - this.output = output; - } - - - /** - * Read the stream in. - * - * @param inputStream The stream to read from. - * @throws IOException Any reading exceptions. - */ - @Override - public void read(final InputStream inputStream) throws IOException - { - String line = null; - - try - { - final InputStreamReader inReader = - new InputStreamReader(inputStream); - final BufferedReader reader = new BufferedReader(inReader); - - while (StringUtil.hasText(line = reader.readLine())) - { - // Deal with arrays stuff. - while (line.startsWith("[") || line.startsWith(",")) - { - line = line.substring(1); - } - - while (line.endsWith("]") || line.endsWith(",")) - { - line = line.substring(0, (line.length() - 1)); - } - - if (StringUtil.hasText(line)) - { - LOGGER.debug(String.format("Reading: %s", line)); - - final JSONObject jsonObject = new JSONObject(line); - final User<HttpPrincipal> webUser = - new User<HttpPrincipal>( - new HttpPrincipal(jsonObject - .getString("id"))); - final String firstName = jsonObject.getString("firstName"); - final String lastName = jsonObject.getString("lastName"); - - webUser.details - .add(new PersonalDetails(firstName, lastName)); - - output.add(webUser); - } - } - } - catch (Exception bug) - { - throw new IOException(bug + (StringUtil.hasText(line) - ? "Error line is " + line : "")); - } - } -} diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapper.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapper.java index 8e3a47447965467f2f822dc5a532fff1ab0571a0..f00b0aeef2821f4740ae2eab7130b33d0001009f 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapper.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapper.java @@ -82,15 +82,15 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; -public class JSONUserListInputStreamWrapper implements InputStreamWrapper +public class JsonUserListInputStreamWrapper implements InputStreamWrapper { private static final Logger LOGGER = Logger - .getLogger(JSONUserListInputStreamWrapper.class); + .getLogger(JsonUserListInputStreamWrapper.class); private final List<User<HttpPrincipal>> output; - public JSONUserListInputStreamWrapper( - final List<User<HttpPrincipal>> output) + public JsonUserListInputStreamWrapper( + final List<User<HttpPrincipal>> output) { this.output = output; } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java index c108f030c4fb867b52b98649648e60c99f5d2243..a22a7519f360b2598a9728110b0163e6dfab2f3c 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java @@ -264,7 +264,7 @@ public class UserClient } else if (principal instanceof NumericPrincipal) { - idTypeStr = IdentityType.UID.getValue(); + idTypeStr = IdentityType.CADC.getValue(); } else if (principal instanceof CookiePrincipal) { diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java similarity index 99% rename from projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java rename to projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java index db221a9de08a4b7b7a8d7d81c02f4b98b8bced97..7401185b0487eafa718057a3fa74732f74f0e6bc 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractXML.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/AbstractReaderWriter.java @@ -100,9 +100,9 @@ import java.util.List; import java.util.Set; /** - * AbstractXML TODO describe class + * AbstractReaderWriter TODO describe class */ -public abstract class AbstractXML +public abstract class AbstractReaderWriter { /** * Write to root Element to a writer. @@ -120,244 +120,58 @@ public abstract class AbstractXML } /** - * Get a UserRequest object from a JDOM element. + * Get a User object from a JDOM element. * - * @param element The UserRequest JDOM element. - * @return A UserRequest object. + * @param element The User JDOM element. + * @return A User object. * @throws ReaderException */ - protected final Group getGroup(Element element) + protected final User<Principal> getUser(Element element) throws ReaderException { - String uri = element.getAttributeValue("uri"); - if (uri == null) + // userID element of the User element + Element userIDElement = element.getChild("userID"); + if (userIDElement == null) { - String error = "group missing required uri attribute"; + String error = "userID element not found in user element"; throw new ReaderException(error); } - // Group groupID - int index = uri.indexOf(AC.GROUP_URI); - if (index == -1) + // identity element of the userID element + Element userIDIdentityElement = userIDElement.getChild("identity"); + if (userIDIdentityElement == null) { - String error = "group uri attribute malformed: " + uri; + String error = "identity element not found in userID element"; throw new ReaderException(error); } - String groupID = uri.substring(AC.GROUP_URI.length()); - - // Group owner - User<? extends Principal> user = null; - Element ownerElement = element.getChild("owner"); - if (ownerElement != null) - { - // Owner user - Element userElement = ownerElement.getChild("user"); - if (userElement == null) - { - String error = "owner missing required user element"; - throw new ReaderException(error); - } - user = getUser(userElement); - } - - Group group = new Group(groupID, user); - - // description - Element descriptionElement = element.getChild("description"); - if (descriptionElement != null) - { - group.description = descriptionElement.getText(); - } - - // lastModified - Element lastModifiedElement = element.getChild("lastModified"); - if (lastModifiedElement != null) - { - try - { - DateFormat df = DateUtil.getDateFormat(DateUtil.IVOA_DATE_FORMAT, DateUtil.UTC); - group.lastModified = df.parse(lastModifiedElement.getText()); - } - catch (ParseException e) - { - String error = "Unable to parse group lastModified because " + e.getMessage(); - - throw new ReaderException(error); - } - } - - // properties - Element propertiesElement = element.getChild("properties"); - if (propertiesElement != null) - { - List<Element> propertyElements = propertiesElement.getChildren("property"); - for (Element propertyElement : propertyElements) - { - group.getProperties().add(getGroupProperty(propertyElement)); - } - } - - // groupMembers - Element groupMembersElement = element.getChild("groupMembers"); - if (groupMembersElement != null) - { - List<Element> groupElements = groupMembersElement.getChildren("group"); - for (Element groupMember : groupElements) - { - group.getGroupMembers().add(getGroup(groupMember)); - } - } - - // userMembers - Element userMembersElement = element.getChild("userMembers"); - if (userMembersElement != null) - { - List<Element> userElements = userMembersElement.getChildren("user"); - for (Element userMember : userElements) - { - group.getUserMembers().add(getUser(userMember)); - } - } - // groupAdmins - Element groupAdminsElement = element.getChild("groupAdmins"); - if (groupAdminsElement != null) - { - List<Element> groupElements = groupAdminsElement.getChildren("group"); - for (Element groupMember : groupElements) - { - group.getGroupAdmins().add(getGroup(groupMember)); - } - } + Principal userID = getPrincipal(userIDIdentityElement); + User<Principal> user = new User<Principal>(userID); - // userAdmins - Element userAdminsElement = element.getChild("userAdmins"); - if (userAdminsElement != null) + // identities + Element identitiesElement = element.getChild("identities"); + if (identitiesElement != null) { - List<Element> userElements = userAdminsElement.getChildren("user"); - for (Element userMember : userElements) + List<Element> identityElements = identitiesElement.getChildren("identity"); + for (Element identityElement : identityElements) { - group.getUserAdmins().add(getUser(userMember)); + user.getIdentities().add(getPrincipal(identityElement)); } - } - - return group; - } - - /** - * Get a JDOM element from a Group object. - * - * @param group The UserRequest. - * @return A JDOM Group representation. - * @throws WriterException - */ - protected final Element getElement(Group group) - throws WriterException - { - return getElement(group, true); - } - - /** - * Get a JDOM element from a Group object. - * - * @param group The UserRequest. - * @param deepCopy Return all Group elements. - * @return A JDOM Group representation. - * @throws WriterException - */ - protected final Element getElement(Group group, boolean deepCopy) - throws WriterException - { - // Create the root group element. - Element groupElement = new Element("group"); - String groupURI = AC.GROUP_URI + group.getID(); - groupElement.setAttribute(new Attribute("uri", groupURI)); - // Group owner - if (group.getOwner() != null) - { - Element ownerElement = new Element("owner"); - Element userElement = getElement(group.getOwner()); - ownerElement.addContent(userElement); - groupElement.addContent(ownerElement); } - if (deepCopy) + // details + Element detailsElement = element.getChild("details"); + if (detailsElement != null) { - // Group description - if (group.description != null) - { - Element descriptionElement = new Element("description"); - descriptionElement.setText(group.description); - groupElement.addContent(descriptionElement); - } - - // lastModified - if (group.lastModified != null) - { - Element lastModifiedElement = new Element("lastModified"); - DateFormat df = DateUtil.getDateFormat(DateUtil.IVOA_DATE_FORMAT, DateUtil.UTC); - lastModifiedElement.setText(df.format(group.lastModified)); - groupElement.addContent(lastModifiedElement); - } - - // Group properties - if (!group.getProperties().isEmpty()) - { - Element propertiesElement = new Element("properties"); - for (GroupProperty property : group.getProperties()) - { - propertiesElement.addContent(getElement(property)); - } - groupElement.addContent(propertiesElement); - } - - // Group groupMembers. - if ((group.getGroupMembers() != null) && (!group.getGroupMembers().isEmpty())) - { - Element groupMembersElement = new Element("groupMembers"); - for (Group groupMember : group.getGroupMembers()) - { - groupMembersElement.addContent(getElement(groupMember, false)); - } - groupElement.addContent(groupMembersElement); - } - - // Group userMembers - if ((group.getUserMembers() != null) && (!group.getUserMembers().isEmpty())) - { - Element userMembersElement = new Element("userMembers"); - for (User<? extends Principal> userMember : group.getUserMembers()) - { - userMembersElement.addContent(getElement(userMember)); - } - groupElement.addContent(userMembersElement); - } - - // Group groupAdmins. - if ((group.getGroupAdmins() != null) && (!group.getGroupAdmins().isEmpty())) - { - Element groupAdminsElement = new Element("groupAdmins"); - for (Group groupMember : group.getGroupAdmins()) - { - groupAdminsElement.addContent(getElement(groupMember, false)); - } - groupElement.addContent(groupAdminsElement); - } - - // Group userAdmins - if ((group.getUserAdmins() != null) && (!group.getUserAdmins().isEmpty())) + List<Element> userDetailsElements = detailsElement.getChildren("userDetails"); + for (Element userDetailsElement : userDetailsElements) { - Element userAdminsElement = new Element("userAdmins"); - for (User<? extends Principal> userMember : group.getUserAdmins()) - { - userAdminsElement.addContent(getElement(userMember)); - } - groupElement.addContent(userAdminsElement); + user.details.add(getUserDetails(userDetailsElement)); } } - return groupElement; + return user; } /** @@ -392,128 +206,364 @@ public abstract class AbstractXML } /** - * Get a JDOM element from a UserRequest object. + * Get a Principal object from a JDOM element. * - * @param userRequest The UserRequest. - * @return A JDOM UserRequest representation. - * @throws WriterException + * @param element The Principal JDOM element. + * @return A Principal object. + * @throws ReaderException */ - protected final Element getElement(UserRequest<? extends Principal> userRequest) - throws WriterException + protected final Principal getPrincipal(Element element) + throws ReaderException { - // Create the userRequest Element. - Element userRequestElement = new Element("userRequest"); - - // user element - Element userElement = getElement(userRequest.getUser()); - userRequestElement.addContent(userElement); + if (element == null) + { + String error = "null identity element"; + throw new ReaderException(error); + } - // password element - Element passwordElement = new Element("password"); - passwordElement.setText(String.valueOf(userRequest.getPassword())); - userRequestElement.addContent(passwordElement); + if (!element.getName().equals("identity")) + { + String error = "expected identity element name, found " + + element.getName(); + throw new ReaderException(error); + } - return userRequestElement; + String type = element.getAttributeValue("type"); + if (type == null) + { + String error = "type attribute not found in identity element" + + element.getName(); + throw new ReaderException(error); + } + + String identity = element.getText(); + Principal principal; + if (type.equals(IdentityType.OPENID.getValue())) + { + principal = new OpenIdPrincipal(identity); + } + else if (type.equals(IdentityType.CADC.getValue())) + { + Integer cadcID; + try + { + cadcID = Integer.valueOf(identity); + } + catch (NumberFormatException e) + { + String error = "Non-integer cadcID: " + identity; + throw new ReaderException(error); + } + principal = new NumericPrincipal(cadcID); + } + else if (type.equals(IdentityType.USERNAME.getValue())) + { + principal = new HttpPrincipal(identity); + } + else if (type.equals(IdentityType.X500.getValue())) + { + principal = new X500Principal(identity); + } + else + { + String error = "Unknown type attribute: " + type; + throw new ReaderException(error); + } + + return principal; } /** - * Get a User object from a JDOM element. + * Get a UserDetails object from a JDOM element. * - * @param element The User JDOM element. - * @return A User object. + * @param element The UserDetails JDOM element. + * @return A UserDetails object. * @throws ReaderException */ - protected final User<Principal> getUser(Element element) + protected final UserDetails getUserDetails(Element element) throws ReaderException { - // userID element of the User element - Element userIDElement = element.getChild("userID"); - if (userIDElement == null) + if (element == null) { - String error = "userID element not found in user element"; + throw new ReaderException("null UserDetails"); + } + + if (!element.getName().equals(UserDetails.NAME)) + { + String error = "expected element name userDetails, found " + + element.getName(); throw new ReaderException(error); } - // identity element of the userID element - Element userIDIdentityElement = userIDElement.getChild("identity"); - if (userIDIdentityElement == null) + String type = element.getAttributeValue(UserDetails.TYPE_ATTRIBUTE); + if (type == null) { - String error = "identity element not found in userID element"; + String error = "userDetails missing required attribute type"; throw new ReaderException(error); } - Principal userID = getPrincipal(userIDIdentityElement); - User<Principal> user = new User<Principal>(userID); + if (type.equals(PosixDetails.NAME)) + { + return getPosixDetails(element); + } + if (type.equals(PersonalDetails.NAME)) + { + return getPersonalDetails(element); + } - // identities - Element identitiesElement = element.getChild("identities"); - if (identitiesElement != null) + String error = "Unknown UserDetails attribute type " + type; + throw new ReaderException(error); + } + + /** + * Get a PosixDetails object from a JDOM element. + * + * @param element The PosixDetails JDOM element. + * @return A PosixDetails object. + * @throws ReaderException + */ + protected final PosixDetails getPosixDetails(Element element) + throws ReaderException + { + // uid + Element uidElement = element.getChild(PosixDetails.UID); + if (uidElement == null) { - List<Element> identityElements = identitiesElement.getChildren("identity"); - for (Element identityElement : identityElements) - { - user.getIdentities().add(getPrincipal(identityElement)); - } + String error = "posixDetails missing required element uid"; + throw new ReaderException(error); + } + long uid; + try + { + uid = Long.valueOf(uidElement.getText()); + } + catch (NumberFormatException e) + { + String error = "Cannot parse posixDetails uid to a long"; + throw new ReaderException(error); + } + // gid + Element gidElement = element.getChild(PosixDetails.GID); + if (gidElement == null) + { + String error = "posixDetails missing required element gid"; + throw new ReaderException(error); + } + long gid; + try + { + gid = Long.valueOf(gidElement.getText()); + } + catch (NumberFormatException e) + { + String error = "Cannot parse posixDetails gid to a long"; + throw new ReaderException(error); } - // details - Element detailsElement = element.getChild("details"); - if (detailsElement != null) + // homeDirectory + Element homeDirElement = element.getChild(PosixDetails.HOME_DIRECTORY); + if (homeDirElement == null) { - List<Element> userDetailsElements = detailsElement.getChildren("userDetails"); - for (Element userDetailsElement : userDetailsElements) - { - user.details.add(getUserDetails(userDetailsElement)); - } + String error = "posixDetails missing required element homeDirectory"; + throw new ReaderException(error); } + String homeDirectory = homeDirElement.getText(); - return user; + return new PosixDetails(uid, gid, homeDirectory); } /** - * Get a JDOM element from a User object. + * Get a PersonalDetails object from a JDOM element. * - * @param user The User. - * @return A JDOM User representation. - * @throws WriterException + * @param element The PersonalDetails JDOM element. + * @return A PersonalDetails object. + * @throws ReaderException */ - protected final Element getElement(User<? extends Principal> user) - throws WriterException + protected final PersonalDetails getPersonalDetails(Element element) + throws ReaderException { - // Create the user Element. - Element userElement = new Element("user"); + // firstName + Element firstNameElement = element.getChild(PersonalDetails.FIRSTNAME); + if (firstNameElement == null) + { + String error = "personalDetails missing required element firstName"; + throw new ReaderException(error); + } + String firstName = firstNameElement.getText(); - // userID element - Element userIDElement = new Element("userID"); - userIDElement.addContent(getElement(user.getUserID())); - userElement.addContent(userIDElement); + // lastName + Element lastNameElement = element.getChild(PersonalDetails.LASTNAME); + if (lastNameElement == null) + { + String error = "personalDetails missing required element lastName"; + throw new ReaderException(error); + } + String lastName = lastNameElement.getText(); - // identities - Set<Principal> identities = user.getIdentities(); - if (!identities.isEmpty()) + PersonalDetails details = new PersonalDetails(firstName, lastName); + + // email + Element emailElement = element.getChild(PersonalDetails.EMAIL); + if (emailElement != null) { - Element identitiesElement = new Element("identities"); - for (Principal identity : identities) + details.email = emailElement.getText(); + } + + // address + Element addressElement = element.getChild(PersonalDetails.ADDRESS); + if (addressElement != null) + { + details.address = addressElement.getText(); + } + + // institute + Element instituteElement = element.getChild(PersonalDetails.INSTITUTE); + if (instituteElement != null) + { + details.institute = instituteElement.getText(); + } + + // city + Element cityElement = element.getChild(PersonalDetails.CITY); + if (cityElement != null) + { + details.city = cityElement.getText(); + } + + // country + Element countryElement = element.getChild(PersonalDetails.COUNTRY); + if (countryElement != null) + { + details.country = countryElement.getText(); + } + + return details; + } + + /** + * Get a UserRequest object from a JDOM element. + * + * @param element The UserRequest JDOM element. + * @return A UserRequest object. + * @throws ReaderException + */ + protected final Group getGroup(Element element) + throws ReaderException + { + String uri = element.getAttributeValue("uri"); + if (uri == null) + { + String error = "group missing required uri attribute"; + throw new ReaderException(error); + } + + // Group groupID + int index = uri.indexOf(AC.GROUP_URI); + if (index == -1) + { + String error = "group uri attribute malformed: " + uri; + throw new ReaderException(error); + } + String groupID = uri.substring(AC.GROUP_URI.length()); + + // Group owner + User<? extends Principal> user = null; + Element ownerElement = element.getChild("owner"); + if (ownerElement != null) + { + // Owner user + Element userElement = ownerElement.getChild("user"); + if (userElement == null) { - identitiesElement.addContent(getElement(identity)); + String error = "owner missing required user element"; + throw new ReaderException(error); } - userElement.addContent(identitiesElement); + user = getUser(userElement); } - // details - if (!user.details.isEmpty()) + Group group = new Group(groupID, user); + + // description + Element descriptionElement = element.getChild("description"); + if (descriptionElement != null) { - Element detailsElement = new Element("details"); - Set<UserDetails> userDetails = user.details; - for (UserDetails userDetail : userDetails) + group.description = descriptionElement.getText(); + } + + // lastModified + Element lastModifiedElement = element.getChild("lastModified"); + if (lastModifiedElement != null) + { + try { - detailsElement.addContent(getElement(userDetail)); + DateFormat df = DateUtil.getDateFormat(DateUtil.IVOA_DATE_FORMAT, DateUtil.UTC); + group.lastModified = df.parse(lastModifiedElement.getText()); + } + catch (ParseException e) + { + String error = "Unable to parse group lastModified because " + e.getMessage(); + + throw new ReaderException(error); + } + } + + // properties + Element propertiesElement = element.getChild("properties"); + if (propertiesElement != null) + { + List<Element> propertyElements = propertiesElement.getChildren("property"); + for (Element propertyElement : propertyElements) + { + group.getProperties().add(getGroupProperty(propertyElement)); + } + } + + // groupMembers + Element groupMembersElement = element.getChild("groupMembers"); + if (groupMembersElement != null) + { + List<Element> groupElements = groupMembersElement.getChildren("group"); + for (Element groupMember : groupElements) + { + group.getGroupMembers().add(getGroup(groupMember)); + } + } + + // userMembers + Element userMembersElement = element.getChild("userMembers"); + if (userMembersElement != null) + { + List<Element> userElements = userMembersElement.getChildren("user"); + for (Element userMember : userElements) + { + group.getUserMembers().add(getUser(userMember)); + } + } + + // groupAdmins + Element groupAdminsElement = element.getChild("groupAdmins"); + if (groupAdminsElement != null) + { + List<Element> groupElements = groupAdminsElement.getChildren("group"); + for (Element groupMember : groupElements) + { + group.getGroupAdmins().add(getGroup(groupMember)); + } + } + + // userAdmins + Element userAdminsElement = element.getChild("userAdmins"); + if (userAdminsElement != null) + { + List<Element> userElements = userAdminsElement.getChildren("user"); + for (Element userMember : userElements) + { + group.getUserAdmins().add(getUser(userMember)); } - userElement.addContent(detailsElement); } - return userElement; + return group; } /** @@ -575,329 +625,117 @@ public abstract class AbstractXML } /** - * Get a JDOM element from a GroupProperty object. + * Get a JDOM element from a User object. * - * @param property The GroupProperty. - * @return A JDOM GroupProperty representation. + * @param user The User. + * @return A JDOM User representation. * @throws WriterException */ - protected final Element getElement(GroupProperty property) + protected final Element getElement(User<? extends Principal> user) throws WriterException { - if (property == null) - { - throw new WriterException("null GroupProperty"); - } - - Element propertyElement = new Element(GroupProperty.NAME); - propertyElement.setAttribute(GroupProperty.KEY_ATTRIBUTE, - property.getKey()); - if (property.isReadOnly()) - { - propertyElement.setAttribute(GroupProperty.READONLY_ATTRIBUTE, - "true"); - } - - Object value = property.getValue(); - if ((value instanceof String)) - { - propertyElement.setAttribute(GroupProperty.TYPE_ATTRIBUTE, - GroupProperty.STRING_TYPE); - } - else if ((value instanceof Integer)) - { - propertyElement.setAttribute(GroupProperty.TYPE_ATTRIBUTE, - GroupProperty.INTEGER_TYPE); - } - else - { - String error = "Unsupported value type: " + - value.getClass().getSimpleName(); - throw new IllegalArgumentException(error); - } - propertyElement.setText(String.valueOf(property.getValue())); - - return propertyElement; - } - - /** - * Get a Principal object from a JDOM element. - * - * @param element The Principal JDOM element. - * @return A Principal object. - * @throws ReaderException - */ - protected final Principal getPrincipal(Element element) - throws ReaderException - { - if (element == null) - { - String error = "null identity element"; - throw new ReaderException(error); - } + // Create the user Element. + Element userElement = new Element("user"); - if (!element.getName().equals("identity")) - { - String error = "expected identity element name, found " + - element.getName(); - throw new ReaderException(error); - } + // userID element + Element userIDElement = new Element("userID"); + userIDElement.addContent(getElement(user.getUserID())); + userElement.addContent(userIDElement); - String type = element.getAttributeValue("type"); - if (type == null) + // identities + Set<Principal> identities = user.getIdentities(); + if (!identities.isEmpty()) { - String error = "type attribute not found in identity element" + - element.getName(); - throw new ReaderException(error); + Element identitiesElement = new Element("identities"); + for (Principal identity : identities) + { + identitiesElement.addContent(getElement(identity)); + } + userElement.addContent(identitiesElement); } - String identity = element.getText(); - Principal principal; - if (type.equals(IdentityType.OPENID.getValue())) - { - principal = new OpenIdPrincipal(identity); - } - else if (type.equals(IdentityType.UID.getValue())) + // details + if (!user.details.isEmpty()) { - Integer cadcID; - try - { - cadcID = Integer.valueOf(identity); - } - catch (NumberFormatException e) + Element detailsElement = new Element("details"); + Set<UserDetails> userDetails = user.details; + for (UserDetails userDetail : userDetails) { - String error = "Non-integer cadcID: " + identity; - throw new ReaderException(error); + detailsElement.addContent(getElement(userDetail)); } - principal = new NumericPrincipal(cadcID); - } - else if (type.equals(IdentityType.USERNAME.getValue())) - { - principal = new HttpPrincipal(identity); - } - else if (type.equals(IdentityType.X500.getValue())) - { - principal = new X500Principal(identity); - } - else - { - String error = "Unknown type attribute: " + type; - throw new ReaderException(error); + userElement.addContent(detailsElement); } - return principal; + return userElement; } /** - * Get a JDOM element from a Principal object. + * Get a JDOM element from a UserRequest object. * - * @param identity The Principal. - * @return A JDOM UserDetails representation. + * @param userRequest The UserRequest. + * @return A JDOM UserRequest representation. * @throws WriterException - */ - protected final Element getElement(Principal identity) - throws WriterException - { - if (identity == null) - { - String error = "null identity"; - throw new WriterException(error); - } - - Element identityElement = new Element("identity"); - if ((identity instanceof HttpPrincipal)) - { - identityElement.setAttribute("type", IdentityType.USERNAME.getValue()); - } - else if ((identity instanceof NumericPrincipal)) - { - identityElement.setAttribute("type", IdentityType.UID.getValue()); - } - else if ((identity instanceof OpenIdPrincipal)) - { - identityElement.setAttribute("type", IdentityType.OPENID.getValue()); - } - else if ((identity instanceof X500Principal)) - { - identityElement.setAttribute("type", IdentityType.X500.getValue()); - } - else - { - String error = "Unsupported Principal type " + - identity.getClass().getSimpleName(); - throw new IllegalArgumentException(error); - } - identityElement.setText(identity.getName()); - - return identityElement; - } - - /** - * Get a UserDetails object from a JDOM element. - * - * @param element The UserDetails JDOM element. - * @return A UserDetails object. - * @throws ReaderException - */ - protected final UserDetails getUserDetails(Element element) - throws ReaderException - { - if (element == null) - { - throw new ReaderException("null UserDetails"); - } - - if (!element.getName().equals(UserDetails.NAME)) - { - String error = "expected element name userDetails, found " + - element.getName(); - throw new ReaderException(error); - } - - String type = element.getAttributeValue(UserDetails.TYPE_ATTRIBUTE); - if (type == null) - { - String error = "userDetails missing required attribute type"; - throw new ReaderException(error); - } - - if (type.equals(PosixDetails.NAME)) - { - return getPosixDetails(element); - } - if (type.equals(PersonalDetails.NAME)) - { - return getPersonalDetails(element); - } - - String error = "Unknown UserDetails attribute type " + type; - throw new ReaderException(error); - } - - /** - * Get a PosixDetails object from a JDOM element. - * - * @param element The PosixDetails JDOM element. - * @return A PosixDetails object. - * @throws ReaderException - */ - protected final PosixDetails getPosixDetails(Element element) - throws ReaderException - { - // uid - Element uidElement = element.getChild(PosixDetails.UID); - if (uidElement == null) - { - String error = "posixDetails missing required element uid"; - throw new ReaderException(error); - } - long uid; - try - { - uid = Long.valueOf(uidElement.getText()); - } - catch (NumberFormatException e) - { - String error = "Cannot parse posixDetails uid to a long"; - throw new ReaderException(error); - } - - // gid - Element gidElement = element.getChild(PosixDetails.GID); - if (gidElement == null) - { - String error = "posixDetails missing required element gid"; - throw new ReaderException(error); - } - long gid; - try - { - gid = Long.valueOf(gidElement.getText()); - } - catch (NumberFormatException e) - { - String error = "Cannot parse posixDetails gid to a long"; - throw new ReaderException(error); - } + */ + protected final Element getElement(UserRequest<? extends Principal> userRequest) + throws WriterException + { + // Create the userRequest Element. + Element userRequestElement = new Element("userRequest"); - // homeDirectory - Element homeDirElement = element.getChild(PosixDetails.HOME_DIRECTORY); - if (homeDirElement == null) - { - String error = "posixDetails missing required element homeDirectory"; - throw new ReaderException(error); - } - String homeDirectory = homeDirElement.getText(); + // user element + Element userElement = getElement(userRequest.getUser()); + userRequestElement.addContent(userElement); - return new PosixDetails(uid, gid, homeDirectory); + // password element + Element passwordElement = new Element("password"); + passwordElement.setText(String.valueOf(userRequest.getPassword())); + userRequestElement.addContent(passwordElement); + + return userRequestElement; } /** - * Get a PersonalDetails object from a JDOM element. + * Get a JDOM element from a Principal object. * - * @param element The PersonalDetails JDOM element. - * @return A PersonalDetails object. - * @throws ReaderException + * @param identity The Principal. + * @return A JDOM UserDetails representation. + * @throws WriterException */ - protected final PersonalDetails getPersonalDetails(Element element) - throws ReaderException + protected final Element getElement(Principal identity) + throws WriterException { - // firstName - Element firstNameElement = element.getChild(PersonalDetails.FIRSTNAME); - if (firstNameElement == null) - { - String error = "personalDetails missing required element firstName"; - throw new ReaderException(error); - } - String firstName = firstNameElement.getText(); - - // lastName - Element lastNameElement = element.getChild(PersonalDetails.LASTNAME); - if (lastNameElement == null) + if (identity == null) { - String error = "personalDetails missing required element lastName"; - throw new ReaderException(error); + String error = "null identity"; + throw new WriterException(error); } - String lastName = lastNameElement.getText(); - - PersonalDetails details = new PersonalDetails(firstName, lastName); - // email - Element emailElement = element.getChild(PersonalDetails.EMAIL); - if (emailElement != null) + Element identityElement = new Element("identity"); + if ((identity instanceof HttpPrincipal)) { - details.email = emailElement.getText(); + identityElement.setAttribute("type", IdentityType.USERNAME.getValue()); } - - // address - Element addressElement = element.getChild(PersonalDetails.ADDRESS); - if (addressElement != null) + else if ((identity instanceof NumericPrincipal)) { - details.address = addressElement.getText(); + identityElement.setAttribute("type", IdentityType.CADC.getValue()); } - - // institute - Element instituteElement = element.getChild(PersonalDetails.INSTITUTE); - if (instituteElement != null) + else if ((identity instanceof OpenIdPrincipal)) { - details.institute = instituteElement.getText(); + identityElement.setAttribute("type", IdentityType.OPENID.getValue()); } - - // city - Element cityElement = element.getChild(PersonalDetails.CITY); - if (cityElement != null) + else if ((identity instanceof X500Principal)) { - details.city = cityElement.getText(); + identityElement.setAttribute("type", IdentityType.X500.getValue()); } - - // country - Element countryElement = element.getChild(PersonalDetails.COUNTRY); - if (countryElement != null) + else { - details.country = countryElement.getText(); + String error = "Unsupported Principal type " + + identity.getClass().getSimpleName(); + throw new IllegalArgumentException(error); } + identityElement.setText(identity.getName()); - return details; + return identityElement; } /** @@ -1014,5 +852,166 @@ public abstract class AbstractXML return detailsElement; } + /** + * Get a JDOM element from a Group object. + * + * @param group The UserRequest. + * @return A JDOM Group representation. + * @throws WriterException + */ + protected final Element getElement(Group group) + throws WriterException + { + return getElement(group, true); + } + + /** + * Get a JDOM element from a Group object. + * + * @param group The UserRequest. + * @param deepCopy Return all Group elements. + * @return A JDOM Group representation. + * @throws WriterException + */ + protected final Element getElement(Group group, boolean deepCopy) + throws WriterException + { + // Create the root group element. + Element groupElement = new Element("group"); + String groupURI = AC.GROUP_URI + group.getID(); + groupElement.setAttribute(new Attribute("uri", groupURI)); + + // Group owner + if (group.getOwner() != null) + { + Element ownerElement = new Element("owner"); + Element userElement = getElement(group.getOwner()); + ownerElement.addContent(userElement); + groupElement.addContent(ownerElement); + } + + if (deepCopy) + { + // Group description + if (group.description != null) + { + Element descriptionElement = new Element("description"); + descriptionElement.setText(group.description); + groupElement.addContent(descriptionElement); + } + + // lastModified + if (group.lastModified != null) + { + Element lastModifiedElement = new Element("lastModified"); + DateFormat df = DateUtil.getDateFormat(DateUtil.IVOA_DATE_FORMAT, DateUtil.UTC); + lastModifiedElement.setText(df.format(group.lastModified)); + groupElement.addContent(lastModifiedElement); + } + + // Group properties + if (!group.getProperties().isEmpty()) + { + Element propertiesElement = new Element("properties"); + for (GroupProperty property : group.getProperties()) + { + propertiesElement.addContent(getElement(property)); + } + groupElement.addContent(propertiesElement); + } + + // Group groupMembers. + if ((group.getGroupMembers() != null) && (!group.getGroupMembers().isEmpty())) + { + Element groupMembersElement = new Element("groupMembers"); + for (Group groupMember : group.getGroupMembers()) + { + groupMembersElement.addContent(getElement(groupMember, false)); + } + groupElement.addContent(groupMembersElement); + } + + // Group userMembers + if ((group.getUserMembers() != null) && (!group.getUserMembers().isEmpty())) + { + Element userMembersElement = new Element("userMembers"); + for (User<? extends Principal> userMember : group.getUserMembers()) + { + userMembersElement.addContent(getElement(userMember)); + } + groupElement.addContent(userMembersElement); + } + + // Group groupAdmins. + if ((group.getGroupAdmins() != null) && (!group.getGroupAdmins().isEmpty())) + { + Element groupAdminsElement = new Element("groupAdmins"); + for (Group groupMember : group.getGroupAdmins()) + { + groupAdminsElement.addContent(getElement(groupMember, false)); + } + groupElement.addContent(groupAdminsElement); + } + + // Group userAdmins + if ((group.getUserAdmins() != null) && (!group.getUserAdmins().isEmpty())) + { + Element userAdminsElement = new Element("userAdmins"); + for (User<? extends Principal> userMember : group.getUserAdmins()) + { + userAdminsElement.addContent(getElement(userMember)); + } + groupElement.addContent(userAdminsElement); + } + } + + return groupElement; + } + + /** + * Get a JDOM element from a GroupProperty object. + * + * @param property The GroupProperty. + * @return A JDOM GroupProperty representation. + * @throws WriterException + */ + protected final Element getElement(GroupProperty property) + throws WriterException + { + if (property == null) + { + throw new WriterException("null GroupProperty"); + } + + Element propertyElement = new Element(GroupProperty.NAME); + propertyElement.setAttribute(GroupProperty.KEY_ATTRIBUTE, + property.getKey()); + if (property.isReadOnly()) + { + propertyElement.setAttribute(GroupProperty.READONLY_ATTRIBUTE, + "true"); + } + + Object value = property.getValue(); + if ((value instanceof String)) + { + propertyElement.setAttribute(GroupProperty.TYPE_ATTRIBUTE, + GroupProperty.STRING_TYPE); + } + else if ((value instanceof Integer)) + { + propertyElement.setAttribute(GroupProperty.TYPE_ATTRIBUTE, + GroupProperty.INTEGER_TYPE); + } + else + { + String error = "Unsupported value type: " + + value.getClass().getSimpleName(); + throw new IllegalArgumentException(error); + } + propertyElement.setText(String.valueOf(property.getValue())); + + return propertyElement; + } } diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java index 10d46bbea732562d47648a2cd81a691d904b9a47..da9f16c848b0c53e57051d62d4a241012b1392db 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListReader.java @@ -89,7 +89,7 @@ import java.util.List; * Class to read an XML representation of a List of Groups * into a Collection of Group objects. */ -public class GroupListReader extends AbstractXML +public class GroupListReader extends AbstractReaderWriter { /** * Construct a list of Group's from an XML String source. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java index e406a4cd61a3c66c4d433879d5b7836f646ecc11..a42cff8bef88bf2965dd59888ea8cd81e8838abb 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupListWriter.java @@ -85,7 +85,7 @@ import java.util.Collection; /** * Class to write a XML representation from a Collection of Groups objects. */ -public class GroupListWriter extends AbstractXML +public class GroupListWriter extends AbstractReaderWriter { /** * Write a Collection of Group's to a StringBuilder. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java index 31de44fcb7aa99aefc085b97db6b98ec139be433..b9c64d1bcd3a75ed9855739db1df0f999fe0fe7d 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupReader.java @@ -86,7 +86,7 @@ import java.net.URISyntaxException; /** * Class to read a XML representation of a Group to a Group object. */ -public class GroupReader extends AbstractXML +public class GroupReader extends AbstractReaderWriter { /** diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java index 54eba4f2d390d170d0efd7c299b304cf5c3dc43b..67687c5374fee4350aedaf80eb67d277e869de1e 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/GroupWriter.java @@ -82,7 +82,7 @@ import java.io.Writer; /** * Class to write a XML representation of a Group object. */ -public class GroupWriter extends AbstractXML +public class GroupWriter extends AbstractReaderWriter { /** * Write a Group to a StringBuilder. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java index 4877e7c2cc876f07e888ef2563548b01babda0f1..ae454fcb8ebe8aeb4c66537d711cb4b73a00276a 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListReader.java @@ -90,7 +90,7 @@ import java.util.List; * Class to read an XML representation of a List of Users * into a List of User objects. */ -public class UserListReader extends AbstractXML +public class UserListReader extends AbstractReaderWriter { /** * Construct a List of Users from an XML String source. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java index 92697e1f092aa52a71f85087350edcb41f834a89..1674324dffa067f6fc06bd9bc3629c7c7bf27d15 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserListWriter.java @@ -81,12 +81,11 @@ import java.io.UnsupportedEncodingException; import java.io.Writer; import java.security.Principal; import java.util.Collection; -import java.util.List; /** * Class to write a XML representation of a List of User's. */ -public class UserListWriter extends AbstractXML +public class UserListWriter extends AbstractReaderWriter { /** * Write a Collection of User's to a StringBuilder. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java index b4181956db7610c795219c5e1fd103680479dbcf..c3cbae20aaa3f64e875560f521b1776366f98aca 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserReader.java @@ -87,7 +87,7 @@ import java.security.Principal; /** * Class to read a XML representation of a User to a User object. */ -public class UserReader extends AbstractXML +public class UserReader extends AbstractReaderWriter { /** * Construct a User from an XML String source. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java index 317d753c4756ef2f585a4044be738fcabf3ab8c4..dffef3e5e7f65d9fc3217f18f19f3a641189a095 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestReader.java @@ -86,7 +86,7 @@ import java.security.Principal; /** * Class to read a XML representation of a UserRequest to a UserRequest object. */ -public class UserRequestReader extends AbstractXML +public class UserRequestReader extends AbstractReaderWriter { /** * Construct a UserRequest from an XML String source. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java index ef1006820b1bd5ad6cd50722e1a307ed9ceb17d6..e87840d129da63713cd78b9b5107413dec04404e 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserRequestWriter.java @@ -80,7 +80,7 @@ import java.security.Principal; /** * Class to write a XML representation of a UserRequest object. */ -public class UserRequestWriter extends AbstractXML +public class UserRequestWriter extends AbstractReaderWriter { /** * Write a UserRequest to a StringBuilder. diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java index e2fe3bf80cde9544841a5f9a3a244dae71cb70d0..7df99cbb6e0d284eb1c8f5df5fde0995f5398fc2 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UserWriter.java @@ -83,7 +83,7 @@ import java.security.Principal; /** * Class to write a XML representation of a User object. */ -public class UserWriter extends AbstractXML +public class UserWriter extends AbstractReaderWriter { /** * Write a User to a StringBuilder. diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapperTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapperTest.java index fe977e4e3e5120c17b8e407df7bc210767384099..d8bd34ea6a1aae47bc8b0bd4b7182f3838932329 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapperTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/client/JsonUserListInputStreamWrapperTest.java @@ -80,15 +80,15 @@ import org.junit.Test; import static org.junit.Assert.*; -public class JSONUserListInputStreamWrapperTest +public class JsonUserListInputStreamWrapperTest { @Test public void readInputStream() throws Exception { final List<User<HttpPrincipal>> output = new ArrayList<User<HttpPrincipal>>(); - final JSONUserListInputStreamWrapper testSubject = - new JSONUserListInputStreamWrapper(output); + final JsonUserListInputStreamWrapper testSubject = + new JsonUserListInputStreamWrapper(output); final InputStream inputStream = new ByteArrayInputStream("[{\"id\":\"CADCTest\",\"firstName\":\"CADCtest\",\"lastName\":\"USER\"}\n,{\"id\":\"User_2\",\"firstName\":\"User\",\"lastName\":\"2\"}]".getBytes()); diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java index 172d211ec5ea4a2554c891db2c96f2ec1b55bc4b..0a2598471ee0c64f290d0bee13e48852d1a74f0e 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/GroupPropertyReaderWriterTest.java @@ -83,7 +83,7 @@ import static org.junit.Assert.*; * * @author jburke */ -public class GroupPropertyReaderWriterTest extends AbstractXML +public class GroupPropertyReaderWriterTest extends AbstractReaderWriter { private static Logger log = Logger.getLogger(GroupPropertyReaderWriterTest.class); diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java index 7ff46919aa479a05a077ca1b07f26a175a700018..8bb1d674b19e633333e8e331c9add568e585a3b5 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/IdentityReaderWriterTest.java @@ -89,7 +89,7 @@ import static org.junit.Assert.fail; * * @author jburke */ -public class IdentityReaderWriterTest extends AbstractXML +public class IdentityReaderWriterTest extends AbstractReaderWriter { private static Logger log = Logger.getLogger(IdentityReaderWriterTest.class); @@ -165,7 +165,7 @@ public class IdentityReaderWriterTest extends AbstractXML assertEquals(expected, actual); - // UID + // CADC expected = new NumericPrincipal(123l); element = getElement(expected); assertNotNull(element); diff --git a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java index 3a1baaa140a213beef10ce1a5e30f3faf54f0701..4a6304dd4e31fa88ccb2fd34f53c46164972ce27 100644 --- a/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java +++ b/projects/cadcAccessControl/test/src/ca/nrc/cadc/ac/xml/UserDetailsReaderWriterTest.java @@ -85,7 +85,7 @@ import static org.junit.Assert.fail; * * @author jburke */ -public class UserDetailsReaderWriterTest extends AbstractXML +public class UserDetailsReaderWriterTest extends AbstractReaderWriter { private static Logger log = Logger.getLogger(UserDetailsReaderWriterTest.class);