use of org.apereo.portal.security.IAuthorizationPrincipal in project uPortal by Jasig.
the class AuthorizationImpl method getAllPermissionsForPrincipal.
/**
* Returns the <code>IPermissions</code> owner has granted this <code>Principal</code> for the
* specified activity and target. Null parameters will be ignored, that is, all <code>
* IPermissions</code> matching the non-null parameters are retrieved. So, <code>
* getPermissions(principal,null, null, null)</code> should retrieve all <code>IPermissions
* </code> for a <code>Principal</code>. Note that this includes <code>IPermissions</code>
* inherited from groups the <code>Principal</code> belongs to.
*
* @return org.apereo.portal.security.IPermission[]
* @param principal IAuthorizationPrincipal
* @param owner java.lang.String
* @param activity java.lang.String
* @param target java.lang.String
* @exception AuthorizationException indicates authorization information could not be retrieved.
*/
public IPermission[] getAllPermissionsForPrincipal(IAuthorizationPrincipal principal, String owner, String activity, String target) throws AuthorizationException {
IPermission[] perms = getPermissionsForPrincipal(principal, owner, activity, target);
ArrayList<IPermission> al = new ArrayList<IPermission>(Arrays.asList(perms));
Iterator i = getInheritedPrincipals(principal);
while (i.hasNext()) {
IAuthorizationPrincipal p = (IAuthorizationPrincipal) i.next();
perms = getPermissionsForPrincipal(p, owner, activity, target);
al.addAll(Arrays.asList(perms));
}
if (log.isTraceEnabled()) {
log.trace("query for all permissions for principal=[" + principal + "], owner=[" + owner + "], activity=[" + activity + "], target=[" + target + "] returned permissions [" + al + "]");
}
return ((IPermission[]) al.toArray(new IPermission[al.size()]));
}
use of org.apereo.portal.security.IAuthorizationPrincipal in project uPortal by Jasig.
the class AnyUnblockedGrantPermissionPolicy method hasUnblockedPathToGrant.
/**
* This method performs the actual, low-level checking of a single activity and target. Is IS
* responsible for performing the same check for affiliated groups in the Groups hierarchy, but
* it is NOT responsible for understanding the nuances of relationships some activities and/or
* targets have with one another (e.g. MANAGE_APPROVED, ALL_PORTLETS, etc.). It performs the
* following steps, in order:
*
* <ol>
* <li>Find out if the specified principal is <em>specifically</em> granted or denied; if an
* answer is found in this step, return it
* <li>Find out what groups this principal belongs to; convert each one to a principal and
* seek an answer by invoking ourselves recursively; if an answer is found in this step,
* return it
* <li>Return false (no explicit GRANT means no permission)
* </ol>
*/
private boolean hasUnblockedPathToGrant(IAuthorizationService service, IAuthorizationPrincipal principal, IPermissionOwner owner, IPermissionActivity activity, IPermissionTarget target, Set<IGroupMember> seenGroups) throws GroupsException {
if (log.isTraceEnabled()) {
log.trace("Searching for unblocked path to GRANT for principal '{}' to " + "'{}' on target '{}' having already checked: {}", principal.getKey(), activity.getFname(), target.getKey(), seenGroups);
}
/*
* Step #1: Specific GRANT/DENY attached to this principal
*/
final IPermission[] permissions = service.getPermissionsForPrincipal(principal, owner.getFname(), activity.getFname(), target.getKey());
final Set<IPermission> activePermissions = removeInactivePermissions(permissions);
final boolean denyExists = containsType(activePermissions, IPermission.PERMISSION_TYPE_DENY);
if (denyExists) {
// We need go no further; DENY trumps both GRANT & inherited permissions
return false;
}
final boolean grantExists = containsType(activePermissions, IPermission.PERMISSION_TYPE_GRANT);
if (grantExists) {
// We need go no further; explicit GRANT at this level of the hierarchy
if (log.isTraceEnabled()) {
log.trace("Found unblocked path to this permission set including a GRANT: {}", activePermissions);
}
return true;
}
/*
* Step #2: Seek an answer from affiliated groups
*/
IGroupMember principalAsGroupMember = service.getGroupMember(principal);
if (seenGroups.contains(principalAsGroupMember)) {
if (log.isTraceEnabled()) {
log.trace("Declining to re-examine principal '{}' for permission to '{}' " + "on '{}' because this group is among already checked groups: {}", principal.getKey(), activity.getFname(), target.getKey(), seenGroups);
}
return false;
}
seenGroups.add(principalAsGroupMember);
Set<IEntityGroup> immediatelyContainingGroups = principalAsGroupMember.getParentGroups();
for (IGroupMember parentGroup : immediatelyContainingGroups) {
try {
if (parentGroup != null) {
IAuthorizationPrincipal parentPrincipal = service.newPrincipal(parentGroup);
boolean parentHasUnblockedPathToGrant = hasUnblockedPathToGrantWithCache(service, parentPrincipal, owner, activity, target, seenGroups);
if (parentHasUnblockedPathToGrant) {
return true;
}
// Parent didn't have a path to grant, fall through and try another parent (if any)
}
} catch (Exception e) {
// problem evaluating this path, but let's not let it stop
// us from exploring other paths. Though a portion of the
// group structure is broken, permission may be granted by
// an unbroken portion
log.error("Error evaluating permissions of parent group [" + parentGroup + "]", e);
}
}
/*
* Step #3: No explicit GRANT means no permission
*/
return false;
}
use of org.apereo.portal.security.IAuthorizationPrincipal in project uPortal by Jasig.
the class XalanAuthorizationHelperBean method canRender.
/* (non-Javadoc)
* @see org.apereo.portal.security.xslt.IAuthorizationHelper#canRender(java.lang.String, java.lang.String)
*/
@Override
public boolean canRender(final String userName, final String fname) {
if (userName == null || fname == null) {
return false;
}
final IAuthorizationPrincipal userPrincipal = this.getUserPrincipal(userName);
if (userPrincipal == null) {
return false;
}
final String portletId;
try {
final IPortletDefinition portletDefinition = this.portletDefinitionRegistry.getPortletDefinitionByFname(fname);
if (portletDefinition == null) {
if (this.logger.isInfoEnabled()) {
this.logger.info("No PortletDefinition for fname='" + fname + "', returning false.");
}
return false;
}
portletId = portletDefinition.getPortletDefinitionId().getStringId();
} catch (Exception e) {
this.logger.warn("Could not find PortletDefinition for fname='" + fname + "' while checking if user '" + userName + "' can render it. Returning FALSE.", e);
return false;
}
return userPrincipal.canRender(portletId);
}
use of org.apereo.portal.security.IAuthorizationPrincipal in project uPortal by Jasig.
the class MarketplaceService method loadMarketplaceEntriesFor.
/**
* Load the list of marketplace entries for a user. Will load entries async. This method is
* primarily intended for seeding data. Most impls should call browseableMarketplaceEntriesFor()
* instead.
*
* <p>Note: Set is immutable since it is potentially shared between threads. If the set needs
* mutability, be sure to consider the thread safety implications. No protections have been
* provided against modifying the MarketplaceEntry itself, so be careful when modifying the
* entities contained in the list.
*
* @param user The non-null user
* @param categories Restricts the output to entries within the specified categories if
* non-empty
* @return a Future that will resolve to a set of MarketplaceEntry objects the requested user
* has browse access to.
* @throws java.lang.IllegalArgumentException if user is null
* @since 4.2
*/
@Async
public Future<ImmutableSet<MarketplaceEntry>> loadMarketplaceEntriesFor(final IPerson user, final Set<PortletCategory> categories) {
final IAuthorizationPrincipal principal = AuthorizationPrincipalHelper.principalFromUser(user);
List<IPortletDefinition> allDisplayablePortletDefinitions = this.portletDefinitionRegistry.getAllPortletDefinitions();
if (!categories.isEmpty()) {
// Indicates we plan to restrict portlets displayed in the Portlet
// Marketplace to those that belong to one or more specified groups.
Element portletDefinitionsElement = marketplaceCategoryCache.get(categories);
if (portletDefinitionsElement == null) {
/*
* Collection not in cache -- need to recreate it
*/
// Gather the complete collection of allowable categories (specified categories & their descendants)
final Set<PortletCategory> allSpecifiedAndDecendantCategories = new HashSet<>();
for (PortletCategory pc : categories) {
collectSpecifiedAndDescendantCategories(pc, allSpecifiedAndDecendantCategories);
}
// Filter portlets that match the criteria
Set<IPortletDefinition> filteredPortletDefinitions = new HashSet<>();
for (final IPortletDefinition portletDefinition : allDisplayablePortletDefinitions) {
final Set<PortletCategory> parents = portletCategoryRegistry.getParentCategories(portletDefinition);
for (final PortletCategory parent : parents) {
if (allSpecifiedAndDecendantCategories.contains(parent)) {
filteredPortletDefinitions.add(portletDefinition);
break;
}
}
}
portletDefinitionsElement = new Element(categories, new ArrayList<>(filteredPortletDefinitions));
marketplaceCategoryCache.put(portletDefinitionsElement);
}
allDisplayablePortletDefinitions = (List<IPortletDefinition>) portletDefinitionsElement.getObjectValue();
}
final Set<MarketplaceEntry> visiblePortletDefinitions = new HashSet<>();
for (final IPortletDefinition portletDefinition : allDisplayablePortletDefinitions) {
if (mayBrowsePortlet(principal, portletDefinition)) {
final MarketplacePortletDefinition marketplacePortletDefinition = getOrCreateMarketplacePortletDefinition(portletDefinition);
final MarketplaceEntry entry = new MarketplaceEntry(marketplacePortletDefinition, user);
// flag whether this use can add the portlet...
boolean canAdd = mayAddPortlet(user, portletDefinition);
entry.setCanAdd(canAdd);
visiblePortletDefinitions.add(entry);
}
}
logger.trace("These portlet definitions {} are browseable by {}.", visiblePortletDefinitions, user);
Future<ImmutableSet<MarketplaceEntry>> result = new AsyncResult<>(ImmutableSet.copyOf(visiblePortletDefinitions));
Element cacheElement = new Element(user.getUserName(), result);
marketplaceUserPortletDefinitionCache.put(cacheElement);
return result;
}
use of org.apereo.portal.security.IAuthorizationPrincipal in project uPortal by Jasig.
the class AuthorizationTester method testPermissionPrincipal.
/**
* Tests concurrent access to permissions via "singleton" principal objects. Only run this test
* when the property org.apereo.portal.security.IAuthorizationService.cachePermissions=true,
* since performance of the db calls will distort the time needed to complete the various parts
* of the test.
*/
public void testPermissionPrincipal() throws Exception {
print("***** ENTERING AuthorizationTester.testPermissionPrincipal() *****");
Class type = IPERSON_CLASS;
String key = "student";
int numPrincipals = 10;
int numTestingThreads = 10;
int idx = 0;
long pauseBeforeUpdateMillis = 3000;
long pauseAfterUpdateMillis = 10000;
IAuthorizationPrincipal[] principals = new IAuthorizationPrincipal[numPrincipals];
for (idx = 0; idx < numPrincipals; idx++) {
principals[idx] = getService().newPrincipal(key, type);
}
String msg = "Test that principal " + principals[0] + " is being cached.";
print(msg);
for (idx = 1; idx < numPrincipals; idx++) {
assertTrue(msg, principals[idx] == principals[0]);
}
IAuthorizationPrincipal p1 = principals[0];
IPermission testPermission = (IPermission) testPermissions.get(0);
msg = "Testing first principal for " + testPermission + " (should be TRUE -- inherited from Everyone)";
print(msg);
boolean testResult = p1.hasPermission(OWNER, TEST_ACTIVITY, testPermission.getTarget());
assertTrue(msg, testResult);
print("Starting testing Threads.");
Thread[] testers = new Thread[numTestingThreads];
for (idx = 0; idx < numTestingThreads; idx++) {
String id = "" + idx;
PrincipalTester pt = new PrincipalTester(key, type, 10, id, testPermission);
testers[idx] = new Thread(pt);
testers[idx].start();
}
print("Will now sleep for " + pauseBeforeUpdateMillis + " ms to let testing threads run.");
try {
Thread.sleep(pauseBeforeUpdateMillis);
} catch (Exception ex) {
}
/*
* Remove a permission and test a principal. After a pause, the testing threads
* will wake up and perform the 2nd part of their tests to confirm this update.
*/
msg = "Deleting " + testPermission;
print(msg);
IPermission[] perms = new IPermission[1];
perms[0] = testPermission;
getService().removePermissions(perms);
msg = "Testing first principal for " + testPermission + " (should be FALSE -- has been removed.)";
print(msg);
testResult = p1.hasPermission(OWNER, TEST_ACTIVITY, testPermission.getTarget());
assertTrue(msg, !testResult);
print("Will now sleep for " + pauseAfterUpdateMillis + " ms to let testing threads complete.");
try {
Thread.sleep(pauseAfterUpdateMillis);
} catch (Exception ex) {
}
print("***** LEAVING AuthorizationTester.testPermissionPrincipal() *****" + CR);
}
Aggregations