    001package org.apache.turbine.util;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import org.apache.fulcrum.security.SecurityService;
    025import org.apache.fulcrum.security.entity.Permission;
    026import org.apache.fulcrum.security.entity.Role;
    027import org.apache.fulcrum.security.model.turbine.TurbineAccessControlList;
    028import org.apache.fulcrum.security.model.turbine.TurbineModelManager;
    029import org.apache.fulcrum.security.util.RoleSet;
    030import org.apache.fulcrum.security.util.UnknownEntityException;
    031import org.apache.turbine.services.TurbineServices;
    032
    033/**
    034 * Utility for doing security checks in Screens and Actions.
    035 *
    036 * Sample usage:<br>
    037 *
    038 * <pre>
    039 * SecurityCheck mycheck =
    040 *   new SecurityCheck(data, "Unauthorized to do this!", "WrongPermission");
    041 * if (!mycheck.hasPermission("add_user");
    042 *   return;
    043 *</pre>
    044 *
    045 * @author <a href="mailto:mbryson@mindspring.com">Dave Bryson</a>
    046 * @author <a href="jh@byteaction.de">J&#252;rgen Hoffmann</a>
    047 * @version $Id: SecurityCheck.java 1819127 2017-12-23 09:32:08Z gk $
    048 */
    049public class SecurityCheck
    050{
    051    private String message;
    052
    053    private String failScreen;
    054
    055    private RunData data = null;
    056
    057    private SecurityService securityService = null;
    058
    059    /**
    060     * Holds information if a missing Permission or Role should be created and granted on-the-fly.
    061     * This is good behavior, if these change a lot.
    062     */
    063    private boolean initialize;
    064
    065    /**
    066     * Constructor.
    067     *
    068     * @param data A Turbine RunData object.
    069     * @param message The message to display upon failure.
    070     * @param failedScreen The screen to redirect to upon failure.
    071     */
    072    public SecurityCheck(RunData data,
    073                         String message,
    074                         String failedScreen)
    075    {
    076        this(data, message, failedScreen, false);
    077    }
    078
    079    /**
    080     * Constructor.
    081     *
    082     * @param data
    083     *            A Turbine RunData object.
    084     * @param message
    085     *            The message to display upon failure.
    086     * @param failedScreen
    087     *            The screen to redirect to upon failure.
    088     * @param initialize
    089     *            if a non-existing Permission or Role should be created.
    090     */
    091    public SecurityCheck(RunData data, String message, String failedScreen, boolean initialize)
    092    {
    093        this.data = data;
    094        this.message = message;
    095        this.failScreen = failedScreen;
    096        this.initialize = initialize;
    097        this.securityService = (SecurityService)TurbineServices
    098                .getInstance()
    099                .getService(SecurityService.ROLE);
    100    }
    101
    102    /**
    103     * Does the user have this role?
    104     *
    105     * @param role A Role.
    106     * @return True if the user has this role.
    107     * @throws Exception a generic exception.
    108     */
    109    public boolean hasRole(Role role)
    110            throws Exception
    111    {
    112        boolean value = false;
    113        TurbineAccessControlList acl = data.getACL();
    114        if (acl == null ||
    115            !acl.hasRole(role))
    116        {
    117            data.setScreen(failScreen);
    118            data.setMessage(message);
    119        }
    120        else
    121        {
    122            value = true;
    123        }
    124        return value;
    125    }
    126
    127    /**
    128     * Does the user have this role?
    129     *
    130     * @param role
    131     *            A String.
    132     * @return True if the user has this role.
    133     * @throws Exception
    134     *                a generic exception.
    135     */
    136    public boolean hasRole(String role) throws Exception
    137    {
    138        Role roleObject = null;
    139
    140        try
    141        {
    142            roleObject = securityService.getRoleManager().getRoleByName(role);
    143        }
    144        catch (UnknownEntityException e)
    145        {
    146            if(initialize)
    147            {
    148                roleObject = securityService.getRoleManager().getRoleInstance(role);
    149                securityService.getRoleManager().addRole(roleObject);
    150                TurbineModelManager modelManager = (TurbineModelManager)securityService.getModelManager();
    151                if (data.getUser() == null) {
    152                  throw new UnknownEntityException("user is null");
    153                }
    154                modelManager.grant(data.getUser().getUserDelegate(), modelManager.getGlobalGroup(), roleObject);
    155            }
    156            else
    157            {
    158                throw(e);
    159            }
    160        }
    161
    162        return hasRole(roleObject);
    163    }
    164
    165    /**
    166     * Does the user have this permission?
    167     *
    168     * @param permission A Permission.
    169     * @return True if the user has this permission.
    170     * @throws Exception a generic exception.
    171     */
    172    public boolean hasPermission(Permission permission)
    173            throws Exception
    174    {
    175        boolean value = false;
    176        TurbineAccessControlList acl = data.getACL();
    177        if (acl == null ||
    178            !acl.hasPermission(permission))
    179        {
    180            data.setScreen(failScreen);
    181            data.setMessage(message);
    182        }
    183        else
    184        {
    185            value = true;
    186        }
    187        return value;
    188    }
    189
    190    /**
    191     * Does the user have this permission? If initialize is set to <code>true</code>
    192     * The permission will be created and granted to the first available Role of
    193     * the user, that the SecurityCheck is running against.
    194     *
    195     * If the User has no Roles, the first Role via SecurityService is granted the
    196     * permission.
    197     *
    198     * @param permission
    199     *            A String.
    200     * @return True if the user has this permission.
    201     * @throws Exception
    202     *                a generic exception.
    203     */
    204    public boolean hasPermission(String permission)
    205            throws Exception
    206    {
    207        Permission permissionObject = null;
    208        try
    209        {
    210            permissionObject = securityService.getPermissionManager().getPermissionByName(permission);
    211        }
    212        catch (UnknownEntityException e)
    213        {
    214            if(initialize)
    215            {
    216                permissionObject = securityService.getPermissionManager().getPermissionInstance(permission);
    217                securityService.getPermissionManager().addPermission(permissionObject);
    218
    219                Role role = null;
    220                TurbineAccessControlList acl = data.getACL();
    221                RoleSet roles = acl.getRoles();
    222                if(roles.size() > 0)
    223                {
    224                                        role = roles.toArray(new Role[0])[0];
    225                                }
    226
    227                if(role == null)
    228                {
    229                    /*
    230                     * The User within data has no roles yet, let us grant the permission
    231                     * to the first role available through SecurityService.
    232                     */
    233                    roles = securityService.getRoleManager().getAllRoles();
    234                    if(roles.size() > 0)
    235                    {
    236                                                role = roles.toArray(new Role[0])[0];
    237                                        }
    238                }
    239
    240                if(role != null)
    241                {
    242                    /*
    243                     * If we have no role, there is nothing we can do about it. So only grant it,
    244                     * if we have a role to grant it to.
    245                     */
    246                    TurbineModelManager modelManager = (TurbineModelManager)securityService.getModelManager();
    247                    modelManager.grant(role, permissionObject);
    248                }
    249            }
    250            else
    251            {
    252                throw(e);
    253            }
    254        }
    255
    256        return hasPermission(permissionObject);
    257    }
    258
    259    /**
    260     * Get the message that should be displayed.  This is initialized
    261     * in the constructor.
    262     *
    263     * @return A String.
    264     */
    265    public String getMessage()
    266    {
    267        return message;
    268    }
    269
    270    /**
    271     * Get the screen that should be displayed.  This is initialized
    272     * in the constructor.
    273     *
    274     * @return A String.
    275     */
    276    public String getFailScreen()
    277    {
    278        return failScreen;
    279    }
    280}