Skip to content

Commit

Permalink
KNL-1577 new method to remap username and clear relevant caches (saka…
Browse files Browse the repository at this point in the history
  • Loading branch information
ottenhoff authored Dec 19, 2017
1 parent c53ab6a commit 6ad08f9
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public interface UserDirectoryService extends EntityProducer
/** User eid for the admin user. */
static final String ADMIN_EID = "admin";

/** Cache keys for the id/eid mapping **/
static final String EIDCACHE = "eid:";
static final String IDCACHE = "id:";

/**
* This function returns a boolean value of true/false,
* depending on if the given password meets the validation criteria.
Expand Down Expand Up @@ -178,14 +182,24 @@ User addUser(String id, String eid, String firstName, String lastName, String em
* @return true if the user is allowed to update their own first and last names, false if not.
*/
public boolean allowUpdateUserName(String id);

/**
* Gets the UserEdit object from storage inorder to update the user eid and email
*
* @param id The user id.
* @param newEmail the new email that will set the eid + email fields
* @return UserEdit object
*/
public boolean updateUserId(String id, String newEmail);

/**
* Gets the UserEdit object from storage inorder to update the user Eid()
* Gets the UserEdit object from storage to remap the username (eid)
*
* @param eId The user id.
* @param newEmail the Id with which userId will be updated
* @param id The internal user id.
* @param newEid the new username
* @return UserEdit object
*/
public boolean updateUserId(String eId,String newEmail);
public boolean updateUserEid(String id, String newEid);

/**
* check permissions for editUser()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ public static boolean updateUserId(java.lang.String param0,java.lang.String para
return service.updateUserId(param0,param1);
}

public static boolean updateUserEid(java.lang.String param0,java.lang.String param1)
{
org.sakaiproject.user.api.UserDirectoryService service = getInstance();
if (service == null) return false;

return service.updateUserEid(param0,param1);
}

public static org.sakaiproject.user.api.UserEdit editUser(java.lang.String param0)
throws org.sakaiproject.user.api.UserNotDefinedException, org.sakaiproject.user.api.UserPermissionException,
org.sakaiproject.user.api.UserLockedException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
*/
@Slf4j
public class AuthnCacheWatcher implements Observer {
//Copied from DbUserService as they are private
private static final String EIDCACHE = "eid:";
private static final String IDCACHE = "id:";
private AuthenticationCache authenticationCache;
private UserDirectoryService userDirectoryService;
private EventTrackingService eventTrackingService;
Expand Down Expand Up @@ -86,9 +83,9 @@ public void setUserDirectoryService(UserDirectoryService userDirectoryService) {

public void init() {
log.info("init()");
if (userCache == null) { // this is the user id->eid mapping cache
userCache = memoryService.getCache("org.sakaiproject.user.api.UserDirectoryService");
}
if (userCache == null) { // this is the user id->eid mapping cache
userCache = memoryService.getCache("org.sakaiproject.user.api.UserDirectoryService");
}
eventTrackingService.addObserver(this);
}

Expand All @@ -103,11 +100,10 @@ public void update(Observable arg0, Object arg) {
if (!(arg instanceof Event))
return;
Event event = (Event) arg;



// check the event function against the functions we have notifications watching for
String function = event.getEvent();

//we err on the side of caution here in checking all events that might invalidate the data in the cache -DH
if (UserDirectoryService.SECURE_ADD_USER.equals(function) || UserDirectoryService.SECURE_UPDATE_USER_OWN_PASSWORD.equals(function)
|| UserDirectoryService.SECURE_UPDATE_USER_ANY.equals(function) || UserDirectoryService.SECURE_UPDATE_USER_OWN.equals(function)) {
Expand All @@ -121,8 +117,8 @@ public void update(Observable arg0, Object arg) {
String eid = userDirectoryService.getUserEid(refId);
log.debug("removing " + eid + " from cache");
authenticationCache.removeAuthentification(eid);
userCache.remove(EIDCACHE + eid);
userCache.remove(IDCACHE + refId);
userCache.remove(UserDirectoryService.IDCACHE + eid);
userCache.remove(UserDirectoryService.EIDCACHE + refId);
} catch (UserNotDefinedException e) {
//not sure how we'd end up here
log.warn(e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ public abstract class BaseUserDirectoryService implements UserDirectoryService,

/** A cache of users */
protected Cache<String, UserEdit> m_callCache = null;


/** A cache of users' id/eid map */
protected Cache<String, String> m_userCache = null;

/** Optional service to provide site-specific aliases for a user's display ID and display name. */
protected ContextualUserDisplayService m_contextualUserDisplayService = null;

Expand Down Expand Up @@ -540,6 +543,7 @@ public void init()
}

// caching for users
m_userCache = memoryService().getCache("org.sakaiproject.user.api.UserDirectoryService");
m_callCache = memoryService().getCache("org.sakaiproject.user.api.UserDirectoryService.callCache");
if (!m_callCache.isDistributed()) {
// KNL_1229 use an Observer for cache cleanup when the cache is not distributed
Expand Down Expand Up @@ -621,7 +625,9 @@ public void update(Observable observable, Object o) {
)
) {
String userRef = event.getResource();
removeCachedUser(userRef);
UserEdit u = getCachedUser(userRef);
String oldEid = u != null ? u.getEid() : null;
removeCachedUser(userRef, oldEid);
}
}

Expand All @@ -638,8 +644,8 @@ public void destroy()
m_provider = null;
m_anon = null;
m_passwordPolicyProvider = null;
m_callCache.close();
m_userCacheObserver = null;
m_callCache.close();
m_userCacheObserver = null;

log.info("destroy()");
}
Expand Down Expand Up @@ -1592,7 +1598,7 @@ public void removeUser(UserEdit user) throws UserPermissionException
}

// Remove from cache.
removeCachedUser(ref);
removeCachedUser(ref, user.getEid());
}

/**
Expand Down Expand Up @@ -1785,12 +1791,17 @@ protected void putCachedUser(String ref, UserEdit user)
}
}

protected void removeCachedUser(String ref)
protected void removeCachedUser(String ref, String eid)
{
if (m_callCache != null)
{
m_callCache.remove(ref);
}

if (m_userCache != null && StringUtils.isNotBlank(eid))
{
m_userCache.remove(IDCACHE + eid);
}
}

/**********************************************************************************************************************************************************************************************************************************************************
Expand Down Expand Up @@ -1980,6 +1991,7 @@ public boolean updateUserId(String id,String newEmail)
}
user.setEid(newEmail);
user.setEmail(newEmail);
((BaseUserEdit) user).setEvent(SECURE_UPDATE_USER_ANY);
commitEdit(user);
return true;
}
Expand All @@ -1996,6 +2008,38 @@ public boolean updateUserId(String id,String newEmail)
}
}

public boolean updateUserEid(String id, String newEid)
{
try {
List<String> locksSucceeded = new ArrayList<String>();

List<String> locks = new ArrayList<String>();
locks.add(SECURE_UPDATE_USER_ANY);
locksSucceeded = unlock(locks, userReference(id));

if(!locksSucceeded.isEmpty()) {
UserEdit user = m_storage.edit(id);
if (user == null) {
log.warn("Can't find user " + id + " when trying to update user eid");
return false;
}
user.setEid(newEid);
((BaseUserEdit) user).setEvent(SECURE_UPDATE_USER_ANY);
commitEdit(user);
return true;
}
else {
log.warn("User with id: "+id+" failed permission checks" );
return false;
}
} catch (UserPermissionException e) {
log.warn("You do not have sufficient permission to edit the user eid with Id: "+id, e);
return false;
} catch (UserAlreadyDefinedException e) {
log.error("A user already exists with EID of: "+id +"having eid :"+ newEid, e);
return false;
}
}

/**********************************************************************************************************************************************************************************************************************************************************
* UserEdit implementation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ public void setIdEidCache(Cache cache)
*/
protected class DbStorage extends BaseDbFlatStorage implements Storage, SqlReader
{
private static final String EIDCACHE = "eid:";
private static final String IDCACHE = "id:";

/**
* Construct.
Expand Down Expand Up @@ -549,7 +547,7 @@ protected void unMap(String id)
if (!m_separateIdEid) return;

// clear both sides of the cache
String eid = (String) cache.get(EIDCACHE+id);
String eid = (String) cache.get(EIDCACHE+id);
if ( eid != null ) {
cache.remove(IDCACHE+eid);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,36 @@ public String changeUserInfo(
return "success";
}

/**
* Edit a user's eid
* Commonly needed when a user changes legal name and username changes at institution
*
* @param sessionid the id of a valid session
* @param eid the current username (ie jsmith26) of the user you want to edit
* @param mewEid the new username
* @return success or exception message
* @throws RuntimeException
*/
@WebMethod
@Path("/changeUserEid")
@Produces("text/plain")
@GET
public String changeUserEid(
@WebParam(name = "sessionid", partName = "sessionid") @QueryParam("sessionid") String sessionid,
@WebParam(name = "eid", partName = "eid") @QueryParam("eid") String eid,
@WebParam(name = "newEid", partName = "newEid") @QueryParam("newEid") String newEid) {
Session session = establishSession(sessionid);

try {
String userid = userDirectoryService.getUserByEid(eid).getId();
boolean success = userDirectoryService.updateUserEid(userid, newEid);
return success ? "success" : "failure";
} catch (Exception e) {
log.error("WS changeUserEid(): " + e.getClass().getName() + " : " + e.getMessage());
return e.getClass().getName() + " : " + e.getMessage();
}
}

/**
* Edit a user's firstname/lastname
*
Expand Down

0 comments on commit 6ad08f9

Please sign in to comment.