Newer
Older
* @throws AccessControlException If not allowed to peform the search.
* @throws IllegalArgumentException If a parameter is null.
* @throws IOException If an unknown error occured.
*/
Patrick Dowler
committed
public Group getMembership(String groupName, Role role)
throws UserNotFoundException, AccessControlException, IOException
Patrick Dowler
committed
if (groupName == null || role == null)
Patrick Dowler
committed
throw new IllegalArgumentException("groupName and role are required.");
Patrick Dowler
committed
Principal userID = getCurrentUserID();
if (userID != null)
Patrick Dowler
committed
Group cachedGroup = getCachedGroup(userID, groupName, role);
if (cachedGroup != null)
{
return cachedGroup;
}
Patrick Dowler
committed
//String idType = AuthenticationUtil.getPrincipalType(userID);
//String id = userID.getName();
String roleString = role.getValue();
StringBuilder searchGroupURL = new StringBuilder(this.baseURL);
searchGroupURL.append("/search?");
Patrick Dowler
committed
//searchGroupURL.append("ID=").append(NetUtil.encode(id));
//searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType));
Patrick Dowler
committed
searchGroupURL.append("&ROLE=").append(NetUtil.encode(roleString));
searchGroupURL.append("&GROUPID=").append(NetUtil.encode(groupName));
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);
Patrick Dowler
committed
if (groups.isEmpty())
{
return null;
}
if (groups.size() == 1)
{
Patrick Dowler
committed
Group ret = groups.get(0);
addCachedGroup(userID, ret, role);
return ret;
}
throw new IllegalStateException(
Patrick Dowler
committed
"Duplicate membership for " + userID + " in group " + groupName);
}
catch (Exception bug)
{
log.error("Unexpected exception", bug);
throw new RuntimeException(bug);
}
/**
* Check group membership of the current Subject.
* @param groupName
* @return
* @throws UserNotFoundException
* @throws AccessControlException
*/
public boolean isMember(String groupName)
throws UserNotFoundException, AccessControlException, IOException
{
Patrick Dowler
committed
return isMember(groupName, Role.MEMBER);
}
Patrick Dowler
committed
Patrick Dowler
committed
*
* @param groupName
* @param role
* @return
* @throws UserNotFoundException
* @throws AccessControlException
* @throws IOException
Patrick Dowler
committed
public boolean isMember(String groupName, Role role)
throws UserNotFoundException, AccessControlException, IOException
Patrick Dowler
committed
return isMember(getCurrentUserID(), groupName, role);
Patrick Dowler
committed
private boolean isMember(Principal userID, String groupName, Role role)
throws UserNotFoundException, AccessControlException, IOException
Patrick Dowler
committed
Group group = getMembership(groupName, role);
/**
* @param sslSocketFactory the sslSocketFactory to set
*/
public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory)
{
Patrick Dowler
committed
if (mySocketFactory != null)
throw new IllegalStateException("Illegal use of GMSClient: "
+ "cannot set SSLSocketFactory after using one created from Subject");
Patrick Dowler
committed
private int subjectHashCode = 0;
private SSLSocketFactory getSSLSocketFactory()
{
Patrick Dowler
committed
AccessControlContext ac = AccessController.getContext();
Subject s = Subject.getSubject(ac);
Patrick Dowler
committed
// no real Subject: can only use the one from setSSLSocketFactory
if (s == null || s.getPrincipals().isEmpty())
{
return sslSocketFactory;
}
Patrick Dowler
committed
// lazy init
if (this.mySocketFactory == null)
{
log.debug("getSSLSocketFactory: " + s);
this.mySocketFactory = SSLUtil.getSocketFactory(s);
this.subjectHashCode = s.hashCode();
}
else
Patrick Dowler
committed
int c = s.hashCode();
if (c != subjectHashCode)
throw new IllegalStateException("Illegal use of "
Patrick Dowler
committed
+ this.getClass().getSimpleName()
+ ": subject change not supported for internal SSLSocketFactory");
Patrick Dowler
committed
return this.mySocketFactory;
protected void clearCache()
{
AccessControlContext acContext = AccessController.getContext();
Subject subject = Subject.getSubject(acContext);
if (subject != null)
{
Patrick Dowler
committed
subject.getPrivateCredentials().remove(new GroupMemberships());
Patrick Dowler
committed
protected GroupMemberships getGroupCache(Principal userID)
{
AccessControlContext acContext = AccessController.getContext();
Subject subject = Subject.getSubject(acContext);
// only consult cache if the userID is of the calling subject
if (userIsSubject(userID, subject))
Patrick Dowler
committed
Set<GroupMemberships> gset = subject.getPrivateCredentials(GroupMemberships.class);
if (gset == null || gset.isEmpty())
GroupMemberships mems = new GroupMemberships(new User(userID));
Patrick Dowler
committed
subject.getPrivateCredentials().add(mems);
return mems;
Patrick Dowler
committed
GroupMemberships mems = gset.iterator().next();
return mems;
Patrick Dowler
committed
return null; // no cache
}
Patrick Dowler
committed
protected Group getCachedGroup(Principal userID, String groupID, Role role)
{
List<Group> groups = getCachedGroups(userID, role, false);
if (groups == null)
return null; // no cache
for (Group g : groups)
{
if (g.getID().equals(groupID))
return g;
Patrick Dowler
committed
protected List<Group> getCachedGroups(Principal userID, Role role, boolean complete)
{
GroupMemberships mems = getGroupCache(userID);
if (mems == null)
return null; // no cache
Patrick Dowler
committed
Boolean cacheState = mems.complete.get(role);
if (!complete || Boolean.TRUE.equals(cacheState))
return mems.memberships.get(role);
Patrick Dowler
committed
// caller wanted complete and we don't have that
Patrick Dowler
committed
protected void addCachedGroup(Principal userID, Group group, Role role)
Patrick Dowler
committed
GroupMemberships mems = getGroupCache(userID);
if (mems == null)
return; // no cache
Patrick Dowler
committed
}
protected void setCachedGroups(Principal userID, List<Group> groups, Role role)
Patrick Dowler
committed
GroupMemberships mems = getGroupCache(userID);
if (mems == null)
return; // no cache
protected boolean userIsSubject(Principal userID, Subject subject)
{
if (userID == null || subject == null)
{
return false;
}
for (Principal subjectPrincipal : subject.getPrincipals())
Patrick Dowler
committed
if (AuthenticationUtil.equals(subjectPrincipal, userID))