Search in sources :

Example 16 with UserProfile

use of org.apache.wiki.auth.user.UserProfile in project jspwiki by apache.

the class UserManager method getUserProfile.

/**
 * <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
 */
public UserProfile getUserProfile(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;
}
Also used : UserProfile(org.apache.wiki.auth.user.UserProfile) Principal(java.security.Principal)

Example 17 with UserProfile

use of org.apache.wiki.auth.user.UserProfile in project jspwiki by apache.

the class UserManager method setUserProfile.

/**
 * <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 {
    // 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.");
    }
    // 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) ? false : !(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()) {
        final WorkflowBuilder builder = WorkflowBuilder.getBuilder(m_engine);
        final Principal submitter = session.getUserPrincipal();
        final Task completionTask = new SaveUserProfileTask(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(PREFS_FULL_NAME, profile.getFullname());
        facts[1] = new Fact(PREFS_LOGIN_NAME, profile.getLoginName());
        facts[2] = new Fact(FACT_SUBMITTER, submitter.getName());
        if (hasEmail) {
            facts[3] = new Fact(PREFS_EMAIL, profile.getEmail());
        }
        final Workflow workflow = builder.buildApprovalWorkflow(submitter, SAVE_APPROVER, null, SAVE_DECISION_MESSAGE_KEY, facts, completionTask, null);
        workflow.setAttribute(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");
        }
        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);
    } else // For existing accounts, just save the profile
    {
        // 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);
        }
    }
}
Also used : Task(org.apache.wiki.workflow.Task) WikiException(org.apache.wiki.api.exceptions.WikiException) UserProfile(org.apache.wiki.auth.user.UserProfile) DecisionRequiredException(org.apache.wiki.workflow.DecisionRequiredException) Workflow(org.apache.wiki.workflow.Workflow) DuplicateUserException(org.apache.wiki.auth.user.DuplicateUserException) Fact(org.apache.wiki.workflow.Fact) Decision(org.apache.wiki.workflow.Decision) WikiPermission(org.apache.wiki.auth.permissions.WikiPermission) Permission(java.security.Permission) AllPermission(org.apache.wiki.auth.permissions.AllPermission) WorkflowBuilder(org.apache.wiki.workflow.WorkflowBuilder) WikiPermission(org.apache.wiki.auth.permissions.WikiPermission) Principal(java.security.Principal)

Example 18 with UserProfile

use of org.apache.wiki.auth.user.UserProfile in project jspwiki by apache.

the class PageManager method actionPerformed.

/**
 * Listens for {@link org.apache.wiki.event.WikiSecurityEvent#PROFILE_NAME_CHANGED}
 * events. If a user profile's name changes, each page ACL is inspected. If an entry contains
 * a name that has changed, it is replaced with the new one. No events are emitted
 * as a consequence of this method, because the page contents are still the same; it is
 * only the representations of the names within the ACL that are changing.
 *
 * @param event The event
 */
public void actionPerformed(WikiEvent event) {
    if (!(event instanceof WikiSecurityEvent)) {
        return;
    }
    WikiSecurityEvent se = (WikiSecurityEvent) event;
    if (se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED) {
        UserProfile[] profiles = (UserProfile[]) se.getTarget();
        Principal[] oldPrincipals = new Principal[] { new WikiPrincipal(profiles[0].getLoginName()), new WikiPrincipal(profiles[0].getFullname()), new WikiPrincipal(profiles[0].getWikiName()) };
        Principal newPrincipal = new WikiPrincipal(profiles[1].getFullname());
        // Examine each page ACL
        try {
            int pagesChanged = 0;
            Collection pages = getAllPages();
            for (Iterator it = pages.iterator(); it.hasNext(); ) {
                WikiPage page = (WikiPage) it.next();
                boolean aclChanged = changeAcl(page, oldPrincipals, newPrincipal);
                if (aclChanged) {
                    // If the Acl needed changing, change it now
                    try {
                        m_engine.getAclManager().setPermissions(page, page.getAcl());
                    } catch (WikiSecurityException e) {
                        log.error("Could not change page ACL for page " + page.getName() + ": " + e.getMessage(), e);
                    }
                    pagesChanged++;
                }
            }
            log.info("Profile name change for '" + newPrincipal.toString() + "' caused " + pagesChanged + " page ACLs to change also.");
        } catch (ProviderException e) {
            // Oooo! This is really bad...
            log.error("Could not change user name in Page ACLs because of Provider error:" + e.getMessage(), e);
        }
    }
}
Also used : UserProfile(org.apache.wiki.auth.user.UserProfile) ProviderException(org.apache.wiki.api.exceptions.ProviderException) WikiSecurityException(org.apache.wiki.auth.WikiSecurityException) WikiPrincipal(org.apache.wiki.auth.WikiPrincipal) Iterator(java.util.Iterator) Collection(java.util.Collection) WikiSecurityEvent(org.apache.wiki.event.WikiSecurityEvent) WikiPrincipal(org.apache.wiki.auth.WikiPrincipal) Principal(java.security.Principal)

Example 19 with UserProfile

use of org.apache.wiki.auth.user.UserProfile in project jspwiki by apache.

the class GroupManager method actionPerformed.

/**
 * Listens for {@link org.apache.wiki.event.WikiSecurityEvent#PROFILE_NAME_CHANGED}
 * events. If a user profile's name changes, each group is inspected. If an entry contains
 * a name that has changed, it is replaced with the new one. No group events are emitted
 * as a consequence of this method, because the group memberships are still the same; it is
 * only the representations of the names within that are changing.
 * @param event the incoming event
 */
public void actionPerformed(WikiEvent event) {
    if (!(event instanceof WikiSecurityEvent)) {
        return;
    }
    WikiSecurityEvent se = (WikiSecurityEvent) event;
    if (se.getType() == WikiSecurityEvent.PROFILE_NAME_CHANGED) {
        WikiSession session = se.getSrc();
        UserProfile[] profiles = (UserProfile[]) se.getTarget();
        Principal[] oldPrincipals = new Principal[] { new WikiPrincipal(profiles[0].getLoginName()), new WikiPrincipal(profiles[0].getFullname()), new WikiPrincipal(profiles[0].getWikiName()) };
        Principal newPrincipal = new WikiPrincipal(profiles[1].getFullname());
        // Examine each group
        int groupsChanged = 0;
        try {
            for (Group group : m_groupDatabase.groups()) {
                boolean groupChanged = false;
                for (Principal oldPrincipal : oldPrincipals) {
                    if (group.isMember(oldPrincipal)) {
                        group.remove(oldPrincipal);
                        group.add(newPrincipal);
                        groupChanged = true;
                    }
                }
                if (groupChanged) {
                    setGroup(session, group);
                    groupsChanged++;
                }
            }
        } catch (WikiException e) {
            // Oooo! This is really bad...
            log.error("Could not change user name in Group lists because of GroupDatabase error:" + e.getMessage());
        }
        log.info("Profile name change for '" + newPrincipal.toString() + "' caused " + groupsChanged + " groups to change also.");
    }
}
Also used : WikiSession(org.apache.wiki.WikiSession) WikiException(org.apache.wiki.api.exceptions.WikiException) UserProfile(org.apache.wiki.auth.user.UserProfile) WikiPrincipal(org.apache.wiki.auth.WikiPrincipal) WikiSecurityEvent(org.apache.wiki.event.WikiSecurityEvent) GroupPrincipal(org.apache.wiki.auth.GroupPrincipal) WikiPrincipal(org.apache.wiki.auth.WikiPrincipal) Principal(java.security.Principal)

Aggregations

UserProfile (org.apache.wiki.auth.user.UserProfile)19 Principal (java.security.Principal)10 WikiSession (org.apache.wiki.WikiSession)9 WikiSessionTest (org.apache.wiki.WikiSessionTest)6 Test (org.junit.Test)6 UserDatabase (org.apache.wiki.auth.user.UserDatabase)5 HttpServletRequest (javax.servlet.http.HttpServletRequest)4 WikiPrincipal (org.apache.wiki.auth.WikiPrincipal)4 Collection (java.util.Collection)3 NoSuchPrincipalException (org.apache.wiki.auth.NoSuchPrincipalException)3 UserManager (org.apache.wiki.auth.UserManager)3 WikiSecurityException (org.apache.wiki.auth.WikiSecurityException)3 Group (org.apache.wiki.auth.authorize.Group)3 Decision (org.apache.wiki.workflow.Decision)3 DecisionRequiredException (org.apache.wiki.workflow.DecisionRequiredException)3 Fact (org.apache.wiki.workflow.Fact)3 List (java.util.List)2 WikiException (org.apache.wiki.api.exceptions.WikiException)2 GroupPrincipal (org.apache.wiki.auth.GroupPrincipal)2 UnresolvedPrincipal (org.apache.wiki.auth.acl.UnresolvedPrincipal)2