001    package 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    
024    import org.apache.turbine.om.security.Permission;
025    import org.apache.turbine.om.security.Role;
026    import org.apache.turbine.services.security.TurbineSecurity;
027    import org.apache.turbine.util.security.RoleSet;
028    import org.apache.turbine.util.security.UnknownEntityException;
029    
030    /**
031     * Utility for doing security checks in Screens and Actions.
032     *
033     * Sample usage:<br>
034     *
035     * <pre><code>
036     * SecurityCheck mycheck =
037     *   new SecurityCheck(data, "Unauthorized to do this!", "WrongPermission");
038     * if (!mycheck.hasPermission("add_user");
039     *   return;
040     *</code></pre>
041     *
042     * @author <a href="mailto:mbryson@mindspring.com">Dave Bryson</a>
043     * @author <a href="jh@byteaction.de">J&#252;rgen Hoffmann</a>
044     * @version $Id: SecurityCheck.java 615328 2008-01-25 20:25:05Z tv $
045     */
046    public class SecurityCheck
047    {
048        private String message;
049    
050        private String failScreen;
051    
052        private RunData data = null;
053    
054        /**
055         * Holds information if a missing Permission or Role should be created and granted on-the-fly.
056         * This is good behaviour, if these change a lot.
057         */
058        private boolean initialize;
059    
060        /**
061         * Constructor.
062         *
063         * @param data A Turbine RunData object.
064         * @param message The message to display upon failure.
065         * @param failedScreen The screen to redirect to upon failure.
066         */
067        public SecurityCheck(RunData data,
068                             String message,
069                             String failedScreen)
070        {
071            this(data, message, failedScreen, false);
072        }
073    
074        /**
075         * Constructor.
076         *
077         * @param data
078         *            A Turbine RunData object.
079         * @param message
080         *            The message to display upon failure.
081         * @param failedScreen
082         *            The screen to redirect to upon failure.
083         * @param initialize
084         *            if a non-existing Permission or Role should be created.
085         */
086        public SecurityCheck(RunData data, String message, String failedScreen, boolean initialize)
087        {
088            this.data = data;
089            this.message = message;
090            this.failScreen = failedScreen;
091            this.initialize = initialize;
092        }
093    
094        /**
095         * Does the user have this role?
096         *
097         * @param role A Role.
098         * @return True if the user has this role.
099         * @exception Exception, a generic exception.
100         */
101        public boolean hasRole(Role role)
102                throws Exception
103        {
104            boolean value = false;
105            if (data.getACL() == null ||
106                    !data.getACL().hasRole(role))
107            {
108                data.setScreen(failScreen);
109                data.setMessage(message);
110            }
111            else
112            {
113                value = true;
114            }
115            return value;
116        }
117    
118        /**
119         * Does the user have this role?
120         *
121         * @param role
122         *            A String.
123         * @return True if the user has this role.
124         * @exception Exception,
125         *                a generic exception.
126         */
127        public boolean hasRole(String role) throws Exception
128        {
129            Role roleObject = null;
130            try
131            {
132                roleObject = TurbineSecurity.getRoleByName(role);
133            }
134            catch (UnknownEntityException e)
135            {
136                if(initialize)
137                {
138                    roleObject = TurbineSecurity.createRole(role);
139                    TurbineSecurity.grant(data.getUser(), TurbineSecurity.getGlobalGroup(), roleObject);
140                }
141                else
142                {
143                    throw(e);
144                }
145            }
146            return hasRole(TurbineSecurity.getRoleByName(role));
147        }
148    
149        /**
150         * Does the user have this permission?
151         *
152         * @param permission A Permission.
153         * @return True if the user has this permission.
154         * @exception Exception, a generic exception.
155         */
156        public boolean hasPermission(Permission permission)
157                throws Exception
158        {
159            boolean value = false;
160            if (data.getACL() == null ||
161                    !data.getACL().hasPermission(permission))
162            {
163                data.setScreen(failScreen);
164                data.setMessage(message);
165            }
166            else
167            {
168                value = true;
169            }
170            return value;
171        }
172    
173        /**
174         * Does the user have this permission? If initialze is set to <code>true</code>
175         * The permission will be created and granted to the first available Role of
176         * the user, that the SecurityCheck is running against.
177         *
178         * If the User has no Roles, the first Role via TurbineSecurity is granted the
179         * permission.
180         *
181         * @param permission
182         *            A String.
183         * @return True if the user has this permission.
184         * @exception Exception,
185         *                a generic exception.
186         */
187        public boolean hasPermission(String permission)
188                throws Exception
189        {
190            Permission permissionObject = null;
191            try
192            {
193                permissionObject = TurbineSecurity.getPermissionByName(permission);
194            }
195            catch (UnknownEntityException e)
196            {
197                if(initialize)
198                {
199                    permissionObject = TurbineSecurity.createPermission(permission);
200    
201                    Role role = null;
202                    RoleSet roles = data.getACL().getRoles();
203                    if(roles.size() > 0) role = roles.getRolesArray()[0];
204    
205                    if(role == null)
206                    {
207                        /*
208                         * The User within data has no roles yet, let us grant the permission
209                         * to the first role available through TurbineSecurity.
210                         */
211                        roles = TurbineSecurity.getAllRoles();
212                        if(roles.size() > 0) role = roles.getRolesArray()[0];
213                    }
214    
215                    if(role != null)
216                    {
217                        /*
218                         * If we have no role, there is nothing we can do about it. So only grant it,
219                         * if we have a role to grant it to.
220                         */
221                        TurbineSecurity.grant(data.getACL().getRoles().getRolesArray()[0], permissionObject);
222                    }
223                }
224                else
225                {
226                    throw(e);
227                }
228            }
229            return hasPermission(permissionObject);
230        }
231    
232        /**
233         * Get the message that should be displayed.  This is initialized
234         * in the constructor.
235         *
236         * @return A String.
237         */
238        public String getMessage()
239        {
240            return message;
241        }
242    
243        /**
244         * Get the screen that should be displayed.  This is initialized
245         * in the constructor.
246         *
247         * @return A String.
248         */
249        public String getFailScreen()
250        {
251            return failScreen;
252        }
253    }