Skip to content
Snippets Groups Projects
Commit ef06e9f4 authored by Alinga Yeung's avatar Alinga Yeung
Browse files

Story 1657 rework. Updated based on Brian's review comments. Moved...

Story 1657 rework. Updated based on Brian's review comments. Moved IdentityType to cadcUtil to consolidate its usage.
parent ed7c3c02
No related branches found
No related tags found
No related merge requests found
Showing with 132 additions and 164 deletions
......@@ -93,6 +93,7 @@
<property name="cadcUtil" value="${lib}/cadcUtil.jar"/>
<property name="cadcUWS" value="${lib}/cadcUWS.jar"/>
<property name="wsUtil" value="${lib}/wsUtil.jar"/>
<property name="wsUtil-augment" value="${lib}/wsUtil-augment.jar"/>
<property name="javacsv" value="${ext.lib}/javacsv.jar"/>
<property name="jdom2" value="${ext.lib}/jdom2.jar"/>
......@@ -102,7 +103,7 @@
<property name="xerces" value="${ext.lib}/xerces.jar"/>
<property name="jars"
value="${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}:${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${wsUtil}"/>
value="${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}:${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${wsUtil}:${wsUtil-augment}"/>
<target name="build" depends="compile">
<jar jarfile="${build}/lib/${project}.jar"
......
......@@ -71,6 +71,8 @@ import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.server.UserPersistence;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import java.security.AccessControlContext;
import java.security.AccessController;
......@@ -82,6 +84,8 @@ import javax.security.auth.Subject;
import org.apache.log4j.Logger;
import com.sun.security.auth.X500Principal;
public class GetUserAction extends AbstractUserAction
{
......@@ -98,16 +102,18 @@ public class GetUserAction extends AbstractUserAction
public void doAction() throws Exception
{
log.debug("alinga-- GetUserAction.doAction(): enter");
User<Principal> user;
if (isServops())
if (isAugmentUser())
{
log.debug("alinga-- GetUserAction.doAction(): is an augment user");
Subject subject = new Subject();
subject.getPrincipals().add(this.userID);
user = (User<Principal>) Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
user = Subject.doAs(subject, new PrivilegedExceptionAction<User<Principal>>()
{
@Override
public Object run() throws Exception
public User<Principal> run() throws Exception
{
return getUser(userID);
}
......@@ -116,10 +122,12 @@ public class GetUserAction extends AbstractUserAction
}
else
{
log.debug("alinga-- GetUserAction.doAction(): is not an augment user");
user = getUser(this.userID);
}
writeUser(user);
log.debug("alinga-- GetUserAction.doAction(): exit");
}
protected User<Principal> getUser(Principal principal) throws Exception
......@@ -130,6 +138,12 @@ public class GetUserAction extends AbstractUserAction
try
{
user = userPersistence.getUser(principal);
}
catch (UserNotFoundException e)
{
user = userPersistence.getPendingUser(principal);
}
if (detail != null)
{
// Only return user principals
......@@ -156,32 +170,46 @@ public class GetUserAction extends AbstractUserAction
throw new IllegalArgumentException("Illegal detail parameter " + detail);
}
}
}
catch (UserNotFoundException e)
{
user = userPersistence.getPendingUser(principal);
}
return user;
}
protected boolean isServops()
protected boolean isAugmentUser()
{
boolean isServops = false;
AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
if (subject != null)
{
for (Principal principal : subject.getPrincipals())
log.debug("alinga-- GetUserAction.isAugmentUser(): subject is not null.");
for (Principal principal : subject.getPrincipals(X500Principal.class))
{
log.debug("alinga-- GetUserAction.isAugmentUser(): principal = " + principal);
log.debug("alinga-- GetUserAction.isAugmentUser(): principal name = " + principal.getName());
log.debug("alinga-- GetUserAction.isAugmentUser(): augmentUserDN = " + this.getAugmentUserDN());
if (principal instanceof X500Principal)
{
log.debug("alinga-- UserClientTest constructor(): servops is X500Principal.");
}
else if (principal instanceof HttpPrincipal)
{
log.debug("alinga-- UserClientTest constructor(): servops is X500Principal.");
}
else if (principal instanceof NumericPrincipal)
{
log.debug("alinga-- UserClientTest constructor(): servops is X500Principal.");
}
else
{
log.debug("alinga-- UserClientTest constructor(): servops is unknown principal.");
}
if (principal.getName().equals(this.getAugmentUserDN()))
{
isServops = true;
break;
return true;
}
}
}
return isServops;
return false;
}
}
......@@ -68,17 +68,18 @@
*/
package ca.nrc.cadc.ac.server.web.users;
import ca.nrc.cadc.ac.IdentityType;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.server.web.WebUtil;
import ca.nrc.cadc.auth.CookiePrincipal;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.IdentityType;
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;
......
......@@ -71,15 +71,18 @@ package ca.nrc.cadc.ac.server;
import ca.nrc.cadc.ac.Role;
import ca.nrc.cadc.ac.server.web.groups.AddUserMemberActionTest;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.IdentityType;
import ca.nrc.cadc.util.Log4jInit;
import ca.nrc.cadc.uws.Parameter;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
......@@ -152,7 +155,7 @@ public class RequestValidatorTest
paramList.clear();
paramList.add(new Parameter("ID", "foo"));
paramList.add(new Parameter("IDTYPE", AuthenticationUtil.AUTH_TYPE_HTTP));
paramList.add(new Parameter("IDTYPE", IdentityType.USERNAME.getValue()));
paramList.add(new Parameter("ROLE", "foo"));
try
{
......@@ -163,7 +166,7 @@ public class RequestValidatorTest
paramList.clear();
paramList.add(new Parameter("ID", "foo"));
paramList.add(new Parameter("IDTYPE", AuthenticationUtil.AUTH_TYPE_HTTP));
paramList.add(new Parameter("IDTYPE", IdentityType.USERNAME.getValue()));
paramList.add(new Parameter("ROLE", "foo"));
paramList.add(new Parameter("GROUPID", ""));
try
......@@ -175,7 +178,7 @@ public class RequestValidatorTest
paramList.clear();
paramList.add(new Parameter("ID", "foo"));
paramList.add(new Parameter("IDTYPE", AuthenticationUtil.AUTH_TYPE_HTTP));
paramList.add(new Parameter("IDTYPE", IdentityType.USERNAME.getValue()));
paramList.add(new Parameter("ROLE", Role.MEMBER.getValue()));
rv.validate(paramList);
......
......@@ -74,7 +74,9 @@ import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.server.GroupPersistence;
import ca.nrc.cadc.ac.server.UserPersistence;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.IdentityType;
import ca.nrc.cadc.util.Log4jInit;
import java.security.Principal;
import org.apache.log4j.Level;
......@@ -107,7 +109,7 @@ public class AddUserMemberActionTest
try
{
String userID = "foo";
String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP;
String userIDType = IdentityType.USERNAME.getValue();
Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType);
User<Principal> user = new User<Principal>(userPrincipal);
......@@ -159,7 +161,7 @@ public class AddUserMemberActionTest
try
{
String userID = "foo";
String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP;
String userIDType = IdentityType.USERNAME.getValue();
Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType);
User<Principal> user = new User<Principal>(userPrincipal);
......
......@@ -74,8 +74,11 @@ import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.server.GroupPersistence;
import ca.nrc.cadc.ac.server.UserPersistence;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.IdentityType;
import ca.nrc.cadc.util.Log4jInit;
import java.security.Principal;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.easymock.EasyMock;
......@@ -106,7 +109,7 @@ public class RemoveUserMemberActionTest
try
{
String userID = "foo";
String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP;
String userIDType = IdentityType.USERNAME.getValue();
Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType);
User<Principal> user = new User<Principal>(userPrincipal);
......@@ -156,7 +159,7 @@ public class RemoveUserMemberActionTest
try
{
String userID = "foo";
String userIDType = AuthenticationUtil.AUTH_TYPE_HTTP;
String userIDType = IdentityType.USERNAME.getValue();
Principal userPrincipal = AuthenticationUtil.createPrincipal(userID, userIDType);
User<Principal> user = new User<Principal>(userPrincipal);
......
......@@ -71,13 +71,10 @@ package ca.nrc.cadc.ac.client;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Principal;
import java.util.Iterator;
import java.util.Set;
import javax.net.ssl.SSLSocketFactory;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
......@@ -87,9 +84,9 @@ import ca.nrc.cadc.auth.HttpPrincipal;
import org.apache.log4j.Logger;
import ca.nrc.cadc.ac.xml.UserReader;
import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.CookiePrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.auth.SSLUtil;
import ca.nrc.cadc.net.HttpDownload;
......@@ -102,8 +99,6 @@ public class UserClient
private static final Logger log = Logger.getLogger(UserClient.class);
// socket factory to use when connecting
private SSLSocketFactory sslSocketFactory;
private SSLSocketFactory mySocketFactory;
private String baseURL;
/**
......@@ -148,12 +143,11 @@ public class UserClient
*/
public void augmentSubject(Subject subject)
{
URL url = this.getURL(subject);
Principal principal = this.getPrincipal(subject);
URL url = this.getURL(principal);
log.debug("augmentSubject request to " + url.toString());
ByteArrayOutputStream out = new ByteArrayOutputStream();
HttpDownload download = new HttpDownload(url, out);
download.setSSLSocketFactory(getSSLSocketFactory());
download.run();
this.handleThrowable(download);
......@@ -162,7 +156,7 @@ public class UserClient
protected void augmentSubject(Subject subject, Set<Principal> principals)
{
if (principals.isEmpty())
if (!principals.iterator().hasNext())
{
String name = subject.getPrincipals().iterator().next().getName();
String msg = "No UserIdentity in LDAP server for principal: " + name;
......@@ -197,6 +191,33 @@ public class UserClient
}
}
protected Principal getPrincipal(final Subject subject)
{
Set<Principal> principals = subject.getPrincipals();
Iterator<Principal> iterator = principals.iterator();
if (iterator.hasNext())
{
Principal principal = iterator.next();
log.debug("alinga-- UserClient.getPrincipal(): principal = " + principal);
if (iterator.hasNext())
{
Principal principal1 = iterator.next();
log.debug("alinga-- UserClient.getPrincipal(): principal1 = " + principal1);
log.debug("alinga-- UserClient.getPrincipal(): number of principals = " + principals.size());
// Should only have one principal
final String msg = "Subject has more than one principal.";
throw new IllegalArgumentException(msg);
}
return principal;
}
else
{
final String msg = "Subject has no principal.";
throw new IllegalArgumentException(msg);
}
}
protected Set<Principal> getPrincipals(ByteArrayOutputStream out)
{
try
......@@ -224,127 +245,34 @@ public class UserClient
}
}
protected URL getURL(Subject subject)
protected URL getURL(Principal principal)
{
try
{
String userID = subject.getPrincipals().iterator().next().getName();
String encodedUserID = URLEncoder.encode(userID, "UTF-8");
URL url = new URL(this.baseURL + "/users/" + encodedUserID +
"?idType=" + this.getIdType(subject) + "&detail=identity");
String userID = principal.getName();
URL url = new URL(this.baseURL + "/users/" + userID +
"?idType=" + this.getIdType(principal) + "&detail=identity");
log.debug("getURL(): returned url ="
+ ""
+ " " + url.toString());
return url;
}
catch (UnsupportedEncodingException e)
{
throw new RuntimeException(e);
}
catch (MalformedURLException e)
{
throw new RuntimeException(e);
}
}
protected String getIdType(Subject subject)
protected String getIdType(Principal principal)
{
Set<Principal> principals = subject.getPrincipals();
if (principals.size() > 0)
{
String idTypeStr = null;
Principal principal = principals.iterator().next();
if (principal instanceof HttpPrincipal)
{
idTypeStr = IdentityType.USERNAME.getValue();
}
else if (principal instanceof X500Principal)
{
idTypeStr = IdentityType.X500.getValue();
}
else if (principal instanceof NumericPrincipal)
{
idTypeStr = IdentityType.CADC.getValue();
}
else if (principal instanceof CookiePrincipal)
{
idTypeStr = IdentityType.COOKIE.getValue();
}
else
String idTypeStr = AuthenticationUtil.getPrincipalType(principal);
if (idTypeStr == null)
{
final String msg = "Subject has unsupported principal " +
principal.getName() +
", not one of (X500, Cookie, HTTP or Cadc).";
principal.getName();
throw new IllegalArgumentException(msg);
}
return idTypeStr;
}
else
{
final String msg = "Subject has no principal.";
throw new IllegalArgumentException(msg);
}
}
/**
* @param sslSocketFactory the sslSocketFactory to set
*/
public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory)
{
if (mySocketFactory != null)
{
throw new IllegalStateException(
"Illegal use of GMSClient: cannot set SSLSocketFactory " +
"after using one created from Subject");
}
this.sslSocketFactory = sslSocketFactory;
clearCache();
}
private int subjectHashCode = 0;
private SSLSocketFactory getSSLSocketFactory()
{
AccessControlContext ac = AccessController.getContext();
Subject s = Subject.getSubject(ac);
// no real Subject: can only use the one from setSSLSocketFactory
if (s == null || s.getPrincipals().isEmpty())
{
return sslSocketFactory;
}
// lazy init
if (this.mySocketFactory == null)
{
log.debug("getSSLSocketFactory: " + s);
this.mySocketFactory = SSLUtil.getSocketFactory(s);
this.subjectHashCode = s.hashCode();
}
else
{
int c = s.hashCode();
if (c != subjectHashCode)
{
throw new IllegalStateException(
"Illegal use of " + this.getClass().getSimpleName() +
": subject change not supported for internal " +
"SSLSocketFactory");
}
}
return this.mySocketFactory;
}
protected void clearCache()
{
AccessControlContext acContext = AccessController.getContext();
Subject subject = Subject.getSubject(acContext);
if (subject != null)
{
log.debug("Clearing cache");
subject.getPrivateCredentials().clear();
}
}
}
......@@ -72,7 +72,6 @@ package ca.nrc.cadc.ac.xml;
import ca.nrc.cadc.ac.AC;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.GroupProperty;
import ca.nrc.cadc.ac.IdentityType;
import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.PosixDetails;
import ca.nrc.cadc.ac.ReaderException;
......@@ -81,9 +80,11 @@ import ca.nrc.cadc.ac.UserDetails;
import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.ac.WriterException;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.IdentityType;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.auth.OpenIdPrincipal;
import ca.nrc.cadc.date.DateUtil;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
......@@ -91,6 +92,7 @@ import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import javax.security.auth.x500.X500Principal;
import java.io.IOException;
import java.io.Writer;
import java.security.Principal;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment