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><code>
039 * SecurityCheck mycheck =
040 *   new SecurityCheck(data, "Unauthorized to do this!", "WrongPermission");
041 * if (!mycheck.hasPermission("add_user");
042 *   return;
043 *</code></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 1706239 2015-10-01 13:18:35Z tv $
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     * @exception 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     * @exception 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                modelManager.grant(data.getUser(), modelManager.getGlobalGroup(), roleObject);
152            }
153            else
154            {
155                throw(e);
156            }
157        }
158
159        return hasRole(roleObject);
160    }
161
162    /**
163     * Does the user have this permission?
164     *
165     * @param permission A Permission.
166     * @return True if the user has this permission.
167     * @exception Exception, a generic exception.
168     */
169    public boolean hasPermission(Permission permission)
170            throws Exception
171    {
172        boolean value = false;
173        TurbineAccessControlList acl = data.getACL();
174        if (acl == null ||
175            !acl.hasPermission(permission))
176        {
177            data.setScreen(failScreen);
178            data.setMessage(message);
179        }
180        else
181        {
182            value = true;
183        }
184        return value;
185    }
186
187    /**
188     * Does the user have this permission? If initialize is set to <code>true</code>
189     * The permission will be created and granted to the first available Role of
190     * the user, that the SecurityCheck is running against.
191     *
192     * If the User has no Roles, the first Role via TurbineSecurity is granted the
193     * permission.
194     *
195     * @param permission
196     *            A String.
197     * @return True if the user has this permission.
198     * @exception Exception,
199     *                a generic exception.
200     */
201    public boolean hasPermission(String permission)
202            throws Exception
203    {
204        Permission permissionObject = null;
205        try
206        {
207            permissionObject = securityService.getPermissionManager().getPermissionByName(permission);
208        }
209        catch (UnknownEntityException e)
210        {
211            if(initialize)
212            {
213                permissionObject = securityService.getPermissionManager().getPermissionInstance(permission);
214                securityService.getPermissionManager().addPermission(permissionObject);
215
216                Role role = null;
217                TurbineAccessControlList acl = data.getACL();
218                RoleSet roles = acl.getRoles();
219                if(roles.size() > 0)
220                {
221                                        role = roles.toArray(new Role[0])[0];
222                                }
223
224                if(role == null)
225                {
226                    /*
227                     * The User within data has no roles yet, let us grant the permission
228                     * to the first role available through TurbineSecurity.
229                     */
230                    roles = securityService.getRoleManager().getAllRoles();
231                    if(roles.size() > 0)
232                    {
233                                                role = roles.toArray(new Role[0])[0];
234                                        }
235                }
236
237                if(role != null)
238                {
239                    /*
240                     * If we have no role, there is nothing we can do about it. So only grant it,
241                     * if we have a role to grant it to.
242                     */
243                    TurbineModelManager modelManager = (TurbineModelManager)securityService.getModelManager();
244                    modelManager.grant(role, permissionObject);
245                }
246            }
247            else
248            {
249                throw(e);
250            }
251        }
252
253        return hasPermission(permissionObject);
254    }
255
256    /**
257     * Get the message that should be displayed.  This is initialized
258     * in the constructor.
259     *
260     * @return A String.
261     */
262    public String getMessage()
263    {
264        return message;
265    }
266
267    /**
268     * Get the screen that should be displayed.  This is initialized
269     * in the constructor.
270     *
271     * @return A String.
272     */
273    public String getFailScreen()
274    {
275        return failScreen;
276    }
277}