001/*
002 * (C) Copyright 2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 * Contributors:
014 *     Nuxeo - initial API and implementation
015 */
016
017package org.nuxeo.ecm.webapp.security;
018
019import static org.jboss.seam.ScopeType.CONVERSATION;
020import static org.jboss.seam.annotations.Install.FRAMEWORK;
021import static org.nuxeo.ecm.platform.ui.web.api.WebActions.CURRENT_TAB_CHANGED_EVENT;
022import static org.nuxeo.ecm.platform.ui.web.api.WebActions.CURRENT_TAB_SELECTED_EVENT;
023
024import java.io.Serializable;
025
026import javax.faces.application.FacesMessage;
027import javax.faces.component.EditableValueHolder;
028import javax.faces.component.UIComponent;
029import javax.faces.context.FacesContext;
030
031import org.apache.commons.lang.StringUtils;
032import org.apache.commons.logging.Log;
033import org.apache.commons.logging.LogFactory;
034import org.jboss.seam.annotations.Install;
035import org.jboss.seam.annotations.Name;
036import org.jboss.seam.annotations.Observer;
037import org.jboss.seam.annotations.Scope;
038import org.jboss.seam.core.Events;
039import org.jboss.seam.international.StatusMessage;
040import org.nuxeo.ecm.core.api.DocumentModel;
041import org.nuxeo.ecm.core.api.NuxeoPrincipal;
042import org.nuxeo.ecm.directory.BaseSession;
043import org.nuxeo.ecm.platform.ui.web.util.ComponentUtils;
044import org.nuxeo.ecm.platform.usermanager.exceptions.GroupAlreadyExistsException;
045
046/**
047 * /** Handles users management related web actions.
048 *
049 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
050 * @since 5.4.2
051 */
052@Name("groupManagementActions")
053@Scope(CONVERSATION)
054@Install(precedence = FRAMEWORK)
055public class GroupManagementActions extends AbstractUserGroupManagement implements Serializable {
056
057    private static final long serialVersionUID = 1L;
058
059    private static final Log log = LogFactory.getLog(GroupManagementActions.class);
060
061    public static final String GROUPS_TAB = USER_CENTER_CATEGORY + ":" + USERS_GROUPS_HOME + ":" + "GroupsHome";
062
063    public static final String GROUPS_LISTING_CHANGED = "groupsListingChanged";
064
065    protected Boolean canEditGroups;
066
067    protected DocumentModel selectedGroup;
068
069    protected DocumentModel newGroup;
070
071    protected boolean createAnotherGroup = false;
072
073    @Override
074    protected String computeListingMode() {
075        return userManager.getGroupListingMode();
076    }
077
078    public DocumentModel getSelectedGroup() {
079        shouldResetStateOnTabChange = true;
080        return selectedGroup;
081    }
082
083    /**
084     * @since 6.0
085     */
086    public String getSelectedGroupName() {
087        return selectedGroup.getId();
088    }
089
090    /**
091     * @since 6.0
092     */
093    public void setSelectedGroupName(String groupName) {
094        setSelectedGroup(groupName);
095    }
096
097    /**
098     * @since 6.0
099     */
100    public void setShowGroup(String showGroup) {
101        showUserOrGroup = Boolean.valueOf(showGroup);
102    }
103
104    public void setSelectedGroup(String groupName) {
105        selectedGroup = refreshGroup(groupName);
106    }
107
108    // refresh to get references
109    protected DocumentModel refreshGroup(String groupName) {
110        return userManager.getGroupModel(groupName);
111    }
112
113    public DocumentModel getNewGroup() {
114        if (newGroup == null) {
115            newGroup = userManager.getBareGroupModel();
116        }
117        return newGroup;
118    }
119
120    public void clearSearch() {
121        searchString = null;
122        fireSeamEvent(GROUPS_LISTING_CHANGED);
123    }
124
125    public void createGroup() {
126        try {
127            selectedGroup = userManager.createGroup(newGroup);
128            newGroup = null;
129            facesMessages.add(StatusMessage.Severity.INFO,
130                    resourcesAccessor.getMessages().get("info.groupManager.groupCreated"));
131            if (createAnotherGroup ) {
132                showCreateForm = true;
133            } else {
134                showCreateForm = false;
135                showUserOrGroup = true;
136                detailsMode = null;
137            }
138            fireSeamEvent(GROUPS_LISTING_CHANGED);
139        } catch (GroupAlreadyExistsException e) {
140            String message = resourcesAccessor.getMessages().get("error.groupManager.groupAlreadyExists");
141            facesMessages.addToControl("groupName", StatusMessage.Severity.ERROR, message);
142        }
143    }
144
145    public void updateGroup() {
146        userManager.updateGroup(selectedGroup);
147        detailsMode = DETAILS_VIEW_MODE;
148        fireSeamEvent(GROUPS_LISTING_CHANGED);
149    }
150
151    public void deleteGroup() {
152        userManager.deleteGroup(selectedGroup);
153        selectedGroup = null;
154        showUserOrGroup = false;
155        fireSeamEvent(GROUPS_LISTING_CHANGED);
156    }
157
158    public boolean getAllowCreateGroup() {
159        return getCanEditGroups();
160    }
161
162    protected boolean getCanEditGroups() {
163        if (canEditGroups == null) {
164            canEditGroups = false;
165            if (!userManager.areGroupsReadOnly() && currentUser instanceof NuxeoPrincipal) {
166                if (webActions.checkFilter(USERS_GROUPS_MANAGEMENT_ACCESS_FILTER)) {
167                    canEditGroups = true;
168                }
169            }
170        }
171        return canEditGroups;
172    }
173
174    public boolean getAllowDeleteGroup() {
175        if (getAllAdminGroups().contains(selectedGroup.getId())) {
176            return ((NuxeoPrincipal) currentUser).isAdministrator();
177        }
178
179        return getCanEditGroups() && !BaseSession.isReadOnlyEntry(selectedGroup);
180    }
181
182    public boolean getAllowEditGroup() {
183        // Changing administrator group is only given to administrators (not
184        // powerusers)
185        // NXP-10584
186        if (getAllAdminGroups().contains(selectedGroup.getId())) {
187            return ((NuxeoPrincipal) currentUser).isAdministrator();
188        }
189
190        return getCanEditGroups() && !BaseSession.isReadOnlyEntry(selectedGroup);
191    }
192
193    public void validateGroupName(FacesContext context, UIComponent component, Object value) {
194        if (!(value instanceof String) || !StringUtils.containsOnly((String) value, VALID_CHARS)) {
195            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, ComponentUtils.translate(context,
196                    "label.groupManager.wrongGroupName"), null);
197            ((EditableValueHolder) component).setValid(false);
198            context.addMessage(component.getClientId(context), message);
199            // also add global message
200            context.addMessage(null, message);
201        }
202    }
203
204    public String viewGroup() {
205        if (selectedGroup != null) {
206            return viewGroup(selectedGroup.getId());
207        } else {
208            return null;
209        }
210    }
211
212    public String viewGroup(String groupName) {
213        webActions.setCurrentTabIds(MAIN_TAB_HOME + "," + GROUPS_TAB);
214        setSelectedGroup(groupName);
215        showUserOrGroup = true;
216        // do not reset the state before actually viewing the group
217        shouldResetStateOnTabChange = false;
218        return VIEW_HOME;
219    }
220
221    protected void fireSeamEvent(String eventName) {
222        Events evtManager = Events.instance();
223        evtManager.raiseEvent(eventName);
224    }
225
226    @Observer(value = { GROUPS_LISTING_CHANGED })
227    public void onUsersListingChanged() {
228        contentViewActions.refreshOnSeamEvent(GROUPS_LISTING_CHANGED);
229        contentViewActions.resetPageProviderOnSeamEvent(GROUPS_LISTING_CHANGED);
230    }
231
232    @Observer(value = { CURRENT_TAB_CHANGED_EVENT + "_" + MAIN_TABS_CATEGORY,
233            CURRENT_TAB_CHANGED_EVENT + "_" + NUXEO_ADMIN_CATEGORY,
234            CURRENT_TAB_CHANGED_EVENT + "_" + USER_CENTER_CATEGORY,
235            CURRENT_TAB_CHANGED_EVENT + "_" + USERS_GROUPS_MANAGER_SUB_TAB,
236            CURRENT_TAB_CHANGED_EVENT + "_" + USERS_GROUPS_HOME_SUB_TAB,
237            CURRENT_TAB_SELECTED_EVENT + "_" + MAIN_TABS_CATEGORY,
238            CURRENT_TAB_SELECTED_EVENT + "_" + NUXEO_ADMIN_CATEGORY,
239            CURRENT_TAB_SELECTED_EVENT + "_" + USER_CENTER_CATEGORY,
240            CURRENT_TAB_SELECTED_EVENT + "_" + USERS_GROUPS_MANAGER_SUB_TAB,
241            CURRENT_TAB_SELECTED_EVENT + "_" + USERS_GROUPS_HOME_SUB_TAB }, create = false)
242    public void resetState() {
243        if (shouldResetStateOnTabChange) {
244            newGroup = null;
245            showUserOrGroup = false;
246            showCreateForm = false;
247            detailsMode = DETAILS_VIEW_MODE;
248        }
249    }
250
251    public boolean isCreateAnotherGroup() {
252        return createAnotherGroup;
253    }
254
255    public void setCreateAnotherGroup(boolean createAnotherGroup) {
256        this.createAnotherGroup = createAnotherGroup;
257    }
258
259}