001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software GmbH & Co. KG, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.workplace.tools.accounts;
029
030import org.opencms.file.CmsGroup;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsUser;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
036import org.opencms.module.CmsModule;
037import org.opencms.security.CmsOrganizationalUnit;
038import org.opencms.security.CmsRole;
039import org.opencms.util.CmsRequestUtil;
040import org.opencms.util.CmsUUID;
041import org.opencms.workplace.CmsWorkplace;
042import org.opencms.workplace.CmsWorkplaceUserInfoManager;
043import org.opencms.workplace.tools.CmsDefaultToolHandler;
044
045import java.util.Iterator;
046import java.util.List;
047
048import org.apache.commons.logging.Log;
049
050/**
051 * Users management tool handler that hides the tool if the current user
052 * has not the needed privileges.<p>
053 *
054 * @since 6.0.0
055 */
056public class CmsAccountsToolHandler extends CmsDefaultToolHandler {
057
058    /** Path for the kill session tool. */
059    public static final String PATH_KILL_SESSIONS = "/accounts/orgunit/users/edit/kill_sessions";
060
061    /** Path for the unlock tool. */
062    public static final String PATH_UNLOCK = "/accounts/orgunit/users/edit/unlock";
063
064    /** Visibility parameter value constant. */
065    protected static final String VISIBILITY_ALL = "all";
066
067    /** Account manager file path constant. */
068    private static final String ACCMAN_FILE = "account_managers.jsp";
069
070    /** All additional info file path constant. */
071    private static final String ALLINFO_FILE = "user_allinfo.jsp";
072
073    /** Assign users file path constant. */
074    private static final String ASSIGN_FILE = "user_assign.jsp";
075
076    /** Delete file path constant. */
077    private static final String DELETE_FILE = "unit_delete.jsp";
078
079    /** Group users file path constant. */
080    private static final String GROUP_USERS_FILE = "group_users.jsp";
081
082    /** Edit group users file path constant. */
083    private static final String GROUPUSERS_FILE = "group_users.jsp";
084
085    /** The log object for this class. */
086    private static final Log LOG = CmsLog.getLog(CmsAccountsToolHandler.class);
087
088    /** New file path constant. */
089    private static final String NEW_FILE = "unit_new.jsp";
090
091    /** Organizational unit edit file path constant. */
092    private static final String OU_EDIT_FILE = "unit_edit.jsp";
093
094    /** Organizational unit roles file path constant. */
095    private static final String OUROLES_FILE = "roles_list.jsp";
096
097    /** Overview file path constant. */
098    private static final String OVERVIEW_FILE = "unit_overview.jsp";
099
100    /** Visibility flag module parameter name. */
101    private static final String PARAM_VISIBILITY_FLAG = "visibility";
102
103    /** Parent file path constant. */
104    private static final String PARENT_FILE = "unit_parent.jsp";
105
106    /** Role users edit file path constant. */
107    private static final String ROLEUSERS_EDIT_FILE = "role_users.jsp";
108
109    /** Switch user file path constant. */
110    private static final String SWITCHUSER_FILE = "user_switch.jsp";
111
112    /** User roles file path constant. */
113    private static final String USERROLE_FILE = "user_role.jsp";
114
115    /** Visibility parameter value constant. */
116    private static final String VISIBILITY_NONE = "none";
117
118    /** Flag to indicate if the current ou is a webuser ou. */
119    private boolean m_webuserOu;
120
121    /**
122     * @see org.opencms.workplace.tools.A_CmsToolHandler#getDisabledHelpText()
123     */
124    @Override
125    public String getDisabledHelpText() {
126
127        if (super.getDisabledHelpText().equals(DEFAULT_DISABLED_HELPTEXT)) {
128            if (getLink().equals(getPath(GROUPUSERS_FILE))) {
129                return "${key." + Messages.GUI_VIRTUAL_GROUP_DISABLED_EDITION_HELP_0 + "}";
130            }
131            if (getLink().equals(getPath(ROLEUSERS_EDIT_FILE))) {
132                return "${key." + Messages.GUI_ROLEUSERS_EDIT_DISABLED_HELP_0 + "}";
133            }
134            return "${key." + Messages.GUI_ORGUNIT_ADMIN_TOOL_DISABLED_DELETE_HELP_0 + "}";
135        }
136        return super.getDisabledHelpText();
137    }
138
139    /**
140     * @see org.opencms.workplace.tools.A_CmsToolHandler#isEnabled(org.opencms.workplace.CmsWorkplace)
141     */
142    @Override
143    public boolean isEnabled(CmsWorkplace wp) {
144
145        if (getLink().equals(getPath(GROUPUSERS_FILE))) {
146            String groupId = CmsRequestUtil.getNotEmptyDecodedParameter(
147                wp.getJsp().getRequest(),
148                A_CmsEditGroupDialog.PARAM_GROUPID);
149            try {
150                return !wp.getCms().readGroup(new CmsUUID(groupId)).isVirtual();
151            } catch (Exception e) {
152                return false;
153            }
154        }
155        if (!getLink().equals(ASSIGN_FILE)) {
156            wp.getSession().removeAttribute(A_CmsOrgUnitUsersList.ORGUNIT_USERS);
157            wp.getSession().removeAttribute(A_CmsOrgUnitUsersList.NOT_ORGUNIT_USERS);
158        }
159
160        if (getLink().equals(DELETE_FILE)) {
161            String ouFqn = CmsRequestUtil.getNotEmptyDecodedParameter(
162                wp.getJsp().getRequest(),
163                A_CmsOrgUnitDialog.PARAM_OUFQN);
164            if (ouFqn == null) {
165                ouFqn = wp.getCms().getRequestContext().getOuFqn();
166            }
167            try {
168                if (OpenCms.getOrgUnitManager().getUsers(wp.getCms(), ouFqn, true).size() > 0) {
169                    return false;
170                }
171                if (OpenCms.getOrgUnitManager().getGroups(wp.getCms(), ouFqn, true).size() > 0) {
172                    List<CmsGroup> groups = OpenCms.getOrgUnitManager().getGroups(wp.getCms(), ouFqn, true);
173                    Iterator<CmsGroup> itGroups = groups.iterator();
174                    while (itGroups.hasNext()) {
175                        CmsGroup group = itGroups.next();
176                        if (!OpenCms.getDefaultUsers().isDefaultGroup(group.getName())) {
177                            return false;
178                        }
179                    }
180                }
181                if (OpenCms.getOrgUnitManager().getOrganizationalUnits(wp.getCms(), ouFqn, true).size() > 0) {
182                    return false;
183                }
184            } catch (CmsException e) {
185                // noop
186            }
187        }
188
189        if (getLink().equals(getPath(ROLEUSERS_EDIT_FILE))) {
190            String roleName = CmsRequestUtil.getNotEmptyDecodedParameter(
191                wp.getJsp().getRequest(),
192                CmsRolesList.PARAM_ROLE);
193            if (roleName == null) {
194                return false;
195            }
196            if (!OpenCms.getRoleManager().hasRole(wp.getCms(), CmsRole.valueOfGroupName(roleName))) {
197                return false;
198            }
199        } else if (getPath().indexOf("/users/edit/") > -1) {
200            // check if the current user is the root administrator
201            if (OpenCms.getRoleManager().hasRole(wp.getCms(), CmsRole.ROOT_ADMIN)) {
202                return true;
203            }
204
205            String paramId = CmsRequestUtil.getNotEmptyDecodedParameter(
206                wp.getJsp().getRequest(),
207                A_CmsEditUserDialog.PARAM_USERID);
208            if (paramId == null) {
209                return false;
210            }
211            CmsUUID userId = new CmsUUID(paramId);
212            try {
213                CmsUser user = wp.getCms().readUser(userId);
214                // check if the user to change is root administrator
215                if (OpenCms.getRoleManager().hasRole(wp.getCms(), user.getName(), CmsRole.ROOT_ADMIN)) {
216                    return false;
217                }
218
219                // check if the current user is an administrator
220                if (OpenCms.getRoleManager().hasRole(wp.getCms(), CmsRole.ADMINISTRATOR)) {
221                    return true;
222                }
223                // check if the user to change is an administrator
224                return !OpenCms.getRoleManager().hasRole(wp.getCms(), user.getName(), CmsRole.ADMINISTRATOR);
225            } catch (CmsException e) {
226                // should never happen
227                if (LOG.isErrorEnabled()) {
228                    LOG.error(e.getLocalizedMessage(), e);
229                }
230            }
231            return false;
232        }
233
234        return true;
235    }
236
237    /**
238     * @see org.opencms.workplace.tools.CmsDefaultToolHandler#isVisible(org.opencms.file.CmsObject)
239     */
240    @Override
241    public boolean isVisible(CmsObject cms) {
242
243        if (getVisibilityFlag().equals(VISIBILITY_NONE)) {
244            return false;
245        }
246
247        if (getLink().equals(getPath(ALLINFO_FILE))) {
248            CmsWorkplaceUserInfoManager manager = OpenCms.getWorkplaceManager().getUserInfoManager();
249            if ((manager == null) || (manager.getBlocks() == null) || manager.getBlocks().isEmpty()) {
250                return false;
251            }
252        }
253
254        if (!OpenCms.getRoleManager().hasRole(cms, CmsRole.ACCOUNT_MANAGER)) {
255            return false;
256        }
257        return true;
258    }
259
260    /**
261     * @see org.opencms.workplace.tools.A_CmsToolHandler#isVisible(org.opencms.workplace.CmsWorkplace)
262     */
263    @Override
264    public boolean isVisible(CmsWorkplace wp) {
265
266        CmsObject cms = wp.getCms();
267        if (!isVisible(cms)) {
268            return false;
269        }
270
271        String ouFqn = CmsRequestUtil.getNotEmptyDecodedParameter(
272            wp.getJsp().getRequest(),
273            A_CmsOrgUnitDialog.PARAM_OUFQN);
274        if (ouFqn == null) {
275            ouFqn = cms.getRequestContext().getOuFqn();
276        }
277        String parentOu = CmsOrganizationalUnit.getParentFqn(ouFqn);
278        try {
279            m_webuserOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, ouFqn).hasFlagWebuser();
280        } catch (CmsException e) {
281            // ignore
282            if (LOG.isErrorEnabled()) {
283                LOG.error(e.getLocalizedMessage(), e);
284            }
285        }
286
287        if (getLink().equals(getPath(OVERVIEW_FILE))) {
288            if (parentOu != null) {
289                return !OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(parentOu));
290            }
291            return true;
292        } else if (getLink().equals(getPath(OU_EDIT_FILE))) {
293            if (parentOu != null) {
294                return (OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR)
295                    && OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(parentOu)));
296            } else {
297                return false;
298            }
299        } else if (getLink().equals(getPath(NEW_FILE))) {
300            if (m_webuserOu) {
301                return false;
302            }
303            return OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR);
304        } else if (getLink().equals(getPath(PARENT_FILE))) {
305            if (parentOu != null) {
306                return OpenCms.getRoleManager().hasRole(cms, CmsRole.ACCOUNT_MANAGER.forOrgUnit(parentOu));
307            } else {
308                return false;
309            }
310        } else if (getLink().equals(getPath(DELETE_FILE))) {
311            if (parentOu != null) {
312                return (OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR)
313                    && OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(parentOu)));
314            } else {
315                return false;
316            }
317        } else if (getLink().equals(getPath(ASSIGN_FILE))) {
318            try {
319                List<CmsOrganizationalUnit> orgUnits = OpenCms.getRoleManager().getOrgUnitsForRole(
320                    cms,
321                    CmsRole.ACCOUNT_MANAGER.forOrgUnit(""),
322                    true);
323                if (orgUnits.size() == 1) {
324                    return false;
325                }
326                return !m_webuserOu;
327            } catch (CmsException e) {
328                // ignore
329                if (LOG.isErrorEnabled()) {
330                    LOG.error(e.getLocalizedMessage(), e);
331                }
332            }
333        } else if (getLink().equals(getPath(OUROLES_FILE))) {
334            return !m_webuserOu;
335        } else if (getLink().equals(getPath(SWITCHUSER_FILE))) {
336            boolean visible = false;
337            CmsUUID userId = new CmsUUID(
338                CmsRequestUtil.getNotEmptyDecodedParameter(wp.getJsp().getRequest(), A_CmsEditUserDialog.PARAM_USERID));
339            try {
340                CmsUser user = cms.readUser(userId);
341                visible = OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR.forOrgUnit(user.getOuFqn()));
342                visible &= OpenCms.getRoleManager().hasRole(cms, user.getName(), CmsRole.ELEMENT_AUTHOR);
343            } catch (CmsException e) {
344                // should never happen
345                if (LOG.isErrorEnabled()) {
346                    LOG.error(e.getLocalizedMessage(), e);
347                }
348            }
349            return visible;
350        } else if (getPath().indexOf("/users/edit/") > -1) {
351            // check if the current user is the root administrator
352            if (OpenCms.getRoleManager().hasRole(cms, CmsRole.ROOT_ADMIN) && !PATH_UNLOCK.equals(getPath())) {
353                return true;
354            }
355
356            if (PATH_KILL_SESSIONS.equals(getPath())) {
357                return OpenCms.getRoleManager().hasRole(cms, CmsRole.ACCOUNT_MANAGER);
358            }
359            CmsUUID userId = new CmsUUID(
360                CmsRequestUtil.getNotEmptyDecodedParameter(wp.getJsp().getRequest(), A_CmsEditUserDialog.PARAM_USERID));
361            try {
362                CmsUser user = cms.readUser(userId);
363                if (PATH_UNLOCK.equals(getPath())) {
364                    return OpenCms.getRoleManager().hasRole(cms, CmsRole.ACCOUNT_MANAGER)
365                        && OpenCms.getLoginManager().isUserLocked(user);
366                }
367
368                // check if the user to change is root administrator
369                if (OpenCms.getRoleManager().hasRole(cms, user.getName(), CmsRole.ROOT_ADMIN)) {
370                    return false;
371                }
372                // check if the current user is an administrator
373                if (OpenCms.getRoleManager().hasRole(cms, CmsRole.ADMINISTRATOR)) {
374                    return true;
375                }
376                // check if the user to change is an administrator
377                return !OpenCms.getRoleManager().hasRole(cms, user.getName(), CmsRole.ADMINISTRATOR);
378            } catch (CmsException e) {
379                // should never happen
380                if (LOG.isErrorEnabled()) {
381                    LOG.error(e.getLocalizedMessage(), e);
382                }
383            }
384            return false;
385        } else if (getLink().equals(getPath(USERROLE_FILE)) || getLink().equals(getPath(GROUP_USERS_FILE))) {
386            String userId = CmsRequestUtil.getNotEmptyDecodedParameter(
387                wp.getJsp().getRequest(),
388                A_CmsEditUserDialog.PARAM_USERID);
389            if (userId == null) {
390                return false;
391            }
392            try {
393                return !cms.readUser(new CmsUUID(userId)).isWebuser();
394            } catch (Exception e) {
395                // ignore
396                if (LOG.isErrorEnabled()) {
397                    LOG.error(e.getLocalizedMessage(), e);
398                }
399            }
400        } else if (getLink().equals(getPath(ACCMAN_FILE))) {
401            return m_webuserOu;
402        }
403        return true;
404    }
405
406    /**
407     * Returns the path to the jsp.<p>
408     *
409     * @param jspName the jsp name
410     *
411     * @return the full path
412     */
413    protected String getPath(String jspName) {
414
415        return "/system/workplace/admin/accounts/" + jspName;
416    }
417
418    /**
419     * Returns the visibility flag module parameter value.<p>
420     *
421     * @return the visibility flag module parameter value
422     */
423    protected String getVisibilityFlag() {
424
425        CmsModule module = OpenCms.getModuleManager().getModule(this.getClass().getPackage().getName());
426        if (module == null) {
427            return VISIBILITY_ALL;
428        }
429        return module.getParameter(PARAM_VISIBILITY_FLAG, VISIBILITY_ALL);
430    }
431}