View Javadoc

1   /*
2    * Apache License
3    * Version 2.0, January 2004
4    * http://www.apache.org/licenses/
5    *
6    * Copyright 2008 by chenillekit.org
7    *
8    * Licensed under the Apache License, Version 2.0 (the "License");
9    * you may not use this file except in compliance with the License.
10   * You may obtain a copy of the License at
11   *
12   * http://www.apache.org/licenses/LICENSE-2.0
13   */
14  package org.chenillekit.access.services.impl;
15  
16  import org.apache.tapestry5.runtime.Component;
17  import org.apache.tapestry5.services.ApplicationStateManager;
18  import org.apache.tapestry5.services.ComponentSource;
19  import org.apache.tapestry5.services.MetaDataLocator;
20  import org.chenillekit.access.ChenilleKitAccessConstants;
21  import org.chenillekit.access.WebSessionUser;
22  import org.chenillekit.access.internal.ChenillekitAccessInternalUtils;
23  import org.chenillekit.access.services.AccessValidator;
24  import org.slf4j.Logger;
25  
26  /**
27   *
28   * @version $Id: AccessValidatorImpl.java 380 2008-12-30 10:21:52Z mlusetti $
29   */
30  public class AccessValidatorImpl implements AccessValidator
31  {
32  	private final ComponentSource componentSource;
33  	private final MetaDataLocator locator;
34  	private final Logger logger;
35  	private final ApplicationStateManager manager;
36  	private final Class<? extends WebSessionUser> sessionUser;
37  
38  
39  	public AccessValidatorImpl(ComponentSource componentSource, MetaDataLocator locator,
40  							Logger logger, ApplicationStateManager manager, Class<? extends WebSessionUser> sessionUser)
41  	{
42  		this.componentSource = componentSource;
43  		this.locator = locator;
44  		this.logger = logger;
45  		this.manager = manager;
46  		this.sessionUser = sessionUser;
47  	}
48  
49  
50  	/**
51  	 * We check for page/component and event type access rights.
52  	 * <p/>
53  	 * first we check the access rights for the requested page,
54  	 * if access granted, we step down to the next level, the components.
55  	 *
56  	 * @see org.chenillekit.access.services.AccessValidator#hasAccess(java.lang.String, java.lang.String, java.lang.String)
57  	 */
58  	public boolean hasAccess(String pageName, String componentId, String eventType)
59  	{
60  		boolean hasAccess = true;
61  
62  		if (logger.isDebugEnabled())
63  			logger.debug(ChenilleKitAccessConstants.CHENILLEKIT_ACCESS, "check access for pageName/componentId/eventType: {}/{}/{}",
64  						new Object[]{pageName, componentId, eventType});
65  
66  		Component page = getPage(pageName);
67  
68  		if (page != null)
69  		{
70  			hasAccess = checkForPageAccess(page);
71  			if (hasAccess)
72  			{
73  				hasAccess = checkForComponentEventHandlerAccess(page, componentId, eventType);
74  
75  //				if (hasAccess)
76  //				{
77  //					Field[] fields = page.getClass().getDeclaredFields();
78  //					for (Field field : fields)
79  //					{
80  //						if (field.isAnnotationPresent(Restricted.class) &&
81  //								field.isAnnotationPresent(org.apache.tapestry5.annotations.Component.class))
82  //						{
83  //							if (logger.isDebugEnabled())
84  //								logger.debug("found restricted component '{}' in page '{}'", field.getName(), pageName);
85  //
86  //							Component pageComponent = page.getComponentResources().getEmbeddedComponent(field.getName());
87  //						}
88  //					}
89  //				}
90  			}
91  		}
92  
93  		return hasAccess;
94  	}
95  
96  	private boolean checkForComponentEventHandlerAccess(Component page,
97  							String componentId,String eventType)
98  	{
99  		boolean hasAccess = true;
100 		if (componentId != null && eventType != null)
101 		{
102 			try {
103 				String groupMeta = ChenillekitAccessInternalUtils.buildMetaForHandlerMethod(componentId,
104 						eventType,
105 						ChenilleKitAccessConstants.RESTRICTED_EVENT_HANDLER_GROUPS_SUFFIX);
106 
107 				String roleMeta = ChenillekitAccessInternalUtils.buildMetaForHandlerMethod(componentId,
108 						eventType,
109 						ChenilleKitAccessConstants.RESTRICTED_EVENT_HANDLER_ROLE_SUFFIX);
110 
111 				String groups = locator.findMeta(groupMeta, page.getComponentResources(), String.class);
112 				Integer role = locator.findMeta(roleMeta, page.getComponentResources(), Integer.class);
113 
114 				hasAccess = hasAccess(groups, role, page);
115 
116 			} catch (RuntimeException re)
117 			{
118 				// FIXME Swallow?
119 			}
120 		}
121 
122 		return hasAccess;
123 
124 	}
125 
126 	/**
127 	 * check for page restriction, and if page restricted we check for users access rights.
128 	 *
129 	 * @param page the page(component) object
130 	 *
131 	 * @return true if user has access or the page is not restricted
132 	 */
133 	private boolean checkForPageAccess(Component page)
134 	{
135 		String groups = locator.findMeta(ChenilleKitAccessConstants.RESTRICTED_PAGE_GROUP, page.getComponentResources(), String.class);
136 		Integer role = locator.findMeta(ChenilleKitAccessConstants.RESTRICTED_PAGE_ROLE, page.getComponentResources(), Integer.class);
137 
138 		if (logger.isDebugEnabled())
139 		{
140 			logger.debug("Page  : " + page.getComponentResources().getPageName());
141 			logger.debug("Groups: " + groups);
142 			logger.debug("Role  : " + role);
143 		}
144 
145 		return hasAccess(groups, role, page);
146 	}
147 
148 	private boolean hasAccess(String groups, Integer role, Component page)
149 	{
150 		if (groups.equals(ChenilleKitAccessConstants.NO_RESTRICTION) && role.equals(Integer.valueOf(0)))
151 		{
152 			return true;
153 		}
154 
155 		boolean hasAccess = true;
156 
157 		if (groups != null || role != null)
158 		{
159 			WebSessionUser webSessionUser = manager.getIfExists(sessionUser);
160 
161 			if (webSessionUser == null)
162 			{
163 				if (logger.isDebugEnabled())
164 					logger.debug( "No user defined just yet" );
165 				return false;
166 			}
167 
168 			boolean hasGroup = true;
169 			if (groups != null)
170 			{
171 				if (logger.isDebugEnabled())
172 					logger.debug("groups "+webSessionUser.getGroups()+" section "+groups);
173 				hasGroup = ChenillekitAccessInternalUtils.hasUserRequiredGroup(webSessionUser.getGroups(),
174 								ChenillekitAccessInternalUtils.getStringAsStringArray(groups));
175 			}
176 
177 			boolean hasRole = true;
178 			if (role != null)
179 			{
180 				if (logger.isDebugEnabled())
181 					logger.debug("role "+webSessionUser.getRoleWeight()+">="+role);
182 				hasRole = ChenillekitAccessInternalUtils.hasUserRequiredRole(webSessionUser.getRoleWeight(),
183 								role);
184 			}
185 
186 			hasAccess = hasGroup && hasRole;
187 
188 			if (logger.isDebugEnabled())
189 			{
190 				logger.debug("Page '{}' - hasRole = {} / hasGroup = {}",
191 						new Object[]{page.getComponentResources().getPageName(), hasRole, hasGroup});
192 			}
193 		}
194 		else
195 		{
196 			// XXX Notify?
197 		}
198 
199 		return hasAccess;
200 
201 	}
202 
203 	/**
204 	 * get the page component.
205 	 *
206 	 * @param pageName the name of page
207 	 *
208 	 * @return may be null if not found
209 	 */
210 	private Component getPage(String pageName)
211 	{
212 		Component component = null;
213 
214 		// This should be unnecessary...
215 		boolean found = false;
216 		while (!found)
217 		{
218 			try
219 			{
220 				component = componentSource.getPage(pageName);
221 				found = true;
222 			}
223 			catch (IllegalArgumentException iae)
224 			{
225 				if (pageName.lastIndexOf('/') != -1)
226 				{
227 					pageName = pageName.substring(0, pageName.lastIndexOf('/'));
228 					if (logger.isTraceEnabled())
229 						logger.trace(ChenilleKitAccessConstants.CHENILLEKIT_ACCESS, "New pagename: {}", pageName);
230 				}
231 				else
232 				{
233 					throw iae;
234 				}
235 			}
236 		}
237 
238 		return component;
239 	}
240 
241 }