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;
}
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);
}
}
}
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);
}
}
}
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.");
}
}
Aggregations