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

Made user fname and lname available in GMS

parent 884b0d11
No related branches found
No related tags found
No related merge requests found
......@@ -102,20 +102,11 @@ import com.unboundid.ldap.sdk.SearchResult;
import com.unboundid.ldap.sdk.SearchResultEntry;
import com.unboundid.ldap.sdk.SearchScope;
import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
import java.util.logging.Level;
public class LdapGroupDAO<T extends Principal> extends LdapDAO
{
private static final Logger logger = Logger.getLogger(LdapGroupDAO.class);
private static final String ACTUAL_GROUP_TOKEN = "<ACTUAL_GROUP>";
private static final String GROUP_READ_ACI = "(targetattr = \"*\") " +
"(version 3.0;acl \"Group Read\";allow (read,compare,search)" +
"(groupdn = \"ldap:///<ACTUAL_GROUP>\");)";
private static final String GROUP_WRITE_ACI = "(targetattr = \"*\") " +
"(version 3.0;acl \"Group Write\";allow " +
"(read,compare,search,selfwrite,write,add)" +
"(groupdn = \"ldap:///<ACTUAL_GROUP>\");)";
private LdapUserDAO<T> userPersist;
......@@ -282,7 +273,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO
User<X500Principal> user;
try
{
user = userPersist.getMember(memberDN, false);
user = userPersist.getMember(memberDN);
}
catch (UserNotFoundException e)
{
......
......@@ -68,12 +68,25 @@
*/
package ca.nrc.cadc.ac.server.ldap;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.apache.log4j.Logger;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.net.TransientException;
import com.unboundid.ldap.sdk.CompareRequest;
import com.unboundid.ldap.sdk.CompareResult;
import com.unboundid.ldap.sdk.DN;
......@@ -82,30 +95,39 @@ import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.SearchRequest;
import com.unboundid.ldap.sdk.SearchResultEntry;
import com.unboundid.ldap.sdk.SearchScope;
import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV1RequestControl;
import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.apache.log4j.Logger;
public class LdapUserDAO<T extends Principal> extends LdapDAO
{
private static final Logger logger = Logger.getLogger(LdapUserDAO.class);
// Map of identity type to LDAP attribute
private Map<Class<?>, String> attribType = new HashMap<Class<?>, String>();
private Map<Class<?>, String> userLdapAttrib = new HashMap<Class<?>, String>();
// User attributes returned to the GMS
private static final String LDAP_FNAME = "givenname";
private static final String LDAP_LNAME = "sn";
//TODO to add the rest
private String[] userAttribs = new String[]{LDAP_FNAME, LDAP_LNAME};
private String[] memberAttribs = new String[]{LDAP_FNAME, LDAP_LNAME};
public LdapUserDAO(LdapConfig config)
{
super(config);
this.attribType.put(HttpPrincipal.class, "cn");
this.attribType.put(X500Principal.class, "distinguishedname");
this.attribType.put(NumericPrincipal.class, "entryid");
this.userLdapAttrib.put(HttpPrincipal.class, "uid");
this.userLdapAttrib.put(X500Principal.class, "distinguishedname");
// add the id attributes to user and member attributes
String[] princs = userLdapAttrib.values().toArray(new String[userLdapAttrib.values().size()]);
String[] tmp = new String[userAttribs.length + princs.length];
System.arraycopy(princs, 0, tmp, 0, princs.length);
System.arraycopy(userAttribs, 0, tmp, princs.length, userAttribs.length);
userAttribs = tmp;
tmp = new String[memberAttribs.length + princs.length];
System.arraycopy(princs, 0, tmp, 0, princs.length);
System.arraycopy(memberAttribs, 0, tmp, princs.length, memberAttribs.length);
memberAttribs = tmp;
}
/**
......@@ -122,7 +144,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
public User<T> getUser(T userID)
throws UserNotFoundException, TransientException, AccessControlException
{
String searchField = (String) attribType.get(userID.getClass());
String searchField = (String) userLdapAttrib.get(userID.getClass());
if (searchField == null)
{
throw new IllegalArgumentException(
......@@ -135,8 +157,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
try
{
SearchRequest searchRequest = new SearchRequest(config.getUsersDN(),
SearchScope.SUB, searchField,
new String[] {"cn", "entryid", "entrydn", "dn"});
SearchScope.SUB, searchField, userAttribs);
searchRequest.addControl(
new ProxiedAuthorizationV2RequestControl("dn:" +
......@@ -157,12 +178,13 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
}
User<T> user = new User<T>(userID);
user.getIdentities().add(
new HttpPrincipal(searchResult.getAttributeValue("cn")));
user.getIdentities().add(
new NumericPrincipal(
searchResult.getAttributeValueAsInteger("entryid")));
new HttpPrincipal(searchResult.getAttributeValue(userLdapAttrib
.get(HttpPrincipal.class))));
String fname = searchResult.getAttributeValue(LDAP_FNAME);
String lname = searchResult.getAttributeValue(LDAP_LNAME);
user.details.add(new PersonalDetails(fname, lname));
//TODO populate user with the other returned personal or posix attributes
return user;
}
......@@ -182,14 +204,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
{
try
{
String searchField = (String) attribType.get(userID.getClass());
String searchField = (String) userLdapAttrib.get(userID.getClass());
if (searchField == null)
{
throw new IllegalArgumentException(
"Unsupported principal type " + userID.getClass());
}
User user = getUser(userID);
User<T> user = getUser(userID);
Filter filter = Filter.createANDFilter(
Filter.createEqualityFilter(searchField,
user.getUserID().getName()),
......@@ -256,14 +278,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
{
try
{
String searchField = (String) attribType.get(userID.getClass());
String searchField = (String) userLdapAttrib.get(userID.getClass());
if (searchField == null)
{
throw new IllegalArgumentException(
"Unsupported principal type " + userID.getClass());
}
User user = getUser(userID);
User<T> user = getUser(userID);
Filter filter = Filter.createANDFilter(
Filter.createEqualityFilter(searchField,
user.getUserID().getName()),
......@@ -301,14 +323,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
{
try
{
String searchField = (String) attribType.get(userID.getClass());
String searchField = (String) userLdapAttrib.get(userID.getClass());
if (searchField == null)
{
throw new IllegalArgumentException(
"Unsupported principal type " + userID.getClass());
}
User user = getUser(userID);
User<T> user = getUser(userID);
DN userDN = getUserDN(user);
CompareRequest compareRequest =
......@@ -333,16 +355,16 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
}
/**
* Returns a member user identified by the X500Principal only.
* Returns a member user identified by the X500Principal only. The
* returned object has the fields required by the GMS.
* Note that this method binds as a proxy user and not as the
* subject.
* @param userDN
* @param bindAsSubject - true if Ldap commands executed as subject
* (proxy authorization) or false if they are executed as the user
* in the connection.
* @return
* @throws UserNotFoundException
* @throws LDAPException
*/
User<X500Principal> getMember(DN userDN, boolean bindAsSubject)
User<X500Principal> getMember(DN userDN)
throws UserNotFoundException, LDAPException
{
Filter filter =
......@@ -351,50 +373,37 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
SearchRequest searchRequest =
new SearchRequest(this.config.getUsersDN(), SearchScope.SUB,
filter,
(String[]) this.attribType.values().toArray(
new String[this.attribType.values().size()]));
if (bindAsSubject)
{
searchRequest.addControl(
new ProxiedAuthorizationV2RequestControl("dn:" +
getSubjectDN().toNormalizedString()));
}
filter, memberAttribs);
SearchResultEntry searchResult =
getConnection().searchForEntry(searchRequest);
if (searchResult == null)
{
String msg = "User not found " + userDN;
String msg = "Member not found " + userDN;
logger.debug(msg);
throw new UserNotFoundException(msg);
}
User<X500Principal> user = new User<X500Principal>(
new X500Principal(searchResult.getAttributeValue(
(String) attribType.get(X500Principal.class))));
(String) userLdapAttrib.get(X500Principal.class))));
String princ = searchResult.getAttributeValue(
(String) userLdapAttrib.get(HttpPrincipal.class));
if (princ != null)
{
user.getIdentities().add(new HttpPrincipal(princ));
}
String fname = searchResult.getAttributeValue(LDAP_FNAME);
String lname = searchResult.getAttributeValue(LDAP_LNAME);
user.details.add(new PersonalDetails(fname, lname));
return user;
}
/**
* Returns a member user identified by the X500Principal only.
* @param userDN
* @return
* @throws UserNotFoundException
* @throws LDAPException
*/
User<X500Principal> getMember(DN userDN)
throws UserNotFoundException, LDAPException
{
return getMember(userDN, true);
}
DN getUserDN(User<? extends Principal> user)
throws LDAPException, UserNotFoundException
{
String searchField = (String) attribType.get(user.getUserID().getClass());
String searchField = (String) userLdapAttrib.get(user.getUserID().getClass());
if (searchField == null)
{
throw new IllegalArgumentException(
......
......@@ -68,22 +68,33 @@
*/
package ca.nrc.cadc.ac.server.ldap;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.util.Log4jInit;
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 java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
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 org.junit.BeforeClass;
import org.junit.Test;
import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserDetails;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.util.Log4jInit;
import com.unboundid.ldap.sdk.DN;
/**
*
* @author jburke
......@@ -102,7 +113,9 @@ public class LdapUserDAOTest
// static String userBaseDN = "ou=Users,ou=ds,dc=canfar,dc=net";
// static String groupBaseDN = "ou=Groups,ou=ds,dc=canfar,dc=net";
static final String testUserDN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
static final String testUserX509DN = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
static final String testUserDN = "uid=cadcdaotest1," + usersDN;
static User<X500Principal> testUser;
static LdapConfig config;
......@@ -113,9 +126,12 @@ public class LdapUserDAOTest
{
Log4jInit.setLevel("ca.nrc.cadc.ac", Level.DEBUG);
testUser = new User<X500Principal>(new X500Principal(testUserDN));
testUser = new User<X500Principal>(new X500Principal(testUserX509DN));
config = new LdapConfig(server, port, adminDN, adminPW, usersDN, groupsDN, adminGroupsDN);
testUser.details.add(new PersonalDetails("CADC", "DAOTest1"));
testUser.getIdentities().add(new HttpPrincipal("CadcDaoTest1"));
}
LdapUserDAO<X500Principal> getUserDAO()
......@@ -139,8 +155,8 @@ public class LdapUserDAOTest
{
try
{
User actual = getUserDAO().getUser(testUser.getUserID());
assertEquals(testUser, actual);
User<X500Principal> actual = getUserDAO().getUser(testUser.getUserID());
check(testUser, actual);
return null;
}
......@@ -150,6 +166,7 @@ public class LdapUserDAOTest
}
}
});
}
/**
......@@ -217,4 +234,90 @@ public class LdapUserDAOTest
});
}
/**
* Test of getMember.
*/
@Test
public void testGetMember() throws Exception
{
Subject subject = new Subject();
subject.getPrincipals().add(testUser.getUserID());
// do everything as owner
Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
{
public Object run() throws Exception
{
try
{
User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN));
check(testUser, actual);
return null;
}
catch (Exception e)
{
throw new Exception("Problems", e);
}
}
});
// should also work as a different user
subject = new Subject();
subject.getPrincipals().add(new HttpPrincipal("CadcDaoTest2"));
// do everything as owner
Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
{
public Object run() throws Exception
{
try
{
User<X500Principal> actual = getUserDAO().getMember(new DN(testUserDN));
check(testUser, actual);
return null;
}
catch (Exception e)
{
throw new Exception("Problems", e);
}
}
});
}
private static void check(final User<? extends Principal> user1, final User<? extends Principal> user2)
{
assertEquals(user1, user2);
assertEquals(user1.details, user2.details);
assertEquals(user1.details.size(), user2.details.size());
assertEquals(user1.getIdentities(), user2.getIdentities());
for(UserDetails d1 : user1.details)
{
assertTrue(user2.details.contains(d1));
if(d1 instanceof PersonalDetails)
{
PersonalDetails pd1 = (PersonalDetails)d1;
boolean found = false;
for(UserDetails d2 : user2.details)
{
if(d2 instanceof PersonalDetails)
{
PersonalDetails pd2 = (PersonalDetails)d2;
assertEquals(pd1, pd2); // already done in contains above but just in case
assertEquals(pd1.address, pd2.address);
assertEquals(pd1.city, pd2.city);
assertEquals(pd1.country, pd2.country);
assertEquals(pd1.email, pd2.email);
assertEquals(pd1.institute, pd2.institute);
found = true;
}
assertTrue(found);
}
}
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment