001/*
002 * (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Quentin Lamerand <qlamerand@nuxeo.com>
018 */
019
020package org.nuxeo.ecm.user.center.profile;
021
022import static org.nuxeo.ecm.platform.ui.web.api.WebActions.CURRENT_TAB_CHANGED_EVENT;
023import static org.nuxeo.ecm.platform.ui.web.api.WebActions.CURRENT_TAB_SELECTED_EVENT;
024import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.MAIN_TABS_CATEGORY;
025import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.NUXEO_ADMIN_CATEGORY;
026import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.USERS_GROUPS_HOME_SUB_TAB;
027import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.USERS_GROUPS_MANAGER_SUB_TAB;
028import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.USER_CENTER_CATEGORY;
029import static org.nuxeo.ecm.webapp.security.UserManagementActions.USERS_LISTING_CHANGED;
030import static org.nuxeo.ecm.webapp.security.UserManagementActions.USER_SELECTED_CHANGED;
031
032import java.io.Serializable;
033
034import org.apache.commons.lang3.StringUtils;
035import org.jboss.seam.ScopeType;
036import org.jboss.seam.annotations.In;
037import org.jboss.seam.annotations.Name;
038import org.jboss.seam.annotations.Observer;
039import org.jboss.seam.annotations.Scope;
040import org.jboss.seam.annotations.intercept.BypassInterceptors;
041import org.jboss.seam.international.LocaleSelector;
042import org.nuxeo.ecm.core.api.CoreSession;
043import org.nuxeo.ecm.core.api.DocumentModel;
044import org.nuxeo.ecm.core.api.NuxeoPrincipal;
045import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
046import org.nuxeo.ecm.platform.usermanager.UserManager;
047import org.nuxeo.ecm.webapp.security.UserManagementActions;
048import org.nuxeo.runtime.api.Framework;
049
050/**
051 * Seam component to manage user profile editing
052 *
053 * @author <a href="mailto:qlamerand@nuxeo.com">Quentin Lamerand</a>
054 * @since 5.5
055 */
056@Name("userProfileActions")
057@Scope(ScopeType.CONVERSATION)
058public class UserProfileActions implements Serializable {
059
060    private static final long serialVersionUID = 1L;
061
062    public static final String PROFILE_VIEW_MODE = "view";
063
064    public static final String PROFILE_EDIT_MODE = "edit";
065
066    public static final String PROFILE_EDIT_PASSWORD_MODE = "editPassword";
067
068    @In(create = true)
069    protected transient UserManagementActions userManagementActions;
070
071    @In(create = true)
072    protected NuxeoPrincipal currentUser;
073
074    @In(create = true)
075    protected transient CoreSession documentManager;
076
077    @In(create = true)
078    protected transient NavigationContext navigationContext;
079
080    @In(create = true)
081    protected transient LocaleSelector localeSelector;
082
083    @In(create = true)
084    protected transient UserManager userManager;
085
086    protected String mode = PROFILE_VIEW_MODE;
087
088    protected DocumentModel userProfileDocument;
089
090    protected DocumentModel currentUserProfile;
091
092    public void updateUser() {
093        if (userProfileDocument != null) {
094            // Ensure to remove user schema from datamodel when saving changes
095            // on user profile, otherwise an exception is thrown, see
096            // NXP-11397.
097            userProfileDocument.getDataModels().remove(userManager.getUserSchemaName());
098            documentManager.saveDocument(userProfileDocument);
099            documentManager.save();
100        }
101
102        // Update selected user after profile to prevent from
103        // org.nuxeo.ecm.webapp.security.UserManagementActions.USER_SELECTED_CHANGED
104        // event to reset userProfileDocument field.
105        userManagementActions.updateUser();
106
107        mode = PROFILE_VIEW_MODE;
108    }
109
110    public String getMode() {
111        return mode;
112    }
113
114    public boolean getCanEdit() {
115        return userManagementActions.getAllowEditUser() && userManagementActions.isNotReadOnly();
116    }
117
118    public void setMode(String mode) {
119        this.mode = mode;
120    }
121
122    public DocumentModel getCurrentUserModel() {
123        DocumentModel selectedUser = userManagementActions.getSelectedUser();
124        DocumentModel currentUserModel = currentUser.getModel();
125        if (selectedUser == null || !selectedUser.getId().equals(currentUserModel.getId())) {
126            userManagementActions.setSelectedUser(currentUserModel);
127        }
128        return currentUserModel;
129    }
130
131    public DocumentModel getUserProfileDocument() {
132        // Need to set selectedUser in UserManagementActions to avoid an NPE
133        // when calling updateUser() if UserManagementActions#selectedUser has
134        // been set to null meanwhile (by opening a new tab for instance).
135        getCurrentUserModel();
136        if (userProfileDocument == null) {
137            userProfileDocument = Framework.getService(UserProfileService.class).getUserProfileDocument(documentManager);
138            String locale = (String) userProfileDocument.getPropertyValue(UserProfileConstants.USER_PROFILE_LOCALE);
139            if (StringUtils.isEmpty(locale)) {
140                String currentLocale = localeSelector.getLocaleString();
141                if (!StringUtils.isEmpty(currentLocale)) {
142                    userProfileDocument.setPropertyValue(UserProfileConstants.USER_PROFILE_LOCALE, currentLocale);
143                }
144            }
145        }
146        return userProfileDocument;
147    }
148
149    public DocumentModel getUserProfileDocument(String userName) {
150        UserProfileService userProfileService = Framework.getService(UserProfileService.class);
151        return userProfileService.getUserProfileDocument(userName, documentManager);
152    }
153
154    public DocumentModel getUserProfile() {
155        if (currentUserProfile == null) {
156            UserProfileService userProfileService = Framework.getService(UserProfileService.class);
157            currentUserProfile = userProfileService.getUserProfile(getCurrentUserModel(), documentManager);
158        }
159        return currentUserProfile;
160    }
161
162    public DocumentModel getSelectedUserProfile() {
163        DocumentModel selectedUser = userManagementActions.getSelectedUser();
164        if (selectedUser == null) {
165            return null;
166        }
167        if (userProfileDocument == null) {
168            UserProfileService userProfileService = Framework.getService(UserProfileService.class);
169            userProfileDocument = userProfileService.getUserProfile(selectedUser, documentManager);
170        }
171        return userProfileDocument;
172    }
173
174    @Observer(value = { CURRENT_TAB_CHANGED_EVENT + "_" + MAIN_TABS_CATEGORY,
175            CURRENT_TAB_CHANGED_EVENT + "_" + NUXEO_ADMIN_CATEGORY,
176            CURRENT_TAB_CHANGED_EVENT + "_" + USER_CENTER_CATEGORY,
177            CURRENT_TAB_CHANGED_EVENT + "_" + USERS_GROUPS_MANAGER_SUB_TAB,
178            CURRENT_TAB_CHANGED_EVENT + "_" + USERS_GROUPS_HOME_SUB_TAB,
179            CURRENT_TAB_SELECTED_EVENT + "_" + MAIN_TABS_CATEGORY,
180            CURRENT_TAB_SELECTED_EVENT + "_" + NUXEO_ADMIN_CATEGORY,
181            CURRENT_TAB_SELECTED_EVENT + "_" + USER_CENTER_CATEGORY,
182            CURRENT_TAB_SELECTED_EVENT + "_" + USERS_GROUPS_MANAGER_SUB_TAB,
183            CURRENT_TAB_SELECTED_EVENT + "_" + USERS_GROUPS_HOME_SUB_TAB, USERS_LISTING_CHANGED, USER_SELECTED_CHANGED }, create = false)
184    @BypassInterceptors
185    public void resetState() {
186        userProfileDocument = null;
187        currentUserProfile = null;
188    }
189}