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 java.util.Iterator;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import javax.security.auth.Subject;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.GroupAlreadyExistsException;
import ca.nrc.cadc.ac.GroupNotFoundException;
import ca.nrc.cadc.ac.Role;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.xml.GroupListReader;
import ca.nrc.cadc.ac.xml.GroupReader;
import ca.nrc.cadc.ac.xml.GroupWriter;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.SSLUtil;
import ca.nrc.cadc.net.HttpDownload;
import ca.nrc.cadc.net.HttpPost;
import ca.nrc.cadc.net.HttpUpload;
import ca.nrc.cadc.net.InputStreamWrapper;
import ca.nrc.cadc.net.NetUtil;
Patrick Dowler
committed
import ca.nrc.cadc.net.event.TransferEvent;
import ca.nrc.cadc.net.event.TransferListener;
* 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;
* @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: " +
}
if (baseURL.endsWith("/"))
{
this.baseURL = baseURL.substring(0, baseURL.length() - 1);
}
else
{
this.baseURL = baseURL;
}
}
Patrick Dowler
committed
public void transferEvent(TransferEvent te)
Patrick Dowler
committed
if ( TransferEvent.RETRYING == te.getState() )
log.debug("retry after request failed, reason: " + te.getError());
Patrick Dowler
committed
public String getEventHeader()
{
return null; // no custom eventID header
}
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,
{
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 groupWriter = new GroupWriter();
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) ||
{
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);
GroupReader groupReader = new GroupReader();
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) ||
{
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);
GroupReader groupReader = new GroupReader();
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);
}
}
});
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 + ": " +
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 groupWriter = new GroupWriter();
groupWriter.write(group, groupXML);
HttpPost transfer = new HttpPost(updateGroupURL, groupXML.toString(),
"application/xml", true);
transfer.setSSLSocketFactory(getSSLSocketFactory());
Patrick Dowler
committed
transfer.setTransferListener(this);
Throwable error = transfer.getThrowable();
if (error != null)
{
// transfer returns a -1 code for anonymous access.
if ((transfer.getResponseCode() == -1) ||
(transfer.getResponseCode() == 401) ||
{
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);
GroupReader groupReader = new GroupReader();
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) 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 + ": " +
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/" +
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) ||
{
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) ||
{
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,
throws GroupNotFoundException, AccessControlException, IOException
{
URL removeGroupMemberURL = new URL(this.baseURL + "/groups/" +
targetGroupName + "/groupMembers/" +
log.debug("removeGroupMember request to " +
// reset the state of the cache
clearCache();
(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 + ": " +
if ((responseCode == -1) ||
(responseCode == 401) ||
{
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=" +
// reset the state of the cache
clearCache();
(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 + ": " +
if ((responseCode == -1) ||
(responseCode == 401) ||
{
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);
}
}
/**
* 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);
GroupListReader groupListReader = new GroupListReader();
List<Group> groups = groupListReader.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);
GroupListReader groupListReader = new GroupListReader();
List<Group> groups = groupListReader.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)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
/**
* Check if userID is a member of groupName.
* This is equivalent to isMember(userID, groupName, Role.MEMBER)
* @param userID Identifies the user.
* @param groupName Identifies the group.
* @return True if the user is a member of the group
* @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 boolean isMember(Principal userID, String groupName)
throws UserNotFoundException, AccessControlException, IOException
{
return isMember(userID, groupName, Role.MEMBER);
}
/**
* Check if userID is a member (of type role) of groupName.
* @param userID Identifies the user.
* @param groupName Identifies the group.
* @param role The type of membership.
* @return True if the user is a member of the group
* @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 boolean isMember(Principal userID, String groupName, Role role)
throws UserNotFoundException, AccessControlException, IOException