Skip to content
Snippets Groups Projects
Commit 760ab4aa authored by Adrian Damian's avatar Adrian Damian
Browse files

Added support for numeric ID

parent 2794a880
Branches
Tags
No related merge requests found
...@@ -68,6 +68,20 @@ ...@@ -68,6 +68,20 @@
*/ */
package ca.nrc.cadc.ac.server.ldap; package ca.nrc.cadc.ac.server.ldap;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.security.auth.x500.X500Principal;
import org.apache.log4j.Logger;
import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.PosixDetails; import ca.nrc.cadc.ac.PosixDetails;
import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.User;
...@@ -77,7 +91,9 @@ import ca.nrc.cadc.ac.UserNotFoundException; ...@@ -77,7 +91,9 @@ import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.AuthenticationUtil;
import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.net.TransientException; import ca.nrc.cadc.net.TransientException;
import com.unboundid.ldap.sdk.AddRequest; import com.unboundid.ldap.sdk.AddRequest;
import com.unboundid.ldap.sdk.Attribute; import com.unboundid.ldap.sdk.Attribute;
import com.unboundid.ldap.sdk.BindRequest; import com.unboundid.ldap.sdk.BindRequest;
...@@ -100,17 +116,6 @@ import com.unboundid.ldap.sdk.SimpleBindRequest; ...@@ -100,17 +116,6 @@ import com.unboundid.ldap.sdk.SimpleBindRequest;
import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl; import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedRequest; import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedRequest;
import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult; import com.unboundid.ldap.sdk.extensions.PasswordModifyExtendedResult;
import org.apache.log4j.Logger;
import javax.security.auth.x500.X500Principal;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class LdapUserDAO<T extends Principal> extends LdapDAO public class LdapUserDAO<T extends Principal> extends LdapDAO
...@@ -129,6 +134,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -129,6 +134,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
protected static final String LDAP_ENTRYDN = "entrydn"; protected static final String LDAP_ENTRYDN = "entrydn";
protected static final String LDAP_COMMON_NAME = "cn"; protected static final String LDAP_COMMON_NAME = "cn";
protected static final String LDAP_DISTINGUISHED_NAME = "distinguishedName"; protected static final String LDAP_DISTINGUISHED_NAME = "distinguishedName";
protected static final String LDAP_NUMERICID = "numericid";
protected static final String LADP_USER_PASSWORD = "userPassword"; protected static final String LADP_USER_PASSWORD = "userPassword";
protected static final String LDAP_FIRST_NAME = "givenName"; protected static final String LDAP_FIRST_NAME = "givenName";
protected static final String LDAP_LAST_NAME = "sn"; protected static final String LDAP_LAST_NAME = "sn";
...@@ -139,6 +145,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -139,6 +145,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
protected static final String LDAP_INSTITUTE = "institute"; protected static final String LDAP_INSTITUTE = "institute";
protected static final String LDAP_UID = "uid"; protected static final String LDAP_UID = "uid";
private String[] userAttribs = new String[] private String[] userAttribs = new String[]
{ {
LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY, LDAP_FIRST_NAME, LDAP_LAST_NAME, LDAP_ADDRESS, LDAP_CITY,
...@@ -155,6 +162,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -155,6 +162,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
super(config); super(config);
this.userLdapAttrib.put(HttpPrincipal.class, LDAP_UID); this.userLdapAttrib.put(HttpPrincipal.class, LDAP_UID);
this.userLdapAttrib.put(X500Principal.class, LDAP_DISTINGUISHED_NAME); this.userLdapAttrib.put(X500Principal.class, LDAP_DISTINGUISHED_NAME);
this.userLdapAttrib.put(NumericPrincipal.class, LDAP_NUMERICID);
// add the id attributes to user and member attributes // add the id attributes to user and member attributes
String[] princs = userLdapAttrib.values() String[] princs = userLdapAttrib.values()
...@@ -350,16 +358,25 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -350,16 +358,25 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
try try
{ {
// add new user // add new user
DN userX500DN = getUserRequestsDN(user.getUserID().getName());
List<Attribute> attributes = new ArrayList<Attribute>(); List<Attribute> attributes = new ArrayList<Attribute>();
addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_ORG_PERSON); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_INET_ORG_PERSON);
addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_CADC_ACCOUNT); addAttribute(attributes, LDAP_OBJECT_CLASS, LDAP_CADC_ACCOUNT);
addAttribute(attributes, LDAP_COMMON_NAME, user.getUserID() addAttribute(attributes, LDAP_COMMON_NAME, user.getUserID()
.getName()); .getName());
addAttribute(attributes, LDAP_DISTINGUISHED_NAME, userDN
.toNormalizedString());
addAttribute(attributes, LADP_USER_PASSWORD, userRequest addAttribute(attributes, LADP_USER_PASSWORD, userRequest
.getPassword()); .getPassword());
addAttribute(attributes, LDAP_NUMERICID,
String.valueOf(genNextNumericId()));
for (Principal princ : user.getIdentities())
{
if (princ instanceof X500Principal)
{
addAttribute(attributes, LDAP_DISTINGUISHED_NAME,
princ.getName());
}
}
for (UserDetails details : user.details) for (UserDetails details : user.details)
{ {
if (details.getClass() == PersonalDetails.class) if (details.getClass() == PersonalDetails.class)
...@@ -462,9 +479,15 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -462,9 +479,15 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
throw new UserNotFoundException(msg); throw new UserNotFoundException(msg);
} }
User<T> user = new User<T>(userID); User<T> user = new User<T>(userID);
user.getIdentities().add(new HttpPrincipal(searchResult.getAttributeValue( user.getIdentities().add(new HttpPrincipal(
searchResult.getAttributeValue(
userLdapAttrib.get(HttpPrincipal.class)))); userLdapAttrib.get(HttpPrincipal.class))));
user.getIdentities().add(new NumericPrincipal(
searchResult.getAttributeValueAsLong(
userLdapAttrib.get(NumericPrincipal.class))));
user.getIdentities().add(new X500Principal(
searchResult.getAttributeValue(
userLdapAttrib.get(X500Principal.class))));
String fname = searchResult.getAttributeValue(LDAP_FIRST_NAME); String fname = searchResult.getAttributeValue(LDAP_FIRST_NAME);
String lname = searchResult.getAttributeValue(LDAP_LAST_NAME); String lname = searchResult.getAttributeValue(LDAP_LAST_NAME);
PersonalDetails personaDetails = new PersonalDetails(fname, lname); PersonalDetails personaDetails = new PersonalDetails(fname, lname);
...@@ -772,10 +795,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -772,10 +795,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
"Unsupported principal type " + userID.getClass()); "Unsupported principal type " + userID.getClass());
} }
User<T> user = getUser(userID);
Filter filter = Filter.createANDFilter( Filter filter = Filter.createANDFilter(
Filter.createEqualityFilter(searchField, Filter.createEqualityFilter(searchField,
user.getUserID().getName()), userID.getName()),
Filter.createEqualityFilter(LDAP_MEMBEROF, groupID)); Filter.createEqualityFilter(LDAP_MEMBEROF, groupID));
SearchRequest searchRequest = SearchRequest searchRequest =
...@@ -972,4 +994,18 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO ...@@ -972,4 +994,18 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
LdapDAO.checkLdapResult(code); LdapDAO.checkLdapResult(code);
} }
} }
/**
* Method to return a randomly generated user numeric ID. The default
* implementation returns a value between 10000 and Integer.MAX_VALUE.
* @return
*/
protected int genNextNumericId()
{
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
return rand.nextInt(Integer.MAX_VALUE - 10000) + 10000;
}
} }
...@@ -68,39 +68,47 @@ ...@@ -68,39 +68,47 @@
*/ */
package ca.nrc.cadc.ac.server.ldap; package ca.nrc.cadc.ac.server.ldap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.Random;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.nrc.cadc.ac.PersonalDetails; import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserDetails; import ca.nrc.cadc.ac.UserDetails;
import ca.nrc.cadc.ac.UserRequest; import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.util.Log4jInit; import ca.nrc.cadc.util.Log4jInit;
import com.unboundid.ldap.sdk.DN;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.junit.BeforeClass;
import org.junit.Test;
import javax.security.auth.Subject; import com.unboundid.ldap.sdk.DN;
import javax.security.auth.x500.X500Principal;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
{ {
private static final Logger log = Logger.getLogger(LdapUserDAOTest.class); private static final Logger log = Logger.getLogger(LdapUserDAOTest.class);
static final String testUserX509DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca"; static final String testUserX509DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
static int nextUserNumericID = 666;
static String testUserDN; static String testUserDN;
static User<X500Principal> testUser; static User<X500Principal> testUser;
static User<X500Principal> testMember;
static LdapConfig config; static LdapConfig config;
static Random ran = new Random(); // source of randomness for numeric ids
@BeforeClass @BeforeClass
public static void setUpBeforeClass() public static void setUpBeforeClass()
...@@ -110,17 +118,32 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -110,17 +118,32 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
// get the configuration of the development server from and config files... // get the configuration of the development server from and config files...
config = getLdapConfig(); config = getLdapConfig();
X500Principal testUserX500Princ = new X500Principal(testUserX509DN);
testUser = new User<X500Principal>(new X500Principal(testUserX509DN)); testUser = new User<X500Principal>(testUserX500Princ);
testUser.details.add(new PersonalDetails("CADC", "DAOTest1")); testUser.details.add(new PersonalDetails("CADC", "DAOTest1"));
testUser.getIdentities().add(new HttpPrincipal("CadcDaoTest1")); testUser.getIdentities().add(new HttpPrincipal("CadcDaoTest1"));
testUser.getIdentities().add(testUserX500Princ);
testUser.getIdentities().add(new NumericPrincipal(666));
testUserDN = "uid=cadcdaotest1," + config.getUsersDN(); testUserDN = "uid=cadcdaotest1," + config.getUsersDN();
// member returned by getMember contains only the fields required by
// the GMS
testMember = new User<X500Principal>(testUserX500Princ);
testMember.details.add(new PersonalDetails("CADC", "DAOTest1"));
testMember.getIdentities().add(new HttpPrincipal("CadcDaoTest1"));
} }
LdapUserDAO getUserDAO() LdapUserDAO getUserDAO()
{ {
return new LdapUserDAO(config); return new LdapUserDAO(config){
protected int genNextNumericId()
{
return nextUserNumericID;
}
};
} }
String getUserID() String getUserID()
...@@ -134,8 +157,13 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -134,8 +157,13 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
@Test @Test
public void testAddUser() throws Exception public void testAddUser() throws Exception
{ {
final User<HttpPrincipal> expected = new User<HttpPrincipal>(new HttpPrincipal(getUserID())); String userID = getUserID();
expected.getIdentities().add(new HttpPrincipal(getUserID())); final User<HttpPrincipal> expected = new User<HttpPrincipal>(new HttpPrincipal(userID));
expected.getIdentities().add(new HttpPrincipal(userID));
expected.getIdentities().add(new X500Principal("cn=" + userID + ",ou=cadc,o=hia,c=ca"));
nextUserNumericID = ran.nextInt(Integer.MAX_VALUE);
expected.getIdentities().add(new NumericPrincipal(nextUserNumericID));
expected.details.add(new PersonalDetails("foo", "bar")); expected.details.add(new PersonalDetails("foo", "bar"));
final UserRequest<HttpPrincipal> userRequest = final UserRequest<HttpPrincipal> userRequest =
...@@ -265,6 +293,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -265,6 +293,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
Subject subject = new Subject(); Subject subject = new Subject();
subject.getPrincipals().add(testUser.getUserID()); subject.getPrincipals().add(testUser.getUserID());
// do everything as owner // do everything as owner
Subject.doAs(subject, new PrivilegedExceptionAction<Object>() Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
{ {
...@@ -273,7 +302,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -273,7 +302,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
try try
{ {
User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN)); User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN));
check(testUser, actual); check(testMember, actual);
return null; return null;
} }
catch (Exception e) catch (Exception e)
...@@ -296,7 +325,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -296,7 +325,7 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
try try
{ {
User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN)); User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN));
check(testUser, actual); check(testMember, actual);
return null; return null;
} }
catch (Exception e) catch (Exception e)
...@@ -490,6 +519,10 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -490,6 +519,10 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
HttpPrincipal principal = new HttpPrincipal(username); HttpPrincipal principal = new HttpPrincipal(username);
testUser2 = new User<HttpPrincipal>(principal); testUser2 = new User<HttpPrincipal>(principal);
testUser2.getIdentities().add(principal); testUser2.getIdentities().add(principal);
testUser2.getIdentities().add(new X500Principal("cn=" + username + ",ou=cadc,o=hia,c=ca"));
// update nextNumericId
nextUserNumericID = ran.nextInt(Integer.MAX_VALUE);
testUser2.getIdentities().add(new NumericPrincipal(nextUserNumericID));
testUser2.details.add(new PersonalDetails("firstName", "lastName")); testUser2.details.add(new PersonalDetails("firstName", "lastName"));
final UserRequest userRequest = new UserRequest(testUser2, password); final UserRequest userRequest = new UserRequest(testUser2, password);
...@@ -575,7 +608,20 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest ...@@ -575,7 +608,20 @@ public class LdapUserDAOTest<T extends Principal> extends AbstractLdapDAOTest
assertEquals(user1, user2); assertEquals(user1, user2);
assertEquals(user1.details, user2.details); assertEquals(user1.details, user2.details);
assertEquals(user1.details.size(), user2.details.size()); assertEquals(user1.details.size(), user2.details.size());
assertEquals(user1.getIdentities(), user2.getIdentities()); assertEquals(user1.getIdentities().size(), user2.getIdentities().size());
for( Principal princ1 : user1.getIdentities())
{
boolean found = false;
for( Principal princ2 : user2.getIdentities())
{
if (princ2.getClass() == princ1.getClass())
{
assertEquals(princ1, princ2);
found = true;
}
}
assertTrue(princ1.getName(), found);
}
for(UserDetails d1 : user1.details) for(UserDetails d1 : user1.details)
{ {
assertTrue(user2.details.contains(d1)); assertTrue(user2.details.contains(d1));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment