Search in sources :

Example 1 with UnresolvedPrincipal

use of org.apache.wiki.auth.acl.UnresolvedPrincipal in project jspwiki by apache.

the class WorkflowManager method getApprover.

/**
 * Looks up and resolves the actor who approves a Decision for a particular
 * Workflow, based on the Workflow's message key. If not found, or if
 * Principal is Unresolved, throws WikiException. This particular
 * implementation always returns the GroupPrincipal <code>Admin</code>
 *
 * @param messageKey the Decision's message key
 * @return the actor who approves Decisions
 * @throws WikiException if the message key was not found, or the
 * Principal value corresponding to the key could not be resolved
 */
public Principal getApprover(String messageKey) throws WikiException {
    Principal approver = m_approvers.get(messageKey);
    if (approver == null) {
        throw new WikiException("Workflow '" + messageKey + "' does not require approval.");
    }
    // Try to resolve UnresolvedPrincipals
    if (approver instanceof UnresolvedPrincipal) {
        String name = approver.getName();
        approver = m_engine.getAuthorizationManager().resolvePrincipal(name);
        // cache
        if (approver instanceof UnresolvedPrincipal) {
            throw new WikiException("Workflow approver '" + name + "' cannot not be resolved.");
        }
        m_approvers.put(messageKey, approver);
    }
    return approver;
}
Also used : WikiException(org.apache.wiki.api.exceptions.WikiException) Principal(java.security.Principal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal)

Example 2 with UnresolvedPrincipal

use of org.apache.wiki.auth.acl.UnresolvedPrincipal in project jspwiki by apache.

the class AuthorizationManager method checkPermission.

/**
 * Returns <code>true</code> or <code>false</code>, depending on
 * whether a Permission is allowed for the Subject associated with
 * a supplied WikiSession. The access control algorithm works this way:
 * <ol>
 * <li>The {@link org.apache.wiki.auth.acl.Acl} for the page is obtained</li>
 * <li>The Subject associated with the current
 * {@link org.apache.wiki.WikiSession} is obtained</li>
 * <li>If the Subject's Principal set includes the Role Principal that is
 * the administrator group, always allow the Permission</li>
 * <li>For all permissions, check to see if the Permission is allowed according
 * to the default security policy. If it isn't, deny the permission and halt
 * further processing.</li>
 * <li>If there is an Acl, get the list of Principals assigned this
 * Permission in the Acl: these will be role, group or user Principals, or
 * {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}s (see below).
 * Then iterate through the Subject's Principal set and determine whether
 * the user (Subject) possesses any one of these specified Roles or
 * Principals. The matching process delegates to
 * {@link #hasRoleOrPrincipal(WikiSession, Principal)}.
 * </ol>
 * <p>
 * Note that when iterating through the Acl's list of authorized Principals,
 * it is possible that one or more of the Acl's Principal entries are of
 * type <code>UnresolvedPrincipal</code>. This means that the last time
 * the ACL was read, the Principal (user, built-in Role, authorizer Role, or
 * wiki Group) could not be resolved: the Role was not valid, the user
 * wasn't found in the UserDatabase, or the Group wasn't known to (e.g.,
 * cached) in the GroupManager. If an <code>UnresolvedPrincipal</code> is
 * encountered, this method will attempt to resolve it first <em>before</em>
 * checking to see if the Subject possesses this principal, by calling
 * {@link #resolvePrincipal(String)}. If the (re-)resolution does not
 * succeed, the access check for the principal will fail by definition (the
 * Subject should never contain UnresolvedPrincipals).
 * </p>
 * <p>
 * If security not set to JAAS, will return true.
 * </p>
 * @param session the current wiki session
 * @param permission the Permission being checked
 * @see #hasRoleOrPrincipal(WikiSession, Principal)
 * @return the result of the Permission check
 */
public boolean checkPermission(WikiSession session, Permission permission) {
    // 
    if (session == null || permission == null) {
        fireEvent(WikiSecurityEvent.ACCESS_DENIED, null, permission);
        return false;
    }
    Principal user = session.getLoginPrincipal();
    // Always allow the action if user has AllPermission
    Permission allPermission = new AllPermission(m_engine.getApplicationName());
    boolean hasAllPermission = checkStaticPermission(session, allPermission);
    if (hasAllPermission) {
        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
        return true;
    }
    // If the user doesn't have *at least* the permission
    // granted by policy, return false.
    boolean hasPolicyPermission = checkStaticPermission(session, permission);
    if (!hasPolicyPermission) {
        fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
        return false;
    }
    // If this isn't a PagePermission, it's allowed
    if (!(permission instanceof PagePermission)) {
        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
        return true;
    }
    // 
    // If the page or ACL is null, it's allowed.
    // 
    String pageName = ((PagePermission) permission).getPage();
    WikiPage page = m_engine.getPage(pageName);
    Acl acl = (page == null) ? null : m_engine.getAclManager().getPermissions(page);
    if (page == null || acl == null || acl.isEmpty()) {
        fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
        return true;
    }
    // 
    // Next, iterate through the Principal objects assigned
    // this permission. If the context's subject possesses
    // any of these, the action is allowed.
    Principal[] aclPrincipals = acl.findPrincipals(permission);
    log.debug("Checking ACL entries...");
    log.debug("Acl for this page is: " + acl);
    log.debug("Checking for principal: " + Arrays.toString(aclPrincipals));
    log.debug("Permission: " + permission);
    for (Principal aclPrincipal : aclPrincipals) {
        // try to resolve it here & correct the Acl
        if (aclPrincipal instanceof UnresolvedPrincipal) {
            AclEntry aclEntry = acl.getEntry(aclPrincipal);
            aclPrincipal = resolvePrincipal(aclPrincipal.getName());
            if (aclEntry != null && !(aclPrincipal instanceof UnresolvedPrincipal)) {
                aclEntry.setPrincipal(aclPrincipal);
            }
        }
        if (hasRoleOrPrincipal(session, aclPrincipal)) {
            fireEvent(WikiSecurityEvent.ACCESS_ALLOWED, user, permission);
            return true;
        }
    }
    fireEvent(WikiSecurityEvent.ACCESS_DENIED, user, permission);
    return false;
}
Also used : WikiPage(org.apache.wiki.WikiPage) PagePermission(org.apache.wiki.auth.permissions.PagePermission) AllPermission(org.apache.wiki.auth.permissions.AllPermission) Permission(java.security.Permission) AclEntry(org.apache.wiki.auth.acl.AclEntry) AllPermission(org.apache.wiki.auth.permissions.AllPermission) Acl(org.apache.wiki.auth.acl.Acl) Principal(java.security.Principal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal) PagePermission(org.apache.wiki.auth.permissions.PagePermission) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal)

Example 3 with UnresolvedPrincipal

use of org.apache.wiki.auth.acl.UnresolvedPrincipal in project jspwiki by apache.

the class AuthorizationManager method resolvePrincipal.

/**
 * <p>Given a supplied string representing a Principal's name from an Acl, this
 * method resolves the correct type of Principal (role, group, or user).
 * This method is guaranteed to always return a Principal.
 * The algorithm is straightforward:</p>
 * <ol>
 * <li>If the name matches one of the built-in {@link org.apache.wiki.auth.authorize.Role} names,
 * return that built-in Role</li>
 * <li>If the name matches one supplied by the current
 * {@link org.apache.wiki.auth.Authorizer}, return that Role</li>
 * <li>If the name matches a group managed by the
 * current {@link org.apache.wiki.auth.authorize.GroupManager}, return that Group</li>
 * <li>Otherwise, assume that the name represents a user
 * principal. Using the current {@link org.apache.wiki.auth.user.UserDatabase}, find the
 * first user who matches the supplied name by calling
 * {@link org.apache.wiki.auth.user.UserDatabase#find(String)}.</li>
 * <li>Finally, if a user cannot be found, manufacture
 * and return a generic {@link org.apache.wiki.auth.acl.UnresolvedPrincipal}</li>
 * </ol>
 * @param name the name of the Principal to resolve
 * @return the fully-resolved Principal
 */
public Principal resolvePrincipal(String name) {
    // Check built-in Roles first
    Role role = new Role(name);
    if (Role.isBuiltInRole(role)) {
        return role;
    }
    // Check Authorizer Roles
    Principal principal = m_authorizer.findRole(name);
    if (principal != null) {
        return principal;
    }
    // Check Groups
    principal = m_engine.getGroupManager().findRole(name);
    if (principal != null) {
        return principal;
    }
    // Ok, no luck---this must be a user principal
    Principal[] principals = null;
    UserProfile profile = null;
    UserDatabase db = m_engine.getUserManager().getUserDatabase();
    try {
        profile = db.find(name);
        principals = db.getPrincipals(profile.getLoginName());
        for (int i = 0; i < principals.length; i++) {
            principal = principals[i];
            if (principal.getName().equals(name)) {
                return principal;
            }
        }
    } catch (NoSuchPrincipalException e) {
    // We couldn't find the user...
    }
    // Ok, no luck---mark this as unresolved and move on
    return new UnresolvedPrincipal(name);
}
Also used : Role(org.apache.wiki.auth.authorize.Role) UserProfile(org.apache.wiki.auth.user.UserProfile) UserDatabase(org.apache.wiki.auth.user.UserDatabase) Principal(java.security.Principal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal)

Example 4 with UnresolvedPrincipal

use of org.apache.wiki.auth.acl.UnresolvedPrincipal in project jspwiki by apache.

the class AuthorizationManagerTest method testResolveUsers.

@Test
public void testResolveUsers() throws WikiException {
    // We should be able to resolve a user by login, user, or wiki name
    UserProfile profile = m_engine.getUserManager().getUserDatabase().newProfile();
    profile.setEmail("authmanagertest@tester.net");
    profile.setFullname("AuthorizationManagerTest User");
    profile.setLoginName("authmanagertest");
    try {
        m_engine.getUserManager().getUserDatabase().save(profile);
    } catch (WikiSecurityException e) {
        Assert.fail("Failed save: " + e.getLocalizedMessage());
    }
    Assert.assertEquals(new WikiPrincipal("authmanagertest", WikiPrincipal.LOGIN_NAME), m_auth.resolvePrincipal("authmanagertest"));
    Assert.assertEquals(new WikiPrincipal("AuthorizationManagerTest User", WikiPrincipal.FULL_NAME), m_auth.resolvePrincipal("AuthorizationManagerTest User"));
    Assert.assertEquals(new WikiPrincipal("AuthorizationManagerTestUser", WikiPrincipal.WIKI_NAME), m_auth.resolvePrincipal("AuthorizationManagerTestUser"));
    try {
        m_engine.getUserManager().getUserDatabase().deleteByLoginName("authmanagertest");
    } catch (WikiSecurityException e) {
        Assert.fail("Failed delete: " + e.getLocalizedMessage());
    }
    // A wiki group should resolve to itself
    Group group1 = m_groupMgr.parseGroup("SampleGroup", "", true);
    m_groupMgr.setGroup(m_session, group1);
    Assert.assertEquals(group1.getPrincipal(), m_auth.resolvePrincipal("SampleGroup"));
    m_groupMgr.removeGroup("SampleGroup");
    // A built-in role should resolve to itself
    Assert.assertEquals(Role.AUTHENTICATED, m_auth.resolvePrincipal("Authenticated"));
    // We shouldn't be able to spoof a built-in role
    Assert.assertNotSame(new WikiPrincipal("Authenticated"), m_auth.resolvePrincipal("Authenticated"));
    // An unknown user should resolve to a generic UnresolvedPrincipal
    Principal principal = new UnresolvedPrincipal("Bart Simpson");
    Assert.assertEquals(principal, m_auth.resolvePrincipal("Bart Simpson"));
}
Also used : Group(org.apache.wiki.auth.authorize.Group) UserProfile(org.apache.wiki.auth.user.UserProfile) Principal(java.security.Principal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal) UnresolvedPrincipal(org.apache.wiki.auth.acl.UnresolvedPrincipal) WikiSessionTest(org.apache.wiki.WikiSessionTest) Test(org.junit.Test)

Aggregations

Principal (java.security.Principal)4 UnresolvedPrincipal (org.apache.wiki.auth.acl.UnresolvedPrincipal)4 UserProfile (org.apache.wiki.auth.user.UserProfile)2 Permission (java.security.Permission)1 WikiPage (org.apache.wiki.WikiPage)1 WikiSessionTest (org.apache.wiki.WikiSessionTest)1 WikiException (org.apache.wiki.api.exceptions.WikiException)1 Acl (org.apache.wiki.auth.acl.Acl)1 AclEntry (org.apache.wiki.auth.acl.AclEntry)1 Group (org.apache.wiki.auth.authorize.Group)1 Role (org.apache.wiki.auth.authorize.Role)1 AllPermission (org.apache.wiki.auth.permissions.AllPermission)1 PagePermission (org.apache.wiki.auth.permissions.PagePermission)1 UserDatabase (org.apache.wiki.auth.user.UserDatabase)1 Test (org.junit.Test)1