Search in sources :

Example 11 with GroupPrincipal

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));
}
Also used : WikiPrincipal(org.apache.wiki.auth.WikiPrincipal) GroupPrincipal(org.apache.wiki.auth.GroupPrincipal) Permission(java.security.Permission) Subject(javax.security.auth.Subject)

Example 12 with GroupPrincipal

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>&lt;groupmember&gt;</code>
 * <em>and</em> the current
 * thread&#8217;s Subject is a member of the Group indicated by the implied
 * GroupPermission. Thus, a GroupPermission with the group
 * <code>&lt;groupmember&gt;</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}&#8217;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&#8217;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&#8217;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&#8217;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&#8217;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&#8217;s Principals
 * <th width="25%">Result</th>
 * </tr>
 * <tr>
 * <td><code>GroupPermission ("&lt;groupmember&gt;")</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>&lt;groupmember&gt;</code></td>
 * </tr>
 * <tr>
 * <td><code>GroupPermission ("&lt;groupmember&gt;")</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&#8217;s group (TestGroup)</td>
 * </tr>
 * <tr>
 * <td><code>GroupPermission ("&lt;groupmember&gt;")</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 ("&lt;groupmember&gt;")</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&#8217;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&#8217;s Subject contains a
 *         GroupPrincipal matching the implied GroupPermission&#8217;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;
}
Also used : DomainCombiner(java.security.DomainCombiner) SubjectDomainCombiner(javax.security.auth.SubjectDomainCombiner) AccessControlContext(java.security.AccessControlContext) GroupPrincipal(org.apache.wiki.auth.GroupPrincipal) SubjectDomainCombiner(javax.security.auth.SubjectDomainCombiner) Subject(javax.security.auth.Subject) Principal(java.security.Principal) GroupPrincipal(org.apache.wiki.auth.GroupPrincipal)

Example 13 with GroupPrincipal

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;
}
Also used : GroupPrincipal(org.apache.wiki.auth.GroupPrincipal) WikiPage(org.apache.wiki.WikiPage)

Aggregations

GroupPrincipal (org.apache.wiki.auth.GroupPrincipal)13 WikiPrincipal (org.apache.wiki.auth.WikiPrincipal)4 Test (org.junit.Test)4 Principal (java.security.Principal)3 WikiPage (org.apache.wiki.WikiPage)3 Permission (java.security.Permission)2 Subject (javax.security.auth.Subject)2 GroupPermission (org.apache.wiki.auth.permissions.GroupPermission)2 Before (org.junit.Before)2 AccessControlContext (java.security.AccessControlContext)1 DomainCombiner (java.security.DomainCombiner)1 ArrayList (java.util.ArrayList)1 Properties (java.util.Properties)1 ResourceBundle (java.util.ResourceBundle)1 SubjectDomainCombiner (javax.security.auth.SubjectDomainCombiner)1 MockHttpServletRequest (net.sourceforge.stripes.mock.MockHttpServletRequest)1 TestEngine (org.apache.wiki.TestEngine)1 WikiSession (org.apache.wiki.WikiSession)1 WikiException (org.apache.wiki.api.exceptions.WikiException)1 AuthorizationManager (org.apache.wiki.auth.AuthorizationManager)1