1 package org.apache.turbine.util;
2
3
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
20 * under the License.
21 */
22
23
24 import org.apache.fulcrum.security.SecurityService;
25 import org.apache.fulcrum.security.entity.Permission;
26 import org.apache.fulcrum.security.entity.Role;
27 import org.apache.fulcrum.security.model.turbine.TurbineAccessControlList;
28 import org.apache.fulcrum.security.model.turbine.TurbineModelManager;
29 import org.apache.fulcrum.security.util.RoleSet;
30 import org.apache.fulcrum.security.util.UnknownEntityException;
31 import org.apache.turbine.services.TurbineServices;
32
33 /**
34 * Utility for doing security checks in Screens and Actions.
35 *
36 * Sample usage:<br>
37 *
38 * <pre>
39 * SecurityCheck mycheck =
40 * new SecurityCheck(data, "Unauthorized to do this!", "WrongPermission");
41 * if (!mycheck.hasPermission("add_user");
42 * return;
43 *</pre>
44 *
45 * @author <a href="mailto:mbryson@mindspring.com">Dave Bryson</a>
46 * @author <a href="jh@byteaction.de">Jürgen Hoffmann</a>
47 * @version $Id$
48 */
49 public class SecurityCheck
50 {
51 private String message;
52
53 private String failScreen;
54
55 private RunData data = null;
56
57 private SecurityService securityService = null;
58
59 /**
60 * Holds information if a missing Permission or Role should be created and granted on-the-fly.
61 * This is good behavior, if these change a lot.
62 */
63 private boolean initialize;
64
65 /**
66 * Constructor.
67 *
68 * @param data A Turbine RunData object.
69 * @param message The message to display upon failure.
70 * @param failedScreen The screen to redirect to upon failure.
71 */
72 public SecurityCheck(RunData data,
73 String message,
74 String failedScreen)
75 {
76 this(data, message, failedScreen, false);
77 }
78
79 /**
80 * Constructor.
81 *
82 * @param data
83 * A Turbine RunData object.
84 * @param message
85 * The message to display upon failure.
86 * @param failedScreen
87 * The screen to redirect to upon failure.
88 * @param initialize
89 * if a non-existing Permission or Role should be created.
90 */
91 public SecurityCheck(RunData data, String message, String failedScreen, boolean initialize)
92 {
93 this.data = data;
94 this.message = message;
95 this.failScreen = failedScreen;
96 this.initialize = initialize;
97 this.securityService = (SecurityService)TurbineServices
98 .getInstance()
99 .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 }