use of org.apache.wiki.auth.GroupPrincipal in project jspwiki by apache.
the class GroupPermissionTest method testImpliesMember.
public final void testImpliesMember() {
GroupPermission p1;
Permission p2;
Subject s;
// <groupmember> implies TestGroup if Subject has GroupPermission("TestGroup")
p1 = new GroupPermission("*:<groupmember>", "view");
p2 = new GroupPermission("*:TestGroup", "view");
s = new Subject();
s.getPrincipals().add(new GroupPrincipal("TestGroup"));
Assert.assertTrue(subjectImplies(s, p1, p2));
// <groupmember> doesn't imply it if Subject has no GroupPermission("TestGroup")
s = new Subject();
s.getPrincipals().add(new WikiPrincipal("TestGroup"));
Assert.assertFalse(subjectImplies(s, p1, p2));
// <groupmember> doesn't imply it if Subject's GP doesn't match
s = new Subject();
s.getPrincipals().add(new GroupPrincipal("FooGroup"));
Assert.assertFalse(subjectImplies(s, p1, p2));
// <groupmember> doesn't imply it if p2 isn't GroupPermission type
p2 = new PagePermission("*:TestGroup", "view");
s = new Subject();
s.getPrincipals().add(new GroupPrincipal("TestGroup"));
Assert.assertFalse(subjectImplies(s, p1, p2));
// <groupmember> implies TestGroup if not called with Subject combiner
p1 = new GroupPermission("*:<groupmember>", "view");
p2 = new GroupPermission("*:TestGroup", "view");
Assert.assertFalse(p1.impliesMember(p2));
}
use of org.apache.wiki.auth.GroupPrincipal in project jspwiki by apache.
the class GroupPermission method impliesMember.
/**
* <p>
* Returns <code>true</code> if this GroupPermission was created with the
* token <code><groupmember></code>
* <em>and</em> the current
* thread’s Subject is a member of the Group indicated by the implied
* GroupPermission. Thus, a GroupPermission with the group
* <code><groupmember></code> implies GroupPermission for group
* "TestGroup" only if the Subject is a member of TestGroup.
* </p>
* <p>
* We make this determination by obtaining the current {@link Thread}’s
* {@link java.security.AccessControlContext} and requesting the
* {@link javax.security.auth.SubjectDomainCombiner}. If the combiner is
* not <code>null</code>, then we know that the access check was
* requested using a {@link javax.security.auth.Subject}; that is, that an
* upstream caller caused a Subject to be associated with the Thread’s
* ProtectionDomain by executing a
* {@link javax.security.auth.Subject#doAs(Subject, java.security.PrivilegedAction)}
* operation.
* </p>
* <p>
* If a SubjectDomainCombiner exists, determining group membership is
* simple: just iterate through the Subject’s Principal set and look for all
* Principals of type {@link org.apache.wiki.auth.GroupPrincipal}. If the
* name of any Principal matches the value of the implied Permission’s
* {@link GroupPermission#getGroup()} value, then the Subject is a member of
* this group -- and therefore this <code>impliesMember</code> call
* returns <code>true</code>.
* </p>
* <p>
* This may sound complicated, but it really isn’t. Consider the following
* examples:
* </p>
* <table border="1"> <thead>
* <tr>
* <th width="25%">This object</th>
* <th width="25%"><code>impliesMember</code> parameter</th>
* <th width="25%">Calling Subject’s Principals
* <th width="25%">Result</th>
* </tr>
* <tr>
* <td><code>GroupPermission ("<groupmember>")</code></td>
* <td><code>GroupPermission ("*:TestGroup")</code></td>
* <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("TestGroup")</code></td>
* <td><code>true</code></td>
* </tr>
* <tr>
* <td><code>GroupPermission ("*:TestGroup")</code></td>
* <td><code>GroupPermission ("*:TestGroup")</code></td>
* <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("TestGroup")</code></td>
* <td><code>false</code> - this object does not contain
* <code><groupmember></code></td>
* </tr>
* <tr>
* <td><code>GroupPermission ("<groupmember>")</code></td>
* <td><code>GroupPermission ("*:TestGroup")</code></td>
* <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("FooGroup")</code></td>
* <td><code>false</code> - Subject does not contain GroupPrincipal
* matching implied Permission’s group (TestGroup)</td>
* </tr>
* <tr>
* <td><code>GroupPermission ("<groupmember>")</code></td>
* <td><code>WikiPermission ("*:createGroups")</code></td>
* <td><code>WikiPrincipal ("Biff"),<br/>GroupPrincipal ("TestGroup")</code></td>
* <td><code>false</code> - implied permission not of type
* GroupPermission</td>
* </tr>
* <tr>
* <td><code>GroupPermission ("<groupmember>")</code></td>
* <td><code>GroupPermission ("*:TestGroup")</code></td>
* <td>-</td>
* <td><code>false</code> - <code>Subject.doAs()</code> not called
* upstream</td>
* </tr>
* </table>
* <p>
* Note that JSPWiki’s access control checks are made inside of
* {@link org.apache.wiki.auth.AuthorizationManager#checkPermission(org.apache.wiki.WikiSession, Permission)},
* which performs a <code>Subject.doAs()</code> call. Thus, this
* Permission functions exactly the way it should during normal
* operations.
* </p>
* @param permission the implied permission
* @return <code>true</code> if the calling Thread’s Subject contains a
* GroupPrincipal matching the implied GroupPermission’s group;
* <code>false</code> otherwise
*/
protected boolean impliesMember(Permission permission) {
if (!(permission instanceof GroupPermission)) {
return false;
}
GroupPermission gp = (GroupPermission) permission;
if (!MEMBER_TOKEN.equals(m_group)) {
return false;
}
// For the current thread, retrieve the SubjectDomainCombiner
// (if one was used to create current AccessControlContext )
AccessControlContext acc = AccessController.getContext();
DomainCombiner dc = acc.getDomainCombiner();
if (dc != null && dc instanceof SubjectDomainCombiner) {
// <member> implies permission if subject possesses
// GroupPrincipal with same name as target
Subject subject = ((SubjectDomainCombiner) dc).getSubject();
Set<GroupPrincipal> principals = subject.getPrincipals(GroupPrincipal.class);
for (Principal principal : principals) {
if (principal.getName().equals(gp.m_group)) {
return true;
}
}
}
return false;
}
use of org.apache.wiki.auth.GroupPrincipal in project jspwiki by apache.
the class CommandResolver method findCommand.
/**
* <p>
* Attempts to locate a Command for a supplied wiki context and HTTP
* request, incorporating the correct WikiPage into the command if reqiured.
* This method will first determine what page the user requested by
* delegating to {@link #extractPageFromParameter(String, HttpServletRequest)}. If
* this page equates to a special page, we return the Command
* corresponding to that page. Otherwise, this method simply returns the
* Command for the supplied request context.
* </p>
* <p>
* The reason this method attempts to resolve against special pages is
* because some of them resolve to contexts that may be different from the
* one supplied. For example, a VIEW request context for the special page
* "UserPreferences" should return a PREFS context instead.
* </p>
* <p>
* When the caller supplies a request context and HTTP request that
* specifies an actual wiki page (rather than a special page), this method
* will return a "targeted" Command that includes the resolved WikiPage
* as the target. (See {@link #resolvePage(HttpServletRequest, String)}
* for the resolution algorithm). Specifically, the Command will
* return a non-<code>null</code> value for its {@link AbstractCommand#getTarget()} method.
* </p>
* <p><em>Note: if this method determines that the Command is the VIEW PageCommand,
* then the Command returned will always be targeted to the front page.</em></p>
* @param request the HTTP request; if <code>null</code>, delegates
* to {@link #findCommand(String)}
* @param defaultContext the request context to use by default
* @return the resolved wiki command
*/
public Command findCommand(HttpServletRequest request, String defaultContext) {
// Corner case if request is null
if (request == null) {
return findCommand(defaultContext);
}
Command command = null;
// Determine the name of the page (which may be null)
String pageName = extractPageFromParameter(defaultContext, request);
// Can we find a special-page command matching the extracted page?
if (pageName != null) {
command = m_specialPages.get(pageName);
}
// and compare to our list of special pages
if (command == null) {
command = extractCommandFromPath(request);
// Otherwise: use the default context
if (command == null) {
command = CONTEXTS.get(defaultContext);
if (command == null) {
throw new IllegalArgumentException("Wiki context " + defaultContext + " is illegal.");
}
}
}
// For PageCommand.VIEW, default to front page if a page wasn't supplied
if (PageCommand.VIEW.equals(command) && pageName == null) {
pageName = m_engine.getFrontPage();
}
// If we were passed a page parameter, try to resolve it
if (command instanceof PageCommand && pageName != null) {
// If there's a matching WikiPage, "wrap" the command
WikiPage page = resolvePage(request, pageName);
if (page != null) {
return command.targetedCommand(page);
}
}
// If "create group" command, target this wiki
String wiki = m_engine.getApplicationName();
if (WikiCommand.CREATE_GROUP.equals(command)) {
return WikiCommand.CREATE_GROUP.targetedCommand(wiki);
}
// If group command, see if we were passed a group name
if (command instanceof GroupCommand) {
String groupName = request.getParameter("group");
groupName = TextUtil.replaceEntities(groupName);
if (groupName != null && groupName.length() > 0) {
GroupPrincipal group = new GroupPrincipal(groupName);
return command.targetedCommand(group);
}
}
// No page provided; return an "ordinary" command
return command;
}
Aggregations