You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jspwiki.apache.org by ju...@apache.org on 2020/02/24 16:52:56 UTC
[jspwiki] 14/38: JSPWIKI-120: rename + extract interface from
AuthorizationManager
This is an automated email from the ASF dual-hosted git repository.
juanpablo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/jspwiki.git
commit f1b62ab54488614ac209b26ffa727504df5cf81d
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 18:43:16 2020 +0100
JSPWIKI-120: rename + extract interface from AuthorizationManager
---
.../org/apache/wiki/auth/AuthorizationManager.java | 654 +++------------------
.../main/java/org/apache/wiki/auth/Authorizer.java | 10 +-
.../wiki/auth/DefaultAuthorizationManager.java | 425 +++++++++++++
.../apache/wiki/auth/authorize/GroupDatabase.java | 4 +-
.../apache/wiki/auth/authorize/GroupManager.java | 141 +++--
.../wiki/auth/authorize/JDBCGroupDatabase.java | 118 ++--
.../apache/wiki/auth/authorize/WebAuthorizer.java | 20 +-
.../auth/authorize/WebContainerAuthorizer.java | 92 ++-
.../wiki/auth/authorize/XMLGroupDatabase.java | 35 +-
.../src/main/resources/ini/classmappings.xml | 2 +-
.../wiki/auth/AuthenticationManagerTest.java | 103 ++--
.../java/org/apache/wiki/auth/TestAuthorizer.java | 42 +-
12 files changed, 774 insertions(+), 872 deletions(-)
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
index 265cef2..a0ab560 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/AuthorizationManager.java
@@ -18,382 +18,145 @@
*/
package org.apache.wiki.auth;
-
-import org.apache.log4j.Logger;
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiPage;
import org.apache.wiki.WikiSession;
-import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.WikiException;
-import org.apache.wiki.auth.acl.Acl;
-import org.apache.wiki.auth.acl.AclEntry;
-import org.apache.wiki.auth.acl.UnresolvedPrincipal;
import org.apache.wiki.auth.authorize.Role;
-import org.apache.wiki.auth.permissions.AllPermission;
-import org.apache.wiki.auth.permissions.PagePermission;
-import org.apache.wiki.auth.user.UserDatabase;
-import org.apache.wiki.auth.user.UserProfile;
import org.apache.wiki.event.WikiEventListener;
import org.apache.wiki.event.WikiEventManager;
import org.apache.wiki.event.WikiSecurityEvent;
-import org.apache.wiki.i18n.InternationalizationManager;
-import org.apache.wiki.preferences.Preferences;
-import org.apache.wiki.util.ClassUtil;
-import org.freshcookies.security.policy.LocalPolicy;
import javax.servlet.http.HttpServletResponse;
-import java.io.File;
import java.io.IOException;
-import java.net.URL;
-import java.security.AccessControlException;
-import java.security.AccessController;
-import java.security.CodeSource;
import java.security.Permission;
import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.ProtectionDomain;
-import java.security.cert.Certificate;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Map;
import java.util.Properties;
-import java.util.ResourceBundle;
-import java.util.WeakHashMap;
+
/**
- * <p>Manages all access control and authorization; determines what authenticated
- * users are allowed to do.</p>
- * <p>Privileges in JSPWiki are expressed as Java-standard {@link java.security.Permission}
- * classes. There are two types of permissions:</p>
+ * <p>Manages all access control and authorization; determines what authenticated users are allowed to do.</p>
+ * <p>Privileges in JSPWiki are expressed as Java-standard {@link java.security.Permission} classes. There are two types of permissions:</p>
* <ul>
- * <li>{@link org.apache.wiki.auth.permissions.WikiPermission} - privileges that apply
- * to an entire wiki instance: <em>e.g.,</em> editing user profiles, creating pages, creating groups</li>
- * <li>{@link org.apache.wiki.auth.permissions.PagePermission} - privileges that apply
- * to a single wiki page or range of pages: <em>e.g.,</em> reading, editing, renaming
+ * <li>{@link org.apache.wiki.auth.permissions.WikiPermission} - privileges that apply to an entire wiki instance: <em>e.g.,</em>
+ * editing user profiles, creating pages, creating groups</li>
+ * <li>{@link org.apache.wiki.auth.permissions.PagePermission} - privileges that apply to a single wiki page or range of pages:
+ * <em>e.g.,</em> reading, editing, renaming
* </ul>
- * <p>Calling classes determine whether they are entitled to perform a particular action
- * by constructing the appropriate permission first, then passing it and the current
- * {@link org.apache.wiki.WikiSession} to the
- * {@link #checkPermission(WikiSession, Permission)} method. If the session's
- * Subject possesses the permission, the action is allowed.</p>
- * <p>For WikiPermissions, the decision criteria is relatively simple: the caller either
- * possesses the permission, as granted by the wiki security policy -- or not.</p>
- * <p>For PagePermissions, the logic is exactly the same if the page being checked
- * does not have an access control list. However, if the page does have an ACL, the
- * authorization decision is made based the <em>union</em> of the permissions
- * granted in the ACL and in the security policy. In other words, the user must
- * be named in the ACL (or belong to a group or role that is named in the ACL)
- * <em>and</em> be granted (at least) the same permission in the security policy. We
- * do this to prevent a user from gaining more permissions than they already
- * have, based on the security policy.</p>
- * <p>See the {@link #checkPermission(WikiSession, Permission)} and
- * {@link #hasRoleOrPrincipal(WikiSession, Principal)} methods for more information
- * on the authorization logic.</p>
+ * <p>Calling classes determine whether they are entitled to perform a particular action by constructing the appropriate permission first,
+ * then passing it and the current {@link org.apache.wiki.WikiSession} to the {@link #checkPermission(WikiSession, Permission)} method. If
+ * the session's Subject possesses the permission, the action is allowed.</p>
+ * <p>For WikiPermissions, the decision criteria is relatively simple: the caller either possesses the permission, as granted by the wiki
+ * security policy -- or not.</p>
+ * <p>For PagePermissions, the logic is exactly the same if the page being checked does not have an access control list. However, if the
+ * page does have an ACL, the authorization decision is made based the <em>union</em> of the permissions granted in the ACL and in the
+ * security policy. In other words, the user must be named in the ACL (or belong to a group or role that is named in the ACL) <em>and</em>
+ * be granted (at least) the same permission in the security policy. We do this to prevent a user from gaining more permissions than they
+ * already have, based on the security policy.</p>
+ * <p>See the implementation on {@link #checkPermission(WikiSession, Permission)} method for more information on the authorization logic.</p>
+ *
* @since 2.3
* @see AuthenticationManager
*/
-public class AuthorizationManager {
+public interface AuthorizationManager {
- private static final Logger log = Logger.getLogger( AuthorizationManager.class );
- /**
- * The default external Authorizer is the {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer}
- */
- public static final String DEFAULT_AUTHORIZER = "org.apache.wiki.auth.authorize.WebContainerAuthorizer";
+ /** The default external Authorizer is the {@link org.apache.wiki.auth.authorize.WebContainerAuthorizer} */
+ String DEFAULT_AUTHORIZER = "org.apache.wiki.auth.authorize.WebContainerAuthorizer";
/** Property that supplies the security policy file name, in WEB-INF. */
- protected static final String POLICY = "jspwiki.policy.file";
+ String POLICY = "jspwiki.policy.file";
/** Name of the default security policy file, in WEB-INF. */
- protected static final String DEFAULT_POLICY = "jspwiki.policy";
-
- /**
- * The property name in jspwiki.properties for specifying the external {@link Authorizer}.
- */
- public static final String PROP_AUTHORIZER = "jspwiki.authorizer";
+ String DEFAULT_POLICY = "jspwiki.policy";
- private Authorizer m_authorizer = null;
-
- /** Cache for storing ProtectionDomains used to evaluate the local policy. */
- private Map<Principal, ProtectionDomain> m_cachedPds = new WeakHashMap<>();
-
- private WikiEngine m_engine = null;
-
- private LocalPolicy m_localPolicy = null;
+ /** The property name in jspwiki.properties for specifying the external {@link Authorizer}. */
+ String PROP_AUTHORIZER = "jspwiki.authorizer";
/**
- * Constructs a new AuthorizationManager instance.
- */
- public AuthorizationManager()
- {
- }
-
- /**
- * Returns <code>true</code> or <code>false</code>, depending on
- * whether a Permission is allowed for the Subject associated with
+ * 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)}.
+ * <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.</li>
* </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).
+ * 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( final WikiSession session, final Permission permission )
- {
- //
- // A slight sanity check.
- //
- if ( session == null || permission == null )
- {
- fireEvent( WikiSecurityEvent.ACCESS_DENIED, null, permission );
- return false;
- }
-
- final Principal user = session.getLoginPrincipal();
-
- // Always allow the action if user has AllPermission
- final Permission allPermission = new AllPermission( m_engine.getApplicationName() );
- final 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.
- final 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.
- //
- final String pageName = ((PagePermission)permission).getPage();
- final WikiPage page = m_engine.getPageManager().getPage( pageName );
- final 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.
-
- final 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 )
- {
- // If the ACL principal we're looking at is unresolved,
- // try to resolve it here & correct the Acl
- if ( aclPrincipal instanceof UnresolvedPrincipal )
- {
- final 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;
- }
+ boolean checkPermission( WikiSession session, Permission permission );
/**
- * <p>Determines if the Subject associated with a
- * supplied WikiSession contains a desired Role or GroupPrincipal.
- * The algorithm simply checks to see if the Subject possesses
- * the Role or GroupPrincipal it in its Principal set. Note that
- * any user (anonymous, asserted, authenticated) can possess
- * a built-in role. But a user <em>must</em> be authenticated to
- * possess a role other than one of the built-in ones.
- * We do this to prevent privilege escalation.</p>
+ * <p>Determines if the Subject associated with a supplied WikiSession contains a desired Role or GroupPrincipal. The algorithm
+ * simply checks to see if the Subject possesses the Role or GroupPrincipal it in its Principal set. Note that any user (anonymous,
+ * asserted, authenticated) can possess a built-in role. But a user <em>must</em> be authenticated to possess a role other than one
+ * of the built-in ones. We do this to prevent privilege escalation.</p>
* <p>For all other cases, this method returns <code>false</code>.</p>
- * <p>Note that this method does <em>not</em> consult the external
- * Authorizer or GroupManager; it relies on the Principals that
- * have been injected into the user's Subject at login time, or
- * after group creation/modification/deletion.</p>
- * @param session the current wiki session, which must be non-null. If null,
- * the result of this method always returns <code>false</code>
- * @param principal the Principal (role or group principal) to look
- * for, which must be non-<code>null</code>. If <code>null</code>,
- * the result of this method always returns <code>false</code>
- * @return <code>true</code> if the Subject supplied with the WikiContext
- * posesses the Role or GroupPrincipal, <code>false</code> otherwise
+ * <p>Note that this method does <em>not</em> consult the external Authorizer or GroupManager; it relies on the Principals that
+ * have been injected into the user's Subject at login time, or after group creation/modification/deletion.</p>
+ *
+ * @param session the current wiki session, which must be non-null. If null, the result of this method always returns <code>false</code>
+ * @param principal the Principal (role or group principal) to look for, which must be non-<code>null</code>. If <code>null</code>,
+ * the result of this method always returns <code>false</code>
+ * @return <code>true</code> if the Subject supplied with the WikiContext posesses the Role or GroupPrincipal, <code>false</code> otherwise
*/
- public boolean isUserInRole( final WikiSession session, final Principal principal )
- {
- if ( session == null || principal == null ||
- AuthenticationManager.isUserPrincipal( principal ) )
- {
+ default boolean isUserInRole( final WikiSession session, final Principal principal ) {
+ if ( session == null || principal == null || AuthenticationManager.isUserPrincipal( principal ) ) {
return false;
}
// Any type of user can possess a built-in role
- if ( principal instanceof Role && Role.isBuiltInRole( (Role)principal ) )
- {
+ if ( principal instanceof Role && Role.isBuiltInRole( (Role)principal ) ) {
return session.hasPrincipal( principal );
}
// Only authenticated users can possess groups or custom roles
- if ( session.isAuthenticated() && AuthenticationManager.isRolePrincipal( principal ) )
- {
+ if ( session.isAuthenticated() && AuthenticationManager.isRolePrincipal( principal ) ) {
return session.hasPrincipal( principal );
}
return false;
}
/**
- * Returns the current external {@link Authorizer} in use. This method
- * is guaranteed to return a properly-initialized Authorizer, unless
- * it could not be initialized. In that case, this method throws
- * a {@link org.apache.wiki.auth.WikiSecurityException}.
- * @throws org.apache.wiki.auth.WikiSecurityException if the Authorizer could
- * not be initialized
+ * Returns the current external {@link Authorizer} in use. This method is guaranteed to return a properly-initialized Authorizer, unless
+ * it could not be initialized. In that case, this method throws a {@link org.apache.wiki.auth.WikiSecurityException}.
+ *
+ * @throws org.apache.wiki.auth.WikiSecurityException if the Authorizer could not be initialized
* @return the current Authorizer
*/
- public Authorizer getAuthorizer() throws WikiSecurityException
- {
- if ( m_authorizer != null )
- {
- return m_authorizer;
- }
- throw new WikiSecurityException( "Authorizer did not initialize properly. Check the logs." );
- }
-
- /**
- * <p>Determines if the Subject associated with a supplied WikiSession contains
- * a desired user Principal or built-in Role principal, OR is a member a
- * Group or external Role. The rules are as follows:</p>
- * <ol>
- * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to
- * {@link #isUserInRole(WikiSession, Principal)} and
- * return the result.</li>
- * <li>Otherwise, we're looking for a user Principal,
- * so iterate through the Principal set and see if
- * any share the same name as the one we are looking for.</li>
- * </ol>
- * <p><em>Note: if the Principal parameter is a user principal, the session
- * must be authenticated in order for the user to "possess it". Anonymous
- * or asserted sessions will never posseess a named user principal.</em></p>
- * @param session the current wiki session, which must be non-null. If null,
- * the result of this method always returns <code>false</code>
- * @param principal the Principal (role, group, or user principal) to look
- * for, which must be non-null. If null, the result of this
- * method always returns <code>false</code>
- * @return <code>true</code> if the Subject supplied with the WikiContext
- * posesses the Role, GroupPrincipal or desired
- * user Principal, <code>false</code> otherwise
- */
- protected boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal )
- {
- // If either parameter is null, always deny
- if( session == null || principal == null )
- {
- return false;
- }
-
- // If principal is role, delegate to isUserInRole
- if( AuthenticationManager.isRolePrincipal( principal ) )
- {
- return isUserInRole( session, principal );
- }
-
- // We must be looking for a user principal, assuming that the user
- // has been properly logged in.
- // So just look for a name match.
- if( session.isAuthenticated() && AuthenticationManager.isUserPrincipal( principal ) )
- {
- final String principalName = principal.getName();
- final Principal[] userPrincipals = session.getPrincipals();
- for( final Principal userPrincipal : userPrincipals )
- {
- if( userPrincipal.getName().equals( principalName ) )
- {
- return true;
- }
- }
- }
- return false;
- }
+ Authorizer getAuthorizer() throws WikiSecurityException;
/**
- * Checks whether the current user has access to the wiki context,
- * by obtaining the required Permission ({@link WikiContext#requiredPermission()})
- * and delegating the access check to {@link #checkPermission(WikiSession, Permission)}.
- * If the user is allowed, this method returns <code>true</code>;
- * <code>false</code> otherwise. If access is allowed,
- * the wiki context will be added to the request as an attribute
- * with the key name {@link org.apache.wiki.WikiContext#ATTR_CONTEXT}.
- * Note that this method will automatically redirect the user to
- * a login or error page, as appropriate, if access fails. This is
- * NOT guaranteed to be default behavior in the future.
+ * Checks whether the current user has access to the wiki context, by obtaining the required Permission ({@link WikiContext#requiredPermission()})
+ * and delegating the access check to {@link #checkPermission(WikiSession, Permission)}. If the user is allowed, this method returns
+ * <code>true</code>; <code>false</code> otherwise. If access is allowed, the wiki context will be added to the request as an attribute
+ * with the key name {@link org.apache.wiki.WikiContext#ATTR_CONTEXT}. Note that this method will automatically redirect the user to
+ * a login or error page, as appropriate, if access fails. This is NOT guaranteed to be default behavior in the future.
*
* @param context wiki context to check if it is accesible
* @param response the http response
* @return the result of the access check
* @throws IOException In case something goes wrong
*/
- public boolean hasAccess( final WikiContext context, final HttpServletResponse response ) throws IOException
- {
+ default boolean hasAccess( final WikiContext context, final HttpServletResponse response ) throws IOException {
return hasAccess( context, response, true );
}
@@ -411,294 +174,63 @@ public class AuthorizationManager {
* @return the result of the access check
* @throws IOException If something goes wrong
*/
- public boolean hasAccess( final WikiContext context, final HttpServletResponse response, final boolean redirect ) throws IOException {
- final boolean allowed = checkPermission( context.getWikiSession(), context.requiredPermission() );
- final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
-
- // Stash the wiki context
- if ( context.getHttpRequest() != null && context.getHttpRequest().getAttribute( WikiContext.ATTR_CONTEXT ) == null ) {
- context.getHttpRequest().setAttribute( WikiContext.ATTR_CONTEXT, context );
- }
-
- // If access not allowed, redirect
- if( !allowed && redirect ) {
- final Principal currentUser = context.getWikiSession().getUserPrincipal();
- final String pageurl = context.getPage().getName();
- if( context.getWikiSession().isAuthenticated() ) {
- log.info("User "+currentUser.getName()+" has no access - forbidden (permission=" + context.requiredPermission() + ")" );
- context.getWikiSession().addMessage( MessageFormat.format( rb.getString( "security.error.noaccess.logged" ),
- context.getName()) );
- } else {
- log.info("User "+currentUser.getName()+" has no access - redirecting (permission=" + context.requiredPermission() + ")");
- context.getWikiSession().addMessage( MessageFormat.format( rb.getString("security.error.noaccess"), context.getName() ) );
- }
- response.sendRedirect( m_engine.getURL(WikiContext.LOGIN, pageurl, null ) );
- }
- return allowed;
- }
+ boolean hasAccess( final WikiContext context, final HttpServletResponse response, final boolean redirect ) throws IOException;
/**
- * Initializes AuthorizationManager with an engine and set of properties.
- * Expects to find property 'jspwiki.authorizer' with a valid Authorizer
- * implementation name to take care of role lookup operations.
+ * Initializes AuthorizationManager with an engine and set of properties. Expects to find property 'jspwiki.authorizer' with a valid
+ * Authorizer implementation name to take care of role lookup operations.
+ *
* @param engine the wiki engine
* @param properties the set of properties used to initialize the wiki engine
* @throws WikiException if the AuthorizationManager cannot be initialized
*/
- public void initialize( final WikiEngine engine, final Properties properties ) throws WikiException {
- m_engine = engine;
-
- //
- // JAAS authorization continues
- //
- m_authorizer = getAuthorizerImplementation( properties );
- m_authorizer.initialize( engine, properties );
-
- // Initialize local security policy
- try {
- final String policyFileName = properties.getProperty( POLICY, DEFAULT_POLICY );
- final URL policyURL = engine.findConfigFile( policyFileName );
-
- if (policyURL != null) {
- final File policyFile = new File( policyURL.toURI().getPath() );
- log.info("We found security policy URL: " + policyURL + " and transformed it to file " + policyFile.getAbsolutePath());
- m_localPolicy = new LocalPolicy( policyFile, engine.getContentEncoding().displayName() );
- m_localPolicy.refresh();
- log.info( "Initialized default security policy: " + policyFile.getAbsolutePath() );
- } else {
- final String sb = "JSPWiki was unable to initialize the default security policy (WEB-INF/jspwiki.policy) file. " +
- "Please ensure that the jspwiki.policy file exists in the default location. " +
- "This file should exist regardless of the existance of a global policy file. " +
- "The global policy file is identified by the java.security.policy variable. ";
- final WikiSecurityException wse = new WikiSecurityException( sb );
- log.fatal( sb, wse );
- throw wse;
- }
- } catch ( final Exception e) {
- log.error("Could not initialize local security policy: " + e.getMessage() );
- throw new WikiException( "Could not initialize local security policy: " + e.getMessage(), e );
- }
- }
-
- /**
- * Attempts to locate and initialize a Authorizer to use with this manager.
- * Throws a WikiException if no entry is found, or if one fails to
- * initialize.
- * @param props jspwiki.properties, containing a
- * 'jspwiki.authorization.provider' class name
- * @return a Authorizer used to get page authorization information
- * @throws WikiException
- */
- private Authorizer getAuthorizerImplementation( final Properties props ) throws WikiException {
- final String authClassName = props.getProperty( PROP_AUTHORIZER, DEFAULT_AUTHORIZER );
- return ( Authorizer )locateImplementation( authClassName );
- }
-
- private Object locateImplementation( final String clazz ) throws WikiException {
- if ( clazz != null ) {
- try {
- final Class< ? > authClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", clazz );
- final Object impl = authClass.newInstance();
- return impl;
- } catch( final ClassNotFoundException e ) {
- log.fatal( "Authorizer " + clazz + " cannot be found", e );
- throw new WikiException( "Authorizer " + clazz + " cannot be found", e );
- } catch( final InstantiationException e ) {
- log.fatal( "Authorizer " + clazz + " cannot be created", e );
- throw new WikiException( "Authorizer " + clazz + " cannot be created", e );
- } catch( final IllegalAccessException e ) {
- log.fatal( "You are not allowed to access this authorizer class", e );
- throw new WikiException( "You are not allowed to access this authorizer class", e );
- }
- }
-
- throw new NoRequiredPropertyException( "Unable to find a " + PROP_AUTHORIZER + " entry in the properties.",
- PROP_AUTHORIZER );
- }
-
- /**
- * Checks to see if the local security policy allows a particular static Permission.
- * Do not use this method for normal permission checks; use
- * {@link #checkPermission(WikiSession, Permission)} instead.
- * @param principals the Principals to check
- * @param permission the Permission
- * @return the result
- */
- protected boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission )
- {
- for ( final Principal principal : principals )
- {
- // Get ProtectionDomain for this Principal from cache, or create new one
- ProtectionDomain pd = m_cachedPds.get( principal );
- if ( pd == null )
- {
- final ClassLoader cl = this.getClass().getClassLoader();
- final CodeSource cs = new CodeSource( null, (Certificate[])null );
- pd = new ProtectionDomain( cs, null, cl, new Principal[]{ principal } );
- m_cachedPds.put( principal, pd );
- }
-
- // Consult the local policy and get the answer
- if ( m_localPolicy.implies( pd, permission ) )
- {
- return true;
- }
- }
- return false;
- }
+ void initialize( final Engine engine, final Properties properties ) throws WikiException;
/**
- * Determines whether a Subject possesses a given "static" Permission as
- * defined in the security policy file. This method uses standard Java 2
- * security calls to do its work. Note that the current access control
- * context's <code>codeBase</code> is effectively <em>this class</em>,
- * not that of the caller. Therefore, this method will work best when what
- * matters in the policy is <em>who</em> makes the permission check, not
- * what the caller's code source is. Internally, this method works by
- * executing <code>Subject.doAsPrivileged</code> with a privileged action
- * that simply calls {@link java.security.AccessController#checkPermission(Permission)}.
- * @see AccessController#checkPermission(java.security.Permission) . A
- * caught exception (or lack thereof) determines whether the privilege
- * is absent (or present).
- * @param session the WikiSession whose permission status is being queried
- * @param permission the Permission the Subject must possess
- * @return <code>true</code> if the Subject possesses the permission,
- * <code>false</code> otherwise
- */
- protected boolean checkStaticPermission( final WikiSession session, final Permission permission )
- {
- final Boolean allowed = (Boolean) WikiSession.doPrivileged( session, new PrivilegedAction<Boolean>()
- {
- @Override public Boolean run()
- {
- try
- {
- // Check the JVM-wide security policy first
- AccessController.checkPermission( permission );
- return Boolean.TRUE;
- }
- catch( final AccessControlException e )
- {
- // Global policy denied the permission
- }
-
- // Try the local policy - check each Role/Group and User Principal
- if ( allowedByLocalPolicy( session.getRoles(), permission ) ||
- allowedByLocalPolicy( session.getPrincipals(), permission ) )
- {
- return Boolean.TRUE;
- }
- return Boolean.FALSE;
- }
- } );
- return allowed.booleanValue();
- }
-
- /**
- * <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>
+ * <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>
+ * <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( final String name )
- {
- // Check built-in Roles first
- final 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;
- final 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( final NoSuchPrincipalException e )
- {
- // We couldn't find the user...
- }
- // Ok, no luck---mark this as unresolved and move on
- return new UnresolvedPrincipal( name );
- }
+ Principal resolvePrincipal( final String name );
// events processing .......................................................
/**
* Registers a WikiEventListener with this instance.
+ *
* @param listener the event listener
*/
- public synchronized void addWikiEventListener( final WikiEventListener listener )
- {
- WikiEventManager.addWikiEventListener( this, listener );
- }
+ void addWikiEventListener( WikiEventListener listener );
/**
* Un-registers a WikiEventListener with this instance.
+ *
* @param listener the event listener
*/
- public synchronized void removeWikiEventListener( final WikiEventListener listener )
- {
- WikiEventManager.removeWikiEventListener( this, listener );
- }
+ void removeWikiEventListener( final WikiEventListener listener );
/**
- * Fires a WikiSecurityEvent of the provided type, user,
- * and permission to all registered listeners.
+ * Fires a WikiSecurityEvent of the provided type, user, and permission to all registered listeners.
*
* @see org.apache.wiki.event.WikiSecurityEvent
* @param type the event type to be fired
* @param user the user associated with the event
* @param permission the permission the subject must possess
*/
- protected void fireEvent( final int type, final Principal user, final Object permission )
- {
- if ( WikiEventManager.isListening(this) )
- {
- WikiEventManager.fireEvent(this,new WikiSecurityEvent(this,type,user,permission));
+ default void fireEvent( final int type, final Principal user, final Object permission ) {
+ if( WikiEventManager.isListening( this ) ) {
+ WikiEventManager.fireEvent( this, new WikiSecurityEvent( this, type, user, permission ) );
}
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
index 36d44c2..13f82c2 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/Authorizer.java
@@ -18,11 +18,12 @@
*/
package org.apache.wiki.auth;
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+
import java.security.Principal;
import java.util.Properties;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.WikiSession;
/**
* Interface for service providers of authorization information. After a user
@@ -43,8 +44,7 @@ import org.apache.wiki.WikiSession;
*
* @since 2.3
*/
-public interface Authorizer
-{
+public interface Authorizer {
/**
* Returns an array of role Principals this Authorizer knows about. This
@@ -74,7 +74,7 @@ public interface Authorizer
* @param props the wiki engine initialization properties
* @throws WikiSecurityException if the Authorizer could not be initialized
*/
- void initialize( WikiEngine engine, Properties props ) throws WikiSecurityException;
+ void initialize( Engine engine, Properties props ) throws WikiSecurityException;
/**
* Determines whether the Subject associated with a WikiSession is in a
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
new file mode 100644
index 0000000..a388a08
--- /dev/null
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultAuthorizationManager.java
@@ -0,0 +1,425 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.wiki.auth;
+
+import org.apache.log4j.Logger;
+import org.apache.wiki.WikiContext;
+import org.apache.wiki.WikiPage;
+import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
+import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.acl.Acl;
+import org.apache.wiki.auth.acl.AclEntry;
+import org.apache.wiki.auth.acl.AclManager;
+import org.apache.wiki.auth.acl.UnresolvedPrincipal;
+import org.apache.wiki.auth.authorize.GroupManager;
+import org.apache.wiki.auth.authorize.Role;
+import org.apache.wiki.auth.permissions.AllPermission;
+import org.apache.wiki.auth.permissions.PagePermission;
+import org.apache.wiki.auth.user.UserDatabase;
+import org.apache.wiki.auth.user.UserProfile;
+import org.apache.wiki.event.WikiEventListener;
+import org.apache.wiki.event.WikiEventManager;
+import org.apache.wiki.event.WikiSecurityEvent;
+import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.pages.PageManager;
+import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.util.ClassUtil;
+import org.freshcookies.security.policy.LocalPolicy;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.text.MessageFormat;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.WeakHashMap;
+
+
+/**
+ * <p>Default implementation for {@link AuthorizationManager}</p>
+ * {@inheritDoc}
+ *
+ * <p>See the {@link #checkPermission(WikiSession, Permission)} and {@link #hasRoleOrPrincipal(WikiSession, Principal)} methods for more
+ * information on the authorization logic.</p>
+ * @since 2.3
+ * @see AuthenticationManager
+ */
+public class DefaultAuthorizationManager implements AuthorizationManager {
+
+ private static final Logger log = Logger.getLogger( DefaultAuthorizationManager.class );
+
+ private Authorizer m_authorizer = null;
+
+ /** Cache for storing ProtectionDomains used to evaluate the local policy. */
+ private Map< Principal, ProtectionDomain > m_cachedPds = new WeakHashMap<>();
+
+ private Engine m_engine = null;
+
+ private LocalPolicy m_localPolicy = null;
+
+ /**
+ * Constructs a new DefaultAuthorizationManager instance.
+ */
+ public DefaultAuthorizationManager() {
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean checkPermission( final WikiSession session, final Permission permission ) {
+ // A slight sanity check.
+ if( session == null || permission == null ) {
+ fireEvent( WikiSecurityEvent.ACCESS_DENIED, null, permission );
+ return false;
+ }
+
+ final Principal user = session.getLoginPrincipal();
+
+ // Always allow the action if user has AllPermission
+ final Permission allPermission = new AllPermission( m_engine.getApplicationName() );
+ final 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.
+ final 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.
+ final String pageName = ((PagePermission)permission).getPage();
+ final WikiPage page = m_engine.getManager( PageManager.class ).getPage( pageName );
+ final Acl acl = ( page == null) ? null : m_engine.getManager( AclManager.class ).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.
+ final 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 ) {
+ // If the ACL principal we're looking at is unresolved, try to resolve it here & correct the Acl
+ if ( aclPrincipal instanceof UnresolvedPrincipal ) {
+ final 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;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Authorizer getAuthorizer() throws WikiSecurityException {
+ if ( m_authorizer != null ) {
+ return m_authorizer;
+ }
+ throw new WikiSecurityException( "Authorizer did not initialize properly. Check the logs." );
+ }
+
+ /**
+ * <p>Determines if the Subject associated with a supplied WikiSession contains a desired user Principal or built-in Role principal,
+ * OR is a member a Group or external Role. The rules are as follows:</p>
+ * <ol>
+ * <li>First, if desired Principal is a Role or GroupPrincipal, delegate to {@link #isUserInRole(WikiSession, Principal)} and
+ * return the result.</li>
+ * <li>Otherwise, we're looking for a user Principal, so iterate through the Principal set and see if any share the same name as the
+ * one we are looking for.</li>
+ * </ol>
+ * <p><em>Note: if the Principal parameter is a user principal, the session must be authenticated in order for the user to "possess it".
+ * Anonymous or asserted sessions will never posseess a named user principal.</em></p>
+ *
+ * @param session the current wiki session, which must be non-null. If null, the result of this method always returns <code>false</code>
+ * @param principal the Principal (role, group, or user principal) to look for, which must be non-null. If null, the result of this
+ * method always returns <code>false</code>
+ * @return <code>true</code> if the Subject supplied with the WikiContext posesses the Role, GroupPrincipal or desired
+ * user Principal, <code>false</code> otherwise
+ */
+ protected boolean hasRoleOrPrincipal( final WikiSession session, final Principal principal ) {
+ // If either parameter is null, always deny
+ if( session == null || principal == null ) {
+ return false;
+ }
+
+ // If principal is role, delegate to isUserInRole
+ if( AuthenticationManager.isRolePrincipal( principal ) ) {
+ return isUserInRole( session, principal );
+ }
+
+ // We must be looking for a user principal, assuming that the user has been properly logged in. So just look for a name match.
+ if( session.isAuthenticated() && AuthenticationManager.isUserPrincipal( principal ) ) {
+ final String principalName = principal.getName();
+ final Principal[] userPrincipals = session.getPrincipals();
+ for( final Principal userPrincipal : userPrincipals ) {
+ if( userPrincipal.getName().equals( principalName ) ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean hasAccess( final WikiContext context, final HttpServletResponse response, final boolean redirect ) throws IOException {
+ final boolean allowed = checkPermission( context.getWikiSession(), context.requiredPermission() );
+ final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
+
+ // Stash the wiki context
+ if ( context.getHttpRequest() != null && context.getHttpRequest().getAttribute( WikiContext.ATTR_CONTEXT ) == null ) {
+ context.getHttpRequest().setAttribute( WikiContext.ATTR_CONTEXT, context );
+ }
+
+ // If access not allowed, redirect
+ if( !allowed && redirect ) {
+ final Principal currentUser = context.getWikiSession().getUserPrincipal();
+ final String pageurl = context.getPage().getName();
+ if( context.getWikiSession().isAuthenticated() ) {
+ log.info( "User " + currentUser.getName() + " has no access - forbidden (permission=" + context.requiredPermission() + ")" );
+ context.getWikiSession().addMessage( MessageFormat.format( rb.getString( "security.error.noaccess.logged" ),
+ context.getName()) );
+ } else {
+ log.info( "User " + currentUser.getName() + " has no access - redirecting (permission=" + context.requiredPermission() + ")" );
+ context.getWikiSession().addMessage( MessageFormat.format( rb.getString("security.error.noaccess"), context.getName() ) );
+ }
+ response.sendRedirect( m_engine.getURL(WikiContext.LOGIN, pageurl, null ) );
+ }
+ return allowed;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void initialize( final Engine engine, final Properties properties ) throws WikiException {
+ m_engine = engine;
+
+ // JAAS authorization continues
+ m_authorizer = getAuthorizerImplementation( properties );
+ m_authorizer.initialize( engine, properties );
+
+ // Initialize local security policy
+ try {
+ final String policyFileName = properties.getProperty( POLICY, DEFAULT_POLICY );
+ final URL policyURL = engine.findConfigFile( policyFileName );
+
+ if (policyURL != null) {
+ final File policyFile = new File( policyURL.toURI().getPath() );
+ log.info("We found security policy URL: " + policyURL + " and transformed it to file " + policyFile.getAbsolutePath());
+ m_localPolicy = new LocalPolicy( policyFile, engine.getContentEncoding().displayName() );
+ m_localPolicy.refresh();
+ log.info( "Initialized default security policy: " + policyFile.getAbsolutePath() );
+ } else {
+ final String sb = "JSPWiki was unable to initialize the default security policy (WEB-INF/jspwiki.policy) file. " +
+ "Please ensure that the jspwiki.policy file exists in the default location. " +
+ "This file should exist regardless of the existance of a global policy file. " +
+ "The global policy file is identified by the java.security.policy variable. ";
+ final WikiSecurityException wse = new WikiSecurityException( sb );
+ log.fatal( sb, wse );
+ throw wse;
+ }
+ } catch ( final Exception e) {
+ log.error("Could not initialize local security policy: " + e.getMessage() );
+ throw new WikiException( "Could not initialize local security policy: " + e.getMessage(), e );
+ }
+ }
+
+ /**
+ * Attempts to locate and initialize a Authorizer to use with this manager. Throws a WikiException if no entry is found, or if one
+ * fails to initialize.
+ *
+ * @param props jspwiki.properties, containing a 'jspwiki.authorization.provider' class name.
+ * @return a Authorizer used to get page authorization information.
+ * @throws WikiException if there are problems finding the authorizer implementation.
+ */
+ private Authorizer getAuthorizerImplementation( final Properties props ) throws WikiException {
+ final String authClassName = props.getProperty( PROP_AUTHORIZER, DEFAULT_AUTHORIZER );
+ return ( Authorizer )locateImplementation( authClassName );
+ }
+
+ private Object locateImplementation( final String clazz ) throws WikiException {
+ if ( clazz != null ) {
+ try {
+ final Class< ? > authClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", clazz );
+ return authClass.newInstance();
+ } catch( final ClassNotFoundException e ) {
+ log.fatal( "Authorizer " + clazz + " cannot be found", e );
+ throw new WikiException( "Authorizer " + clazz + " cannot be found", e );
+ } catch( final InstantiationException e ) {
+ log.fatal( "Authorizer " + clazz + " cannot be created", e );
+ throw new WikiException( "Authorizer " + clazz + " cannot be created", e );
+ } catch( final IllegalAccessException e ) {
+ log.fatal( "You are not allowed to access this authorizer class", e );
+ throw new WikiException( "You are not allowed to access this authorizer class", e );
+ }
+ }
+
+ throw new NoRequiredPropertyException( "Unable to find a " + PROP_AUTHORIZER + " entry in the properties.", PROP_AUTHORIZER );
+ }
+
+ /**
+ * Checks to see if the local security policy allows a particular static Permission.
+ * Do not use this method for normal permission checks; use {@link #checkPermission(WikiSession, Permission)} instead.
+ *
+ * @param principals the Principals to check
+ * @param permission the Permission
+ * @return the result
+ */
+ protected boolean allowedByLocalPolicy( final Principal[] principals, final Permission permission ) {
+ for ( final Principal principal : principals ) {
+ // Get ProtectionDomain for this Principal from cache, or create new one
+ ProtectionDomain pd = m_cachedPds.get( principal );
+ if ( pd == null ) {
+ final ClassLoader cl = this.getClass().getClassLoader();
+ final CodeSource cs = new CodeSource( null, (Certificate[])null );
+ pd = new ProtectionDomain( cs, null, cl, new Principal[]{ principal } );
+ m_cachedPds.put( principal, pd );
+ }
+
+ // Consult the local policy and get the answer
+ if ( m_localPolicy.implies( pd, permission ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Determines whether a Subject possesses a given "static" Permission as defined in the security policy file. This method uses standard
+ * Java 2 security calls to do its work. Note that the current access control context's <code>codeBase</code> is effectively <em>this
+ * class</em>, not that of the caller. Therefore, this method will work best when what matters in the policy is <em>who</em> makes the
+ * permission check, not what the caller's code source is. Internally, this method works by executing <code>Subject.doAsPrivileged</code>
+ * with a privileged action that simply calls {@link AccessController#checkPermission(Permission)}.
+ *
+ * @see AccessController#checkPermission(Permission) . A caught exception (or lack thereof) determines whether the
+ * privilege is absent (or present).
+ * @param session the WikiSession whose permission status is being queried
+ * @param permission the Permission the Subject must possess
+ * @return <code>true</code> if the Subject possesses the permission, <code>false</code> otherwise
+ */
+ protected boolean checkStaticPermission( final WikiSession session, final Permission permission ) {
+ return ( Boolean )WikiSession.doPrivileged( session, ( PrivilegedAction< Boolean > )() -> {
+ try {
+ // Check the JVM-wide security policy first
+ AccessController.checkPermission( permission );
+ return Boolean.TRUE;
+ } catch( final AccessControlException e ) {
+ // Global policy denied the permission
+ }
+
+ // Try the local policy - check each Role/Group and User Principal
+ if ( allowedByLocalPolicy( session.getRoles(), permission ) || allowedByLocalPolicy( session.getPrincipals(), permission ) ) {
+ return Boolean.TRUE;
+ }
+ return Boolean.FALSE;
+ } );
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public Principal resolvePrincipal( final String name ) {
+ // Check built-in Roles first
+ final 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.getManager( GroupManager.class ).findRole( name );
+ if ( principal != null ) {
+ return principal;
+ }
+
+ // Ok, no luck---this must be a user principal
+ final Principal[] principals;
+ final UserProfile profile;
+ final UserDatabase db = m_engine.getManager( UserManager.class ).getUserDatabase();
+ try {
+ profile = db.find( name );
+ principals = db.getPrincipals( profile.getLoginName() );
+ for( final Principal value : principals ) {
+ principal = value;
+ if( principal.getName().equals( name ) ) {
+ return principal;
+ }
+ }
+ } catch( final NoSuchPrincipalException e ) {
+ // We couldn't find the user...
+ }
+ // Ok, no luck---mark this as unresolved and move on
+ return new UnresolvedPrincipal( name );
+ }
+
+
+ // events processing .......................................................
+
+ /** {@inheritDoc} */
+ @Override
+ public synchronized void addWikiEventListener( final WikiEventListener listener ) {
+ WikiEventManager.addWikiEventListener( this, listener );
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
+ WikiEventManager.removeWikiEventListener( this, listener );
+ }
+
+}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java
index ca03266..579036a 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupDatabase.java
@@ -18,7 +18,7 @@
*/
package org.apache.wiki.auth.authorize;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
import org.apache.wiki.auth.WikiSecurityException;
@@ -50,7 +50,7 @@ public interface GroupDatabase {
* @throws WikiSecurityException if the database could not be initialized successfully
* @throws NoRequiredPropertyException if a required property is not present
*/
- void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
+ void initialize( Engine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
/**
* Saves a Group to the group database. Note that this method <em>must</em>
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
index 1f3bc60..37e3c33 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/GroupManager.java
@@ -21,14 +21,15 @@ package org.apache.wiki.auth.authorize;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.Logger;
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
import org.apache.wiki.api.exceptions.WikiException;
import org.apache.wiki.auth.AuthenticationManager;
import org.apache.wiki.auth.Authorizer;
import org.apache.wiki.auth.GroupPrincipal;
import org.apache.wiki.auth.NoSuchPrincipalException;
+import org.apache.wiki.auth.UserManager;
import org.apache.wiki.auth.WikiPrincipal;
import org.apache.wiki.auth.WikiSecurityException;
import org.apache.wiki.auth.user.UserProfile;
@@ -67,38 +68,33 @@ import java.util.StringTokenizer;
public class GroupManager implements Authorizer, WikiEventListener {
/** Key used for adding UI messages to a user's WikiSession. */
- public static final String MESSAGES_KEY = "group";
+ public static final String MESSAGES_KEY = "group";
private static final String PROP_GROUPDATABASE = "jspwiki.groupdatabase";
- static final Logger log = Logger.getLogger( GroupManager.class );
+ private static final Logger log = Logger.getLogger( GroupManager.class );
- protected WikiEngine m_engine;
+ protected Engine m_engine;
protected WikiEventListener m_groupListener;
private GroupDatabase m_groupDatabase = null;
/** Map with GroupPrincipals as keys, and Groups as values */
- private final Map<Principal, Group> m_groups = new HashMap<Principal, Group>();
+ private final Map< Principal, Group > m_groups = new HashMap<>();
/**
* <p>
- * Returns a GroupPrincipal matching a given name. If a group cannot be
- * found, return <code>null</code>.
+ * Returns a GroupPrincipal matching a given name. If a group cannot be found, return <code>null</code>.
* </p>
* @param name Name of the group. This is case-sensitive.
* @return A DefaultGroup instance.
*/
- public Principal findRole( String name )
- {
- try
- {
- Group group = getGroup( name );
+ @Override public Principal findRole( final String name ) {
+ try {
+ final Group group = getGroup( name );
return group.getPrincipal();
- }
- catch( NoSuchPrincipalException e )
- {
+ } catch( final NoSuchPrincipalException e ) {
return null;
}
}
@@ -110,9 +106,9 @@ public class GroupManager implements Authorizer, WikiEventListener {
* @return the group
* @throws NoSuchPrincipalException if the group cannot be found
*/
- public Group getGroup( String name ) throws NoSuchPrincipalException
+ public Group getGroup( final String name ) throws NoSuchPrincipalException
{
- Group group = m_groups.get( new GroupPrincipal( name ) );
+ final Group group = m_groups.get( new GroupPrincipal( name ) );
if ( group != null )
{
return group;
@@ -143,37 +139,37 @@ public class GroupManager implements Authorizer, WikiEventListener {
Throwable cause = null;
try
{
- Properties props = m_engine.getWikiProperties();
+ final Properties props = m_engine.getWikiProperties();
dbClassName = props.getProperty( PROP_GROUPDATABASE );
if ( dbClassName == null )
{
dbClassName = XMLGroupDatabase.class.getName();
}
log.info( "Attempting to load group database class " + dbClassName );
- Class<?> dbClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", dbClassName );
+ final Class<?> dbClass = ClassUtil.findClass( "org.apache.wiki.auth.authorize", dbClassName );
m_groupDatabase = (GroupDatabase) dbClass.newInstance();
m_groupDatabase.initialize( m_engine, m_engine.getWikiProperties() );
log.info( "Group database initialized." );
}
- catch( ClassNotFoundException e )
+ catch( final ClassNotFoundException e )
{
log.error( "GroupDatabase class " + dbClassName + " cannot be found.", e );
dbInstantiationError = "Failed to locate GroupDatabase class " + dbClassName;
cause = e;
}
- catch( InstantiationException e )
+ catch( final InstantiationException e )
{
log.error( "GroupDatabase class " + dbClassName + " cannot be created.", e );
dbInstantiationError = "Failed to create GroupDatabase class " + dbClassName;
cause = e;
}
- catch( IllegalAccessException e )
+ catch( final IllegalAccessException e )
{
log.error( "You are not allowed to access group database class " + dbClassName + ".", e );
dbInstantiationError = "Access GroupDatabase class " + dbClassName + " denied";
cause = e;
}
- catch( NoRequiredPropertyException e )
+ catch( final NoRequiredPropertyException e )
{
log.error( "Missing property: " + e.getMessage() + "." );
dbInstantiationError = "Missing property: " + e.getMessage();
@@ -195,7 +191,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
* defensive copy of an internally stored hashmap.
* @return an array of Principals representing the roles
*/
- public Principal[] getRoles()
+ @Override public Principal[] getRoles()
{
return m_groups.keySet().toArray( new Principal[m_groups.size()] );
}
@@ -205,12 +201,11 @@ public class GroupManager implements Authorizer, WikiEventListener {
* obtaining a list of all of the groups it stores.
* @param engine the wiki engine
* @param props the properties used to initialize the wiki engine
- * @see GroupDatabase#initialize(org.apache.wiki.WikiEngine,
- * java.util.Properties)
+ * @see GroupDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
* @see GroupDatabase#groups()
* @throws WikiSecurityException if GroupManager cannot be initialized
*/
- public void initialize( WikiEngine engine, Properties props ) throws WikiSecurityException
+ @Override public void initialize( final Engine engine, final Properties props ) throws WikiSecurityException
{
m_engine = engine;
@@ -218,16 +213,16 @@ public class GroupManager implements Authorizer, WikiEventListener {
{
m_groupDatabase = getGroupDatabase();
}
- catch ( WikiException e )
+ catch ( final WikiException e )
{
throw new WikiSecurityException( e.getMessage(), e );
}
// Load all groups from the database into the cache
- Group[] groups = m_groupDatabase.groups();
+ final Group[] groups = m_groupDatabase.groups();
synchronized( m_groups )
{
- for( Group group : groups )
+ for( final Group group : groups )
{
// Add new group to cache; fire GROUP_ADD event
m_groups.put( group.getPrincipal(), group );
@@ -236,7 +231,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
}
// Make the GroupManager listen for WikiEvents (WikiSecurityEvents for changed user profiles)
- engine.getUserManager().addWikiEventListener( this );
+ engine.getManager( UserManager.class ).addWikiEventListener( this );
// Success!
log.info( "Authorizer GroupManager initialized successfully; loaded " + groups.length + " group(s)." );
@@ -264,7 +259,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
* @return <code>true</code> if the user is considered to be in the role,
* <code>false</code> otherwise
*/
- public boolean isUserInRole( WikiSession session, Principal role )
+ @Override public boolean isUserInRole( final WikiSession session, final Principal role )
{
// Always return false if session/role is null, or if
// role isn't a GroupPrincipal
@@ -274,14 +269,14 @@ public class GroupManager implements Authorizer, WikiEventListener {
}
// Get the group we're examining
- Group group = m_groups.get( role );
+ final Group group = m_groups.get( role );
if ( group == null )
{
return false;
}
// Check each user principal to see if it belongs to the group
- for ( Principal principal : session.getPrincipals() )
+ for ( final Principal principal : session.getPrincipals() )
{
if ( AuthenticationManager.isUserPrincipal( principal ) && group.isMember( principal ) )
{
@@ -321,7 +316,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
* <code>create</code> is <code>false</code>
* and the Group named <code>name</code> does not exist
*/
- public Group parseGroup( String name, String memberLine, boolean create ) throws WikiSecurityException
+ public Group parseGroup( String name, String memberLine, final boolean create ) throws WikiSecurityException
{
// If null name parameter, it's because someone's creating a new group
if ( name == null )
@@ -350,22 +345,22 @@ public class GroupManager implements Authorizer, WikiEventListener {
memberLine = memberLine.trim();
// Create or retrieve the group (may have been previously cached)
- Group group = new Group( name, m_engine.getApplicationName() );
+ final Group group = new Group( name, m_engine.getApplicationName() );
try
{
- Group existingGroup = getGroup( name );
+ final Group existingGroup = getGroup( name );
// If existing, clone it
group.setCreator( existingGroup.getCreator() );
group.setCreated( existingGroup.getCreated() );
group.setModifier( existingGroup.getModifier() );
group.setLastModified( existingGroup.getLastModified() );
- for( Principal existingMember : existingGroup.members() )
+ for( final Principal existingMember : existingGroup.members() )
{
group.add( existingMember );
}
}
- catch( NoSuchPrincipalException e )
+ catch( final NoSuchPrincipalException e )
{
// It's a new group.... throw error if we don't create new ones
if ( !create )
@@ -375,11 +370,11 @@ public class GroupManager implements Authorizer, WikiEventListener {
}
// If passed members not empty, overwrite
- String[] members = extractMembers( memberLine );
+ final String[] members = extractMembers( memberLine );
if ( members.length > 0 )
{
group.clear();
- for( String member : members )
+ for( final String member : members )
{
group.add( new WikiPrincipal( member ) );
}
@@ -416,16 +411,16 @@ public class GroupManager implements Authorizer, WikiEventListener {
* <code>create</code> is <code>false</code>
* and the Group does not exist
*/
- public Group parseGroup( WikiContext context, boolean create ) throws WikiSecurityException
+ public Group parseGroup( final WikiContext context, final boolean create ) throws WikiSecurityException
{
// Extract parameters
- HttpServletRequest request = context.getHttpRequest();
- String name = request.getParameter( "group" );
- String memberLine = request.getParameter( "members" );
+ final HttpServletRequest request = context.getHttpRequest();
+ final String name = request.getParameter( "group" );
+ final String memberLine = request.getParameter( "members" );
// Create the named group; we pass on any NoSuchPrincipalExceptions
// that may be thrown if create == false, or WikiSecurityExceptions
- Group group = parseGroup( name, memberLine, create );
+ final Group group = parseGroup( name, memberLine, create );
// If no members, add the current user by default
if ( group.members().length == 0 )
@@ -449,14 +444,14 @@ public class GroupManager implements Authorizer, WikiEventListener {
* the back-end
* @see org.apache.wiki.auth.authorize.GroupDatabase#delete(Group)
*/
- public void removeGroup( String index ) throws WikiSecurityException
+ public void removeGroup( final String index ) throws WikiSecurityException
{
if ( index == null )
{
throw new IllegalArgumentException( "Group cannot be null." );
}
- Group group = m_groups.get( new GroupPrincipal( index ) );
+ final Group group = m_groups.get( new GroupPrincipal( index ) );
if ( group == null )
{
throw new NoSuchPrincipalException( "Group " + index + " not found" );
@@ -512,12 +507,12 @@ public class GroupManager implements Authorizer, WikiEventListener {
* @param group the Group, which may not be <code>null</code>
* @throws WikiSecurityException if the Group cannot be saved by the back-end
*/
- public void setGroup( WikiSession session, Group group ) throws WikiSecurityException
+ public void setGroup( final WikiSession session, final Group group ) throws WikiSecurityException
{
// TODO: check for appropriate permissions
// If group already exists, delete it; fire GROUP_REMOVE event
- Group oldGroup = m_groups.get( group.getPrincipal() );
+ final Group oldGroup = m_groups.get( group.getPrincipal() );
if ( oldGroup != null )
{
fireEvent( WikiSecurityEvent.GROUP_REMOVE, oldGroup );
@@ -552,7 +547,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
}
// We got an exception! Roll back...
- catch( WikiSecurityException e )
+ catch( final WikiSecurityException e )
{
if ( oldGroup != null )
{
@@ -577,22 +572,22 @@ public class GroupManager implements Authorizer, WikiEventListener {
* @param context the current wiki context
* @param group the supplied Group
*/
- public void validateGroup( WikiContext context, Group group )
+ public void validateGroup( final WikiContext context, final Group group )
{
- InputValidator validator = new InputValidator( MESSAGES_KEY, context );
+ final InputValidator validator = new InputValidator( MESSAGES_KEY, context );
// Name cannot be null or one of the restricted names
try
{
checkGroupName( context, group.getName() );
}
- catch( WikiSecurityException e )
+ catch( final WikiSecurityException e )
{
}
// Member names must be "safe" strings
- Principal[] members = group.members();
+ final Principal[] members = group.members();
for( int i = 0; i < members.length; i++ )
{
validator.validateNotNull( members[i].getName(), "Full name", InputValidator.ID );
@@ -604,15 +599,15 @@ public class GroupManager implements Authorizer, WikiEventListener {
* @param memberLine the list of members
* @return the list of members
*/
- protected String[] extractMembers( String memberLine )
+ protected String[] extractMembers( final String memberLine )
{
- Set<String> members = new HashSet<String>();
+ final Set<String> members = new HashSet<>();
if ( memberLine != null )
{
- StringTokenizer tok = new StringTokenizer( memberLine, "\n" );
+ final StringTokenizer tok = new StringTokenizer( memberLine, "\n" );
while( tok.hasMoreTokens() )
{
- String uid = tok.nextToken().trim();
+ final String uid = tok.nextToken().trim();
if ( uid != null && uid.length() > 0 )
{
members.add( uid );
@@ -631,12 +626,12 @@ public class GroupManager implements Authorizer, WikiEventListener {
* <code>null</code> or the Group name is illegal
* @see Group#RESTRICTED_GROUPNAMES
*/
- protected void checkGroupName( WikiContext context, String name ) throws WikiSecurityException
+ protected void checkGroupName( final WikiContext context, final String name ) throws WikiSecurityException
{
//TODO: groups cannot have the same name as a user
// Name cannot be null
- InputValidator validator = new InputValidator( MESSAGES_KEY, context );
+ final InputValidator validator = new InputValidator( MESSAGES_KEY, context );
validator.validateNotNull( name, "Group name" );
// Name cannot be one of the restricted names either
@@ -654,7 +649,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
* This is a convenience method.
* @param listener the event listener
*/
- public synchronized void addWikiEventListener( WikiEventListener listener )
+ public synchronized void addWikiEventListener( final WikiEventListener listener )
{
WikiEventManager.addWikiEventListener( this, listener );
}
@@ -664,7 +659,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
* This is a convenience method.
* @param listener the event listener
*/
- public synchronized void removeWikiEventListener( WikiEventListener listener )
+ public synchronized void removeWikiEventListener( final WikiEventListener listener )
{
WikiEventManager.removeWikiEventListener( this, listener );
}
@@ -677,7 +672,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
* @param type the event type to be fired
* @param target the changed Object, which may be <code>null</code>
*/
- protected void fireEvent( int type, Object target )
+ protected void fireEvent( final int type, final Object target )
{
if ( WikiEventManager.isListening(this) )
{
@@ -693,32 +688,32 @@ public class GroupManager implements Authorizer, WikiEventListener {
* only the representations of the names within that are changing.
* @param event the incoming event
*/
- public void actionPerformed(WikiEvent event)
+ @Override public void actionPerformed( final WikiEvent event)
{
if (! ( event instanceof WikiSecurityEvent ) )
{
return;
}
- WikiSecurityEvent se = (WikiSecurityEvent)event;
+ final WikiSecurityEvent se = (WikiSecurityEvent)event;
if ( se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED )
{
- WikiSession session = se.getSrc();
- UserProfile[] profiles = (UserProfile[])se.getTarget();
- Principal[] oldPrincipals = new Principal[] {
+ final WikiSession session = se.getSrc();
+ final UserProfile[] profiles = (UserProfile[])se.getTarget();
+ final Principal[] oldPrincipals = new Principal[] {
new WikiPrincipal( profiles[0].getLoginName() ),
new WikiPrincipal( profiles[0].getFullname() ),
new WikiPrincipal( profiles[0].getWikiName() ) };
- Principal newPrincipal = new WikiPrincipal( profiles[1].getFullname() );
+ final Principal newPrincipal = new WikiPrincipal( profiles[1].getFullname() );
// Examine each group
int groupsChanged = 0;
try
{
- for ( Group group : m_groupDatabase.groups() )
+ for ( final Group group : m_groupDatabase.groups() )
{
boolean groupChanged = false;
- for ( Principal oldPrincipal : oldPrincipals )
+ for ( final Principal oldPrincipal : oldPrincipals )
{
if ( group.isMember( oldPrincipal ) )
{
@@ -734,7 +729,7 @@ public class GroupManager implements Authorizer, WikiEventListener {
}
}
}
- catch ( WikiException e )
+ catch ( final WikiException e )
{
// Oooo! This is really bad...
log.error( "Could not change user name in Group lists because of GroupDatabase error:" + e.getMessage() );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java
index d5ac0d2..1f22cf6 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/JDBCGroupDatabase.java
@@ -18,23 +18,29 @@
*/
package org.apache.wiki.auth.authorize;
-import java.security.Principal;
-import java.sql.*;
-import java.util.*;
-import java.util.Date;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.sql.DataSource;
-
import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
import org.apache.wiki.auth.NoSuchPrincipalException;
import org.apache.wiki.auth.WikiPrincipal;
import org.apache.wiki.auth.WikiSecurityException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.sql.DataSource;
+import java.security.Principal;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
/**
* <p>
* Implementation of GroupDatabase that persists {@link Group} objects to a JDBC
@@ -121,13 +127,8 @@ import org.apache.wiki.auth.WikiSecurityException;
* </p>
* <p>
* JDBCGroupDatabase commits changes as transactions if the back-end database
- * supports them. If the database supports transactions, group changes are saved
- * to permanent storage only when the {@link #commit()} method is called. If the
- * database does <em>not</em> support transactions, then changes are made
- * immediately (during the {@link #save(Group, Principal)} method), and the
- * {@linkplain #commit()} method no-ops. Thus, callers should always call the
- * {@linkplain #commit()} method after saving a profile to guarantee that
- * changes are applied.
+ * supports them. Changes are made
+ * immediately (during the {@link #save(Group, Principal)} method).
* </p>
*
* @since 2.3
@@ -222,7 +223,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
private boolean m_supportsCommits = false;
- private WikiEngine m_engine = null;
+ private Engine m_engine = null;
/**
* Looks up and deletes a {@link Group} from the group database. If the
@@ -235,14 +236,14 @@ public class JDBCGroupDatabase implements GroupDatabase {
* supplied group (thrown as {@link NoSuchPrincipalException})
* or if the commit did not succeed
*/
- public void delete( Group group ) throws WikiSecurityException
+ @Override public void delete( final Group group ) throws WikiSecurityException
{
if( !exists( group ) )
{
throw new NoSuchPrincipalException( "Not in database: " + group.getName() );
}
- String groupName = group.getName();
+ final String groupName = group.getName();
Connection conn = null;
PreparedStatement ps = null;
try
@@ -269,7 +270,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
conn.commit();
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
closeQuietly( conn, ps, null );
throw new WikiSecurityException( "Could not delete group " + groupName + ": " + e.getMessage(), e );
@@ -291,9 +292,9 @@ public class JDBCGroupDatabase implements GroupDatabase {
* @throws WikiSecurityException if the groups cannot be returned by the
* back-end
*/
- public Group[] groups() throws WikiSecurityException
+ @Override public Group[] groups() throws WikiSecurityException
{
- Set<Group> groups = new HashSet<Group>();
+ final Set<Group> groups = new HashSet<>();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
@@ -306,14 +307,14 @@ public class JDBCGroupDatabase implements GroupDatabase {
rs = ps.executeQuery();
while ( rs.next() )
{
- String groupName = rs.getString( m_name );
+ final String groupName = rs.getString( m_name );
if( groupName == null )
{
log.warn( "Detected null group name in JDBCGroupDataBase. Check your group database." );
}
else
{
- Group group = new Group( groupName, m_engine.getApplicationName() );
+ final Group group = new Group( groupName, m_engine.getApplicationName() );
group.setCreated( rs.getTimestamp( m_created ) );
group.setCreator( rs.getString( m_creator ) );
group.setLastModified( rs.getTimestamp( m_modified ) );
@@ -323,7 +324,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
}
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
closeQuietly( conn, ps, rs );
throw new WikiSecurityException( e.getMessage(), e );
@@ -346,17 +347,16 @@ public class JDBCGroupDatabase implements GroupDatabase {
*
* @param group the Group to save
* @param modifier the user who saved the Group
- * @throws WikiSecurityException if the Group could not be saved
- * successfully
+ * @throws WikiSecurityException if the Group could not be saved successfully
*/
- public void save( Group group, Principal modifier ) throws WikiSecurityException
+ @Override public void save( final Group group, final Principal modifier ) throws WikiSecurityException
{
if( group == null || modifier == null )
{
throw new IllegalArgumentException( "Group or modifier cannot be null." );
}
- boolean exists = exists( group );
+ final boolean exists = exists( group );
Connection conn = null;
PreparedStatement ps = null;
try
@@ -368,8 +368,8 @@ public class JDBCGroupDatabase implements GroupDatabase {
conn.setAutoCommit( false );
}
- Timestamp ts = new Timestamp( System.currentTimeMillis() );
- Date modDate = new Date( ts.getTime() );
+ final Timestamp ts = new Timestamp( System.currentTimeMillis() );
+ final Date modDate = new Date( ts.getTime() );
if( !exists )
{
// Group is new: insert new group record
@@ -410,10 +410,10 @@ public class JDBCGroupDatabase implements GroupDatabase {
// Insert group member records
ps = conn.prepareStatement( m_insertGroupMembers );
- Principal[] members = group.members();
+ final Principal[] members = group.members();
for( int i = 0; i < members.length; i++ )
{
- Principal member = members[i];
+ final Principal member = members[i];
ps.setString( 1, group.getName() );
ps.setString( 2, member.getName() );
ps.execute();
@@ -425,7 +425,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
conn.commit();
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
closeQuietly(conn, ps, null );
throw new WikiSecurityException( e.getMessage(), e );
@@ -445,18 +445,18 @@ public class JDBCGroupDatabase implements GroupDatabase {
* successfully
* @throws NoRequiredPropertyException if a required property is not present
*/
- public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException
+ @Override public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException
{
- String table;
- String memberTable;
+ final String table;
+ final String memberTable;
m_engine = engine;
- String jndiName = props.getProperty( PROP_GROUPDB_DATASOURCE, DEFAULT_GROUPDB_DATASOURCE );
+ final String jndiName = props.getProperty( PROP_GROUPDB_DATASOURCE, DEFAULT_GROUPDB_DATASOURCE );
try
{
- Context initCtx = new InitialContext();
- Context ctx = (Context) initCtx.lookup( "java:comp/env" );
+ final Context initCtx = new InitialContext();
+ final Context ctx = (Context) initCtx.lookup( "java:comp/env" );
m_ds = (DataSource) ctx.lookup( jndiName );
// Prepare the SQL selectors
@@ -485,7 +485,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
m_deleteGroup = "DELETE FROM " + table + " WHERE " + m_name + "=?";
m_deleteGroupMembers = "DELETE FROM " + memberTable + " WHERE " + m_name + "=?";
}
- catch( NamingException e )
+ catch( final NamingException e )
{
log.error( "JDBCGroupDatabase initialization error: " + e );
throw new NoRequiredPropertyException( PROP_GROUPDB_DATASOURCE, "JDBCGroupDatabase initialization error: " + e);
@@ -501,7 +501,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
ps.executeQuery();
ps.close();
}
- catch( SQLException e )
+ catch( final SQLException e )
{
closeQuietly( conn, ps, null );
log.error( "DB connectivity error: " + e.getMessage() );
@@ -517,7 +517,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
try
{
conn = m_ds.getConnection();
- DatabaseMetaData dmd = conn.getMetaData();
+ final DatabaseMetaData dmd = conn.getMetaData();
if( dmd.supportsTransactions() )
{
m_supportsCommits = true;
@@ -525,7 +525,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
log.info( "JDBCGroupDatabase supports transactions. Good; we will use them." );
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
closeQuietly( conn, null, null );
log.warn( "JDBCGroupDatabase warning: user database doesn't seem to support transactions. Reason: " + e);
@@ -542,15 +542,15 @@ public class JDBCGroupDatabase implements GroupDatabase {
* @param group the Group to look for
* @return the result of the search
*/
- private boolean exists( Group group )
+ private boolean exists( final Group group )
{
- String index = group.getName();
+ final String index = group.getName();
try
{
findGroup( index );
return true;
}
- catch( NoSuchPrincipalException e )
+ catch( final NoSuchPrincipalException e )
{
return false;
}
@@ -565,7 +565,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
* @throws NoSuchPrincipalException if the Group cannot be found
* @throws SQLException if the database query returns an error
*/
- private Group findGroup( String index ) throws NoSuchPrincipalException
+ private Group findGroup( final String index ) throws NoSuchPrincipalException
{
Group group = null;
boolean found = false;
@@ -597,7 +597,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
found = true;
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
closeQuietly( conn, ps, rs );
throw new NoSuchPrincipalException( e.getMessage() );
@@ -624,7 +624,7 @@ public class JDBCGroupDatabase implements GroupDatabase {
* @param group the group to populate
* @return the populated Group
*/
- private Group populateGroup( Group group )
+ private Group populateGroup( final Group group )
{
ResultSet rs = null;
PreparedStatement ps = null;
@@ -639,15 +639,15 @@ public class JDBCGroupDatabase implements GroupDatabase {
rs = ps.executeQuery();
while ( rs.next() )
{
- String memberName = rs.getString( m_member );
+ final String memberName = rs.getString( m_member );
if( memberName != null )
{
- WikiPrincipal principal = new WikiPrincipal( memberName, WikiPrincipal.UNSPECIFIED );
+ final WikiPrincipal principal = new WikiPrincipal( memberName, WikiPrincipal.UNSPECIFIED );
group.add( principal );
}
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
// I guess that means there aren't any principals...
}
@@ -658,23 +658,23 @@ public class JDBCGroupDatabase implements GroupDatabase {
return group;
}
- void closeQuietly( Connection conn, PreparedStatement ps, ResultSet rs ) {
+ void closeQuietly( final Connection conn, final PreparedStatement ps, final ResultSet rs ) {
if( conn != null ) {
try {
conn.close();
- } catch( Exception e ) {
+ } catch( final Exception e ) {
}
}
if( ps != null ) {
try {
ps.close();
- } catch( Exception e ) {
+ } catch( final Exception e ) {
}
}
if( rs != null ) {
try {
rs.close();
- } catch( Exception e ) {
+ } catch( final Exception e ) {
}
}
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java
index d55569e..dd6cf08 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebAuthorizer.java
@@ -18,29 +18,25 @@
*/
package org.apache.wiki.auth.authorize;
-import java.security.Principal;
+import org.apache.wiki.auth.Authorizer;
import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
-import org.apache.wiki.auth.Authorizer;
/**
- * Extends the {@link org.apache.wiki.auth.Authorizer} interface by
- * including a delgate method for
+ * Extends the {@link org.apache.wiki.auth.Authorizer} interface by including a delgate method for
* {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)}.
*/
-public interface WebAuthorizer extends Authorizer
-{
+public interface WebAuthorizer extends Authorizer {
/**
- * Determines whether a user associated with an HTTP request possesses
- * a particular role. This method simply delegates to
- * {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)}
- * by converting the Principal's name to a String.
+ * Determines whether a user associated with an HTTP request possesses a particular role. This method simply delegates to
+ * {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)} by converting the Principal's name to a String.
+ *
* @param request the HTTP request
* @param role the role to check
- * @return <code>true</code> if the user is considered to be in the role,
- * <code>false</code> otherwise
+ * @return <code>true</code> if the user is considered to be in the role, <code>false</code> otherwise
*/
boolean isUserInRole( HttpServletRequest request, Principal role );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java
index cfb78b3..a4c4968 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/WebContainerAuthorizer.java
@@ -20,8 +20,8 @@ package org.apache.wiki.auth.authorize;
import org.apache.log4j.Logger;
import org.apache.wiki.InternalWikiException;
-import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
@@ -56,9 +56,9 @@ public class WebContainerAuthorizer implements WebAuthorizer {
private static final String J2EE_SCHEMA_25_NAMESPACE = "http://xmlns.jcp.org/xml/ns/javaee";
- protected static final Logger log = Logger.getLogger( WebContainerAuthorizer.class );
+ private static final Logger log = Logger.getLogger( WebContainerAuthorizer.class );
- protected WikiEngine m_engine;
+ protected Engine m_engine;
/**
* A lazily-initialized array of Roles that the container knows about. These
@@ -68,15 +68,15 @@ public class WebContainerAuthorizer implements WebAuthorizer {
* that we have no direct way of querying the web container about which
* roles it manages.
*/
- protected Role[] m_containerRoles = new Role[0];
+ protected Role[] m_containerRoles = new Role[0];
/**
* Lazily-initialized boolean flag indicating whether the web container
* protects JSPWiki resources.
*/
- protected boolean m_containerAuthorized = false;
+ protected boolean m_containerAuthorized = false;
- private Document m_webxml = null;
+ private Document m_webxml = null;
/**
* Constructs a new instance of the WebContainerAuthorizer class.
@@ -92,49 +92,36 @@ public class WebContainerAuthorizer implements WebAuthorizer {
* @param props the wiki engine initialization properties
*/
@Override
- public void initialize( WikiEngine engine, Properties props )
- {
+ public void initialize( final Engine engine, final Properties props ) {
m_engine = engine;
m_containerAuthorized = false;
// FIXME: Error handling here is not very verbose
- try
- {
+ try {
m_webxml = getWebXml();
- if ( m_webxml != null )
- {
+ if( m_webxml != null ) {
// Add the J2EE 2.4 schema namespace
m_webxml.getRootElement().setNamespace( Namespace.getNamespace( J2EE_SCHEMA_25_NAMESPACE ) );
- m_containerAuthorized = isConstrained( "/Delete.jsp", Role.ALL )
- && isConstrained( "/Login.jsp", Role.ALL );
+ m_containerAuthorized = isConstrained( "/Delete.jsp", Role.ALL ) && isConstrained( "/Login.jsp", Role.ALL );
}
- if ( m_containerAuthorized )
- {
+ if( m_containerAuthorized ) {
m_containerRoles = getRoles( m_webxml );
log.info( "JSPWiki is using container-managed authentication." );
- }
- else
- {
+ } else {
log.info( "JSPWiki is using custom authentication." );
}
- }
- catch ( IOException e )
- {
- log.error("Initialization failed: ",e);
- throw new InternalWikiException( e.getClass().getName()+": "+e.getMessage() , e);
- }
- catch ( JDOMException e )
- {
- log.error("Malformed XML in web.xml",e);
- throw new InternalWikiException( e.getClass().getName()+": "+e.getMessage() , e);
+ } catch( final IOException e ) {
+ log.error( "Initialization failed: ", e );
+ throw new InternalWikiException( e.getClass().getName() + ": " + e.getMessage(), e );
+ } catch( final JDOMException e ) {
+ log.error( "Malformed XML in web.xml", e );
+ throw new InternalWikiException( e.getClass().getName() + ": " + e.getMessage(), e );
}
- if ( m_containerRoles.length > 0 )
- {
+ if( m_containerRoles.length > 0 ) {
String roles = "";
- for( Role containerRole : m_containerRoles )
- {
+ for( final Role containerRole : m_containerRoles ) {
roles = roles + containerRole + " ";
}
log.info( " JSPWiki determined the web container manages these roles: " + roles );
@@ -153,7 +140,7 @@ public class WebContainerAuthorizer implements WebAuthorizer {
* <code>false</code> otherwise
*/
@Override
- public boolean isUserInRole( HttpServletRequest request, Principal role )
+ public boolean isUserInRole( final HttpServletRequest request, final Principal role )
{
return request.isUserInRole( role.getName() );
}
@@ -182,10 +169,8 @@ public class WebContainerAuthorizer implements WebAuthorizer {
* @see org.apache.wiki.auth.Authorizer#isUserInRole(org.apache.wiki.WikiSession, java.security.Principal)
*/
@Override
- public boolean isUserInRole( WikiSession session, Principal role )
- {
- if ( session == null || role == null )
- {
+ public boolean isUserInRole( final WikiSession session, final Principal role ) {
+ if ( session == null || role == null ) {
return false;
}
return session.hasPrincipal( role );
@@ -197,15 +182,12 @@ public class WebContainerAuthorizer implements WebAuthorizer {
* initialization, this method returns <code>null</code>.
* @param role the name of the Role to retrieve
* @return a Role Principal, or <code>null</code>
- * @see org.apache.wiki.auth.Authorizer#initialize(WikiEngine, Properties)
+ * @see org.apache.wiki.auth.Authorizer#initialize(Engine, Properties)
*/
@Override
- public Principal findRole( String role )
- {
- for( Role containerRole : m_containerRoles )
- {
- if ( containerRole.getName().equals( role ) )
- {
+ public Principal findRole( final String role ) {
+ for( final Role containerRole : m_containerRoles ) {
+ if ( containerRole.getName().equals( role ) ) {
return containerRole;
}
}
@@ -266,9 +248,9 @@ public class WebContainerAuthorizer implements WebAuthorizer {
}
// If a constraint is contained in both lists, we must be constrained
- for ( Iterator< Element > c = constraints.iterator(); c.hasNext(); ) {
+ for ( final Iterator< Element > c = constraints.iterator(); c.hasNext(); ) {
final Element constraint = c.next();
- for ( Iterator< Element > r = roles.iterator(); r.hasNext(); ) {
+ for ( final Iterator< Element > r = roles.iterator(); r.hasNext(); ) {
final Element roleConstraint = r.next();
if ( constraint.equals( roleConstraint ) ) {
return true;
@@ -362,14 +344,14 @@ public class WebContainerAuthorizer implements WebAuthorizer {
*/
protected Document getWebXml() throws JDOMException, IOException
{
- URL url;
- SAXBuilder builder = new SAXBuilder();
+ final URL url;
+ final SAXBuilder builder = new SAXBuilder();
builder.setXMLReaderFactory( XMLReaders.NONVALIDATING );
builder.setEntityResolver( new LocalEntityResolver() );
Document doc = null;
if ( m_engine.getServletContext() == null )
{
- ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
+ final ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
url = cl.getResource( "WEB-INF/web.xml" );
if( url != null )
log.info( "Examining " + url.toExternalForm() );
@@ -414,13 +396,13 @@ public class WebContainerAuthorizer implements WebAuthorizer {
* @throws IOException if the resource cannot be opened
*/
@Override
- public InputSource resolveEntity( String publicId, String systemId ) throws SAXException, IOException
+ public InputSource resolveEntity( final String publicId, final String systemId ) throws SAXException, IOException
{
- String file = systemId.substring( systemId.lastIndexOf( '/' ) + 1 );
- URL url;
+ final String file = systemId.substring( systemId.lastIndexOf( '/' ) + 1 );
+ final URL url;
if ( m_engine.getServletContext() == null )
{
- ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
+ final ClassLoader cl = WebContainerAuthorizer.class.getClassLoader();
url = cl.getResource( "WEB-INF/dtd/" + file );
}
else
@@ -430,7 +412,7 @@ public class WebContainerAuthorizer implements WebAuthorizer {
if( url != null )
{
- InputSource is = new InputSource( url.openStream() );
+ final InputSource is = new InputSource( url.openStream() );
log.debug( "Resolved systemID=" + systemId + " using local file " + url );
return is;
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java
index 153a2d6..6b0ec1d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/authorize/XMLGroupDatabase.java
@@ -20,7 +20,7 @@ package org.apache.wiki.auth.authorize;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.log4j.Logger;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
import org.apache.wiki.auth.NoSuchPrincipalException;
import org.apache.wiki.auth.WikiPrincipal;
@@ -73,14 +73,11 @@ import java.util.concurrent.ConcurrentHashMap;
* </code></blockquote>
* @since 2.4.17
*/
-public class XMLGroupDatabase implements GroupDatabase
-{
- protected static final Logger log = Logger.getLogger( XMLGroupDatabase.class );
+public class XMLGroupDatabase implements GroupDatabase {
- /**
- * The jspwiki.properties property specifying the file system location of
- * the group database.
- */
+ private static final Logger log = Logger.getLogger( XMLGroupDatabase.class );
+
+ /** The jspwiki.properties property specifying the file system location of the group database. */
public static final String PROP_DATABASE = "jspwiki.xmlGroupDatabaseFile";
private static final String DEFAULT_DATABASE = "groupdatabase.xml";
@@ -109,7 +106,7 @@ public class XMLGroupDatabase implements GroupDatabase
private File m_file = null;
- private WikiEngine m_engine = null;
+ private Engine m_engine = null;
private Map<String, Group> m_groups = new ConcurrentHashMap<>();
@@ -124,10 +121,10 @@ public class XMLGroupDatabase implements GroupDatabase
* the commit did not succeed
*/
@Override
- public void delete( Group group ) throws WikiSecurityException
+ public void delete( final Group group ) throws WikiSecurityException
{
- String index = group.getName();
- boolean exists = m_groups.containsKey( index );
+ final String index = group.getName();
+ final boolean exists = m_groups.containsKey( index );
if ( !exists )
{
@@ -153,7 +150,7 @@ public class XMLGroupDatabase implements GroupDatabase
public Group[] groups() throws WikiSecurityException
{
buildDOM();
- Collection<Group> groups = m_groups.values();
+ final Collection<Group> groups = m_groups.values();
return groups.toArray( new Group[groups.size()] );
}
@@ -168,7 +165,7 @@ public class XMLGroupDatabase implements GroupDatabase
* @throws WikiSecurityException if the database could not be initialized successfully
*/
@Override
- public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException
+ public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException
{
m_engine = engine;
@@ -184,7 +181,7 @@ public class XMLGroupDatabase implements GroupDatabase
}
// Get database file location
- String file = TextUtil.getStringProperty(props, PROP_DATABASE , defaultFile.getAbsolutePath());
+ final String file = TextUtil.getStringProperty(props, PROP_DATABASE , defaultFile.getAbsolutePath());
if ( file == null )
{
log.warn( "XML group database property " + PROP_DATABASE + " not found; trying " + defaultFile );
@@ -213,16 +210,16 @@ public class XMLGroupDatabase implements GroupDatabase
* @throws WikiSecurityException if the Group could not be saved successfully
*/
@Override
- public void save( Group group, Principal modifier ) throws WikiSecurityException {
+ public void save( final Group group, final Principal modifier ) throws WikiSecurityException {
if ( group == null || modifier == null ) {
throw new IllegalArgumentException( "Group or modifier cannot be null." );
}
checkForRefresh();
- String index = group.getName();
- boolean isNew = !( m_groups.containsKey( index ) );
- Date modDate = new Date( System.currentTimeMillis() );
+ final String index = group.getName();
+ final boolean isNew = !( m_groups.containsKey( index ) );
+ final Date modDate = new Date( System.currentTimeMillis() );
if ( isNew )
{
// If new, set created info
diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml
index ff4ad5a..b419955 100644
--- a/jspwiki-main/src/main/resources/ini/classmappings.xml
+++ b/jspwiki-main/src/main/resources/ini/classmappings.xml
@@ -73,7 +73,7 @@
</mapping>
<mapping>
<requestedClass>org.apache.wiki.auth.AuthorizationManager</requestedClass>
- <mappedClass>org.apache.wiki.auth.AuthorizationManager</mappedClass>
+ <mappedClass>org.apache.wiki.auth.DefaultAuthorizationManager</mappedClass>
</mapping>
<mapping>
<requestedClass>org.apache.wiki.auth.UserManager</requestedClass>
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java
index 803f1fd..0c1a106 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/AuthenticationManagerTest.java
@@ -17,16 +17,12 @@
under the License.
*/
package org.apache.wiki.auth;
-import java.security.Principal;
-import java.util.Map;
-import java.util.Properties;
-
-import javax.servlet.http.HttpServletRequest;
import org.apache.wiki.TestEngine;
import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
import org.apache.wiki.WikiSessionTest;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.auth.authorize.Group;
import org.apache.wiki.auth.authorize.GroupManager;
import org.apache.wiki.auth.authorize.Role;
@@ -36,45 +32,42 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
+import java.util.Map;
+import java.util.Properties;
+
/**
* Tests the AuthorizationManager class.
*
*/
-public class AuthenticationManagerTest
-{
- public static class DummyAuthorizer implements WebAuthorizer
- {
+public class AuthenticationManagerTest {
+
+ public static class DummyAuthorizer implements WebAuthorizer {
private static Principal[] m_roles = new Principal[] { new Role( "ContainerRole" ), new Role( "AuthorizerRole" ),
new Role( "DummyRole" ) };
- public Principal findRole( String role )
- {
- for( Principal principal : m_roles )
- {
- if( principal.getName().equals( role ) )
- {
+ @Override public Principal findRole( final String role ) {
+ for( final Principal principal : m_roles ) {
+ if( principal.getName().equals( role ) ) {
return principal;
}
}
return null;
}
- public Principal[] getRoles()
- {
+ @Override public Principal[] getRoles() {
return m_roles;
}
- public void initialize( WikiEngine engine, Properties props ) throws WikiSecurityException
- {
+ @Override public void initialize( final Engine engine, final Properties props ) throws WikiSecurityException {
}
- public boolean isUserInRole( HttpServletRequest request, Principal role )
- {
+ @Override public boolean isUserInRole( final HttpServletRequest request, final Principal role ) {
return request != null && "ContainerRole".equals( role.getName() );
}
- public boolean isUserInRole( WikiSession session, Principal role )
- {
+ @Override public boolean isUserInRole( final WikiSession session, final Principal role ) {
return session != null && "AuthorizerRole".equals( role.getName() );
}
}
@@ -88,9 +81,8 @@ public class AuthenticationManagerTest
private WikiSession m_session;
@BeforeEach
- public void setUp() throws Exception
- {
- Properties props = TestEngine.getTestProperties();
+ public void setUp() throws Exception {
+ final Properties props = TestEngine.getTestProperties();
m_engine = new TestEngine( props );
m_auth = m_engine.getAuthenticationManager();
m_groupMgr = m_engine.getGroupManager();
@@ -98,15 +90,13 @@ public class AuthenticationManagerTest
}
/**
- * Tests a dummy WebAuthorizer that is guaranteed to return true for one
- * role for each of the two <code>isInRole</code> methods.
+ * Tests a dummy WebAuthorizer that is guaranteed to return true for one role for each of the two <code>isInRole</code> methods.
*
* @throws Exception
*/
@Test
- public void testCustomAuthorizer() throws Exception
- {
- Properties props = TestEngine.getTestProperties();
+ public void testCustomAuthorizer() throws Exception {
+ final Properties props = TestEngine.getTestProperties();
props.put( AuthorizationManager.PROP_AUTHORIZER, "org.apache.wiki.auth.AuthenticationManagerTest$DummyAuthorizer" );
m_engine = new TestEngine( props );
@@ -134,24 +124,22 @@ public class AuthenticationManagerTest
}
@Test
- public void testCustomJAASLoginModule() throws Exception
- {
- Properties props = TestEngine.getTestProperties();
+ public void testCustomJAASLoginModule() throws Exception {
+ final Properties props = TestEngine.getTestProperties();
// Supply a custom LoginModule class
props.put( "jspwiki.loginModule.class", "org.apache.wiki.auth.login.CookieAssertionLoginModule" );
// Init the engine and verify that we initialized with a custom auth
// login module
- WikiEngine engine = new TestEngine( props );
- AuthenticationManager authMgr = engine.getAuthenticationManager();
+ final WikiEngine engine = new TestEngine( props );
+ final DefaultAuthenticationManager authMgr = ( DefaultAuthenticationManager )engine.getAuthenticationManager();
Assertions.assertEquals( CookieAssertionLoginModule.class, authMgr.m_loginModuleClass );
}
@Test
- public void testCustomJAASLoginModuleOptions() throws Exception
- {
- Properties props = TestEngine.getTestProperties();
+ public void testCustomJAASLoginModuleOptions() throws Exception {
+ final Properties props = TestEngine.getTestProperties();
// Supply a custom LoginModule options
props.put( "jspwiki.loginModule.options.key1", "value1" );
@@ -160,9 +148,9 @@ public class AuthenticationManagerTest
// Init the engine and verify that we initialized with the correct
// options
- WikiEngine engine = new TestEngine( props );
- AuthenticationManager authMgr = engine.getAuthenticationManager();
- Map<String, String> options = authMgr.m_loginModuleOptions;
+ final WikiEngine engine = new TestEngine( props );
+ final DefaultAuthenticationManager authMgr = ( DefaultAuthenticationManager )engine.getAuthenticationManager();
+ final Map<String, String> options = authMgr.m_loginModuleOptions;
Assertions.assertEquals( 3, options.size() );
Assertions.assertTrue( options.containsKey( "key1" ) );
Assertions.assertTrue( options.containsKey( "key2" ) );
@@ -173,8 +161,7 @@ public class AuthenticationManagerTest
}
@Test
- public void testIsUserPrincipal()
- {
+ public void testIsUserPrincipal() {
Assertions.assertTrue( AuthenticationManager.isUserPrincipal( new WikiPrincipal( "Foo" ) ) );
Assertions.assertFalse( AuthenticationManager.isUserPrincipal( new GroupPrincipal( "Group1" ) ) );
Assertions.assertFalse( AuthenticationManager.isUserPrincipal( new Role( "Role1" ) ) );
@@ -182,9 +169,8 @@ public class AuthenticationManagerTest
}
@Test
- public void testLoginCustom() throws Exception
- {
- WikiSession session = WikiSessionTest.authenticatedSession( m_engine, Users.JANNE, Users.JANNE_PASS );
+ public void testLoginCustom() throws Exception {
+ final WikiSession session = WikiSessionTest.authenticatedSession( m_engine, Users.JANNE, Users.JANNE_PASS );
Assertions.assertTrue( session.hasPrincipal( Role.ALL ) );
Assertions.assertTrue( session.hasPrincipal( Role.AUTHENTICATED ) );
Assertions.assertTrue( session.hasPrincipal( new WikiPrincipal( Users.JANNE, WikiPrincipal.LOGIN_NAME ) ) );
@@ -193,43 +179,38 @@ public class AuthenticationManagerTest
}
@Test
- public void testLoginCustomWithGroup() throws Exception
- {
- // Flush any pre-existing groups (left over from previous Assertions.failures,
- // perhaps)
- try
- {
+ public void testLoginCustomWithGroup() throws Exception {
+ // Flush any pre-existing groups (left over from previous Assertions.failures, perhaps)
+ try {
m_groupMgr.removeGroup( "Test1" );
m_groupMgr.removeGroup( "Test2" );
- }
- catch( NoSuchPrincipalException e )
- {
+ } catch( final NoSuchPrincipalException e ) {
}
// Log in 'janne' and verify there are 5 principals in the subject
// (ALL, AUTHENTICATED, login, fullname, wikiname Principals)
- WikiSession session = WikiSession.guestSession( m_engine );
+ final WikiSession session = WikiSession.guestSession( m_engine );
m_auth.login( session, null, Users.JANNE, Users.JANNE_PASS );
Assertions.assertEquals( 3, session.getPrincipals().length );
Assertions.assertEquals( 2, session.getRoles().length );
Assertions.assertTrue( session.hasPrincipal( new WikiPrincipal( "JanneJalkanen", WikiPrincipal.WIKI_NAME ) ) );
// Listen for any manager group-add events
- GroupManager manager = m_engine.getGroupManager();
- SecurityEventTrap trap = new SecurityEventTrap();
+ final GroupManager manager = m_engine.getGroupManager();
+ final SecurityEventTrap trap = new SecurityEventTrap();
manager.addWikiEventListener( trap );
// Create two groups; one with Janne in it, and one without
Group groupTest1 = m_groupMgr.parseGroup( "Test1", "JanneJalkanen \n Bob \n Charlie", true );
m_groupMgr.setGroup( m_session, groupTest1 );
groupTest1 = m_groupMgr.getGroup( "Test1" );
- Principal principalTest1 = groupTest1.getPrincipal();
+ final Principal principalTest1 = groupTest1.getPrincipal();
Group groupTest2 = m_groupMgr.parseGroup( "Test2", "Alice \n Bob \n Charlie", true );
m_groupMgr.setGroup( m_session, groupTest2 );
groupTest2 = m_groupMgr.getGroup( "Test2" );
- Principal principalTest2 = groupTest2.getPrincipal();
+ final Principal principalTest2 = groupTest2.getPrincipal();
// We should see two security events (one for each group create)
// We should also see a GroupPrincipal for group Test1, but not Test2
diff --git a/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java b/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java
index c0761e9..5b272e7 100644
--- a/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java
+++ b/jspwiki-main/src/test/java/org/apache/wiki/auth/TestAuthorizer.java
@@ -18,24 +18,23 @@
*/
package org.apache.wiki.auth;
-import java.security.Principal;
-import java.util.Properties;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.auth.authorize.Role;
import org.apache.wiki.auth.authorize.WebAuthorizer;
+import javax.servlet.http.HttpServletRequest;
+import java.security.Principal;
+import java.util.Properties;
+
/**
- * A very fast authorizer that does almost nothing. The WebContainerAuthorizer module
- * is very slow, as it parses the web.xml each time, so we use this for most of
- * the different tests.
+ * A very fast authorizer that does almost nothing. The WebContainerAuthorizer module is very slow, as it parses the web.xml each time,
+ * so we use this for most of the different tests.
+ *
* @since 2.3
*/
-public class TestAuthorizer implements WebAuthorizer
-{
+public class TestAuthorizer implements WebAuthorizer {
+
private Role[] m_roles = new Role[]{
new Role( "Admin" ),
Role.AUTHENTICATED,
@@ -48,33 +47,28 @@ public class TestAuthorizer implements WebAuthorizer
super();
}
- public Principal findRole( String role )
+ @Override public Principal findRole( final String role )
{
return null;
}
- public void initialize( WikiEngine engine, Properties props )
- {
+ @Override public void initialize( final Engine engine, final Properties props ) {
}
/**
- * Returns an array of Principal objects containing five elements:
- * Role "Admin", Role.AUTHENTICATED, Role "IT", Role "Finance" and
+ * Returns an array of Principal objects containing five elements: Role "Admin", Role.AUTHENTICATED, Role "IT", Role "Finance" and
* Role "Engineering."
*/
- public Principal[] getRoles()
+ @Override public Principal[] getRoles()
{
return m_roles;
}
/**
- * Returns <code>true</code> if the WikiSession's Subject contains
- * a particular role principal.
+ * Returns <code>true</code> if the WikiSession's Subject contains a particular role principal.
*/
- public boolean isUserInRole( WikiSession session, Principal role )
- {
- if ( session == null || role == null )
- {
+ @Override public boolean isUserInRole( final WikiSession session, final Principal role ) {
+ if ( session == null || role == null ) {
return false;
}
@@ -87,7 +81,7 @@ public class TestAuthorizer implements WebAuthorizer
* {@link javax.servlet.http.HttpServletRequest#isUserInRole(String)}.
* @see org.apache.wiki.auth.authorize.WebAuthorizer#isUserInRole(javax.servlet.http.HttpServletRequest, java.security.Principal)
*/
- public boolean isUserInRole( HttpServletRequest request, Principal role )
+ @Override public boolean isUserInRole( final HttpServletRequest request, final Principal role )
{
return request.isUserInRole( role.getName() );
}