Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
************************************************************************
******************* CANADIAN ASTRONOMY DATA CENTRE *******************
************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES **************
*
* (c) 2014. (c) 2014.
* 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/>.
*
* $Revision: 4 $
*
************************************************************************
*/
package ca.nrc.cadc.ac.client;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.Principal;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.security.auth.Subject;
import ca.nrc.cadc.net.*;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.GroupAlreadyExistsException;
import ca.nrc.cadc.ac.GroupNotFoundException;
import ca.nrc.cadc.ac.GroupReader;
import ca.nrc.cadc.ac.GroupWriter;
import ca.nrc.cadc.ac.GroupsReader;
import ca.nrc.cadc.ac.Role;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.SSLUtil;
Patrick Dowler
committed
import ca.nrc.cadc.net.event.TransferEvent;
import ca.nrc.cadc.net.event.TransferListener;
import ca.nrc.cadc.reg.client.RegistryClient;
import java.net.URI;
* Client class for performing group searching and group actions
* with the access control web service.
Patrick Dowler
committed
public class GMSClient implements TransferListener
{
private static final Logger log = Logger.getLogger(GMSClient.class);
Patrick Dowler
committed
private SSLSocketFactory sslSocketFactory;
private SSLSocketFactory mySocketFactory;
private URI serviceURI;
public GMSClient(URI serviceURI)
{
this.serviceURI = serviceURI;
try
{
RegistryClient reg = new RegistryClient();
URL base = reg.getServiceURL(serviceURI, "https");
if (base == null)
throw new IllegalArgumentException("service not found with https access: " + serviceURI);
this.baseURL = base.toExternalForm();
}
catch(MalformedURLException ex)
{
throw new RuntimeException("BUG: failed to construct GMS base URL", ex);
}
finally { }
}
* Constructor.
*
* @param baseURL The URL of the supporting access control web service
* obtained from the registry.
public GMSClient(String baseURL)
throws IllegalArgumentException
{
if (baseURL == null)
{
throw new IllegalArgumentException("baseURL is required");
}
try
{
}
catch (MalformedURLException e)
{
throw new IllegalArgumentException("URL is malformed: " +
e.getMessage());
}
if (baseURL.endsWith("/"))
{
this.baseURL = baseURL.substring(0, baseURL.length() - 1);
}
else
{
this.baseURL = baseURL;
}
}
Patrick Dowler
committed
public void transferEvent(TransferEvent te)
{
if ( TransferEvent.RETRYING == te.getState() )
log.debug("retry after request failed, reason: " + te.getError());
}
public String getEventHeader()
{
return null; // no custom eventID header
}
/**
* Get a list of groups.
*
* @return The list of groups.
*/
public List<Group> getGroups()
{
throw new UnsupportedOperationException("Not yet implemented");
}
*
* @param group The group to create
* @return The newly created group will all the information.
* @throws GroupAlreadyExistsException If a group with the same name already
* exists.
* @throws AccessControlException If unauthorized to perform this operation.
* @throws UserNotFoundException
* @throws IOException
*/
throws GroupAlreadyExistsException, AccessControlException,
UserNotFoundException, IOException
{
URL createGroupURL = new URL(this.baseURL + "/groups");
log.debug("createGroupURL request to " + createGroupURL.toString());
// reset the state of the cache
clearCache();
StringBuilder groupXML = new StringBuilder();
GroupWriter.write(group, groupXML);
log.debug("createGroup: " + groupXML);
byte[] bytes = groupXML.toString().getBytes("UTF-8");
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
HttpUpload transfer = new HttpUpload(in, createGroupURL);
transfer.setSSLSocketFactory(getSSLSocketFactory());
transfer.run();
Throwable error = transfer.getThrowable();
if (error != null)
{
log.debug("createGroup throwable", error);
// transfer returns a -1 code for anonymous uploads.
if ((transfer.getResponseCode() == -1) ||
(transfer.getResponseCode() == 401) ||
(transfer.getResponseCode() == 403))
{
throw new AccessControlException(error.getMessage());
}
if (transfer.getResponseCode() == 400)
{
throw new IllegalArgumentException(error.getMessage());
}
if (transfer.getResponseCode() == 409)
{
throw new GroupAlreadyExistsException(error.getMessage());
}
if (transfer.getResponseCode() == 404)
{
throw new UserNotFoundException(error.getMessage());
}
throw new IOException(error);
}
String retXML = transfer.getResponseBody();
try
{
log.debug("createGroup returned: " + retXML);
return GroupReader.read(retXML);
}
catch (Exception bug)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
}
/**
* Get the group object.
*
* @param groupName Identifies the group to get.
* @return The group.
* @throws GroupNotFoundException If the group was not found.
* @throws AccessControlException If unauthorized to perform this operation.
* @throws java.io.IOException
*/
public Group getGroup(String groupName)
throws GroupNotFoundException, AccessControlException, IOException
{
URL getGroupURL = new URL(this.baseURL + "/groups/" + groupName);
log.debug("getGroup request to " + getGroupURL.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
HttpDownload transfer = new HttpDownload(getGroupURL, out);
transfer.setSSLSocketFactory(getSSLSocketFactory());
transfer.run();
Throwable error = transfer.getThrowable();
if (error != null)
{
log.debug("getGroup throwable (" + transfer.getResponseCode() + ")", error);
// transfer returns a -1 code for anonymous access.
if ((transfer.getResponseCode() == -1) ||
(transfer.getResponseCode() == 401) ||
(transfer.getResponseCode() == 403))
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
{
throw new AccessControlException(error.getMessage());
}
if (transfer.getResponseCode() == 400)
{
throw new IllegalArgumentException(error.getMessage());
}
if (transfer.getResponseCode() == 404)
{
throw new GroupNotFoundException(error.getMessage());
}
throw new IOException(error);
}
try
{
String groupXML = new String(out.toByteArray(), "UTF-8");
log.debug("getGroup returned: " + groupXML);
return GroupReader.read(groupXML);
}
catch (Exception bug)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
}
/**
* Get the all group names.
*
* @return The list of names.
* @throws AccessControlException If unauthorized to perform this operation.
* @throws java.io.IOException
*/
public List<String> getGroupNames()
throws AccessControlException, IOException
{
final URL getGroupNamesURL = new URL(this.baseURL + "/groups");
log.debug("getGroupNames request to " + getGroupNamesURL.toString());
final List<String> groupNames = new ArrayList<String>();
final HttpDownload httpDownload =
new HttpDownload(getGroupNamesURL, new InputStreamWrapper()
@Override
public void read(final InputStream inputStream) throws IOException
{
try
{
InputStreamReader inReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inReader);
String line;
while ((line = reader.readLine()) != null) {
groupNames.add(line);
}
}
catch (Exception bug)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
}
});
// Disable retries.
httpDownload.setRetry(0, 0, HttpTransfer.RetryReason.NONE);
httpDownload.setSSLSocketFactory(getSSLSocketFactory());
httpDownload.run();
final Throwable error = httpDownload.getThrowable();
if (error != null)
final String errMessage = error.getMessage();
final int responseCode = httpDownload.getResponseCode();
log.debug("getGroupNames response " + responseCode + ": " +
errMessage);
if ((responseCode == 401) || (responseCode == 403) ||
(responseCode == -1))
{
throw new AccessControlException(errMessage);
}
if (responseCode == 400)
{
throw new IllegalArgumentException(errMessage);
}
throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage);
}
log.debug("Content-Length: " + httpDownload.getContentLength());
log.debug("Content-Type: " + httpDownload.getContentType());
/**
* Update a group.
*
* @param group The update group object.
* @return The group after update.
* @throws IllegalArgumentException If cyclical membership is detected.
* @throws GroupNotFoundException If the group was not found.
* @throws UserNotFoundException If a member was not found.
* @throws AccessControlException If unauthorized to perform this operation.
* @throws java.io.IOException
*/
public Group updateGroup(Group group)
throws IllegalArgumentException, GroupNotFoundException, UserNotFoundException,
{
URL updateGroupURL = new URL(this.baseURL + "/groups/" + group.getID());
log.debug("updateGroup request to " + updateGroupURL.toString());
// reset the state of the cache
clearCache();
StringBuilder groupXML = new StringBuilder();
GroupWriter.write(group, groupXML);
log.debug("updateGroup: " + groupXML);
HttpPost transfer = new HttpPost(updateGroupURL, groupXML.toString(),
"application/xml", true);
transfer.setSSLSocketFactory(getSSLSocketFactory());
Patrick Dowler
committed
transfer.setTransferListener(this);
Patrick Dowler
committed
Throwable error = transfer.getThrowable();
if (error != null)
{
// transfer returns a -1 code for anonymous access.
if ((transfer.getResponseCode() == -1) ||
(transfer.getResponseCode() == 401) ||
(transfer.getResponseCode() == 403))
{
throw new AccessControlException(error.getMessage());
}
if (transfer.getResponseCode() == 400)
{
throw new IllegalArgumentException(error.getMessage());
}
if (transfer.getResponseCode() == 404)
{
if (error.getMessage() != null && error.getMessage().toLowerCase().contains("user"))
throw new UserNotFoundException(error.getMessage());
else
throw new GroupNotFoundException(error.getMessage());
try
{
String retXML = transfer.getResponseBody();
log.debug("getGroup returned: " + retXML);
return GroupReader.read(retXML);
}
catch (Exception bug)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
/**
* Delete the group.
*
* @param groupName Identifies the group to delete.
* @throws GroupNotFoundException If the group was not found.
* @throws AccessControlException If unauthorized to perform this operation.
* @throws java.io.IOException
*/
public void deleteGroup(String groupName)
throws GroupNotFoundException, AccessControlException, IOException
{
URL deleteGroupURL = new URL(this.baseURL + "/groups/" + groupName);
log.debug("deleteGroup request to " + deleteGroupURL.toString());
// reset the state of the cache
clearCache();
HttpURLConnection conn =
(HttpURLConnection) deleteGroupURL.openConnection();
conn.setRequestMethod("DELETE");
SSLSocketFactory sf = getSSLSocketFactory();
if ((sf != null) && ((conn instanceof HttpsURLConnection)))
{
.setSSLSocketFactory(sf);
try
{
responseCode = conn.getResponseCode();
}
catch(Exception e)
{
throw new AccessControlException(e.getMessage());
}
if (responseCode != 200)
{
String errMessage = NetUtil.getErrorBody(conn);
log.debug("deleteGroup response " + responseCode + ": " +
errMessage);
if ((responseCode == 401) || (responseCode == 403) ||
(responseCode == -1))
{
throw new AccessControlException(errMessage);
}
if (responseCode == 400)
{
throw new IllegalArgumentException(errMessage);
}
if (responseCode == 404)
{
throw new GroupNotFoundException(errMessage);
}
throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage);
/**
* Add a group as a member of another group.
*
* @param targetGroupName The group in which to add the group member.
* @param groupMemberName The group member to add.
* @throws IllegalArgumentException If cyclical membership is detected.
* @throws GroupNotFoundException If the group was not found.
* @throws AccessControlException If unauthorized to perform this operation.
* @throws java.io.IOException
*/
public void addGroupMember(String targetGroupName, String groupMemberName)
throws IllegalArgumentException, GroupNotFoundException,
AccessControlException, IOException
URL addGroupMemberURL = new URL(this.baseURL + "/groups/" +
targetGroupName + "/groupMembers/" +
groupMemberName);
log.debug("addGroupMember request to " + addGroupMemberURL.toString());
// reset the state of the cache
clearCache();
final InputStream is = new ByteArrayInputStream(new byte[0]);
final HttpUpload httpUpload = new HttpUpload(is, addGroupMemberURL);
httpUpload.setSSLSocketFactory(getSSLSocketFactory());
httpUpload.run();
final Throwable error = httpUpload.getThrowable();
if (error != null)
final int responseCode = httpUpload.getResponseCode();
final String errMessage = error.getMessage();
if ((responseCode == -1) ||
(responseCode == 401) ||
(responseCode == 403))
{
throw new AccessControlException(errMessage);
}
if (responseCode == 400)
{
throw new IllegalArgumentException(errMessage);
}
if (responseCode == 404)
{
throw new GroupNotFoundException(errMessage);
}
throw new IOException(errMessage);
}
}
/**
* Add a user as a member of a group.
*
* @param targetGroupName The group in which to add the group member.
* @param userID The user to add.
* @throws GroupNotFoundException If the group was not found.
* @throws UserNotFoundException If the member was not found.
* @throws java.io.IOException
* @throws AccessControlException If unauthorized to perform this operation.
*/
public void addUserMember(String targetGroupName, Principal userID)
throws GroupNotFoundException, UserNotFoundException, AccessControlException, IOException
{
String userIDType = AuthenticationUtil.getPrincipalType(userID);
String encodedUserID = URLEncoder.encode(userID.getName(), "UTF-8");
URL addUserMemberURL = new URL(this.baseURL + "/groups/" +
targetGroupName + "/userMembers/" +
encodedUserID + "?idType=" + userIDType);
log.debug("addUserMember request to " + addUserMemberURL.toString());
// reset the state of the cache
clearCache();
final InputStream is = new ByteArrayInputStream(new byte[0]);
final HttpUpload httpUpload = new HttpUpload(is, addUserMemberURL);
httpUpload.setSSLSocketFactory(getSSLSocketFactory());
httpUpload.run();
final Throwable error = httpUpload.getThrowable();
if (error != null)
final int responseCode = httpUpload.getResponseCode();
final String errMessage = error.getMessage();
if ((responseCode == -1) ||
(responseCode == 401) ||
(responseCode == 403))
{
throw new AccessControlException(errMessage);
}
if (responseCode == 400)
{
throw new IllegalArgumentException(errMessage);
}
if (responseCode == 404)
{
if (errMessage != null && errMessage.toLowerCase().contains("user"))
throw new UserNotFoundException(errMessage);
else
throw new GroupNotFoundException(errMessage);
}
throw new IOException(errMessage);
}
}
/**
* Remove a group as a member of another group.
*
* @param targetGroupName The group from which to remove the group member.
* @param groupMemberName The group member to remove.
* @throws GroupNotFoundException If the group was not found.
* @throws java.io.IOException
* @throws AccessControlException If unauthorized to perform this operation.
*/
public void removeGroupMember(String targetGroupName,
String groupMemberName)
throws GroupNotFoundException, AccessControlException, IOException
{
URL removeGroupMemberURL = new URL(this.baseURL + "/groups/" +
targetGroupName + "/groupMembers/" +
groupMemberName);
log.debug("removeGroupMember request to " +
removeGroupMemberURL.toString());
// reset the state of the cache
clearCache();
HttpURLConnection conn =
(HttpURLConnection) removeGroupMemberURL.openConnection();
conn.setRequestMethod("DELETE");
SSLSocketFactory sf = getSSLSocketFactory();
if ((sf != null) && ((conn instanceof HttpsURLConnection)))
{
((HttpsURLConnection) conn)
.setSSLSocketFactory(getSSLSocketFactory());
// Try to handle anonymous access and throw AccessControlException
int responseCode = -1;
try
{
responseCode = conn.getResponseCode();
}
catch (Exception ignore) {}
if (responseCode != 200)
{
String errMessage = NetUtil.getErrorBody(conn);
log.debug("removeGroupMember response " + responseCode + ": " +
errMessage);
if ((responseCode == -1) ||
(responseCode == 401) ||
(responseCode == 403))
{
throw new AccessControlException(errMessage);
}
if (responseCode == 400)
{
throw new IllegalArgumentException(errMessage);
}
if (responseCode == 404)
{
throw new GroupNotFoundException(errMessage);
}
throw new IOException(errMessage);
}
}
/**
* Remove a user as a member of a group.
*
* @param targetGroupName The group from which to remove the group member.
* @param userID The user to remove.
* @throws GroupNotFoundException If the group was not found.
* @throws UserNotFoundException If the member was not found.
* @throws java.io.IOException
* @throws AccessControlException If unauthorized to perform this operation.
*/
public void removeUserMember(String targetGroupName, Principal userID)
throws GroupNotFoundException, UserNotFoundException, AccessControlException, IOException
{
String userIDType = AuthenticationUtil.getPrincipalType(userID);
String encodedUserID = URLEncoder.encode(userID.toString(), "UTF-8");
URL removeUserMemberURL = new URL(this.baseURL + "/groups/" +
targetGroupName + "/userMembers/" +
encodedUserID + "?idType=" +
userIDType);
// reset the state of the cache
clearCache();
HttpURLConnection conn =
(HttpURLConnection) removeUserMemberURL.openConnection();
conn.setRequestMethod("DELETE");
SSLSocketFactory sf = getSSLSocketFactory();
if ((sf != null) && ((conn instanceof HttpsURLConnection)))
{
((HttpsURLConnection) conn)
.setSSLSocketFactory(getSSLSocketFactory());
// Try to handle anonymous access and throw AccessControlException
int responseCode = -1;
try
{
responseCode = conn.getResponseCode();
}
catch (Exception ignore) {}
if (responseCode != 200)
{
String errMessage = NetUtil.getErrorBody(conn);
log.debug("removeUserMember response " + responseCode + ": " +
errMessage);
if ((responseCode == -1) ||
(responseCode == 401) ||
(responseCode == 403))
{
throw new AccessControlException(errMessage);
}
if (responseCode == 400)
{
throw new IllegalArgumentException(errMessage);
}
if (responseCode == 404)
{
if (errMessage != null && errMessage.toLowerCase().contains("user"))
throw new UserNotFoundException(errMessage);
else
throw new GroupNotFoundException(errMessage);
}
throw new IOException(errMessage);
}
}
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
private Principal getCurrentUserID()
{
Subject cur = AuthenticationUtil.getCurrentSubject();
if (cur == null)
throw new IllegalArgumentException("no subject");
Set<Principal> ps = cur.getPrincipals();
if (ps.isEmpty())
throw new IllegalArgumentException("no principals");
Principal p = ps.iterator().next();
return p;
}
/**
* Get memberships for the current user (subject).
*
* @param role
* @return A list of groups for which the current user has the role.
* @throws AccessControlException
* @throws ca.nrc.cadc.ac.UserNotFoundException
* @throws java.io.IOException
*/
public List<Group> getMemberships(Role role)
throws UserNotFoundException, AccessControlException, IOException
{
return getMemberships(getCurrentUserID(), role);
}
/**
* Get all the memberships of the user of a certain role.
*
* @param userID Identifies the user.
* @param role The role to look up.
* @return A list of groups for which the user has the role.
* @throws UserNotFoundException If the user does not exist.
* @throws AccessControlException If not allowed to peform the search.
* @throws IllegalArgumentException If a parameter is null.
* @throws IOException If an unknown error occured.
*/
public List<Group> getMemberships(Principal userID, Role role)
throws UserNotFoundException, AccessControlException, IOException
if (userID == null || role == null)
{
throw new IllegalArgumentException("userID and role are required.");
}
Patrick Dowler
committed
List<Group> cachedGroups = getCachedGroups(userID, role, true);
if (cachedGroups != null)
{
return cachedGroups;
}
String idType = AuthenticationUtil.getPrincipalType(userID);
String id = userID.getName();
String roleString = role.getValue();
StringBuilder searchGroupURL = new StringBuilder(this.baseURL);
searchGroupURL.append("/search?");
searchGroupURL.append("ID=").append(URLEncoder.encode(id, "UTF-8"));
searchGroupURL.append("&IDTYPE=")
.append(URLEncoder.encode(idType, "UTF-8"));
searchGroupURL.append("&ROLE=")
.append(URLEncoder.encode(roleString, "UTF-8"));
log.debug("getMemberships request to " + searchGroupURL.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
URL url = new URL(searchGroupURL.toString());
HttpDownload transfer = new HttpDownload(url, out);
transfer.setSSLSocketFactory(getSSLSocketFactory());
transfer.run();
Throwable error = transfer.getThrowable();
if (error != null)
{
log.debug("getMemberships throwable", error);
// transfer returns a -1 code for anonymous access.
if ((transfer.getResponseCode() == -1) ||
(transfer.getResponseCode() == 401) ||
(transfer.getResponseCode() == 403))
{
throw new AccessControlException(error.getMessage());
}
if (transfer.getResponseCode() == 404)
{
throw new UserNotFoundException(error.getMessage());
}
if (transfer.getResponseCode() == 400)
{
throw new IllegalArgumentException(error.getMessage());
}
throw new IOException(error);
}
try
{
String groupsXML = new String(out.toByteArray(), "UTF-8");
log.debug("getMemberships returned: " + groupsXML);
List<Group> groups = GroupsReader.read(groupsXML);
setCachedGroups(userID, groups, role);
return groups;
}
catch (Exception bug)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
/**
* Return the group, specified by paramter groupName, if the user,
* identified by userID, is a member of that group. Return null
* otherwise.
*
* This call is identical to getMemberShip(userID, groupName, Role.MEMBER)
*
* @param userID Identifies the user.
* @param groupName Identifies the group.
* @return The group or null of the user is not a member.
* @throws UserNotFoundException If the user does not exist.
* @throws AccessControlException If not allowed to peform the search.
* @throws IllegalArgumentException If a parameter is null.
* @throws IOException If an unknown error occured.
*/
public Group getMembership(Principal userID, String groupName)
throws UserNotFoundException, AccessControlException, IOException
{
return getMembership(userID, groupName, Role.MEMBER);
}
/**
* Return the group, specified by paramter groupName, if the user,
* identified by userID, is a member (of type role) of that group.
* Return null otherwise.
*
* @param userID Identifies the user.
* @param groupName Identifies the group.
* @param role The membership role to search.
* @return The group or null of the user is not a member.
* @throws UserNotFoundException If the user does not exist.
* @throws AccessControlException If not allowed to peform the search.
* @throws IllegalArgumentException If a parameter is null.
* @throws IOException If an unknown error occured.
*/
public Group getMembership(Principal userID, String groupName, Role role)
throws UserNotFoundException, AccessControlException, IOException
if (userID == null || groupName == null || role == null)
{
throw new IllegalArgumentException("userID and role are required.");
}
Patrick Dowler
committed
Group cachedGroup = getCachedGroup(userID, groupName, role);
if (cachedGroup != null)
Patrick Dowler
committed
return cachedGroup;
String idType = AuthenticationUtil.getPrincipalType(userID);
String id = userID.getName();
String roleString = role.getValue();
StringBuilder searchGroupURL = new StringBuilder(this.baseURL);
searchGroupURL.append("/search?");
searchGroupURL.append("ID=").append(URLEncoder.encode(id, "UTF-8"));
searchGroupURL.append("&IDTYPE=")
.append(URLEncoder.encode(idType, "UTF-8"));
searchGroupURL.append("&ROLE=")
.append(URLEncoder.encode(roleString, "UTF-8"));
searchGroupURL.append("&GROUPID=")
.append(URLEncoder.encode(groupName, "UTF-8"));
log.debug("getMembership request to " + searchGroupURL.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
URL url = new URL(searchGroupURL.toString());
HttpDownload transfer = new HttpDownload(url, out);
transfer.setSSLSocketFactory(getSSLSocketFactory());
transfer.run();
Throwable error = transfer.getThrowable();
if (error != null)
{
log.debug("getMembership throwable", error);
// transfer returns a -1 code for anonymous access.
if ((transfer.getResponseCode() == -1) ||
(transfer.getResponseCode() == 401) ||
(transfer.getResponseCode() == 403))
{
throw new AccessControlException(error.getMessage());
}
if (transfer.getResponseCode() == 404)
{
throw new UserNotFoundException(error.getMessage());
}
if (transfer.getResponseCode() == 400)
{
throw new IllegalArgumentException(error.getMessage());
}
throw new IOException(error);
}
try
{
String groupsXML = new String(out.toByteArray(), "UTF-8");
log.debug("getMembership returned: " + groupsXML);
List<Group> groups = GroupsReader.read(groupsXML);
if (groups.size() == 0)
{
return null;
}
if (groups.size() == 1)
{
Patrick Dowler
committed
Group ret = groups.get(0);
addCachedGroup(userID, ret, role);
return ret;
}
throw new IllegalStateException(
"Duplicate membership for " + id + " in group " + groupName);
}
catch (Exception bug)