Index: kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupService.java =================================================================== --- kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupService.java (revision 52281) +++ kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupService.java (working copy) @@ -43,6 +43,7 @@ import org.sakaiproject.db.api.SqlReader; import org.sakaiproject.db.api.SqlService; import org.sakaiproject.db.api.SqlServiceDeadlockException; +import org.sakaiproject.entity.api.Entity; import org.sakaiproject.javax.PagingPosition; import org.sakaiproject.time.api.Time; import org.sakaiproject.user.api.UserNotDefinedException; @@ -721,9 +722,26 @@ boolean auth = (userId != null) && (!userDirectoryService().getAnonymousUser().getId().equals(userId)); String sql = dbAuthzGroupSql.getSelectRealmIdSql(azGroups); int size = 2; + String roleswap = null; // define the roleswap variable if (azGroups != null) { size += azGroups.size(); + for (Iterator i = azGroups.iterator(); i.hasNext();) + { + String[] refs = StringUtil.split(i.next().toString(), Entity.SEPARATOR); // splits the azGroups values so we can look for swapped state + for (int i2 = 0; i2 < refs.length; i2++) // iterate through the groups to see if there is a swapped state in the variable + { + roleswap = (String)sessionManager().getCurrentSession().getAttribute("roleswap/site/" + refs[i2]); + if (roleswap!=null) // break from this loop if a swapped state is found + break; + } + if (roleswap!=null) + { + sql = dbAuthzGroupSql.getSelectRealmIdRoleSwapSql(azGroups); // redefine the sql we use if there's a role swap + size++; // increase the "size" by 1 for our new sql + break; // break from the loop + } + } } Object[] fields = new Object[size]; fields[0] = lock; @@ -735,6 +753,10 @@ { fields[pos++] = i.next(); } + if (roleswap!=null) // add in name of the role for the alternate query + { + fields[pos++] = roleswap; + } } // Get resultset @@ -1451,6 +1473,15 @@ fields[1] = lock; fields[2] = realmId; + // checks to see if the user has the roleswap variable set in the session + String roleswap = (String)sessionManager().getCurrentSession().getAttribute("roleswap" + fields[2]); + + if (roleswap != null) + { + fields[0] = roleswap; // set the field to the student role for the alternate sql + statement = dbAuthzGroupSql.getCountRoleFunctionSql(); // set the function for our alternate sql + } + List resultsNew = m_sql.dbRead(statement, fields, new SqlReader() { public Object readSqlResultRecord(ResultSet result) @@ -1509,10 +1540,13 @@ // any of the grant or role realms String statement = dbAuthzGroupSql.getCountRealmRoleFunctionSql(ANON_ROLE, AUTH_ROLE, auth, inClause); Object[] fields = new Object[2 + (2 * realms.size())]; + Object[] fields2 = new Object[3]; // for roleswap int pos = 0; for (Iterator i = realms.iterator(); i.hasNext();) { String role = (String) i.next(); + if (role.startsWith("/site/")) + fields2[2] = role; fields[pos++] = role; } fields[pos++] = lock; @@ -1523,21 +1557,49 @@ fields[pos++] = role; } - List results = m_sql.dbRead(statement, fields, new SqlReader() - { - public Object readSqlResultRecord(ResultSet result) + // TODO: would be better to get this initially to make the code more efficient, but the realms collection does not have a common + // order for the site's id which is needed to determine if the session variable exists + String roleswap = (String)sessionManager().getCurrentSession().getAttribute("roleswap" + fields2[2]); + List results = null; + if (roleswap != null) + { + fields2[0] = roleswap; + fields2[1] = lock; + statement = dbAuthzGroupSql.getCountRoleFunctionSql(); + results = m_sql.dbRead(statement, fields2, new SqlReader() { - try + public Object readSqlResultRecord(ResultSet result) { - int count = result.getInt(1); - return Integer.valueOf(count); + try + { + int count = result.getInt(1); + return new Integer(count); + } + catch (SQLException ignore) + { + return null; + } } - catch (SQLException ignore) + }); + } + else + { + results = m_sql.dbRead(statement, fields, new SqlReader() + { + public Object readSqlResultRecord(ResultSet result) { - return null; + try + { + int count = result.getInt(1); + return new Integer(count); + } + catch (SQLException ignore) + { + return null; + } } - } - }); + }); + } boolean rv = false; int count = -1; @@ -2225,7 +2287,11 @@ // prepare the return String rv = null; - if ((results != null) && (!results.isEmpty())) + // checks to see if the user has the roleswap variable set in the session + String roleswap = (String)sessionManager().getCurrentSession().getAttribute("roleswap" + fields[0]); + if (roleswap != null) + rv = roleswap; + else if ((results != null) && (!results.isEmpty())) { rv = (String) results.get(0); if (results.size() > 1) Index: kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupSqlDefault.java =================================================================== --- kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupSqlDefault.java (revision 52281) +++ kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupSqlDefault.java (working copy) @@ -68,6 +68,15 @@ { return "select count(1) from SAKAI_REALM_ROLE where ROLE_NAME = ?"; } + + public String getCountRoleFunctionSql() + { + return "select count(1) from SAKAI_REALM_RL_FN MAINTABLE " + + " JOIN SAKAI_REALM_ROLE ROLE ON ROLE.ROLE_KEY = MAINTABLE.ROLE_KEY " + + " JOIN SAKAI_REALM_FUNCTION FUNCTIONS ON FUNCTIONS.FUNCTION_KEY = MAINTABLE.FUNCTION_KEY " + + " JOIN SAKAI_REALM REALM ON REALM.REALM_KEY = MAINTABLE.REALM_KEY " + + " where ROLE.ROLE_NAME = ? AND FUNCTIONS.FUNCTION_NAME = ? AND REALM.REALM_ID = ?"; + } public String getDeleteRealmProvider1Sql() { @@ -298,7 +307,28 @@ } return sql; } + + public String getSelectRealmIdRoleSwapSql(Collection azGroups) + { + String sql = "select SR.REALM_ID " + "from SAKAI_REALM_FUNCTION SRF " + + "inner join SAKAI_REALM_RL_FN SRRF on SRF.FUNCTION_KEY = SRRF.FUNCTION_KEY " + + "inner join SAKAI_REALM_RL_GR SRRG on SRRF.REALM_KEY = SRRG.REALM_KEY " + + "inner join SAKAI_REALM SR on SRRF.REALM_KEY = SR.REALM_KEY " + + "join SAKAI_REALM_ROLE ROLE on ROLE.ROLE_KEY = SRRF.ROLE_KEY " + + "where SRF.FUNCTION_NAME = ? and SRRG.USER_ID = ? and SRRG.ACTIVE = '1' "; + if (azGroups != null) + { + sql += "and SR.REALM_ID in ("; + for (int i = 0; i < azGroups.size() - 1; i++) + sql += "?,"; + + sql += "?) "; + } + sql += "and ROLE.ROLE_NAME = ? "; + return sql; + } + public String getSelectRealmProvider2Sql() { return "SELECT RR.ROLE_NAME, RRD.DESCRIPTION, RRD.PROVIDER_ONLY FROM SAKAI_REALM_ROLE_DESC RRD" Index: kernel-impl/src/main/java/org/sakaiproject/authz/impl/SakaiSecurityTest.java =================================================================== --- kernel-impl/src/main/java/org/sakaiproject/authz/impl/SakaiSecurityTest.java (revision 52281) +++ kernel-impl/src/main/java/org/sakaiproject/authz/impl/SakaiSecurityTest.java (working copy) @@ -23,8 +23,10 @@ import org.sakaiproject.authz.api.AuthzGroupService; import org.sakaiproject.entity.api.EntityManager; +import org.sakaiproject.event.api.EventTrackingService; import org.sakaiproject.memory.api.MemoryService; import org.sakaiproject.thread_local.api.ThreadLocalManager; +import org.sakaiproject.tool.api.SessionManager; import org.sakaiproject.user.api.UserDirectoryService; /** @@ -73,4 +75,20 @@ { return null; } + + /** + * @return the SessionManager collaborator. + */ + protected SessionManager sessionManager() + { + return null; + } + + /** + * @return the EventTrackingService collaborator. + */ + protected EventTrackingService eventTrackingService() + { + return null; + } } Index: kernel-impl/src/main/java/org/sakaiproject/authz/impl/SakaiSecurity.java =================================================================== --- kernel-impl/src/main/java/org/sakaiproject/authz/impl/SakaiSecurity.java (revision 52281) +++ kernel-impl/src/main/java/org/sakaiproject/authz/impl/SakaiSecurity.java (working copy) @@ -32,13 +32,17 @@ import org.sakaiproject.authz.api.AuthzGroupService; import org.sakaiproject.authz.api.SecurityAdvisor; import org.sakaiproject.authz.api.SecurityService; +import org.sakaiproject.entity.api.Entity; import org.sakaiproject.entity.api.EntityManager; import org.sakaiproject.entity.api.Reference; +import org.sakaiproject.event.api.EventTrackingService; import org.sakaiproject.memory.api.MemoryService; import org.sakaiproject.memory.api.MultiRefCache; import org.sakaiproject.thread_local.api.ThreadLocalManager; +import org.sakaiproject.tool.api.SessionManager; import org.sakaiproject.user.api.User; import org.sakaiproject.user.api.UserDirectoryService; +import org.sakaiproject.util.StringUtil; /** *
@@ -84,6 +88,16 @@
* @return the EntityManager collaborator.
*/
protected abstract EntityManager entityManager();
+
+ /**
+ * @return the SessionManager collaborator.
+ */
+ protected abstract SessionManager sessionManager();
+
+ /**
+ * @return the EventTrackingService collaborator.
+ */
+ protected abstract EventTrackingService eventTrackingService();
/**********************************************************************************************************************************************************************************************************************************************************
* Configuration
@@ -271,6 +285,19 @@
{
// check the cache
String command = "unlock@" + userId + "@" + function + "@" + entityRef;
+ String[] refs = StringUtil.split(entityRef, Entity.SEPARATOR);
+ String roleswap = null;
+ for (int i = 0; i < refs.length; i++) // Checking for existence of roll swapped state
+ {
+ roleswap = (String)sessionManager().getCurrentSession().getAttribute("roleswapFlagForClearing/" + refs[i]);
+ if (roleswap!=null) // check if our flag is set
+ {
+ sessionManager().getCurrentSession().removeAttribute("roleswapFlagForClearing/" + refs[i]); // remove the session attribute so we don't repeatedly call thi
+ eventTrackingService().post(eventTrackingService().newEvent(function, "/realm/" + entityRef, true)); // this will clear the cache for the site and render the pages correctly by forcing the permissions to be rechecked
+ break;
+ }
+ }
+
if (m_callCache != null)
{
final Boolean value = (Boolean) m_callCache.get(command);
Index: kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupSql.java
===================================================================
--- kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupSql.java (revision 52281)
+++ kernel-impl/src/main/java/org/sakaiproject/authz/impl/DbAuthzGroupSql.java (working copy)
@@ -38,6 +38,8 @@
String getCountRealmRoleFunctionSql(String anonymousRole, String authorizationRole, boolean authorized, String inClause);
String getCountRealmRoleSql();
+
+ String getCountRoleFunctionSql();
String getDeleteRealmProvider1Sql();
@@ -104,6 +106,8 @@
String getSelectRealmIdSql();
String getSelectRealmIdSql(Collection azGroups);
+
+ String getSelectRealmIdRoleSwapSql(Collection azGroups);
String getSelectRealmProvider2Sql();
Index: kernel-impl/src/main/java/org/sakaiproject/site/impl/BaseSiteService.java
===================================================================
--- kernel-impl/src/main/java/org/sakaiproject/site/impl/BaseSiteService.java (revision 52281)
+++ kernel-impl/src/main/java/org/sakaiproject/site/impl/BaseSiteService.java (working copy)
@@ -438,6 +438,7 @@
entityManager().registerEntityProducer(this, REFERENCE_ROOT);
// register functions
+ functionManager().registerFunction(SITE_ROLE_SWAP);
functionManager().registerFunction(SITE_VISIT);
functionManager().registerFunction(SITE_VISIT_UNPUBLISHED);
functionManager().registerFunction(SECURE_ADD_SITE);
@@ -721,7 +722,11 @@
}
else
{
- unlock(SITE_VISIT_UNPUBLISHED, rv.getReference());
+ String roleswap = (String)sessionManager().getCurrentSession().getAttribute("roleswap/site/" + id);
+ if (roleswap!=null) // if in a swapped mode, treat it as a normal site else do the normal unpublished check
+ unlock(SITE_VISIT, rv.getReference());
+ else
+ unlock(SITE_VISIT_UNPUBLISHED, rv.getReference());
}
return rv;
@@ -754,6 +759,14 @@
/**
* @inheritDoc
*/
+ public boolean allowRoleSwap(String id)
+ {
+ return unlockCheck(SITE_ROLE_SWAP, siteReference(id));
+ }
+
+ /**
+ * @inheritDoc
+ */
public void save(Site site) throws IdUnusedException, PermissionException
{
if (site.getId() == null) throw new IdUnusedException("