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:57 UTC
[jspwiki] 15/38: JSPWIKI-120: rename + extract interface from
UserManager
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 11a0ada483246feb26f70a563c5a53aa29e0218e
Author: juanpablo <ju...@apache.org>
AuthorDate: Thu Feb 20 20:16:19 2020 +0100
JSPWIKI-120: rename + extract interface from UserManager
---
.../{UserManager.java => DefaultUserManager.java} | 383 +++--------
.../java/org/apache/wiki/auth/UserManager.java | 712 ++-------------------
.../wiki/auth/user/AbstractUserDatabase.java | 169 ++---
.../apache/wiki/auth/user/JDBCUserDatabase.java | 143 ++---
.../org/apache/wiki/auth/user/UserDatabase.java | 172 ++---
.../org/apache/wiki/auth/user/XMLUserDatabase.java | 287 ++++-----
.../org/apache/wiki/tasks/DefaultTasksManager.java | 10 +-
.../java/org/apache/wiki/tasks/TasksManager.java | 4 +-
.../wiki/tasks/auth/SaveUserProfileTask.java | 18 +-
.../org/apache/wiki/workflow/WorkflowBuilder.java | 89 +--
.../src/main/resources/ini/classmappings.xml | 2 +-
11 files changed, 546 insertions(+), 1443 deletions(-)
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
similarity index 59%
copy from jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
copy to jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
index 5d51ec4..c2b13af 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/DefaultUserManager.java
@@ -21,11 +21,11 @@ package org.apache.wiki.auth;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
import org.apache.wiki.ajax.AjaxUtil;
import org.apache.wiki.ajax.WikiAjaxDispatcherServlet;
import org.apache.wiki.ajax.WikiAjaxServlet;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.engine.FilterManager;
import org.apache.wiki.api.exceptions.NoRequiredPropertyException;
import org.apache.wiki.api.exceptions.WikiException;
@@ -41,7 +41,9 @@ import org.apache.wiki.event.WikiEventManager;
import org.apache.wiki.event.WikiSecurityEvent;
import org.apache.wiki.filters.SpamFilter;
import org.apache.wiki.i18n.InternationalizationManager;
+import org.apache.wiki.pages.PageManager;
import org.apache.wiki.preferences.Preferences;
+import org.apache.wiki.tasks.TasksManager;
import org.apache.wiki.ui.InputValidator;
import org.apache.wiki.util.ClassUtil;
import org.apache.wiki.util.TextUtil;
@@ -69,10 +71,11 @@ import java.util.WeakHashMap;
/**
- * Provides a facade for obtaining user information.
+ * Default implementation for {@link UserManager}.
+ *
* @since 2.3
*/
-public class UserManager {
+public class DefaultUserManager implements UserManager {
private static final String USERDATABASE_PACKAGE = "org.apache.wiki.auth.user";
private static final String SESSION_MESSAGES = "profile";
@@ -82,47 +85,31 @@ public class UserManager {
private static final String PARAM_LOGINNAME = "loginname";
private static final String UNKNOWN_CLASS = "<unknown>";
- private WikiEngine m_engine;
+ private Engine m_engine;
- private static final Logger log = Logger.getLogger(UserManager.class);
-
- /** Message key for the "save profile" message. */
- private static final String PROP_DATABASE = "jspwiki.userdatabase";
-
- public static final String JSON_USERS = "users";
-
- // private static final String PROP_ACLMANAGER = "jspwiki.aclManager";
+ private static final Logger log = Logger.getLogger( DefaultUserManager.class);
/** Associates wiki sessions with profiles */
- private final Map<WikiSession,UserProfile> m_profiles = new WeakHashMap<>();
+ private final Map< WikiSession, UserProfile > m_profiles = new WeakHashMap<>();
/** The user database loads, manages and persists user identities */
- private UserDatabase m_database;
+ private UserDatabase m_database;
- /**
- * Initializes the engine for its nefarious purposes.
- * @param engine the current wiki engine
- * @param props the wiki engine initialization properties
- */
- public void initialize( final WikiEngine engine, final Properties props ) {
+ /** {@inheritDoc} */
+ @Override
+ public void initialize( final Engine engine, final Properties props ) {
m_engine = engine;
// Attach the PageManager as a listener
// TODO: it would be better if we did this in PageManager directly
- addWikiEventListener( engine.getPageManager() );
+ addWikiEventListener( engine.getManager( PageManager.class ) );
//TODO: Replace with custom annotations. See JSPWIKI-566
WikiAjaxDispatcherServlet.registerServlet( JSON_USERS, new JSONUserModule(this), new AllPermission(null));
}
- /**
- * Returns the UserDatabase employed by this WikiEngine. The UserDatabase is lazily initialized by this method, if it does
- * not exist yet. If the initialization fails, this method will use the inner class DummyUserDatabase as a default (which
- * is enough to get JSPWiki running).
- *
- * @return the dummy user database
- * @since 2.3
- */
+ /** {@inheritDoc} */
+ @Override
public UserDatabase getUserDatabase() {
if( m_database != null ) {
return m_database;
@@ -158,29 +145,8 @@ public class UserManager {
return m_database;
}
- /**
- * <p>Retrieves the {@link org.apache.wiki.auth.user.UserProfile}for the
- * user in a wiki session. If the user is authenticated, the UserProfile
- * returned will be the one stored in the user database; if one does not
- * exist, a new one will be initialized and returned. If the user is
- * anonymous or asserted, the UserProfile will <i>always</i> be newly
- * initialized to prevent spoofing of identities. If a UserProfile needs to
- * be initialized, its
- * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method will
- * return <code>true</code>, and its login name will will be set
- * automatically if the user is authenticated. Note that this method does
- * not modify the retrieved (or newly created) profile otherwise; other
- * fields in the user profile may be <code>null</code>.</p>
- * <p>If a new UserProfile was created, but its
- * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method returns
- * <code>false</code>, this method throws an {@link IllegalStateException}.
- * This is meant as a quality check for UserDatabase providers;
- * it should only be thrown if the implementation is faulty.</p>
- * @param session the wiki session, which may not be <code>null</code>
- * @return the user's profile, which will be newly initialized if the user
- * is anonymous or asserted, or if the user cannot be found in the user
- * database
- */
+ /** {@inheritDoc} */
+ @Override
public UserProfile getUserProfile( final WikiSession session ) {
// Look up cached user profile
UserProfile profile = m_profiles.get( session );
@@ -211,48 +177,12 @@ public class UserManager {
return profile;
}
- /**
- * <p>
- * Saves the {@link org.apache.wiki.auth.user.UserProfile}for the user in
- * a wiki session. This method verifies that a user profile to be saved
- * doesn't collide with existing profiles; that is, the login name
- * or full name is already used by another profile. If the profile
- * collides, a <code>DuplicateUserException</code> is thrown. After saving
- * the profile, the user database changes are committed, and the user's
- * credential set is refreshed; if custom authentication is used, this means
- * the user will be automatically be logged in.
- * </p>
- * <p>
- * When the user's profile is saved successfully, this method fires a
- * {@link WikiSecurityEvent#PROFILE_SAVE} event with the WikiSession as the
- * source and the UserProfile as target. For existing profiles, if the
- * user's full name changes, this method also fires a "name changed"
- * event ({@link WikiSecurityEvent#PROFILE_NAME_CHANGED}) with the
- * WikiSession as the source and an array containing the old and new
- * UserProfiles, respectively. The <code>NAME_CHANGED</code> event allows
- * the GroupManager and PageManager can change group memberships and
- * ACLs if needed.
- * </p>
- * <p>
- * Note that WikiSessions normally attach event listeners to the
- * UserManager, so changes to the profile will automatically cause the
- * correct Principals to be reloaded into the current WikiSession's Subject.
- * </p>
- * @param session the wiki session, which may not be <code>null</code>
- * @param profile the user profile, which may not be <code>null</code>
- * @throws DuplicateUserException if the proposed profile's login name or full name collides with another
- * @throws WikiException if the save fails for some reason. If the current user does not have
- * permission to save the profile, this will be a {@link org.apache.wiki.auth.WikiSecurityException};
- * if if the user profile must be approved before it can be saved, it will be a
- * {@link org.apache.wiki.workflow.DecisionRequiredException}. All other WikiException
- * indicate a condition that is not normal is probably due to mis-configuration
- */
- public void setUserProfile( WikiSession session, UserProfile profile ) throws DuplicateUserException, WikiException
- {
+ /** {@inheritDoc} */
+ @Override
+ public void setUserProfile( final WikiSession session, final UserProfile profile ) throws DuplicateUserException, WikiException {
// Verify user is allowed to save profile!
final Permission p = new WikiPermission( m_engine.getApplicationName(), WikiPermission.EDIT_PROFILE_ACTION );
- if ( !m_engine.getAuthorizationManager().checkPermission( session, p ) )
- {
+ if ( !m_engine.getManager( AuthorizationManager.class ).checkPermission( session, p ) ) {
throw new WikiSecurityException( "You are not allowed to save wiki profiles." );
}
@@ -265,139 +195,97 @@ public class UserManager {
!( oldProfile.getFullname().equals( profile.getFullname() ) &&
oldProfile.getLoginName().equals( profile.getLoginName() ) );
UserProfile otherProfile;
- try
- {
+ try {
otherProfile = getUserDatabase().findByLoginName( profile.getLoginName() );
- if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
- {
+ if( otherProfile != null && !otherProfile.equals( oldProfile ) ) {
throw new DuplicateUserException( "security.error.login.taken", profile.getLoginName() );
}
+ } catch( final NoSuchPrincipalException e ) {
}
- catch( final NoSuchPrincipalException e )
- {
- }
- try
- {
+ try {
otherProfile = getUserDatabase().findByFullName( profile.getFullname() );
- if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
- {
+ if( otherProfile != null && !otherProfile.equals( oldProfile ) ) {
throw new DuplicateUserException( "security.error.fullname.taken", profile.getFullname() );
}
- }
- catch( final NoSuchPrincipalException e )
- {
+ } catch( final NoSuchPrincipalException e ) {
}
// For new accounts, create approval workflow for user profile save.
- if ( newProfile && oldProfile != null && oldProfile.isNew() )
- {
- startUserProfileCreationWorkflow(session, profile);
+ if( newProfile && oldProfile != null && oldProfile.isNew() ) {
+ startUserProfileCreationWorkflow( session, profile );
// If the profile doesn't need approval, then just log the user in
- try
- {
- final AuthenticationManager mgr = m_engine.getAuthenticationManager();
- if ( newProfile && !mgr.isContainerAuthenticated() )
- {
+ try {
+ final AuthenticationManager mgr = m_engine.getManager( AuthenticationManager.class );
+ if( !mgr.isContainerAuthenticated() ) {
mgr.login( session, null, profile.getLoginName(), profile.getPassword() );
}
- }
- catch ( final WikiException e )
- {
+ } catch( final WikiException e ) {
throw new WikiSecurityException( e.getMessage(), e );
}
// Alert all listeners that the profile changed...
// ...this will cause credentials to be reloaded in the wiki session
fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
- }
-
- // For existing accounts, just save the profile
- else
- {
+ } else { // For existing accounts, just save the profile
// If login name changed, rename it first
- if ( nameChanged && oldProfile != null && !oldProfile.getLoginName().equals( profile.getLoginName() ) )
- {
+ if( nameChanged && !oldProfile.getLoginName().equals( profile.getLoginName() ) ) {
getUserDatabase().rename( oldProfile.getLoginName(), profile.getLoginName() );
}
// Now, save the profile (userdatabase will take care of timestamps for us)
getUserDatabase().save( profile );
- if ( nameChanged )
- {
+ if( nameChanged ) {
// Fire an event if the login name or full name changed
final UserProfile[] profiles = new UserProfile[] { oldProfile, profile };
fireEvent( WikiSecurityEvent.PROFILE_NAME_CHANGED, session, profiles );
- }
- else
- {
+ } else {
// Fire an event that says we have new a new profile (new principals)
fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
}
}
}
+ /** {@inheritDoc} */
+ @Override
public void startUserProfileCreationWorkflow( final WikiSession session, final UserProfile profile ) throws WikiException {
final WorkflowBuilder builder = WorkflowBuilder.getBuilder( m_engine );
final Principal submitter = session.getUserPrincipal();
- final Step completionTask = m_engine.getTasksManager().buildSaveUserProfileTask( m_engine, session.getLocale() );
+ final Step completionTask = m_engine.getManager( TasksManager.class ).buildSaveUserProfileTask( m_engine, session.getLocale() );
// Add user profile attribute as Facts for the approver (if required)
final boolean hasEmail = profile.getEmail() != null;
- final Fact[] facts = new Fact[ hasEmail ? 4 : 3];
- facts[0] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() );
- facts[1] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() );
- facts[2] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, submitter.getName() );
- if ( hasEmail )
- {
- facts[3] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_EMAIL, profile.getEmail() );
- }
- final Workflow workflow = builder.buildApprovalWorkflow( submitter,
- WorkflowManager.WF_UP_CREATE_SAVE_APPROVER,
- null,
- WorkflowManager.WF_UP_CREATE_SAVE_DECISION_MESSAGE_KEY,
- facts,
- completionTask,
+ final Fact[] facts = new Fact[ hasEmail ? 4 : 3 ];
+ facts[ 0 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() );
+ facts[ 1 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() );
+ facts[ 2 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, submitter.getName() );
+ if ( hasEmail ) {
+ facts[ 3 ] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_EMAIL, profile.getEmail() );
+ }
+ final Workflow workflow = builder.buildApprovalWorkflow( submitter,
+ WorkflowManager.WF_UP_CREATE_SAVE_APPROVER,
+ null,
+ WorkflowManager.WF_UP_CREATE_SAVE_DECISION_MESSAGE_KEY,
+ facts,
+ completionTask,
null );
workflow.setAttribute( WorkflowManager.WF_UP_CREATE_SAVE_ATTR_SAVED_PROFILE, profile );
- m_engine.getWorkflowManager().start(workflow);
+ m_engine.getManager( WorkflowManager.class ).start( workflow );
final boolean approvalRequired = workflow.getCurrentStep() instanceof Decision;
// If the profile requires approval, redirect user to message page
- if ( approvalRequired )
- {
+ if ( approvalRequired ) {
throw new DecisionRequiredException( "This profile must be approved before it becomes active" );
}
}
- /**
- * <p> Extracts user profile parameters from the HTTP request and populates
- * a UserProfile with them. The UserProfile will either be a copy of the
- * user's existing profile (if one can be found), or a new profile (if not).
- * The rules for populating the profile as as follows: </p> <ul> <li>If the
- * <code>email</code> or <code>password</code> parameter values differ
- * from those in the existing profile, the passed parameters override the
- * old values.</li> <li>For new profiles, the user-supplied
- * <code>fullname</code> parameter is always
- * used; for existing profiles the existing value is used, and whatever
- * value the user supplied is discarded. The wiki name is automatically
- * computed by taking the full name and extracting all whitespace.</li>
- * <li>In all cases, the
- * created/last modified timestamps of the user's existing or new profile
- * always override whatever values the user supplied.</li> <li>If
- * container authentication is used, the login name property of the profile
- * is set to the name of
- * {@link org.apache.wiki.WikiSession#getLoginPrincipal()}. Otherwise,
- * the value of the <code>loginname</code> parameter is used.</li> </ul>
- * @param context the current wiki context
- * @return a new, populated user profile
- */
- public UserProfile parseProfile( WikiContext context )
- {
+ /** {@inheritDoc} */
+ @Override
+ public UserProfile parseProfile( final WikiContext context ) {
// Retrieve the user's profile (may have been previously cached)
final UserProfile profile = getUserProfile( context.getWikiSession() );
final HttpServletRequest request = context.getHttpRequest();
@@ -414,9 +302,7 @@ public class UserManager {
// A special case if we have container authentication
// If authenticated, login name is always taken from container
- if ( m_engine.getAuthenticationManager().isContainerAuthenticated() &&
- context.getWikiSession().isAuthenticated() )
- {
+ if ( m_engine.getManager( AuthenticationManager.class ).isContainerAuthenticated() && context.getWikiSession().isAuthenticated() ) {
loginName = context.getWikiSession().getLoginPrincipal().getName();
}
@@ -428,36 +314,20 @@ public class UserManager {
return profile;
}
- /**
- * Validates a user profile, and appends any errors to the session errors
- * list. If the profile is new, the password will be checked to make sure it
- * isn't null. Otherwise, the password is checked for length and that it
- * matches the value of the 'password2' HTTP parameter. Note that we have a
- * special case when container-managed authentication is used and the user
- * is not authenticated; this will always cause validation to fail. Any
- * validation errors are added to the wiki session's messages collection
- * (see {@link WikiSession#getMessages()}.
- * @param context the current wiki context
- * @param profile the supplied UserProfile
- */
- public void validateProfile( WikiContext context, UserProfile profile )
- {
+ /** {@inheritDoc} */
+ @Override
+ public void validateProfile( final WikiContext context, final UserProfile profile ) {
final boolean isNew = profile.isNew();
final WikiSession session = context.getWikiSession();
final InputValidator validator = new InputValidator( SESSION_MESSAGES, context );
final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
- //
// Query the SpamFilter first
- //
- final FilterManager fm = m_engine.getFilterManager();
- final List<PageFilter> ls = fm.getFilterList();
- for( final PageFilter pf : ls )
- {
- if( pf instanceof SpamFilter )
- {
- if( ((SpamFilter)pf).isValidUserProfile( context, profile ) == false )
- {
+ final FilterManager fm = m_engine.getManager( FilterManager.class );
+ final List< PageFilter > ls = fm.getFilterList();
+ for( final PageFilter pf : ls ) {
+ if( pf instanceof SpamFilter ) {
+ if( !( ( SpamFilter )pf ).isValidUserProfile( context, profile ) ) {
session.addMessage( SESSION_MESSAGES, "Invalid userprofile" );
return;
}
@@ -466,9 +336,8 @@ public class UserManager {
}
// If container-managed auth and user not logged in, throw an error
- if ( m_engine.getAuthenticationManager().isContainerAuthenticated()
- && !context.getWikiSession().isAuthenticated() )
- {
+ if ( m_engine.getManager( AuthenticationManager.class ).isContainerAuthenticated()
+ && !context.getWikiSession().isAuthenticated() ) {
session.addMessage( SESSION_MESSAGES, rb.getString("security.error.createprofilebeforelogin") );
}
@@ -477,23 +346,17 @@ public class UserManager {
validator.validate( profile.getEmail(), rb.getString("security.user.email"), InputValidator.EMAIL );
// If new profile, passwords must match and can't be null
- if ( !m_engine.getAuthenticationManager().isContainerAuthenticated() )
- {
+ if( !m_engine.getManager( AuthenticationManager.class ).isContainerAuthenticated() ) {
final String password = profile.getPassword();
- if ( password == null )
- {
- if ( isNew )
- {
- session.addMessage( SESSION_MESSAGES, rb.getString("security.error.blankpassword") );
+ if( password == null ) {
+ if( isNew ) {
+ session.addMessage( SESSION_MESSAGES, rb.getString( "security.error.blankpassword" ) );
}
- }
- else
- {
+ } else {
final HttpServletRequest request = context.getHttpRequest();
final String password2 = ( request == null ) ? null : request.getParameter( "password2" );
- if ( !password.equals( password2 ) )
- {
- session.addMessage( SESSION_MESSAGES, rb.getString("security.error.passwordnomatch") );
+ if( !password.equals( password2 ) ) {
+ session.addMessage( SESSION_MESSAGES, rb.getString( "security.error.passwordnomatch" ) );
}
}
}
@@ -504,56 +367,38 @@ public class UserManager {
final String email = profile.getEmail();
// It's illegal to use as a full name someone else's login name
- try
- {
+ try {
otherProfile = getUserDatabase().find( fullName );
- if ( otherProfile != null && !profile.equals( otherProfile ) && !fullName.equals( otherProfile.getFullname() ) )
- {
+ if( otherProfile != null && !profile.equals( otherProfile ) && !fullName.equals( otherProfile.getFullname() ) ) {
final Object[] args = { fullName };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalfullname"), args ) );
+ session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.illegalfullname" ), args ) );
}
- }
- catch ( final NoSuchPrincipalException e)
- { /* It's clean */ }
+ } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
// It's illegal to use as a login name someone else's full name
- try
- {
+ try {
otherProfile = getUserDatabase().find( loginName );
- if ( otherProfile != null && !profile.equals( otherProfile ) && !loginName.equals( otherProfile.getLoginName() ) )
- {
+ if( otherProfile != null && !profile.equals( otherProfile ) && !loginName.equals( otherProfile.getLoginName() ) ) {
final Object[] args = { loginName };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalloginname"), args ) );
+ session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.illegalloginname" ), args ) );
}
- }
- catch ( final NoSuchPrincipalException e)
- { /* It's clean */ }
+ } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
// It's illegal to use multiple accounts with the same email
- try
- {
+ try {
otherProfile = getUserDatabase().findByEmail( email );
- if ( otherProfile != null
- && !profile.getUid().equals(otherProfile.getUid()) // Issue JSPWIKI-1042
- && !profile.equals( otherProfile ) && StringUtils.lowerCase( email ).equals( StringUtils.lowerCase(otherProfile.getEmail() ) ) )
- {
+ if( otherProfile != null && !profile.getUid().equals( otherProfile.getUid() ) // Issue JSPWIKI-1042
+ && !profile.equals( otherProfile ) && StringUtils.lowerCase( email )
+ .equals( StringUtils.lowerCase( otherProfile.getEmail() ) ) ) {
final Object[] args = { email };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.email.taken"), args ) );
+ session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString( "security.error.email.taken" ), args ) );
}
- }
- catch ( final NoSuchPrincipalException e)
- { /* It's clean */ }
+ } catch( final NoSuchPrincipalException e ) { /* It's clean */ }
}
- /**
- * A helper method for returning all of the known WikiNames in this system.
- *
- * @return An Array of Principals
- * @throws WikiSecurityException If for reason the names cannot be fetched
- */
- public Principal[] listWikiNames()
- throws WikiSecurityException
- {
+ /** {@inheritDoc} */
+ @Override
+ public Principal[] listWikiNames() throws WikiSecurityException {
return getUserDatabase().getWikiNames();
}
@@ -568,7 +413,7 @@ public class UserManager {
* @param loginName the login name to delete
*/
@Override
- public void deleteByLoginName( String loginName ) {
+ public void deleteByLoginName( final String loginName ) {
// No operation
}
@@ -642,7 +487,7 @@ public class UserManager {
* @param props the properties used to initialize the wiki engine
*/
@Override
- public void initialize(final WikiEngine engine, final Properties props) {
+ public void initialize( final Engine engine, final Properties props ) {
}
/**
@@ -673,8 +518,7 @@ public class UserManager {
* This is a convenience method.
* @param listener the event listener
*/
- public synchronized void addWikiEventListener( WikiEventListener listener )
- {
+ @Override public synchronized void addWikiEventListener( final WikiEventListener listener ) {
WikiEventManager.addWikiEventListener( this, listener );
}
@@ -683,29 +527,11 @@ public class UserManager {
* This is a convenience method.
* @param listener the event listener
*/
- public synchronized void removeWikiEventListener( WikiEventListener listener )
- {
+ @Override public synchronized void removeWikiEventListener( final WikiEventListener listener ) {
WikiEventManager.removeWikiEventListener( this, listener );
}
/**
- * Fires a WikiSecurityEvent of the provided type, Principal and target Object
- * to all registered listeners.
- *
- * @see org.apache.wiki.event.WikiSecurityEvent
- * @param type the event type to be fired
- * @param session the wiki session supporting the event
- * @param profile the user profile (or array of user profiles), which may be <code>null</code>
- */
- protected void fireEvent( int type, WikiSession session, Object profile )
- {
- if ( WikiEventManager.isListening(this) )
- {
- WikiEventManager.fireEvent(this,new WikiSecurityEvent(session,type,profile));
- }
- }
-
- /**
* Implements the JSON API for usermanager.
* <p>
* Even though this gets serialized whenever container shuts down/restarts, this gets reinstalled to the session when JSPWiki starts.
@@ -713,13 +539,13 @@ public class UserManager {
*/
public static final class JSONUserModule implements WikiAjaxServlet {
- private volatile UserManager m_manager;
+ private volatile DefaultUserManager m_manager;
/**
* Create a new JSONUserModule.
* @param mgr Manager
*/
- public JSONUserModule( UserManager mgr )
+ public JSONUserModule( final DefaultUserManager mgr )
{
m_manager = mgr;
}
@@ -730,7 +556,7 @@ public class UserManager {
}
@Override
- public void service(HttpServletRequest req, HttpServletResponse resp, String actionName, List<String> params) throws ServletException, IOException {
+ public void service( final HttpServletRequest req, final HttpServletResponse resp, final String actionName, final List<String> params) throws ServletException, IOException {
try {
if( params.size() < 1 ) {
return;
@@ -753,13 +579,12 @@ public class UserManager {
* @return A UserProfile object
* @throws NoSuchPrincipalException If such a name does not exist.
*/
- public UserProfile getUserInfo( String uid ) throws NoSuchPrincipalException {
+ public UserProfile getUserInfo( final String uid ) throws NoSuchPrincipalException {
if( m_manager != null ) {
- final UserProfile prof = m_manager.getUserDatabase().find( uid );
- return prof;
+ return m_manager.getUserDatabase().find( uid );
}
- throw new IllegalStateException("The manager is offline.");
+ throw new IllegalStateException( "The manager is offline." );
}
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
index 5d51ec4..c59130b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/UserManager.java
@@ -18,102 +18,40 @@
*/
package org.apache.wiki.auth;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.Logger;
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
import org.apache.wiki.WikiSession;
-import org.apache.wiki.ajax.AjaxUtil;
-import org.apache.wiki.ajax.WikiAjaxDispatcherServlet;
-import org.apache.wiki.ajax.WikiAjaxServlet;
-import org.apache.wiki.api.engine.FilterManager;
-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.api.filters.PageFilter;
-import org.apache.wiki.auth.permissions.AllPermission;
-import org.apache.wiki.auth.permissions.WikiPermission;
-import org.apache.wiki.auth.user.AbstractUserDatabase;
import org.apache.wiki.auth.user.DuplicateUserException;
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.filters.SpamFilter;
-import org.apache.wiki.i18n.InternationalizationManager;
-import org.apache.wiki.preferences.Preferences;
-import org.apache.wiki.ui.InputValidator;
-import org.apache.wiki.util.ClassUtil;
-import org.apache.wiki.util.TextUtil;
-import org.apache.wiki.workflow.Decision;
-import org.apache.wiki.workflow.DecisionRequiredException;
-import org.apache.wiki.workflow.Fact;
-import org.apache.wiki.workflow.Step;
-import org.apache.wiki.workflow.Workflow;
-import org.apache.wiki.workflow.WorkflowBuilder;
-import org.apache.wiki.workflow.WorkflowManager;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.security.Permission;
import java.security.Principal;
-import java.text.MessageFormat;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Properties;
-import java.util.ResourceBundle;
-import java.util.WeakHashMap;
/**
* Provides a facade for obtaining user information.
+ *
* @since 2.3
*/
-public class UserManager {
-
- private static final String USERDATABASE_PACKAGE = "org.apache.wiki.auth.user";
- private static final String SESSION_MESSAGES = "profile";
- private static final String PARAM_EMAIL = "email";
- private static final String PARAM_FULLNAME = "fullname";
- private static final String PARAM_PASSWORD = "password";
- private static final String PARAM_LOGINNAME = "loginname";
- private static final String UNKNOWN_CLASS = "<unknown>";
-
- private WikiEngine m_engine;
-
- private static final Logger log = Logger.getLogger(UserManager.class);
+public interface UserManager {
/** Message key for the "save profile" message. */
- private static final String PROP_DATABASE = "jspwiki.userdatabase";
-
- public static final String JSON_USERS = "users";
+ String PROP_DATABASE = "jspwiki.userdatabase";
- // private static final String PROP_ACLMANAGER = "jspwiki.aclManager";
-
- /** Associates wiki sessions with profiles */
- private final Map<WikiSession,UserProfile> m_profiles = new WeakHashMap<>();
-
- /** The user database loads, manages and persists user identities */
- private UserDatabase m_database;
+ String JSON_USERS = "users";
/**
* Initializes the engine for its nefarious purposes.
+ *
* @param engine the current wiki engine
* @param props the wiki engine initialization properties
*/
- public void initialize( final WikiEngine engine, final Properties props ) {
- m_engine = engine;
-
- // Attach the PageManager as a listener
- // TODO: it would be better if we did this in PageManager directly
- addWikiEventListener( engine.getPageManager() );
-
- //TODO: Replace with custom annotations. See JSPWIKI-566
- WikiAjaxDispatcherServlet.registerServlet( JSON_USERS, new JSONUserModule(this), new AllPermission(null));
- }
+ void initialize( final Engine engine, final Properties props );
/**
* Returns the UserDatabase employed by this WikiEngine. The UserDatabase is lazily initialized by this method, if it does
@@ -123,121 +61,44 @@ public class UserManager {
* @return the dummy user database
* @since 2.3
*/
- public UserDatabase getUserDatabase() {
- if( m_database != null ) {
- return m_database;
- }
-
- String dbClassName = UNKNOWN_CLASS;
-
- try {
- dbClassName = TextUtil.getRequiredProperty( m_engine.getWikiProperties(), PROP_DATABASE );
-
- log.info( "Attempting to load user database class " + dbClassName );
- final Class<?> dbClass = ClassUtil.findClass( USERDATABASE_PACKAGE, dbClassName );
- m_database = (UserDatabase) dbClass.newInstance();
- m_database.initialize( m_engine, m_engine.getWikiProperties() );
- log.info("UserDatabase initialized.");
- } catch( final NoSuchElementException | NoRequiredPropertyException e ) {
- log.error( "You have not set the '"+PROP_DATABASE+"'. You need to do this if you want to enable user management by JSPWiki.", e );
- } catch( final ClassNotFoundException e ) {
- log.error( "UserDatabase class " + dbClassName + " cannot be found", e );
- } catch( final InstantiationException e ) {
- log.error( "UserDatabase class " + dbClassName + " cannot be created", e );
- } catch( final IllegalAccessException e ) {
- log.error( "You are not allowed to access this user database class", e );
- } catch( final WikiSecurityException e ) {
- log.error( "Exception initializing user database: " + e.getMessage(), e );
- } finally {
- if( m_database == null ) {
- log.info("I could not create a database object you specified (or didn't specify), so I am falling back to a default.");
- m_database = new DummyUserDatabase();
- }
- }
-
- return m_database;
- }
+ UserDatabase getUserDatabase();
/**
- * <p>Retrieves the {@link org.apache.wiki.auth.user.UserProfile}for the
- * user in a wiki session. If the user is authenticated, the UserProfile
- * returned will be the one stored in the user database; if one does not
- * exist, a new one will be initialized and returned. If the user is
- * anonymous or asserted, the UserProfile will <i>always</i> be newly
- * initialized to prevent spoofing of identities. If a UserProfile needs to
- * be initialized, its
- * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method will
- * return <code>true</code>, and its login name will will be set
- * automatically if the user is authenticated. Note that this method does
- * not modify the retrieved (or newly created) profile otherwise; other
- * fields in the user profile may be <code>null</code>.</p>
- * <p>If a new UserProfile was created, but its
- * {@link org.apache.wiki.auth.user.UserProfile#isNew()} method returns
- * <code>false</code>, this method throws an {@link IllegalStateException}.
- * This is meant as a quality check for UserDatabase providers;
+ * <p>Retrieves the {@link org.apache.wiki.auth.user.UserProfile} for the user in a wiki session. If the user is authenticated, the
+ * UserProfile returned will be the one stored in the user database; if one does not exist, a new one will be initialized and returned.
+ * If the user is anonymous or asserted, the UserProfile will <i>always</i> be newly initialized to prevent spoofing of identities.
+ * If a UserProfile needs to be initialized, its {@link org.apache.wiki.auth.user.UserProfile#isNew()} method will return
+ * <code>true</code>, and its login name will will be set automatically if the user is authenticated. Note that this method does
+ * not modify the retrieved (or newly created) profile otherwise; other fields in the user profile may be <code>null</code>.</p>
+ * <p>If a new UserProfile was created, but its {@link org.apache.wiki.auth.user.UserProfile#isNew()} method returns
+ * <code>false</code>, this method throws an {@link IllegalStateException}. This is meant as a quality check for UserDatabase providers;
* it should only be thrown if the implementation is faulty.</p>
+ *
* @param session the wiki session, which may not be <code>null</code>
- * @return the user's profile, which will be newly initialized if the user
- * is anonymous or asserted, or if the user cannot be found in the user
- * database
+ * @return the user's profile, which will be newly initialized if the user is anonymous or asserted, or if the user cannot be found in
+ * the user database
*/
- public UserProfile getUserProfile( final WikiSession session ) {
- // Look up cached user profile
- UserProfile profile = m_profiles.get( session );
- boolean newProfile = profile == null;
- Principal user = null;
-
- // If user is authenticated, figure out if this is an existing profile
- if ( session.isAuthenticated() ) {
- user = session.getUserPrincipal();
- try {
- profile = getUserDatabase().find( user.getName() );
- newProfile = false;
- } catch( final NoSuchPrincipalException e ) { }
- }
-
- if ( newProfile ) {
- profile = getUserDatabase().newProfile();
- if ( user != null ) {
- profile.setLoginName( user.getName() );
- }
- if ( !profile.isNew() ) {
- throw new IllegalStateException( "New profile should be marked 'new'. Check your UserProfile implementation." );
- }
- }
-
- // Stash the profile for next time
- m_profiles.put( session, profile );
- return profile;
- }
+ UserProfile getUserProfile( WikiSession session );
/**
* <p>
- * Saves the {@link org.apache.wiki.auth.user.UserProfile}for the user in
- * a wiki session. This method verifies that a user profile to be saved
- * doesn't collide with existing profiles; that is, the login name
- * or full name is already used by another profile. If the profile
- * collides, a <code>DuplicateUserException</code> is thrown. After saving
- * the profile, the user database changes are committed, and the user's
- * credential set is refreshed; if custom authentication is used, this means
- * the user will be automatically be logged in.
+ * Saves the {@link org.apache.wiki.auth.user.UserProfile} for the user in a wiki session. This method verifies that a user profile to
+ * be saved doesn't collide with existing profiles; that is, the login name or full name is already used by another profile. If the
+ * profile collides, a <code>DuplicateUserException</code> is thrown. After saving the profile, the user database changes are committed,
+ * and the user's credential set is refreshed; if custom authentication is used, this means the user will be automatically be logged in.
* </p>
* <p>
- * When the user's profile is saved successfully, this method fires a
- * {@link WikiSecurityEvent#PROFILE_SAVE} event with the WikiSession as the
- * source and the UserProfile as target. For existing profiles, if the
- * user's full name changes, this method also fires a "name changed"
- * event ({@link WikiSecurityEvent#PROFILE_NAME_CHANGED}) with the
- * WikiSession as the source and an array containing the old and new
- * UserProfiles, respectively. The <code>NAME_CHANGED</code> event allows
- * the GroupManager and PageManager can change group memberships and
- * ACLs if needed.
+ * When the user's profile is saved successfully, this method fires a {@link WikiSecurityEvent#PROFILE_SAVE} event with the WikiSession
+ * as the source and the UserProfile as target. For existing profiles, if the user's full name changes, this method also fires a
+ * "name changed" event ({@link WikiSecurityEvent#PROFILE_NAME_CHANGED}) with the WikiSession as the source and an array containing
+ * the old and new UserProfiles, respectively. The <code>NAME_CHANGED</code> event allows the GroupManager and PageManager can change
+ * group memberships and ACLs if needed.
* </p>
* <p>
- * Note that WikiSessions normally attach event listeners to the
- * UserManager, so changes to the profile will automatically cause the
+ * Note that WikiSessions normally attach event listeners to the UserManager, so changes to the profile will automatically cause the
* correct Principals to be reloaded into the current WikiSession's Subject.
* </p>
+ *
* @param session the wiki session, which may not be <code>null</code>
* @param profile the user profile, which may not be <code>null</code>
* @throws DuplicateUserException if the proposed profile's login name or full name collides with another
@@ -247,303 +108,42 @@ public class UserManager {
* {@link org.apache.wiki.workflow.DecisionRequiredException}. All other WikiException
* indicate a condition that is not normal is probably due to mis-configuration
*/
- public void setUserProfile( WikiSession session, UserProfile profile ) throws DuplicateUserException, WikiException
- {
- // Verify user is allowed to save profile!
- final Permission p = new WikiPermission( m_engine.getApplicationName(), WikiPermission.EDIT_PROFILE_ACTION );
- if ( !m_engine.getAuthorizationManager().checkPermission( session, p ) )
- {
- throw new WikiSecurityException( "You are not allowed to save wiki profiles." );
- }
+ void setUserProfile( WikiSession session, UserProfile profile ) throws DuplicateUserException, WikiException;
- // Check if profile is new, and see if container allows creation
- final boolean newProfile = profile.isNew();
-
- // Check if another user profile already has the fullname or loginname
- final UserProfile oldProfile = getUserProfile( session );
- final boolean nameChanged = ( oldProfile != null && oldProfile.getFullname() != null ) &&
- !( oldProfile.getFullname().equals( profile.getFullname() ) &&
- oldProfile.getLoginName().equals( profile.getLoginName() ) );
- UserProfile otherProfile;
- try
- {
- otherProfile = getUserDatabase().findByLoginName( profile.getLoginName() );
- if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
- {
- throw new DuplicateUserException( "security.error.login.taken", profile.getLoginName() );
- }
- }
- catch( final NoSuchPrincipalException e )
- {
- }
- try
- {
- otherProfile = getUserDatabase().findByFullName( profile.getFullname() );
- if ( otherProfile != null && !otherProfile.equals( oldProfile ) )
- {
- throw new DuplicateUserException( "security.error.fullname.taken", profile.getFullname() );
- }
- }
- catch( final NoSuchPrincipalException e )
- {
- }
-
- // For new accounts, create approval workflow for user profile save.
- if ( newProfile && oldProfile != null && oldProfile.isNew() )
- {
- startUserProfileCreationWorkflow(session, profile);
-
- // If the profile doesn't need approval, then just log the user in
-
- try
- {
- final AuthenticationManager mgr = m_engine.getAuthenticationManager();
- if ( newProfile && !mgr.isContainerAuthenticated() )
- {
- mgr.login( session, null, profile.getLoginName(), profile.getPassword() );
- }
- }
- catch ( final WikiException e )
- {
- throw new WikiSecurityException( e.getMessage(), e );
- }
-
- // Alert all listeners that the profile changed...
- // ...this will cause credentials to be reloaded in the wiki session
- fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
- }
-
- // For existing accounts, just save the profile
- else
- {
- // If login name changed, rename it first
- if ( nameChanged && oldProfile != null && !oldProfile.getLoginName().equals( profile.getLoginName() ) )
- {
- getUserDatabase().rename( oldProfile.getLoginName(), profile.getLoginName() );
- }
-
- // Now, save the profile (userdatabase will take care of timestamps for us)
- getUserDatabase().save( profile );
-
- if ( nameChanged )
- {
- // Fire an event if the login name or full name changed
- final UserProfile[] profiles = new UserProfile[] { oldProfile, profile };
- fireEvent( WikiSecurityEvent.PROFILE_NAME_CHANGED, session, profiles );
- }
- else
- {
- // Fire an event that says we have new a new profile (new principals)
- fireEvent( WikiSecurityEvent.PROFILE_SAVE, session, profile );
- }
- }
- }
-
- public void startUserProfileCreationWorkflow( final WikiSession session, final UserProfile profile ) throws WikiException {
- final WorkflowBuilder builder = WorkflowBuilder.getBuilder( m_engine );
- final Principal submitter = session.getUserPrincipal();
- final Step completionTask = m_engine.getTasksManager().buildSaveUserProfileTask( m_engine, session.getLocale() );
-
- // Add user profile attribute as Facts for the approver (if required)
- final boolean hasEmail = profile.getEmail() != null;
- final Fact[] facts = new Fact[ hasEmail ? 4 : 3];
- facts[0] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_FULL_NAME, profile.getFullname() );
- facts[1] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_LOGIN_NAME, profile.getLoginName() );
- facts[2] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_SUBMITTER, submitter.getName() );
- if ( hasEmail )
- {
- facts[3] = new Fact( WorkflowManager.WF_UP_CREATE_SAVE_FACT_PREFS_EMAIL, profile.getEmail() );
- }
- final Workflow workflow = builder.buildApprovalWorkflow( submitter,
- WorkflowManager.WF_UP_CREATE_SAVE_APPROVER,
- null,
- WorkflowManager.WF_UP_CREATE_SAVE_DECISION_MESSAGE_KEY,
- facts,
- completionTask,
- null );
-
- workflow.setAttribute( WorkflowManager.WF_UP_CREATE_SAVE_ATTR_SAVED_PROFILE, profile );
- m_engine.getWorkflowManager().start(workflow);
-
- final boolean approvalRequired = workflow.getCurrentStep() instanceof Decision;
-
- // If the profile requires approval, redirect user to message page
- if ( approvalRequired )
- {
- throw new DecisionRequiredException( "This profile must be approved before it becomes active" );
- }
- }
+ void startUserProfileCreationWorkflow( WikiSession session, UserProfile profile ) throws WikiException;
/**
- * <p> Extracts user profile parameters from the HTTP request and populates
- * a UserProfile with them. The UserProfile will either be a copy of the
- * user's existing profile (if one can be found), or a new profile (if not).
- * The rules for populating the profile as as follows: </p> <ul> <li>If the
- * <code>email</code> or <code>password</code> parameter values differ
- * from those in the existing profile, the passed parameters override the
- * old values.</li> <li>For new profiles, the user-supplied
- * <code>fullname</code> parameter is always
- * used; for existing profiles the existing value is used, and whatever
- * value the user supplied is discarded. The wiki name is automatically
- * computed by taking the full name and extracting all whitespace.</li>
- * <li>In all cases, the
- * created/last modified timestamps of the user's existing or new profile
- * always override whatever values the user supplied.</li> <li>If
- * container authentication is used, the login name property of the profile
- * is set to the name of
- * {@link org.apache.wiki.WikiSession#getLoginPrincipal()}. Otherwise,
- * the value of the <code>loginname</code> parameter is used.</li> </ul>
+ * <p> Extracts user profile parameters from the HTTP request and populates a UserProfile with them. The UserProfile will either be a
+ * copy of the user's existing profile (if one can be found), or a new profile (if not). The rules for populating the profile as as
+ * follows: </p>
+ * <ul>
+ * <li>If the <code>email</code> or <code>password</code> parameter values differ from those in the existing profile, the passed
+ * parameters override the old values.</li>
+ * <li>For new profiles, the user-supplied <code>fullname</code> parameter is always used; for existing profiles the existing value is
+ * used, and whatever value the user supplied is discarded. The wiki name is automatically computed by taking the full name and
+ * extracting all whitespace.</li>
+ * <li>In all cases, the created/last modified timestamps of the user's existing or new profile always override whatever values the user
+ * supplied.</li>
+ * <li>If container authentication is used, the login name property of the profile is set to the name of
+ * {@link org.apache.wiki.WikiSession#getLoginPrincipal()}. Otherwise, the value of the <code>loginname</code> parameter is used.</li>
+ * </ul>
+ *
* @param context the current wiki context
* @return a new, populated user profile
*/
- public UserProfile parseProfile( WikiContext context )
- {
- // Retrieve the user's profile (may have been previously cached)
- final UserProfile profile = getUserProfile( context.getWikiSession() );
- final HttpServletRequest request = context.getHttpRequest();
-
- // Extract values from request stream (cleanse whitespace as needed)
- String loginName = request.getParameter( PARAM_LOGINNAME );
- String password = request.getParameter( PARAM_PASSWORD );
- String fullname = request.getParameter( PARAM_FULLNAME );
- String email = request.getParameter( PARAM_EMAIL );
- loginName = InputValidator.isBlank( loginName ) ? null : loginName;
- password = InputValidator.isBlank( password ) ? null : password;
- fullname = InputValidator.isBlank( fullname ) ? null : fullname;
- email = InputValidator.isBlank( email ) ? null : email;
-
- // A special case if we have container authentication
- // If authenticated, login name is always taken from container
- if ( m_engine.getAuthenticationManager().isContainerAuthenticated() &&
- context.getWikiSession().isAuthenticated() )
- {
- loginName = context.getWikiSession().getLoginPrincipal().getName();
- }
-
- // Set the profile fields!
- profile.setLoginName( loginName );
- profile.setEmail( email );
- profile.setFullname( fullname );
- profile.setPassword( password );
- return profile;
- }
+ UserProfile parseProfile( WikiContext context );
/**
- * Validates a user profile, and appends any errors to the session errors
- * list. If the profile is new, the password will be checked to make sure it
- * isn't null. Otherwise, the password is checked for length and that it
- * matches the value of the 'password2' HTTP parameter. Note that we have a
- * special case when container-managed authentication is used and the user
- * is not authenticated; this will always cause validation to fail. Any
- * validation errors are added to the wiki session's messages collection
+ * Validates a user profile, and appends any errors to the session errors list. If the profile is new, the password will be checked to
+ * make sure it isn't null. Otherwise, the password is checked for length and that it matches the value of the 'password2' HTTP
+ * parameter. Note that we have a special case when container-managed authentication is used and the user is not authenticated;
+ * this will always cause validation to fail. Any validation errors are added to the wiki session's messages collection
* (see {@link WikiSession#getMessages()}.
+ *
* @param context the current wiki context
* @param profile the supplied UserProfile
*/
- public void validateProfile( WikiContext context, UserProfile profile )
- {
- final boolean isNew = profile.isNew();
- final WikiSession session = context.getWikiSession();
- final InputValidator validator = new InputValidator( SESSION_MESSAGES, context );
- final ResourceBundle rb = Preferences.getBundle( context, InternationalizationManager.CORE_BUNDLE );
-
- //
- // Query the SpamFilter first
- //
- final FilterManager fm = m_engine.getFilterManager();
- final List<PageFilter> ls = fm.getFilterList();
- for( final PageFilter pf : ls )
- {
- if( pf instanceof SpamFilter )
- {
- if( ((SpamFilter)pf).isValidUserProfile( context, profile ) == false )
- {
- session.addMessage( SESSION_MESSAGES, "Invalid userprofile" );
- return;
- }
- break;
- }
- }
-
- // If container-managed auth and user not logged in, throw an error
- if ( m_engine.getAuthenticationManager().isContainerAuthenticated()
- && !context.getWikiSession().isAuthenticated() )
- {
- session.addMessage( SESSION_MESSAGES, rb.getString("security.error.createprofilebeforelogin") );
- }
-
- validator.validateNotNull( profile.getLoginName(), rb.getString("security.user.loginname") );
- validator.validateNotNull( profile.getFullname(), rb.getString("security.user.fullname") );
- validator.validate( profile.getEmail(), rb.getString("security.user.email"), InputValidator.EMAIL );
-
- // If new profile, passwords must match and can't be null
- if ( !m_engine.getAuthenticationManager().isContainerAuthenticated() )
- {
- final String password = profile.getPassword();
- if ( password == null )
- {
- if ( isNew )
- {
- session.addMessage( SESSION_MESSAGES, rb.getString("security.error.blankpassword") );
- }
- }
- else
- {
- final HttpServletRequest request = context.getHttpRequest();
- final String password2 = ( request == null ) ? null : request.getParameter( "password2" );
- if ( !password.equals( password2 ) )
- {
- session.addMessage( SESSION_MESSAGES, rb.getString("security.error.passwordnomatch") );
- }
- }
- }
-
- UserProfile otherProfile;
- final String fullName = profile.getFullname();
- final String loginName = profile.getLoginName();
- final String email = profile.getEmail();
-
- // It's illegal to use as a full name someone else's login name
- try
- {
- otherProfile = getUserDatabase().find( fullName );
- if ( otherProfile != null && !profile.equals( otherProfile ) && !fullName.equals( otherProfile.getFullname() ) )
- {
- final Object[] args = { fullName };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalfullname"), args ) );
- }
- }
- catch ( final NoSuchPrincipalException e)
- { /* It's clean */ }
-
- // It's illegal to use as a login name someone else's full name
- try
- {
- otherProfile = getUserDatabase().find( loginName );
- if ( otherProfile != null && !profile.equals( otherProfile ) && !loginName.equals( otherProfile.getLoginName() ) )
- {
- final Object[] args = { loginName };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.illegalloginname"), args ) );
- }
- }
- catch ( final NoSuchPrincipalException e)
- { /* It's clean */ }
-
- // It's illegal to use multiple accounts with the same email
- try
- {
- otherProfile = getUserDatabase().findByEmail( email );
- if ( otherProfile != null
- && !profile.getUid().equals(otherProfile.getUid()) // Issue JSPWIKI-1042
- && !profile.equals( otherProfile ) && StringUtils.lowerCase( email ).equals( StringUtils.lowerCase(otherProfile.getEmail() ) ) )
- {
- final Object[] args = { email };
- session.addMessage( SESSION_MESSAGES, MessageFormat.format( rb.getString("security.error.email.taken"), args ) );
- }
- }
- catch ( final NoSuchPrincipalException e)
- { /* It's clean */ }
- }
+ void validateProfile( WikiContext context, UserProfile profile );
/**
* A helper method for returning all of the known WikiNames in this system.
@@ -551,215 +151,35 @@ public class UserManager {
* @return An Array of Principals
* @throws WikiSecurityException If for reason the names cannot be fetched
*/
- public Principal[] listWikiNames()
- throws WikiSecurityException
- {
- return getUserDatabase().getWikiNames();
- }
-
- /**
- * This is a database that gets used if nothing else is available. It does nothing of note - it just mostly throws
- * NoSuchPrincipalExceptions if someone tries to log in.
- */
- public static class DummyUserDatabase extends AbstractUserDatabase {
-
- /**
- * No-op.
- * @param loginName the login name to delete
- */
- @Override
- public void deleteByLoginName( String loginName ) {
- // No operation
- }
-
- /**
- * No-op; always throws <code>NoSuchPrincipalException</code>.
- * @param index the name to search for
- * @return the user profile
- * @throws NoSuchPrincipalException always...
- */
- @Override
- public UserProfile findByEmail(final String index) throws NoSuchPrincipalException {
- throw new NoSuchPrincipalException("No user profiles available");
- }
-
- /**
- * No-op; always throws <code>NoSuchPrincipalException</code>.
- * @param index the name to search for
- * @return the user profile
- * @throws NoSuchPrincipalException always...
- */
- @Override
- public UserProfile findByFullName(final String index) throws NoSuchPrincipalException {
- throw new NoSuchPrincipalException("No user profiles available");
- }
-
- /**
- * No-op; always throws <code>NoSuchPrincipalException</code>.
- * @param index the name to search for
- * @return the user profile
- * @throws NoSuchPrincipalException always...
- */
- @Override
- public UserProfile findByLoginName(final String index) throws NoSuchPrincipalException {
- throw new NoSuchPrincipalException("No user profiles available");
- }
-
- /**
- * No-op; always throws <code>NoSuchPrincipalException</code>.
- * @param uid the unique identifier to search for
- * @return the user profile
- * @throws NoSuchPrincipalException always...
- */
- @Override
- public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException {
- throw new NoSuchPrincipalException("No user profiles available");
- }
- /**
- * No-op; always throws <code>NoSuchPrincipalException</code>.
- * @param index the name to search for
- * @return the user profile
- * @throws NoSuchPrincipalException always...
- */
- @Override
- public UserProfile findByWikiName(final String index) throws NoSuchPrincipalException {
- throw new NoSuchPrincipalException("No user profiles available");
- }
-
- /**
- * No-op.
- * @return a zero-length array
- */
- @Override
- public Principal[] getWikiNames() {
- return new Principal[0];
- }
-
- /**
- * No-op.
- *
- * @param engine the wiki engine
- * @param props the properties used to initialize the wiki engine
- */
- @Override
- public void initialize(final WikiEngine engine, final Properties props) {
- }
-
- /**
- * No-op; always throws <code>NoSuchPrincipalException</code>.
- * @param loginName the login name
- * @param newName the proposed new login name
- * @throws NoSuchPrincipalException always...
- */
- @Override
- public void rename( final String loginName, final String newName ) throws NoSuchPrincipalException {
- throw new NoSuchPrincipalException("No user profiles available");
- }
-
- /**
- * No-op.
- * @param profile the user profile
- */
- @Override
- public void save( final UserProfile profile ) {
- }
-
- }
+ Principal[] listWikiNames() throws WikiSecurityException;
// events processing .......................................................
/**
- * Registers a WikiEventListener with this instance.
- * This is a convenience method.
+ * Registers a WikiEventListener with this instance. This is a convenience method.
+ *
* @param listener the event listener
*/
- public synchronized void addWikiEventListener( WikiEventListener listener )
- {
- WikiEventManager.addWikiEventListener( this, listener );
- }
+ void addWikiEventListener( WikiEventListener listener );
/**
- * Un-registers a WikiEventListener with this instance.
- * This is a convenience method.
+ * Un-registers a WikiEventListener with this instance. This is a convenience method.
+ *
* @param listener the event listener
*/
- public synchronized void removeWikiEventListener( WikiEventListener listener )
- {
- WikiEventManager.removeWikiEventListener( this, listener );
- }
+ void removeWikiEventListener( WikiEventListener listener );
/**
- * Fires a WikiSecurityEvent of the provided type, Principal and target Object
- * to all registered listeners.
+ * Fires a WikiSecurityEvent of the provided type, Principal and target Object to all registered listeners.
*
* @see org.apache.wiki.event.WikiSecurityEvent
* @param type the event type to be fired
* @param session the wiki session supporting the event
* @param profile the user profile (or array of user profiles), which may be <code>null</code>
*/
- protected void fireEvent( int type, WikiSession session, Object profile )
- {
- if ( WikiEventManager.isListening(this) )
- {
- WikiEventManager.fireEvent(this,new WikiSecurityEvent(session,type,profile));
- }
- }
-
- /**
- * Implements the JSON API for usermanager.
- * <p>
- * Even though this gets serialized whenever container shuts down/restarts, this gets reinstalled to the session when JSPWiki starts.
- * This means that it's not actually necessary to save anything.
- */
- public static final class JSONUserModule implements WikiAjaxServlet {
-
- private volatile UserManager m_manager;
-
- /**
- * Create a new JSONUserModule.
- * @param mgr Manager
- */
- public JSONUserModule( UserManager mgr )
- {
- m_manager = mgr;
- }
-
- @Override
- public String getServletMapping() {
- return JSON_USERS;
- }
-
- @Override
- public void service(HttpServletRequest req, HttpServletResponse resp, String actionName, List<String> params) throws ServletException, IOException {
- try {
- if( params.size() < 1 ) {
- return;
- }
- final String uid = params.get(0);
- log.debug("uid="+uid);
- if (StringUtils.isNotBlank(uid)) {
- final UserProfile prof = getUserInfo(uid);
- resp.getWriter().write(AjaxUtil.toJson(prof));
- }
- } catch (final NoSuchPrincipalException e) {
- throw new ServletException(e);
- }
- }
-
- /**
- * Directly returns the UserProfile object attached to an uid.
- *
- * @param uid The user id (e.g. WikiName)
- * @return A UserProfile object
- * @throws NoSuchPrincipalException If such a name does not exist.
- */
- public UserProfile getUserInfo( String uid ) throws NoSuchPrincipalException {
- if( m_manager != null ) {
- final UserProfile prof = m_manager.getUserDatabase().find( uid );
- return prof;
- }
-
- throw new IllegalStateException("The manager is offline.");
+ default void fireEvent( final int type, final WikiSession session, final Object profile ) {
+ if( WikiEventManager.isListening( this ) ) {
+ WikiEventManager.fireEvent( this, new WikiSecurityEvent( session, type, profile ) );
}
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java
index df51c10..78b030d 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/AbstractUserDatabase.java
@@ -20,7 +20,7 @@ package org.apache.wiki.auth.user;
import org.apache.commons.lang3.math.NumberUtils;
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;
@@ -37,12 +37,11 @@ import java.util.Properties;
import java.util.UUID;
/**
- * Abstract UserDatabase class that provides convenience methods for finding
- * profiles, building Principal collections and hashing passwords.
+ * Abstract UserDatabase class that provides convenience methods for finding profiles, building Principal collections and hashing passwords.
+ *
* @since 2.3
*/
-public abstract class AbstractUserDatabase implements UserDatabase
-{
+public abstract class AbstractUserDatabase implements UserDatabase {
protected static final Logger log = Logger.getLogger( AbstractUserDatabase.class );
protected static final String SHA_PREFIX = "{SHA}";
@@ -57,46 +56,33 @@ public abstract class AbstractUserDatabase implements UserDatabase
* @param index the login name, full name, or wiki name
* @see org.apache.wiki.auth.user.UserDatabase#find(java.lang.String)
*/
- public UserProfile find( String index ) throws NoSuchPrincipalException
- {
+ @Override public UserProfile find( final String index ) throws NoSuchPrincipalException {
UserProfile profile = null;
// Try finding by full name
- try
- {
+ try {
profile = findByFullName( index );
+ } catch( final NoSuchPrincipalException e ) {
}
- catch ( NoSuchPrincipalException e )
- {
- }
- if ( profile != null )
- {
+ if( profile != null ) {
return profile;
}
// Try finding by wiki name
- try
- {
+ try {
profile = findByWikiName( index );
+ } catch( final NoSuchPrincipalException e ) {
}
- catch ( NoSuchPrincipalException e )
- {
- }
- if ( profile != null )
- {
+ if( profile != null ) {
return profile;
}
// Try finding by login name
- try
- {
+ try {
profile = findByLoginName( index );
+ } catch( final NoSuchPrincipalException e ) {
}
- catch ( NoSuchPrincipalException e )
- {
- }
- if ( profile != null )
- {
+ if( profile != null ) {
return profile;
}
@@ -107,25 +93,25 @@ public abstract class AbstractUserDatabase implements UserDatabase
* {@inheritDoc}
* @see org.apache.wiki.auth.user.UserDatabase#findByEmail(java.lang.String)
*/
- public abstract UserProfile findByEmail( String index ) throws NoSuchPrincipalException;
+ @Override public abstract UserProfile findByEmail( String index ) throws NoSuchPrincipalException;
/**
* {@inheritDoc}
* @see org.apache.wiki.auth.user.UserDatabase#findByFullName(java.lang.String)
*/
- public abstract UserProfile findByFullName( String index ) throws NoSuchPrincipalException;
+ @Override public abstract UserProfile findByFullName( String index ) throws NoSuchPrincipalException;
/**
* {@inheritDoc}
* @see org.apache.wiki.auth.user.UserDatabase#findByLoginName(java.lang.String)
*/
- public abstract UserProfile findByLoginName( String index ) throws NoSuchPrincipalException;
+ @Override public abstract UserProfile findByLoginName( String index ) throws NoSuchPrincipalException;
/**
* {@inheritDoc}
* @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(java.lang.String)
*/
- public abstract UserProfile findByWikiName( String index ) throws NoSuchPrincipalException;
+ @Override public abstract UserProfile findByWikiName( String index ) throws NoSuchPrincipalException;
/**
* <p>Looks up the Principals representing a user from the user database. These
@@ -142,38 +128,31 @@ public abstract class AbstractUserDatabase implements UserDatabase
* @see org.apache.wiki.auth.user.UserDatabase#getPrincipals(java.lang.String)
* @throws NoSuchPrincipalException {@inheritDoc}
*/
- public Principal[] getPrincipals( String identifier ) throws NoSuchPrincipalException
+ @Override public Principal[] getPrincipals( final String identifier ) throws NoSuchPrincipalException
{
- try
- {
- UserProfile profile = findByLoginName( identifier );
- ArrayList<Principal> principals = new ArrayList<Principal>();
- if ( profile.getLoginName() != null && profile.getLoginName().length() > 0 )
- {
+ try {
+ final UserProfile profile = findByLoginName( identifier );
+ final ArrayList< Principal > principals = new ArrayList<>();
+ if( profile.getLoginName() != null && profile.getLoginName().length() > 0 ) {
principals.add( new WikiPrincipal( profile.getLoginName(), WikiPrincipal.LOGIN_NAME ) );
}
- if ( profile.getFullname() != null && profile.getFullname().length() > 0 )
- {
+ if( profile.getFullname() != null && profile.getFullname().length() > 0 ) {
principals.add( new WikiPrincipal( profile.getFullname(), WikiPrincipal.FULL_NAME ) );
}
- if ( profile.getWikiName() != null && profile.getWikiName().length() > 0 )
- {
+ if( profile.getWikiName() != null && profile.getWikiName().length() > 0 ) {
principals.add( new WikiPrincipal( profile.getWikiName(), WikiPrincipal.WIKI_NAME ) );
}
- return principals.toArray( new Principal[principals.size()] );
- }
- catch( NoSuchPrincipalException e )
- {
+ return principals.toArray( new Principal[ principals.size() ] );
+ } catch( final NoSuchPrincipalException e ) {
throw e;
}
}
/**
* {@inheritDoc}
- * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.WikiEngine, java.util.Properties)
+ * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
*/
- public abstract void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException,
- WikiSecurityException;
+ @Override public abstract void initialize( Engine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
/**
* Factory method that instantiates a new DefaultUserProfile with a new, distinct
@@ -181,7 +160,7 @@ public abstract class AbstractUserDatabase implements UserDatabase
*
* @return A new, empty profile.
*/
- public UserProfile newProfile()
+ @Override public UserProfile newProfile()
{
return DefaultUserProfile.newProfile( this );
}
@@ -190,66 +169,51 @@ public abstract class AbstractUserDatabase implements UserDatabase
* {@inheritDoc}
* @see org.apache.wiki.auth.user.UserDatabase#save(org.apache.wiki.auth.user.UserProfile)
*/
- public abstract void save( UserProfile profile ) throws WikiSecurityException;
+ @Override public abstract void save( UserProfile profile ) throws WikiSecurityException;
/**
- * Validates the password for a given user. If the user does not exist in
- * the user database, this method always returns <code>false</code>. If
- * the user exists, the supplied password is compared to the stored
- * password. Note that if the stored password's value starts with
- * <code>{SHA}</code>, the supplied password is hashed prior to the
- * comparison.
+ * Validates the password for a given user. If the user does not exist in the user database, this method always returns
+ * <code>false</code>. If the user exists, the supplied password is compared to the stored password. Note that if the stored password's
+ * value starts with <code>{SHA}</code>, the supplied password is hashed prior to the comparison.
+ *
* @param loginName the user's login name
* @param password the user's password (obtained from user input, e.g., a web form)
- * @return <code>true</code> if the supplied user password matches the
- * stored password
- * @see org.apache.wiki.auth.user.UserDatabase#validatePassword(java.lang.String,
- * java.lang.String)
+ * @return <code>true</code> if the supplied user password matches the stored password
+ * @see org.apache.wiki.auth.user.UserDatabase#validatePassword(java.lang.String, java.lang.String)
*/
- public boolean validatePassword( String loginName, String password )
- {
- String hashedPassword;
- try
- {
- UserProfile profile = findByLoginName( loginName );
+ @Override public boolean validatePassword( final String loginName, final String password ) {
+ final String hashedPassword;
+ try {
+ final UserProfile profile = findByLoginName( loginName );
String storedPassword = profile.getPassword();
-
+
// Is the password stored as a salted hash (the new 2.8 format?)
- boolean newPasswordFormat = storedPassword.startsWith( SSHA_PREFIX );
-
+ final boolean newPasswordFormat = storedPassword.startsWith( SSHA_PREFIX );
+
// If new format, verify the hash
- if ( newPasswordFormat )
- {
+ if( newPasswordFormat ) {
hashedPassword = getHash( password );
return CryptoUtil.verifySaltedPassword( password.getBytes( StandardCharsets.UTF_8 ), storedPassword );
}
// If old format, verify using the old SHA verification algorithm
- if ( storedPassword.startsWith( SHA_PREFIX ) )
- {
+ if( storedPassword.startsWith( SHA_PREFIX ) ) {
storedPassword = storedPassword.substring( SHA_PREFIX.length() );
}
hashedPassword = getOldHash( password );
- boolean verified = hashedPassword.equals( storedPassword );
-
+ final boolean verified = hashedPassword.equals( storedPassword );
+
// If in the old format and password verified, upgrade the hash to SSHA
- if ( verified )
- {
+ if( verified ) {
profile.setPassword( password );
save( profile );
}
-
+
return verified;
- }
- catch( NoSuchPrincipalException e )
- {
- }
- catch( NoSuchAlgorithmException e )
- {
+ } catch( final NoSuchPrincipalException e ) {
+ } catch( final NoSuchAlgorithmException e ) {
log.error( "Unsupported algorithm: " + e.getMessage() );
- }
- catch( WikiSecurityException e )
- {
+ } catch( final WikiSecurityException e ) {
log.error( "Could not upgrade SHA password to SSHA because profile could not be saved. Reason: " + e.getMessage(), e );
}
return false;
@@ -261,21 +225,17 @@ public abstract class AbstractUserDatabase implements UserDatabase
* @param db The database for which the UID should be generated.
* @return A random, unique UID.
*/
- protected static String generateUid( UserDatabase db ) {
+ protected static String generateUid( final UserDatabase db ) {
// Keep generating UUIDs until we find one that doesn't collide
- String uid = null;
+ String uid;
boolean collision;
- do
- {
+ do {
uid = UUID.randomUUID().toString();
collision = true;
- try
- {
+ try {
db.findByUid( uid );
- }
- catch ( NoSuchPrincipalException e )
- {
+ } catch ( final NoSuchPrincipalException e ) {
collision = false;
}
}
@@ -284,9 +244,9 @@ public abstract class AbstractUserDatabase implements UserDatabase
}
/**
- * Private method that calculates the salted SHA-1 hash of a given
- * <code>String</code>. Note that as of JSPWiki 2.8, this method calculates
- * a <em>salted</em> hash rather than a plain hash.
+ * Private method that calculates the salted SHA-1 hash of a given <code>String</code>. Note that as of JSPWiki 2.8, this method
+ * calculates a <em>salted</em> hash rather than a plain hash.
+ *
* @param text the text to hash
* @return the result hash
*/
@@ -300,8 +260,8 @@ public abstract class AbstractUserDatabase implements UserDatabase
}
/**
- * Private method that calculates the SHA-1 hash of a given
- * <code>String</code>
+ * Private method that calculates the SHA-1 hash of a given <code>String</code>
+ *
* @param text the text to hash
* @return the result hash
* @deprecated this method is retained for backwards compatibility purposes; use {@link #getHash(String)} instead
@@ -310,7 +270,7 @@ public abstract class AbstractUserDatabase implements UserDatabase
try {
final MessageDigest md = MessageDigest.getInstance( "SHA" );
md.update( text.getBytes( StandardCharsets.UTF_8 ) );
- byte[] digestedBytes = md.digest();
+ final byte[] digestedBytes = md.digest();
return ByteUtils.bytes2hex( digestedBytes );
} catch( final NoSuchAlgorithmException e ) {
log.error( "Error creating SHA password hash:" + e.getMessage() );
@@ -320,6 +280,7 @@ public abstract class AbstractUserDatabase implements UserDatabase
/**
* Parses a long integer from a supplied string, or returns 0 if not parsable.
+ *
* @param value the string to parse
* @return the value parsed
*/
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
index 53da585..93ca181 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
@@ -19,7 +19,7 @@
package org.apache.wiki.auth.user;
import org.apache.commons.lang3.StringUtils;
-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;
@@ -181,13 +181,7 @@ import java.util.Set;
* </p>
* <p>
* JDBCUserDatabase commits changes as transactions if the back-end database
- * supports them. If the database supports transactions, user profile 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(UserProfile)} 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(UserProfile)} method).
* </p>
*
* @since 2.3
@@ -316,13 +310,13 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @param loginName the login name of the user profile that shall be deleted
*/
@Override
- public void deleteByLoginName( String loginName ) throws NoSuchPrincipalException, WikiSecurityException {
+ public void deleteByLoginName( final String loginName ) throws NoSuchPrincipalException, WikiSecurityException {
// Get the existing user; if not found, throws NoSuchPrincipalException
findByLoginName( loginName );
- try( Connection conn = m_ds.getConnection() ;
- PreparedStatement ps1 = conn.prepareStatement( m_deleteUserByLoginName );
- PreparedStatement ps2 = conn.prepareStatement( m_deleteRoleByLoginName ) )
+ try( final Connection conn = m_ds.getConnection() ;
+ final PreparedStatement ps1 = conn.prepareStatement( m_deleteUserByLoginName );
+ final PreparedStatement ps2 = conn.prepareStatement( m_deleteRoleByLoginName ) )
{
// Open the database connection
if( m_supportsCommits ) {
@@ -341,7 +335,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
if( m_supportsCommits ) {
conn.commit();
}
- } catch( SQLException e ) {
+ } catch( final SQLException e ) {
throw new WikiSecurityException( e.getMessage(), e );
}
}
@@ -350,7 +344,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#findByEmail(java.lang.String)
*/
@Override
- public UserProfile findByEmail( String index ) throws NoSuchPrincipalException {
+ public UserProfile findByEmail( final String index ) throws NoSuchPrincipalException {
return findByPreparedStatement( m_findByEmail, index );
}
@@ -358,7 +352,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#findByFullName(java.lang.String)
*/
@Override
- public UserProfile findByFullName( String index ) throws NoSuchPrincipalException {
+ public UserProfile findByFullName( final String index ) throws NoSuchPrincipalException {
return findByPreparedStatement( m_findByFullName, index );
}
@@ -366,7 +360,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#findByLoginName(java.lang.String)
*/
@Override
- public UserProfile findByLoginName( String index ) throws NoSuchPrincipalException {
+ public UserProfile findByLoginName( final String index ) throws NoSuchPrincipalException {
return findByPreparedStatement( m_findByLoginName, index );
}
@@ -374,7 +368,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(String)
*/
@Override
- public UserProfile findByUid( String uid ) throws NoSuchPrincipalException {
+ public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException {
return findByPreparedStatement( m_findByUid, uid );
}
@@ -382,7 +376,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(String)
*/
@Override
- public UserProfile findByWikiName( String index ) throws NoSuchPrincipalException {
+ public UserProfile findByWikiName( final String index ) throws NoSuchPrincipalException {
return findByPreparedStatement( m_findByWikiName, index );
}
@@ -395,21 +389,21 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
*/
@Override
public Principal[] getWikiNames() throws WikiSecurityException {
- Set<Principal> principals = new HashSet<>();
- try( Connection conn = m_ds.getConnection();
- PreparedStatement ps = conn.prepareStatement( m_findAll );
- ResultSet rs = ps.executeQuery() )
+ final Set<Principal> principals = new HashSet<>();
+ try( final Connection conn = m_ds.getConnection();
+ final PreparedStatement ps = conn.prepareStatement( m_findAll );
+ final ResultSet rs = ps.executeQuery() )
{
while ( rs.next() ) {
- String wikiName = rs.getString( m_wikiName );
+ final String wikiName = rs.getString( m_wikiName );
if( wikiName == null ) {
log.warn( "Detected null wiki name in XMLUserDataBase. Check your user database." );
} else {
- Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
+ final Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
principals.add( principal );
}
}
- } catch( SQLException e ) {
+ } catch( final SQLException e ) {
throw new WikiSecurityException( e.getMessage(), e );
}
@@ -417,19 +411,18 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
}
/**
- * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.WikiEngine,
- * java.util.Properties)
+ * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
*/
@Override
- public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException {
- String jndiName = props.getProperty( PROP_DB_DATASOURCE, DEFAULT_DB_JNDI_NAME );
+ public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException {
+ final String jndiName = props.getProperty( PROP_DB_DATASOURCE, DEFAULT_DB_JNDI_NAME );
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
- String userTable = props.getProperty( PROP_DB_TABLE, DEFAULT_DB_TABLE );
+ final String userTable = props.getProperty( PROP_DB_TABLE, DEFAULT_DB_TABLE );
m_email = props.getProperty( PROP_DB_EMAIL, DEFAULT_DB_EMAIL );
m_fullName = props.getProperty( PROP_DB_FULL_NAME, DEFAULT_DB_FULL_NAME );
m_lockExpiry = props.getProperty( PROP_DB_LOCK_EXPIRY, DEFAULT_DB_LOCK_EXPIRY );
@@ -475,8 +468,8 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
+ "WHERE " + m_loginName + "=?";
// Prepare the role insert SQL
- String roleTable = props.getProperty( PROP_DB_ROLE_TABLE, DEFAULT_DB_ROLE_TABLE );
- String role = props.getProperty( PROP_DB_ROLE, DEFAULT_DB_ROLE );
+ final String roleTable = props.getProperty( PROP_DB_ROLE_TABLE, DEFAULT_DB_ROLE_TABLE );
+ final String role = props.getProperty( PROP_DB_ROLE, DEFAULT_DB_ROLE );
m_insertRole = "INSERT INTO " + roleTable + " (" + m_loginName + "," + role + ") VALUES (?,?)";
m_findRoles = "SELECT * FROM " + roleTable + " WHERE " + m_loginName + "=?";
@@ -490,28 +483,28 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
m_renameProfile = "UPDATE " + userTable + " SET " + m_loginName + "=?," + m_modified + "=? WHERE " + m_loginName
+ "=?";
m_renameRoles = "UPDATE " + roleTable + " SET " + m_loginName + "=? WHERE " + m_loginName + "=?";
- } catch( NamingException e ) {
+ } catch( final NamingException e ) {
log.error( "JDBCUserDatabase initialization error: " + e.getMessage() );
throw new NoRequiredPropertyException( PROP_DB_DATASOURCE, "JDBCUserDatabase initialization error: " + e.getMessage() );
}
// Test connection by doing a quickie select
- try( Connection conn = m_ds.getConnection(); PreparedStatement ps = conn.prepareStatement( m_findAll ) ) {
- } catch( SQLException e ) {
+ try( final Connection conn = m_ds.getConnection(); final PreparedStatement ps = conn.prepareStatement( m_findAll ) ) {
+ } catch( final SQLException e ) {
log.error( "DB connectivity error: " + e.getMessage() );
throw new WikiSecurityException("DB connectivity error: " + e.getMessage(), e );
}
log.info( "JDBCUserDatabase initialized from JNDI DataSource: " + jndiName );
// Determine if the datasource supports commits
- try( Connection conn = m_ds.getConnection() ) {
- DatabaseMetaData dmd = conn.getMetaData();
+ try( final Connection conn = m_ds.getConnection() ) {
+ final DatabaseMetaData dmd = conn.getMetaData();
if( dmd.supportsTransactions() ) {
m_supportsCommits = true;
conn.setAutoCommit( false );
log.info( "JDBCUserDatabase supports transactions. Good; we will use them." );
}
- } catch( SQLException e ) {
+ } catch( final SQLException e ) {
log.warn( "JDBCUserDatabase warning: user database doesn't seem to support transactions. Reason: " + e.getMessage() );
}
}
@@ -520,30 +513,30 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#rename(String, String)
*/
@Override
- public void rename( String loginName, String newName ) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException {
+ public void rename( final String loginName, final String newName ) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException {
// Get the existing user; if not found, throws NoSuchPrincipalException
- UserProfile profile = findByLoginName( loginName );
+ final UserProfile profile = findByLoginName( loginName );
// Get user with the proposed name; if found, it's a collision
try {
- UserProfile otherProfile = findByLoginName( newName );
+ final UserProfile otherProfile = findByLoginName( newName );
if( otherProfile != null ) {
throw new DuplicateUserException( "security.error.cannot.rename", newName );
}
- } catch( NoSuchPrincipalException e ) {
+ } catch( final NoSuchPrincipalException e ) {
// Good! That means it's safe to save using the new name
}
- try( Connection conn = m_ds.getConnection();
- PreparedStatement ps1 = conn.prepareStatement( m_renameProfile );
- PreparedStatement ps2 = conn.prepareStatement( m_renameRoles ) )
+ try( final Connection conn = m_ds.getConnection();
+ final PreparedStatement ps1 = conn.prepareStatement( m_renameProfile );
+ final PreparedStatement ps2 = conn.prepareStatement( m_renameRoles ) )
{
if( m_supportsCommits ) {
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() );
// Change the login ID for the user record
ps1.setString( 1, newName );
@@ -564,7 +557,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
if( m_supportsCommits ) {
conn.commit();
}
- } catch( SQLException e ) {
+ } catch( final SQLException e ) {
throw new WikiSecurityException( e.getMessage(), e );
}
}
@@ -573,23 +566,23 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @see org.apache.wiki.auth.user.UserDatabase#save(org.apache.wiki.auth.user.UserProfile)
*/
@Override
- public void save( UserProfile profile ) throws WikiSecurityException {
- String initialRole = "Authenticated";
+ public void save( final UserProfile profile ) throws WikiSecurityException {
+ final String initialRole = "Authenticated";
// Figure out which prepared statement to use & execute it
- String loginName = profile.getLoginName();
+ final String loginName = profile.getLoginName();
UserProfile existingProfile = null;
try {
existingProfile = findByLoginName( loginName );
- } catch( NoSuchPrincipalException e ) {
+ } catch( final NoSuchPrincipalException e ) {
// Existing profile will be null
}
// Get a clean password from the passed profile.
// Blank password is the same as null, which means we re-use the existing one.
String password = profile.getPassword();
- String existingPassword = (existingProfile == null) ? null : existingProfile.getPassword();
+ final String existingPassword = (existingProfile == null) ? null : existingProfile.getPassword();
if( NOTHING.equals( password ) ) {
password = null;
}
@@ -602,19 +595,19 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
password = getHash( password );
}
- try( Connection conn = m_ds.getConnection();
- PreparedStatement ps1 = conn.prepareStatement( m_insertProfile );
- PreparedStatement ps2 = conn.prepareStatement( m_findRoles );
- PreparedStatement ps3 = conn.prepareStatement( m_insertRole );
- PreparedStatement ps4 = conn.prepareStatement( m_updateProfile ) )
+ try( final Connection conn = m_ds.getConnection();
+ final PreparedStatement ps1 = conn.prepareStatement( m_insertProfile );
+ final PreparedStatement ps2 = conn.prepareStatement( m_findRoles );
+ final PreparedStatement ps3 = conn.prepareStatement( m_insertRole );
+ final PreparedStatement ps4 = conn.prepareStatement( m_updateProfile ) )
{
if( m_supportsCommits ) {
conn.setAutoCommit( false );
}
- Timestamp ts = new Timestamp( System.currentTimeMillis() );
- Date modDate = new Date( ts.getTime() );
- java.sql.Date lockExpiry = profile.getLockExpiry() == null ? null : new java.sql.Date( profile.getLockExpiry().getTime() );
+ final Timestamp ts = new Timestamp( System.currentTimeMillis() );
+ final Date modDate = new Date( ts.getTime() );
+ final java.sql.Date lockExpiry = profile.getLockExpiry() == null ? null : new java.sql.Date( profile.getLockExpiry().getTime() );
if( existingProfile == null )
{
// User is new: insert new user record
@@ -627,7 +620,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
ps1.setString( 7, profile.getLoginName() );
try {
ps1.setString( 8, Serializer.serializeToBase64( profile.getAttributes() ) );
- } catch ( IOException e ) {
+ } catch ( final IOException e ) {
throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
}
ps1.setTimestamp( 9, ts );
@@ -636,7 +629,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
// Insert new role record
ps2.setString( 1, profile.getLoginName() );
int roles = 0;
- try ( ResultSet rs = ps2.executeQuery() ) {
+ try ( final ResultSet rs = ps2.executeQuery() ) {
while ( rs.next() ) {
roles++;
}
@@ -663,7 +656,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
{
ps4.setString( 8, Serializer.serializeToBase64( profile.getAttributes() ) );
}
- catch ( IOException e )
+ catch ( final IOException e )
{
throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
}
@@ -679,7 +672,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
conn.commit();
}
}
- catch( SQLException e )
+ catch( final SQLException e )
{
throw new WikiSecurityException( e.getMessage(), e );
}
@@ -694,12 +687,12 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
* @return the resolved UserProfile
* @throws SQLException
*/
- private UserProfile findByPreparedStatement( String sql, Object index ) throws NoSuchPrincipalException
+ private UserProfile findByPreparedStatement( final String sql, final Object index ) throws NoSuchPrincipalException
{
UserProfile profile = null;
boolean found = false;
boolean unique = true;
- try( Connection conn = m_ds.getConnection(); PreparedStatement ps = conn.prepareStatement( sql ) ) {
+ try( final Connection conn = m_ds.getConnection(); final PreparedStatement ps = conn.prepareStatement( sql ) ) {
if( m_supportsCommits ) {
conn.setAutoCommit( false );
}
@@ -714,7 +707,7 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
}
// Go and get the record!
- try ( ResultSet rs = ps.executeQuery() ) {
+ try ( final ResultSet rs = ps.executeQuery() ) {
while ( rs.next() ) {
if( profile != null ) {
unique = false;
@@ -731,25 +724,25 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
profile.setEmail( rs.getString( m_email ) );
profile.setFullname( rs.getString( m_fullName ) );
profile.setLastModified( rs.getTimestamp( m_modified ) );
- Date lockExpiry = rs.getDate( m_lockExpiry );
+ final Date lockExpiry = rs.getDate( m_lockExpiry );
profile.setLockExpiry( rs.wasNull() ? null : lockExpiry );
profile.setLoginName( rs.getString( m_loginName ) );
profile.setPassword( rs.getString( m_password ) );
// Fetch the user attributes
- String rawAttributes = rs.getString( m_attributes );
+ final String rawAttributes = rs.getString( m_attributes );
if ( rawAttributes != null ) {
try {
- Map<String,? extends Serializable> attributes = Serializer.deserializeFromBase64( rawAttributes );
+ final Map<String,? extends Serializable> attributes = Serializer.deserializeFromBase64( rawAttributes );
profile.getAttributes().putAll( attributes );
- } catch ( IOException e ) {
+ } catch ( final IOException e ) {
log.error( "Could not parse user profile attributes!", e );
}
}
found = true;
}
}
- } catch( SQLException e ) {
+ } catch( final SQLException e ) {
throw new NoSuchPrincipalException( e.getMessage() );
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java
index 1312ecc..c8928cc 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/UserDatabase.java
@@ -18,103 +18,89 @@
*/
package org.apache.wiki.auth.user;
-import java.security.Principal;
-import java.util.Properties;
-
-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.WikiSecurityException;
+import java.security.Principal;
+import java.util.Properties;
+
/**
* Defines an interface for loading, persisting and storing users.
+ *
* @since 2.3
*/
-public interface UserDatabase
-{
+public interface UserDatabase {
/**
- * Looks up and deletes the first {@link UserProfile} in the user database
- * that matches a profile having a given login name. If the user database
- * does not contain a user with a matching attribute, throws a
- * {@link NoSuchPrincipalException}. This method is intended to be atomic;
- * results cannot be partially committed. If the commit fails, it should
- * roll back its state appropriately. Implementing classes that persist
- * to the file system may wish to make this method <code>synchronized</code>.
+ * Looks up and deletes the first {@link UserProfile} in the user database that matches a profile having a given login name. If the
+ * user database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}. This method is intended
+ * to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state appropriately. Implementing
+ * classes that persist to the file system may wish to make this method <code>synchronized</code>.
+ *
* @param loginName the login name of the user profile that shall be deleted
*/
void deleteByLoginName( String loginName ) throws NoSuchPrincipalException, WikiSecurityException;
/**
* <p>
- * Looks up the Principals representing a user from the user database. These
- * are defined as a set of Principals manufactured from the login name, full
- * name, and wiki name. The order of the Principals returned is not
- * significant. If the user database does not contain a user with the
- * supplied identifier, throws a {@link NoSuchPrincipalException}.
+ * Looks up the Principals representing a user from the user database. These are defined as a set of Principals manufactured from the
+ * login name, full name, and wiki name. The order of the Principals returned is not significant. If the user database does not contain
+ * a user with the supplied identifier, throws a {@link NoSuchPrincipalException}.
* </p>
* <p>
- * Note that if an implememtation wishes to mark one of the returned
- * Principals as representing the user's common name, it should instantiate
- * this Principal using
- * {@link org.apache.wiki.auth.WikiPrincipal#WikiPrincipal(String, String)}
- * with the <code>type</code> parameter set to
- * {@link org.apache.wiki.auth.WikiPrincipal#WIKI_NAME}. The method
- * {@link org.apache.wiki.WikiSession#getUserPrincipal()} will return this
- * principal as the "primary" principal. Note that this method can also be
- * used to mark a WikiPrincipal as a login name or a wiki name.
+ * Note that if an implememtation wishes to mark one of the returned Principals as representing the user's common name, it should
+ * instantiate this Principal using {@link org.apache.wiki.auth.WikiPrincipal#WikiPrincipal(String, String)} with the <code>type</code>
+ * parameter set to {@link org.apache.wiki.auth.WikiPrincipal#WIKI_NAME}. The method
+ * {@link org.apache.wiki.WikiSession#getUserPrincipal()} will return this principal as the "primary" principal. Note that this method
+ * can also be used to mark a WikiPrincipal as a login name or a wiki name.
* </p>
- * @param identifier the name of the user to retrieve; this corresponds to
- * value returned by the user profile's
- * {@link UserProfile#getLoginName()} method.
+ *
+ * @param identifier the name of the user to retrieve; this corresponds to value returned by the user profile's {@link UserProfile#getLoginName()} method.
* @return the array of Principals representing the user's identities
*/
Principal[] getPrincipals( String identifier ) throws NoSuchPrincipalException;
/**
- * Returns all WikiNames that are stored in the UserDatabase
- * as an array of Principal objects. If the database does not
- * contain any profiles, this method will return a zero-length
- * array.
+ * Returns all WikiNames that are stored in the UserDatabase as an array of Principal objects. If the database does not
+ * contain any profiles, this method will return a zero-length array.
+ *
* @return the WikiNames
*/
Principal[] getWikiNames() throws WikiSecurityException;
/**
- * Looks up and returns the first {@link UserProfile} in the user database
- * that whose login name, full name, or wiki name matches the supplied
- * string. This method provides a "forgiving" search algorithm for resolving
- * Principal names when the exact profile attribute that supplied the name
- * is unknown.
+ * Looks up and returns the first {@link UserProfile} in the user database that whose login name, full name, or wiki name matches the
+ * supplied string. This method provides a "forgiving" search algorithm for resolving Principal names when the exact profile attribute
+ * that supplied the name is unknown.
+ *
* @param index the login name, full name, or wiki name
*/
UserProfile find( String index ) throws NoSuchPrincipalException;
/**
- * Looks up and returns the first {@link UserProfile} in the user database
- * that matches a profile having a given e-mail address. If the user
- * database does not contain a user with a matching attribute, throws a
- * {@link NoSuchPrincipalException}.
+ * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given e-mail address. If
+ * the user database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+ *
* @param index the e-mail address of the desired user profile
* @return the user profile
*/
UserProfile findByEmail( String index ) throws NoSuchPrincipalException;
/**
- * Looks up and returns the first {@link UserProfile} in the user database
- * that matches a profile having a given login name. If the user database
- * does not contain a user with a matching attribute, throws a
- * {@link NoSuchPrincipalException}.
+ * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given login name. If the
+ * user database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+ *
* @param index the login name of the desired user profile
* @return the user profile
*/
UserProfile findByLoginName( String index ) throws NoSuchPrincipalException;
/**
- * Looks up and returns the first {@link UserProfile} in the user database
- * that matches a profile having a given unique ID (uid). If the user database
- * does not contain a user with a unique ID, it throws a
- * {@link NoSuchPrincipalException}.
+ * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given unique ID (uid). If
+ * the user database does not contain a user with a unique ID, it throws a {@link NoSuchPrincipalException}.
+ *
* @param uid the unique identifier of the desired user profile
* @return the user profile
* @since 2.8
@@ -122,95 +108,75 @@ public interface UserDatabase
UserProfile findByUid( String uid ) throws NoSuchPrincipalException;
/**
- * Looks up and returns the first {@link UserProfile} in the user database
- * that matches a profile having a given wiki name. If the user database
- * does not contain a user with a matching attribute, throws a
- * {@link NoSuchPrincipalException}.
+ * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given wiki name. If the user
+ * database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+ *
* @param index the wiki name of the desired user profile
* @return the user profile
*/
UserProfile findByWikiName( String index ) throws NoSuchPrincipalException;
/**
- * Looks up and returns the first {@link UserProfile} in the user database
- * that matches a profile having a given full name. If the user database
- * does not contain a user with a matching attribute, throws a
- * {@link NoSuchPrincipalException}.
+ * Looks up and returns the first {@link UserProfile} in the user database that matches a profile having a given full name. If the user
+ * database does not contain a user with a matching attribute, throws a {@link NoSuchPrincipalException}.
+ *
* @param index the fill name of the desired user profile
* @return the user profile
*/
UserProfile findByFullName( String index ) throws NoSuchPrincipalException;
- /**
- * Initializes the user database based on values from a Properties object.
- */
- void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
+ /** Initializes the user database based on values from a Properties object. */
+ void initialize( Engine engine, Properties props ) throws NoRequiredPropertyException, WikiSecurityException;
/**
- * Factory method that instantiates a new user profile.
- * The {@link UserProfile#isNew()} method of profiles created using
+ * Factory method that instantiates a new user profile. The {@link UserProfile#isNew()} method of profiles created using
* this method should return <code>true</code>.
*/
UserProfile newProfile();
/**
- * <p>Renames a {@link UserProfile} in the user database by changing
- * the profile's login name. Because the login name is the profile's unique
- * identifier, implementations should verify that the identifier is
- * "safe" to change before actually changing it. Specifically: the profile
- * with the supplied login name must already exist, and the proposed new
- * name must not be in use by another profile.</p>
- * <p>This method is intended to be atomic; results cannot be partially committed.
- * If the commit fails, it should roll back its state appropriately.
- * Implementing classes that persist to the file system may wish to make
- * this method <code>synchronized</code>.</p>
+ * <p>Renames a {@link UserProfile} in the user database by changing the profile's login name. Because the login name is the profile's
+ * unique identifier, implementations should verify that the identifier is "safe" to change before actually changing it. Specifically:
+ * the profile with the supplied login name must already exist, and the proposed new name must not be in use by another profile.</p>
+ * <p>This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state
+ * appropriately. Implementing classes that persist to the file system may wish to make this method <code>synchronized</code>.</p>
+ *
* @param loginName the existing login name for the profile
* @param newName the proposed new login name
- * @throws NoSuchPrincipalException if the user profile identified by
- * <code>loginName</code> does not exist
- * @throws DuplicateUserException if another user profile with the
- * proposed new login name already exists
- * @throws WikiSecurityException if the profile cannot be renamed for
- * any reason, such as an I/O error, database connection failure
+ * @throws NoSuchPrincipalException if the user profile identified by <code>loginName</code> does not exist
+ * @throws DuplicateUserException if another user profile with the proposed new login name already exists
+ * @throws WikiSecurityException if the profile cannot be renamed for any reason, such as an I/O error, database connection failure
* or lack of support for renames.
*/
void rename( String loginName, String newName ) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException;
/**
* <p>
- * Saves a {@link UserProfile}to the user database, overwriting the
- * existing profile if it exists. The user name under which the profile
- * should be saved is returned by the supplied profile's
- * {@link UserProfile#getLoginName()} method.
+ * Saves a {@link UserProfile}to the user database, overwriting the existing profile if it exists. The user name under which the profile
+ * should be saved is returned by the supplied profile's {@link UserProfile#getLoginName()} method.
* </p>
* <p>
- * The database implementation is responsible for detecting potential
- * duplicate user profiles; specifically, the login name, wiki name, and
- * full name must be unique. The implementation is not required to check for
- * validity of passwords or e-mail addresses. Special case: if the profile
- * already exists and the password is null, it should retain its previous
- * value, rather than being set to null.
+ * The database implementation is responsible for detecting potential duplicate user profiles; specifically, the login name, wiki name,
+ * and full name must be unique. The implementation is not required to check for validity of passwords or e-mail addresses. Special
+ * case: if the profile already exists and the password is null, it should retain its previous value, rather than being set to null.
* </p>
- * <p>Implementations are <em>required</em> to time-stamp the creation
- * or modification fields of the UserProfile./p>
- * <p>This method is intended to be atomic; results cannot be partially committed.
- * If the commit fails, it should roll back its state appropriately.
- * Implementing classes that persist to the file system may wish to make
- * this method <code>synchronized</code>.</p>
+ * <p>Implementations are <em>required</em> to time-stamp the creation or modification fields of the UserProfile./p>
+ * <p>This method is intended to be atomic; results cannot be partially committed. If the commit fails, it should roll back its state
+ * appropriately. Implementing classes that persist to the file system may wish to make this method <code>synchronized</code>.</p>
+ *
* @param profile the user profile to save
* @throws WikiSecurityException if the profile cannot be saved
*/
void save( UserProfile profile ) throws WikiSecurityException;
/**
- * Determines whether a supplied user password is valid, given a login name
- * and password. It is up to the implementing class to determine how the
- * comparison should be made. For example, the password might be hashed
- * before comparing it to the value persisted in the back-end data store.
+ * Determines whether a supplied user password is valid, given a login name and password. It is up to the implementing class to
+ * determine how the comparison should be made. For example, the password might be hashed before comparing it to the value persisted
+ * in the back-end data store.
+ *
* @param loginName the login name
* @param password the password
- * @return <code>true</code> if the password is valid, <code>false</code>
- * otherwise
+ * @return <code>true</code> if the password is valid, <code>false</code> otherwise
*/
boolean validatePassword( String loginName, String password );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
index 466587c..3357407 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
@@ -19,7 +19,7 @@
package org.apache.wiki.auth.user;
import org.apache.commons.lang3.StringUtils;
-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;
@@ -115,17 +115,17 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* {@link NoSuchPrincipalException}.
* @param loginName the login name of the user profile that shall be deleted
*/
- public synchronized void deleteByLoginName( String loginName ) throws NoSuchPrincipalException, WikiSecurityException
+ @Override public synchronized void deleteByLoginName( final String loginName ) throws NoSuchPrincipalException, WikiSecurityException
{
if ( c_dom == null )
{
throw new WikiSecurityException( "FATAL: database does not exist" );
}
- NodeList users = c_dom.getDocumentElement().getElementsByTagName( USER_TAG );
+ final NodeList users = c_dom.getDocumentElement().getElementsByTagName( USER_TAG );
for( int i = 0; i < users.getLength(); i++ )
{
- Element user = (Element) users.item( i );
+ final Element user = (Element) users.item( i );
if ( user.getAttribute( LOGIN_NAME ).equals( loginName ) )
{
c_dom.getDocumentElement().removeChild(user);
@@ -147,9 +147,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @return the user profile
* @see org.apache.wiki.auth.user.UserDatabase#findByEmail(String)
*/
- public UserProfile findByEmail( String index ) throws NoSuchPrincipalException
+ @Override public UserProfile findByEmail( final String index ) throws NoSuchPrincipalException
{
- UserProfile profile = findByAttribute( EMAIL, index );
+ final UserProfile profile = findByAttribute( EMAIL, index );
if ( profile != null )
{
return profile;
@@ -166,9 +166,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @return the user profile
* @see org.apache.wiki.auth.user.UserDatabase#findByFullName(java.lang.String)
*/
- public UserProfile findByFullName( String index ) throws NoSuchPrincipalException
+ @Override public UserProfile findByFullName( final String index ) throws NoSuchPrincipalException
{
- UserProfile profile = findByAttribute( FULL_NAME, index );
+ final UserProfile profile = findByAttribute( FULL_NAME, index );
if ( profile != null )
{
return profile;
@@ -185,9 +185,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @return the user profile
* @see org.apache.wiki.auth.user.UserDatabase#findByLoginName(java.lang.String)
*/
- public UserProfile findByLoginName( String index ) throws NoSuchPrincipalException
+ @Override public UserProfile findByLoginName( final String index ) throws NoSuchPrincipalException
{
- UserProfile profile = findByAttribute( LOGIN_NAME, index );
+ final UserProfile profile = findByAttribute( LOGIN_NAME, index );
if ( profile != null )
{
return profile;
@@ -198,9 +198,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
/**
* {@inheritDoc}
*/
- public UserProfile findByUid( String uid ) throws NoSuchPrincipalException
+ @Override public UserProfile findByUid( final String uid ) throws NoSuchPrincipalException
{
- UserProfile profile = findByAttribute( UID, uid );
+ final UserProfile profile = findByAttribute( UID, uid );
if ( profile != null )
{
return profile;
@@ -217,9 +217,9 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @return the user profile
* @see org.apache.wiki.auth.user.UserDatabase#findByWikiName(java.lang.String)
*/
- public UserProfile findByWikiName( String index ) throws NoSuchPrincipalException
+ @Override public UserProfile findByWikiName( final String index ) throws NoSuchPrincipalException
{
- UserProfile profile = findByAttribute( WIKI_NAME, index );
+ final UserProfile profile = findByAttribute( WIKI_NAME, index );
if ( profile != null )
{
return profile;
@@ -235,25 +235,25 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @return the WikiNames
* @throws WikiSecurityException In case things fail.
*/
- public Principal[] getWikiNames() throws WikiSecurityException
+ @Override public Principal[] getWikiNames() throws WikiSecurityException
{
if ( c_dom == null )
{
throw new IllegalStateException( "FATAL: database does not exist" );
}
- SortedSet<Principal> principals = new TreeSet<Principal>();
- NodeList users = c_dom.getElementsByTagName( USER_TAG );
+ final SortedSet<Principal> principals = new TreeSet<>();
+ final NodeList users = c_dom.getElementsByTagName( USER_TAG );
for( int i = 0; i < users.getLength(); i++ )
{
- Element user = (Element) users.item( i );
- String wikiName = user.getAttribute( WIKI_NAME );
+ final Element user = (Element) users.item( i );
+ final String wikiName = user.getAttribute( WIKI_NAME );
if ( wikiName == null )
{
log.warn( "Detected null wiki name in XMLUserDataBase. Check your user database." );
}
else
{
- Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
+ final Principal principal = new WikiPrincipal( wikiName, WikiPrincipal.WIKI_NAME );
principals.add( principal );
}
}
@@ -264,115 +264,83 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* Initializes the user database based on values from a Properties object.
* The properties object must contain a file path to the XML database file
* whose key is {@link #PROP_USERDATABASE}.
- * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.WikiEngine,
- * java.util.Properties)
+ * @see org.apache.wiki.auth.user.UserDatabase#initialize(org.apache.wiki.api.core.Engine, java.util.Properties)
* @throws NoRequiredPropertyException if the user database cannot be located, parsed, or opened
*/
- public void initialize( WikiEngine engine, Properties props ) throws NoRequiredPropertyException
- {
- File defaultFile = null;
- if( engine.getRootPath() == null )
- {
- log.warn( "Cannot identify JSPWiki root path" );
+ @Override public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException {
+ final File defaultFile;
+ if( engine.getRootPath() == null ) {
+ log.warn( "Cannot identify JSPWiki root path" );
defaultFile = new File( "WEB-INF/" + DEFAULT_USERDATABASE ).getAbsoluteFile();
- }
- else
- {
+ } else {
defaultFile = new File( engine.getRootPath() + "/WEB-INF/" + DEFAULT_USERDATABASE );
}
// Get database file location
- String file = TextUtil.getStringProperty(props, PROP_USERDATABASE, defaultFile.getAbsolutePath());
- if( file == null )
- {
- log.warn( "XML user database property " + PROP_USERDATABASE + " not found; trying " + defaultFile );
+ final String file = TextUtil.getStringProperty( props, PROP_USERDATABASE, defaultFile.getAbsolutePath() );
+ if( file == null ) {
+ log.warn( "XML user database property " + PROP_USERDATABASE + " not found; trying " + defaultFile );
c_file = defaultFile;
- }
- else
- {
+ } else {
c_file = new File( file );
}
- log.info("XML user database at "+c_file.getAbsolutePath());
+ log.info( "XML user database at " + c_file.getAbsolutePath() );
buildDOM();
sanitizeDOM();
}
- private void buildDOM()
- {
+ private void buildDOM() {
// Read DOM
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating( false );
factory.setExpandEntityReferences( false );
factory.setIgnoringComments( true );
factory.setNamespaceAware( false );
- try
- {
+ try {
c_dom = factory.newDocumentBuilder().parse( c_file );
log.debug( "Database successfully initialized" );
c_lastModified = c_file.lastModified();
- c_lastCheck = System.currentTimeMillis();
- }
- catch( ParserConfigurationException e )
- {
+ c_lastCheck = System.currentTimeMillis();
+ } catch( final ParserConfigurationException e ) {
log.error( "Configuration error: " + e.getMessage() );
- }
- catch( SAXException e )
- {
+ } catch( final SAXException e ) {
log.error( "SAX error: " + e.getMessage() );
- }
- catch( FileNotFoundException e )
- {
- log.info("User database not found; creating from scratch...");
- }
- catch( IOException e )
- {
+ } catch( final FileNotFoundException e ) {
+ log.info( "User database not found; creating from scratch..." );
+ } catch( final IOException e ) {
log.error( "IO error: " + e.getMessage() );
}
- if ( c_dom == null )
- {
- try
- {
- //
+ if( c_dom == null ) {
+ try {
// Create the DOM from scratch
- //
c_dom = factory.newDocumentBuilder().newDocument();
- c_dom.appendChild( c_dom.createElement( "users") );
- }
- catch( ParserConfigurationException e )
- {
+ c_dom.appendChild( c_dom.createElement( "users" ) );
+ } catch( final ParserConfigurationException e ) {
log.fatal( "Could not create in-memory DOM" );
}
}
}
- private void saveDOM() throws WikiSecurityException
- {
- if ( c_dom == null )
- {
+ private void saveDOM() throws WikiSecurityException {
+ if( c_dom == null ) {
log.fatal( "User database doesn't exist in memory." );
}
- File newFile = new File( c_file.getAbsolutePath() + ".new" );
- try
- (
- BufferedWriter io = new BufferedWriter( new OutputStreamWriter (
- new FileOutputStream( newFile ), "UTF-8" ) );
- )
- {
+ final File newFile = new File( c_file.getAbsolutePath() + ".new" );
+ try( final BufferedWriter io = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( newFile ), "UTF-8" ) ) ) {
// Write the file header and document root
- io.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- io.write("<users>\n");
+ io.write( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
+ io.write( "<users>\n" );
// Write each profile as a <user> node
- Element root = c_dom.getDocumentElement();
- NodeList nodes = root.getElementsByTagName( USER_TAG );
- for( int i = 0; i < nodes.getLength(); i++ )
- {
- Element user = (Element)nodes.item( i );
- io.write( " <" + USER_TAG + " ");
+ final Element root = c_dom.getDocumentElement();
+ final NodeList nodes = root.getElementsByTagName( USER_TAG );
+ for( int i = 0; i < nodes.getLength(); i++ ) {
+ final Element user = ( Element )nodes.item( i );
+ io.write( " <" + USER_TAG + " " );
io.write( UID );
io.write( "=\"" + user.getAttribute( UID ) + "\" " );
io.write( LOGIN_NAME );
@@ -392,43 +360,34 @@ public class XMLUserDatabase extends AbstractUserDatabase {
io.write( LOCK_EXPIRY );
io.write( "=\"" + user.getAttribute( LOCK_EXPIRY ) + "\" " );
io.write( ">" );
- NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
- for ( int j = 0; j < attributes.getLength(); j++ )
- {
- Element attribute = (Element)attributes.item( j );
- String value = extractText( attribute );
+ final NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
+ for( int j = 0; j < attributes.getLength(); j++ ) {
+ final Element attribute = ( Element )attributes.item( j );
+ final String value = extractText( attribute );
io.write( "\n <" + ATTRIBUTES_TAG + ">" );
io.write( value );
io.write( "</" + ATTRIBUTES_TAG + ">" );
}
- io.write("\n </" +USER_TAG + ">\n");
+ io.write( "\n </" + USER_TAG + ">\n" );
}
- io.write("</users>");
- io.close();
- }
- catch ( IOException e )
- {
+ io.write( "</users>" );
+ } catch( final IOException e ) {
throw new WikiSecurityException( e.getLocalizedMessage(), e );
}
// Copy new file over old version
- File backup = new File( c_file.getAbsolutePath() + ".old" );
- if ( backup.exists() )
- {
- if ( !backup.delete() )
- {
+ final File backup = new File( c_file.getAbsolutePath() + ".old" );
+ if( backup.exists() ) {
+ if( !backup.delete() ) {
log.error( "Could not delete old user database backup: " + backup );
}
}
- if ( !c_file.renameTo( backup ) )
- {
+ if( !c_file.renameTo( backup ) ) {
log.error( "Could not create user database backup: " + backup );
}
- if ( !newFile.renameTo( c_file ) )
- {
+ if( !newFile.renameTo( c_file ) ) {
log.error( "Could not save database: " + backup + " restoring backup." );
- if ( !backup.renameTo( c_file ) )
- {
+ if( !backup.renameTo( c_file ) ) {
log.error( "Restore failed. Check the file permissions." );
}
log.error( "Could not save database: " + c_file + ". Check the file permissions" );
@@ -438,16 +397,12 @@ public class XMLUserDatabase extends AbstractUserDatabase {
private long c_lastCheck = 0;
private long c_lastModified = 0;
- private void checkForRefresh()
- {
- long time = System.currentTimeMillis();
+ private void checkForRefresh() {
+ final long time = System.currentTimeMillis();
+ if( time - c_lastCheck > 60 * 1000L ) {
+ final long lastModified = c_file.lastModified();
- if( time - c_lastCheck > 60*1000L )
- {
- long lastModified = c_file.lastModified();
-
- if( lastModified > c_lastModified )
- {
+ if( lastModified > c_lastModified ) {
buildDOM();
}
}
@@ -456,7 +411,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
/**
* @see org.apache.wiki.auth.user.UserDatabase#rename(String, String)
*/
- public synchronized void rename(String loginName, String newName) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException
+ @Override public synchronized void rename( final String loginName, final String newName) throws NoSuchPrincipalException, DuplicateUserException, WikiSecurityException
{
if ( c_dom == null )
{
@@ -466,31 +421,31 @@ public class XMLUserDatabase extends AbstractUserDatabase {
checkForRefresh();
// Get the existing user; if not found, throws NoSuchPrincipalException
- UserProfile profile = findByLoginName( loginName );
+ final UserProfile profile = findByLoginName( loginName );
// Get user with the proposed name; if found, it's a collision
try
{
- UserProfile otherProfile = findByLoginName( newName );
+ final UserProfile otherProfile = findByLoginName( newName );
if ( otherProfile != null )
{
throw new DuplicateUserException( "security.error.cannot.rename", newName );
}
}
- catch ( NoSuchPrincipalException e )
+ catch ( final NoSuchPrincipalException e )
{
// Good! That means it's safe to save using the new name
}
// Find the user with the old login id attribute, and change it
- NodeList users = c_dom.getElementsByTagName( USER_TAG );
+ final NodeList users = c_dom.getElementsByTagName( USER_TAG );
for( int i = 0; i < users.getLength(); i++ )
{
- Element user = (Element) users.item( i );
+ final Element user = (Element) users.item( i );
if ( user.getAttribute( LOGIN_NAME ).equals( loginName ) )
{
- DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
- Date modDate = new Date( System.currentTimeMillis() );
+ final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+ final Date modDate = new Date( System.currentTimeMillis() );
setAttribute( user, LOGIN_NAME, newName );
setAttribute( user, LAST_MODIFIED, c_format.format( modDate ) );
profile.setLoginName( newName );
@@ -511,7 +466,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @param profile the user profile to save
* @throws WikiSecurityException if the profile cannot be saved
*/
- public synchronized void save( UserProfile profile ) throws WikiSecurityException
+ @Override public synchronized void save( final UserProfile profile ) throws WikiSecurityException
{
if ( c_dom == null )
{
@@ -521,13 +476,13 @@ public class XMLUserDatabase extends AbstractUserDatabase {
checkForRefresh();
- DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
- String index = profile.getLoginName();
- NodeList users = c_dom.getElementsByTagName( USER_TAG );
+ final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+ final String index = profile.getLoginName();
+ final NodeList users = c_dom.getElementsByTagName( USER_TAG );
Element user = null;
for( int i = 0; i < users.getLength(); i++ )
{
- Element currentUser = (Element) users.item( i );
+ final Element currentUser = (Element) users.item( i );
if ( currentUser.getAttribute( LOGIN_NAME ).equals( index ) )
{
user = currentUser;
@@ -537,7 +492,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
boolean isNew = false;
- Date modDate = new Date( System.currentTimeMillis() );
+ final Date modDate = new Date( System.currentTimeMillis() );
if( user == null )
{
// Create new user node
@@ -551,7 +506,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
else
{
// To update existing user node, delete old attributes first...
- NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
+ final NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
for ( int i = 0; i < attributes.getLength(); i++ )
{
user.removeChild( attributes.item( i ) );
@@ -564,14 +519,14 @@ public class XMLUserDatabase extends AbstractUserDatabase {
setAttribute( user, FULL_NAME, profile.getFullname() );
setAttribute( user, WIKI_NAME, profile.getWikiName() );
setAttribute( user, EMAIL, profile.getEmail() );
- Date lockExpiry = profile.getLockExpiry();
+ final Date lockExpiry = profile.getLockExpiry();
setAttribute( user, LOCK_EXPIRY, lockExpiry == null ? "" : c_format.format( lockExpiry ) );
// Hash and save the new password if it's different from old one
- String newPassword = profile.getPassword();
+ final String newPassword = profile.getPassword();
if ( newPassword != null && !newPassword.equals( "" ) )
{
- String oldPassword = user.getAttribute( PASSWORD );
+ final String oldPassword = user.getAttribute( PASSWORD );
if ( !oldPassword.equals( newPassword ) )
{
setAttribute( user, PASSWORD, getHash( newPassword ) );
@@ -583,13 +538,13 @@ public class XMLUserDatabase extends AbstractUserDatabase {
{
try
{
- String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes() );
- Element attributes = c_dom.createElement( ATTRIBUTES_TAG );
+ final String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes() );
+ final Element attributes = c_dom.createElement( ATTRIBUTES_TAG );
user.appendChild( attributes );
- Text value = c_dom.createTextNode( encodedAttributes );
+ final Text value = c_dom.createTextNode( encodedAttributes );
attributes.appendChild( value );
}
- catch ( IOException e )
+ catch ( final IOException e )
{
throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
}
@@ -614,7 +569,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @param index
* @return the profile, or <code>null</code> if not found
*/
- private UserProfile findByAttribute( String matchAttribute, String index )
+ private UserProfile findByAttribute( final String matchAttribute, String index )
{
if ( c_dom == null )
{
@@ -623,7 +578,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
checkForRefresh();
- NodeList users = c_dom.getElementsByTagName( USER_TAG );
+ final NodeList users = c_dom.getElementsByTagName( USER_TAG );
if( users == null ) return null;
@@ -636,7 +591,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
for( int i = 0; i < users.getLength(); i++ )
{
- Element user = (Element) users.item( i );
+ final Element user = (Element) users.item( i );
String userAttribute = user.getAttribute( matchAttribute );
if (!caseSensitiveCompare)
{
@@ -645,7 +600,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
}
if ( userAttribute.equals( index ) )
{
- UserProfile profile = newProfile();
+ final UserProfile profile = newProfile();
// Parse basic attributes
profile.setUid( user.getAttribute( UID ) );
@@ -659,13 +614,13 @@ public class XMLUserDatabase extends AbstractUserDatabase {
profile.setEmail( user.getAttribute( EMAIL ) );
// Get created/modified timestamps
- String created = user.getAttribute( CREATED );
- String modified = user.getAttribute( LAST_MODIFIED );
+ final String created = user.getAttribute( CREATED );
+ final String modified = user.getAttribute( LAST_MODIFIED );
profile.setCreated( parseDate( profile, created ) );
profile.setLastModified( parseDate( profile, modified ) );
// Is the profile locked?
- String lockExpiry = user.getAttribute( LOCK_EXPIRY );
+ final String lockExpiry = user.getAttribute( LOCK_EXPIRY );
if ( lockExpiry == null || lockExpiry.length() == 0 )
{
profile.setLockExpiry( null );
@@ -676,17 +631,17 @@ public class XMLUserDatabase extends AbstractUserDatabase {
}
// Extract all of the user's attributes (should only be one attributes tag, but you never know!)
- NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
+ final NodeList attributes = user.getElementsByTagName( ATTRIBUTES_TAG );
for ( int j = 0; j < attributes.getLength(); j++ )
{
- Element attribute = (Element)attributes.item( j );
- String serializedMap = extractText( attribute );
+ final Element attribute = (Element)attributes.item( j );
+ final String serializedMap = extractText( attribute );
try
{
- Map<String,? extends Serializable> map = Serializer.deserializeFromBase64( serializedMap );
+ final Map<String,? extends Serializable> map = Serializer.deserializeFromBase64( serializedMap );
profile.getAttributes().putAll( map );
}
- catch ( IOException e )
+ catch ( final IOException e )
{
log.error( "Could not parse user profile attributes!", e );
}
@@ -703,15 +658,15 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @param element the base element
* @return the text nodes that are immediate children of the base element, concatenated together
*/
- private String extractText( Element element )
+ private String extractText( final Element element )
{
String text = "";
if ( element.getChildNodes().getLength() > 0 )
{
- NodeList children = element.getChildNodes();
+ final NodeList children = element.getChildNodes();
for ( int k = 0; k < children.getLength(); k++ )
{
- Node child = children.item( k );
+ final Node child = children.item( k );
if ( child.getNodeType() == Node.TEXT_NODE )
{
text = text + ((Text)child).getData();
@@ -729,20 +684,20 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @param date
* @return A parsed date, or null, if both parse attempts fail.
*/
- private Date parseDate( UserProfile profile, String date )
+ private Date parseDate( final UserProfile profile, final String date )
{
try
{
- DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+ final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
return c_format.parse( date );
}
- catch( ParseException e )
+ catch( final ParseException e )
{
try
{
return DateFormat.getDateTimeInstance().parse( date );
}
- catch ( ParseException e2)
+ catch ( final ParseException e2)
{
log.warn("Could not parse 'created' or 'lastModified' "
+ "attribute for "
@@ -764,10 +719,10 @@ public class XMLUserDatabase extends AbstractUserDatabase {
throw new IllegalStateException( "FATAL: database does not exist" );
}
- NodeList users = c_dom.getElementsByTagName( USER_TAG );
+ final NodeList users = c_dom.getElementsByTagName( USER_TAG );
for( int i = 0; i < users.getLength(); i++ )
{
- Element user = (Element) users.item( i );
+ final Element user = (Element) users.item( i );
// Sanitize UID (and generate a new one if one does not exist)
String uid = user.getAttribute( UID ).trim();
@@ -778,10 +733,10 @@ public class XMLUserDatabase extends AbstractUserDatabase {
}
// Sanitize dates
- String loginName = user.getAttribute( LOGIN_NAME );
+ final String loginName = user.getAttribute( LOGIN_NAME );
String created = user.getAttribute( CREATED );
String modified = user.getAttribute( LAST_MODIFIED );
- DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
+ final DateFormat c_format = new SimpleDateFormat( DATE_FORMAT );
try
{
created = c_format.format( c_format.parse( created ) );
@@ -789,7 +744,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
user.setAttribute( CREATED, created );
user.setAttribute( LAST_MODIFIED, modified );
}
- catch( ParseException e )
+ catch( final ParseException e )
{
try
{
@@ -798,7 +753,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
user.setAttribute( CREATED, created );
user.setAttribute( LAST_MODIFIED, modified );
}
- catch ( ParseException e2 )
+ catch ( final ParseException e2 )
{
log.warn( "Could not parse 'created' or 'lastModified' attribute for profile '" + loginName + "'."
+ " It may have been tampered with." );
@@ -813,7 +768,7 @@ public class XMLUserDatabase extends AbstractUserDatabase {
* @param attribute the name of the attribute to set
* @param value the desired attribute value
*/
- private void setAttribute( Element element, String attribute, String value ) {
+ private void setAttribute( final Element element, final String attribute, final String value ) {
if( value != null ) {
element.setAttribute( attribute, value );
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java
index a0f2557..0ee74e5 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/DefaultTasksManager.java
@@ -18,15 +18,15 @@
*/
package org.apache.wiki.tasks;
-import java.util.Locale;
-
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.tasks.auth.SaveUserProfileTask;
import org.apache.wiki.tasks.pages.PreSaveWikiPageTask;
import org.apache.wiki.tasks.pages.SaveWikiPageTask;
import org.apache.wiki.workflow.Step;
+import java.util.Locale;
+
/**
* Default implementation for {@link TasksManager}.
@@ -37,7 +37,7 @@ public class DefaultTasksManager implements TasksManager {
* {@inheritDoc}
*/
@Override
- public Step buildPreSaveWikiPageTask( WikiContext context, String proposedText ) {
+ public Step buildPreSaveWikiPageTask( final WikiContext context, final String proposedText ) {
return new PreSaveWikiPageTask( context, proposedText );
}
@@ -53,7 +53,7 @@ public class DefaultTasksManager implements TasksManager {
* {@inheritDoc}
*/
@Override
- public Step buildSaveUserProfileTask( WikiEngine engine, Locale loc ) {
+ public Step buildSaveUserProfileTask( final Engine engine, final Locale loc ) {
return new SaveUserProfileTask( engine, loc );
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java
index f2a7b61..c78774c 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/TasksManager.java
@@ -19,7 +19,7 @@
package org.apache.wiki.tasks;
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.workflow.Step;
import java.security.Principal;
@@ -64,6 +64,6 @@ public interface TasksManager {
* @param loc text proposed to be saved on the wiki page.
* @return a save user profile task.
*/
- Step buildSaveUserProfileTask( WikiEngine engine, Locale loc );
+ Step buildSaveUserProfileTask( Engine engine, Locale loc );
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
index 3ec7cb3..22f0f20 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/tasks/auth/SaveUserProfileTask.java
@@ -2,8 +2,9 @@ package org.apache.wiki.tasks.auth;
import org.apache.log4j.Logger;
import org.apache.wiki.WikiContext;
-import org.apache.wiki.WikiEngine;
+import org.apache.wiki.api.core.Engine;
import org.apache.wiki.api.exceptions.WikiException;
+import org.apache.wiki.auth.UserManager;
import org.apache.wiki.auth.user.UserProfile;
import org.apache.wiki.i18n.InternationalizationManager;
import org.apache.wiki.tasks.TasksManager;
@@ -24,14 +25,15 @@ public class SaveUserProfileTask extends Task {
private static final long serialVersionUID = 6994297086560480285L;
private static final Logger LOG = Logger.getLogger( SaveUserProfileTask.class );
- private final WikiEngine m_engine;
+ private final Engine m_engine;
private final Locale m_loc;
/**
* Constructs a new Task for saving a user profile.
+ *
* @param engine the wiki engine
*/
- public SaveUserProfileTask( final WikiEngine engine, final Locale loc ) {
+ public SaveUserProfileTask( final Engine engine, final Locale loc ) {
super( TasksManager.USER_PROFILE_SAVE_TASK_MESSAGE_KEY );
m_engine = engine;
m_loc = loc;
@@ -39,8 +41,8 @@ public class SaveUserProfileTask extends Task {
/**
* Saves the user profile to the user database.
- * @return {@link org.apache.wiki.workflow.Outcome#STEP_COMPLETE} if the
- * task completed successfully
+ *
+ * @return {@link org.apache.wiki.workflow.Outcome#STEP_COMPLETE} if the task completed successfully
* @throws WikiException if the save did not complete for some reason
*/
@Override
@@ -49,12 +51,12 @@ public class SaveUserProfileTask extends Task {
final UserProfile profile = ( UserProfile )getWorkflow().getAttribute( WorkflowManager.WF_UP_CREATE_SAVE_ATTR_SAVED_PROFILE );
// Save the profile (userdatabase will take care of timestamps for us)
- m_engine.getUserManager().getUserDatabase().save( profile );
+ m_engine.getManager( UserManager.class ).getUserDatabase().save( profile );
// Send e-mail if user supplied an e-mail address
- if ( profile.getEmail() != null ) {
+ if ( profile != null && profile.getEmail() != null ) {
try {
- final InternationalizationManager i18n = m_engine.getInternationalizationManager();
+ final InternationalizationManager i18n = m_engine.getManager( InternationalizationManager.class );
final String app = m_engine.getApplicationName();
final String to = profile.getEmail();
final String subject = i18n.get( InternationalizationManager.DEF_TEMPLATE, m_loc,
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java
index 4aa3de8..c18b8b8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowBuilder.java
@@ -18,26 +18,26 @@
*/
package org.apache.wiki.workflow;
+import org.apache.wiki.api.core.Engine;
+import org.apache.wiki.api.exceptions.WikiException;
+
import java.security.Principal;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import org.apache.wiki.WikiEngine;
-import org.apache.wiki.api.exceptions.WikiException;
-
/**
* Factory class that creates common Workflow instances such as a standard approval workflow.
*/
-public final class WorkflowBuilder
-{
- private static final Map<WikiEngine, WorkflowBuilder> BUILDERS = new ConcurrentHashMap<>();
- private final WikiEngine m_engine;
+public final class WorkflowBuilder {
+
+ private static final Map< Engine, WorkflowBuilder > BUILDERS = new ConcurrentHashMap<>();
+ private final Engine m_engine;
/**
* Private constructor that creates a new WorkflowBuilder for the supplied WikiEngine.
* @param engine the wiki engine
*/
- private WorkflowBuilder( WikiEngine engine )
+ private WorkflowBuilder( final Engine engine )
{
m_engine = engine;
}
@@ -48,11 +48,9 @@ public final class WorkflowBuilder
* @param engine the wiki engine
* @return the workflow builder
*/
- public static WorkflowBuilder getBuilder( WikiEngine engine )
- {
+ public static WorkflowBuilder getBuilder( final Engine engine ) {
WorkflowBuilder builder = BUILDERS.get( engine );
- if ( builder == null )
- {
+ if ( builder == null ) {
builder = new WorkflowBuilder( engine );
BUILDERS.put( engine, builder );
}
@@ -102,46 +100,40 @@ public final class WorkflowBuilder
* @return the created workflow
* @throws WikiException if the name of the approving user, Role or Group cannot be determined
*/
- public Workflow buildApprovalWorkflow( Principal submitter,
- String workflowApproverKey,
- Step prepTask,
- String decisionKey,
- Fact[] facts,
- Step completionTask,
- String rejectedMessageKey ) throws WikiException
- {
- WorkflowManager mgr = m_engine.getWorkflowManager();
- Workflow workflow = new Workflow( workflowApproverKey, submitter );
+ public Workflow buildApprovalWorkflow( final Principal submitter,
+ final String workflowApproverKey,
+ final Step prepTask,
+ final String decisionKey,
+ final Fact[] facts,
+ final Step completionTask,
+ final String rejectedMessageKey ) throws WikiException {
+ final WorkflowManager mgr = m_engine.getManager( WorkflowManager.class );
+ final Workflow workflow = new Workflow( workflowApproverKey, submitter );
// Is a Decision required to run the approve task?
- boolean decisionRequired = mgr.requiresApproval( workflowApproverKey );
+ final boolean decisionRequired = mgr.requiresApproval( workflowApproverKey );
// If Decision required, create a simple approval workflow
- if ( decisionRequired )
- {
+ if ( decisionRequired ) {
// Look up the name of the approver (user or group) listed in jspwiki.properties;
// approvals go to the approver's decision cue
- Principal approverPrincipal = mgr.getApprover( workflowApproverKey );
- Decision decision = new SimpleDecision( workflow, decisionKey, approverPrincipal );
+ final Principal approverPrincipal = mgr.getApprover( workflowApproverKey );
+ final Decision decision = new SimpleDecision( workflow, decisionKey, approverPrincipal );
// Add facts to the Decision, if any were supplied
- if ( facts != null )
- {
- for ( Fact fact: facts )
- {
+ if( facts != null ) {
+ for( final Fact fact : facts ) {
decision.addFact( fact );
}
// Add the first one as a message key
- if ( facts.length > 0 )
- {
- workflow.addMessageArgument( facts[0].getValue() );
+ if( facts.length > 0 ) {
+ workflow.addMessageArgument( facts[ 0 ].getValue() );
}
}
// If rejected, sent a notification
- if ( rejectedMessageKey != null )
- {
- SimpleNotification rejectNotification = new SimpleNotification( workflow, rejectedMessageKey, submitter );
+ if ( rejectedMessageKey != null ) {
+ final SimpleNotification rejectNotification = new SimpleNotification( workflow, rejectedMessageKey, submitter );
decision.addSuccessor( Outcome.DECISION_DENY, rejectNotification );
}
@@ -149,35 +141,24 @@ public final class WorkflowBuilder
decision.addSuccessor( Outcome.DECISION_APPROVE, completionTask );
// Set the first step
- if ( prepTask == null )
- {
+ if( prepTask == null ) {
workflow.setFirstStep( decision );
- }
- else
- {
+ } else {
workflow.setFirstStep( prepTask );
prepTask.addSuccessor( Outcome.STEP_COMPLETE, decision );
}
- }
-
- // If Decision not required, just run the prep + approved tasks in succession
- else
- {
+ } else { // If Decision not required, just run the prep + approved tasks in succession
// Set the first step
- if ( prepTask == null )
- {
+ if ( prepTask == null ) {
workflow.setFirstStep( completionTask );
- }
- else
- {
+ } else {
workflow.setFirstStep( prepTask );
prepTask.addSuccessor( Outcome.STEP_COMPLETE, completionTask );
}
}
// Make sure our tasks have this workflow as the parent, then return
- if ( prepTask != null )
- {
+ if( prepTask != null ) {
prepTask.setWorkflow( workflow );
}
completionTask.setWorkflow( workflow );
diff --git a/jspwiki-main/src/main/resources/ini/classmappings.xml b/jspwiki-main/src/main/resources/ini/classmappings.xml
index b419955..d572965 100644
--- a/jspwiki-main/src/main/resources/ini/classmappings.xml
+++ b/jspwiki-main/src/main/resources/ini/classmappings.xml
@@ -77,7 +77,7 @@
</mapping>
<mapping>
<requestedClass>org.apache.wiki.auth.UserManager</requestedClass>
- <mappedClass>org.apache.wiki.auth.UserManager</mappedClass>
+ <mappedClass>org.apache.wiki.auth.DefaultUserManager</mappedClass>
</mapping>
<mapping>
<requestedClass>org.apache.wiki.auth.acl.AclManager</requestedClass>