Commit d1ebc41c authored by Brian Major's avatar Brian Major
Browse files

s1885 - added ability for privileged user to permanently delete a user

parent 22e2c986
......@@ -238,6 +238,19 @@ public interface UserPersistence
throws UserNotFoundException, TransientException,
AccessControlException;
/**
* Deactivate the user with the specified Principal from the active users tree.
*
* @param userID A Principal of the User.
*
* @throws UserNotFoundException when the user is not found.
* @throws TransientException If an temporary, unexpected problem occurred.
* @throws AccessControlException If the operation is not permitted.
*/
void deactivateUser(Principal userID)
throws UserNotFoundException, TransientException,
AccessControlException;
/**
* Delete the user with the specified Principal from the pending users tree.
*
......
......@@ -1069,11 +1069,11 @@ public class LdapUserDAO extends LdapDAO
* @throws TransientException If an temporary, unexpected problem occurred.
* @throws AccessControlException If the operation is not permitted.
*/
public void deleteUser(final Principal userID)
public void deleteUser(final Principal userID, boolean markDelete)
throws UserNotFoundException, TransientException,
AccessControlException
{
deleteUser(userID, config.getUsersDN(), true);
deleteUser(userID, config.getUsersDN(), markDelete);
}
/**
......
......@@ -402,7 +402,7 @@ public class LdapUserPersistence extends LdapPersistence implements UserPersiste
* @throws TransientException If an temporary, unexpected problem occurred.
* @throws AccessControlException If the operation is not permitted.
*/
public void deleteUser(Principal userID)
public void deactivateUser(Principal userID)
throws UserNotFoundException, TransientException,
AccessControlException
{
......@@ -415,7 +415,36 @@ public class LdapUserPersistence extends LdapPersistence implements UserPersiste
try
{
userDAO = getLdapUserDao(conns);
userDAO.deleteUser(userID);
userDAO.deleteUser(userID, true);
}
finally
{
conns.releaseConnections();
}
}
/**
* Delete the user specified by userID.
*
* @param userID The userID.
*
* @throws UserNotFoundException when the user is not found.
* @throws TransientException If an temporary, unexpected problem occurred.
* @throws AccessControlException If the operation is not permitted.
*/
public void deleteUser(Principal userID)
throws UserNotFoundException, TransientException,
AccessControlException
{
// admin API: permission checks done in action layer
// and in ACIs.
LdapUserDAO userDAO = null;
LdapConnections conns = new LdapConnections(this);
try
{
userDAO = getLdapUserDao(conns);
userDAO.deleteUser(userID, false);
}
finally
{
......
......@@ -84,12 +84,12 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.nrc.cadc.ac.server.web.users.CreateUserAction;
import org.apache.log4j.Logger;
import ca.nrc.cadc.ac.server.PluginFactory;
import ca.nrc.cadc.ac.server.UserPersistence;
import ca.nrc.cadc.ac.server.web.users.AbstractUserAction;
import ca.nrc.cadc.ac.server.web.users.CreateUserAction;
import ca.nrc.cadc.ac.server.web.users.GetUserAction;
import ca.nrc.cadc.ac.server.web.users.UserActionFactory;
import ca.nrc.cadc.ac.server.web.users.UserLogInfo;
......@@ -186,6 +186,17 @@ public class UserServlet extends HttpServlet
Subject subject;
Subject privilegedSubject = getPrivilegedSubject(request);
log.debug("privileged subject: " + privilegedSubject);
if (privilegedSubject != null)
{
action.setIsPrivilegedUser(true);
action.setPrivilegedSubject(true);
logInfo.setSubject(privilegedSubject);
}
else
{
action.setIsPrivilegedUser(false);
action.setPrivilegedSubject(false);
}
// If the calling subject is not a PrivilegedSubject,
// AND it is a PUT request, throw an AccessControlException
......@@ -194,7 +205,6 @@ public class UserServlet extends HttpServlet
profiler.checkpoint("check non-privileged user");
if (privilegedSubject == null)
{
action.setPrivilegedSubject(false);
subject = AuthenticationUtil.getSubject(request);
logInfo.setSubject(subject);
log.debug("augmented subject: " + subject);
......@@ -202,7 +212,6 @@ public class UserServlet extends HttpServlet
}
else
{
action.setPrivilegedSubject(true);
log.debug("subject not augmented: " + privilegedSubject);
subject = privilegedSubject;
logInfo.setSubject(privilegedSubject);
......@@ -214,11 +223,8 @@ public class UserServlet extends HttpServlet
// AND it is a GET request, do not augment the subject.
else if (action instanceof GetUserAction && privilegedSubject != null)
{
profiler.checkpoint("check privileged user");
subject = Subject.getSubject(AccessController.getContext());
log.debug("subject not augmented: " + subject);
action.setAugmentUser(true);
logInfo.setSubject(privilegedSubject);
profiler.checkpoint("set privileged user");
}
else
......
......@@ -72,27 +72,23 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.security.AccessControlException;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import ca.nrc.cadc.ac.WriterException;
import org.apache.log4j.Logger;
import ca.nrc.cadc.ac.ReaderException;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserAlreadyExistsException;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.ac.WriterException;
import ca.nrc.cadc.ac.json.JsonUserListWriter;
import ca.nrc.cadc.ac.json.JsonUserReader;
import ca.nrc.cadc.ac.json.JsonUserRequestReader;
import ca.nrc.cadc.ac.json.JsonUserWriter;
import ca.nrc.cadc.ac.server.UserPersistence;
import ca.nrc.cadc.ac.server.web.SyncOutput;
import ca.nrc.cadc.ac.xml.UserListWriter;
import ca.nrc.cadc.ac.xml.UserReader;
import ca.nrc.cadc.ac.xml.UserRequestReader;
import ca.nrc.cadc.ac.xml.UserWriter;
import ca.nrc.cadc.net.TransientException;
import ca.nrc.cadc.profiler.Profiler;
......@@ -104,7 +100,7 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob
public static final String JSON_CONTENT_TYPE = "application/json";
private Profiler profiler = new Profiler(AbstractUserAction.class);
protected boolean isAugmentUser;
protected boolean isPrivilegedUser;
protected boolean isPrivilegedSubject;
protected UserLogInfo logInfo;
protected SyncOutput syncOut;
......@@ -114,19 +110,19 @@ public abstract class AbstractUserAction implements PrivilegedExceptionAction<Ob
AbstractUserAction()
{
this.isAugmentUser = false;
this.isPrivilegedUser = false;
}
public abstract void doAction() throws Exception;
public void setAugmentUser(final boolean isAugmentUser)
public void setIsPrivilegedUser(boolean isPrivilegedUser)
{
this.isAugmentUser = isAugmentUser;
this.isPrivilegedUser = isPrivilegedUser;
}
public boolean isAugmentUser()
public boolean isPrivilegedUser()
{
return this.isAugmentUser;
return this.isPrivilegedUser;
}
public void setPrivilegedSubject(final boolean isPrivilegedSubject)
......
......@@ -68,23 +68,36 @@
*/
package ca.nrc.cadc.ac.server.web.users;
import ca.nrc.cadc.ac.server.UserPersistence;
import java.security.AccessControlException;
import java.security.Principal;
public class DeleteUserAction extends AbstractUserAction
{
private final Principal userID;
private boolean markAsDeleted;
DeleteUserAction(Principal userID)
DeleteUserAction(Principal userID, boolean markAsDeleted)
{
super();
this.userID = userID;
this.markAsDeleted = markAsDeleted;
}
public void doAction() throws Exception
{
userPersistence.deleteUser(userID);
if (markAsDeleted)
{
userPersistence.deactivateUser(userID);
}
else
{
// only the privileged user can do real deletes
if (!super.isPrivilegedSubject)
{
throw new AccessControlException("Forbidden");
}
userPersistence.deleteUser(userID);
}
}
}
......@@ -113,7 +113,7 @@ public class GetUserAction extends AbstractUserAction
* If the calling Subject user is the notAugmentedX500User, AND it is
* a GET, call the userDAO to get the User with all identities.
*/
if (isAugmentUser())
if (isPrivilegedUser())
{
log.debug("getting augmented user " + principal.getName());
user = userPersistence.getAugmentedUser(principal);
......
......@@ -203,7 +203,13 @@ public abstract class UserActionFactory
{
String userID = NetUtil.decode(segments[0]);
Principal p = getIdentity(userID, request.getParameter("idType"));
action = new DeleteUserAction(p);
String hardDelete = request.getParameter("hard");
boolean markAsDeleted = true;
if (hardDelete != null && hardDelete.equalsIgnoreCase(Boolean.TRUE.toString()))
{
markAsDeleted = false;
}
action = new DeleteUserAction(p, markAsDeleted);
}
if (action != null)
......
......@@ -84,12 +84,12 @@ import java.util.Collection;
import javax.security.auth.Subject;
import javax.security.auth.x500.X500Principal;
import ca.nrc.cadc.ac.UserAlreadyExistsException;
import org.apache.log4j.Logger;
import org.junit.Test;
import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserAlreadyExistsException;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.UserRequest;
import ca.nrc.cadc.auth.DNPrincipal;
......@@ -600,7 +600,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
userDAO.addUserRequest(userRequest);
userDAO.approveUserRequest(userID);
userDAO.deleteUser(userID);
userDAO.deleteUser(userID, false);
return null;
}
......@@ -777,7 +777,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
}
// delete the user
userDAO.deleteUser(testUser.getHttpPrincipal());
userDAO.deleteUser(testUser.getHttpPrincipal(), false);
// login as deleted user
try
......@@ -1042,7 +1042,7 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
try
{
final LdapUserDAO userDAO = getUserDAO();
userDAO.deleteUser(userID);
userDAO.deleteUser(userID, false);
return null;
}
......
......@@ -266,7 +266,7 @@ public class GetUserActionTest
final HttpPrincipal userID = new HttpPrincipal("CADCtest");
final GetUserAction testSubject = new GetUserAction(userID, null);
testSubject.userPersistence = mockUserPersistence;
testSubject.setAugmentUser(true);
testSubject.setIsPrivilegedUser(true);
final NumericPrincipal numericPrincipal = new NumericPrincipal(UUID.randomUUID());
final X500Principal x500Principal = new X500Principal("cn=foo,o=bar");
......
......@@ -67,14 +67,16 @@
package ca.nrc.cadc.ac.server.web.users;
import ca.nrc.cadc.util.Log4jInit;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import ca.nrc.cadc.util.Log4jInit;
public class UserActionFactoryTest
{
......@@ -113,6 +115,7 @@ public class UserActionFactoryTest
HttpServletRequest request = EasyMock.createMock(HttpServletRequest.class);
EasyMock.expect(request.getPathInfo()).andReturn("userName");
EasyMock.expect(request.getParameter("idType")).andReturn("sessionID");
EasyMock.expect(request.getParameter("hard")).andReturn(null);
EasyMock.replay(request);
AbstractUserAction action = UserActionFactory.httpDeleteFactory().createAction(request);
EasyMock.verify(request);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment