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
15 package org.chenillekit.access;
16
17 import java.io.IOException;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Properties;
21 import java.util.Set;
22
23 import org.apache.tapestry5.ioc.Configuration;
24 import org.apache.tapestry5.ioc.MappedConfiguration;
25 import org.apache.tapestry5.ioc.OrderedConfiguration;
26 import org.apache.tapestry5.ioc.ServiceBinder;
27 import org.apache.tapestry5.ioc.annotations.InjectService;
28 import org.apache.tapestry5.ioc.annotations.Marker;
29 import org.apache.tapestry5.ioc.internal.util.Defense;
30 import org.apache.tapestry5.ioc.services.ChainBuilder;
31 import org.apache.tapestry5.services.ApplicationStateManager;
32 import org.apache.tapestry5.services.ComponentClassResolver;
33 import org.apache.tapestry5.services.ComponentClassTransformWorker;
34 import org.apache.tapestry5.services.ComponentEventRequestFilter;
35 import org.apache.tapestry5.services.ComponentSource;
36 import org.apache.tapestry5.services.LibraryMapping;
37 import org.apache.tapestry5.services.MetaDataLocator;
38 import org.apache.tapestry5.services.PageRenderRequestFilter;
39 import org.chenillekit.access.annotations.ChenilleKitAccess;
40 import org.chenillekit.access.internal.NoOpAuthenticationService;
41 import org.chenillekit.access.services.AccessValidator;
42 import org.chenillekit.access.services.AuthenticationService;
43 import org.chenillekit.access.services.impl.AccessValidatorImpl;
44 import org.chenillekit.access.services.impl.ComponentEventAccessFilter;
45 import org.chenillekit.access.services.impl.PageRenderAccessFilter;
46 import org.chenillekit.access.services.impl.RestrictedWorker;
47 import org.slf4j.Logger;
48
49 /**
50 *
51 * @version $Id: ChenilleKitAccessModule.java 380 2008-12-30 10:21:52Z mlusetti $
52 */
53 public class ChenilleKitAccessModule
54 {
55 /**
56 *
57 * @param binder
58 */
59 public static void bind(ServiceBinder binder)
60 {
61 binder.bind(ComponentEventRequestFilter.class, ComponentEventAccessFilter.class).withMarker(ChenilleKitAccess.class);
62 binder.bind(PageRenderRequestFilter.class, PageRenderAccessFilter.class).withMarker(ChenilleKitAccess.class);
63 }
64
65 /**
66 *
67 * @param configuration
68 * @param chainBuilder
69 * @return
70 */
71 public static AuthenticationService buildAuthenticationService(
72 final List<AuthenticationService> configuration,
73 @InjectService("ChainBuilder")
74 ChainBuilder chainBuilder)
75 {
76 return chainBuilder.build(AuthenticationService.class, configuration);
77 }
78
79 /**
80 *
81 * @param configuration
82 */
83 public static void contributeAuthenticationService(OrderedConfiguration<AuthenticationService> configuration)
84 {
85 configuration.add("no-op", new NoOpAuthenticationService(), "after:*");
86 }
87
88 /**
89 * Contribute our {@link ComponentClassTransformWorker} to transformation pipeline to add our code to
90 * loaded classes
91 * @param configuration component class transformer configuration
92 */
93 public static void contributeComponentClassTransformWorker(
94 OrderedConfiguration<ComponentClassTransformWorker> configuration)
95 {
96 configuration.add("Restricted", new RestrictedWorker(), "after:Secure");
97 }
98
99 /**
100 * Contribute our virtual folder to {@link ComponentClassResolver} service
101 *
102 * @param configuration configuration for the service where we contribute to
103 */
104 public static void contributeComponentClassResolver(Configuration<LibraryMapping> configuration)
105 {
106 configuration.add(new LibraryMapping("ckaccess", "org.chenillekit.access"));
107 }
108
109
110 /**
111 * build the authentificate service.
112 *
113 * @param logger system logger
114 * @param contribution contribution map
115 * @param userService user storage service
116 * @param appServerLoginService assure login to the appserver can be handled correctly
117 * @return auth service for login handling
118 */
119 // public static AuthRedirectService buildAuthRedirectService(final Logger logger,
120 // final Map<String, Class> contribution,
121 // final WebSessionUserService userService,
122 // final AppServerLoginService appServerLoginService)
123 // {
124 // try
125 // {
126 // Class authServiceClass = contribution.get(ChenilleKitAccessConstants.WEB_USER_AUTH_SERVICE);
127 // Defense.notNull(authServiceClass, ChenilleKitAccessConstants.WEB_USER_AUTH_SERVICE);
128 // return new AuthRedirectServiceImpl(logger, (AuthService)authServiceClass.newInstance(), userService, appServerLoginService);
129 // }
130 // catch (InstantiationException e)
131 // {
132 // throw new RuntimeException(e);
133 // }
134 // catch (IllegalAccessException e)
135 // {
136 // throw new RuntimeException(e);
137 // }
138 // }
139
140 /**
141 *
142 * @param componentSource component source
143 * @param locator meta data locator
144 * @param logger system logger
145 * @return build access validator
146 */
147 @Marker(ChenilleKitAccess.class)
148 public static AccessValidator buildAccessValidator(ComponentSource componentSource,
149 MetaDataLocator locator,
150 Logger logger, ApplicationStateManager manager,
151 Map<String, Class> contribution)
152 {
153 Class webSessionUserClass = contribution.get(ChenilleKitAccessConstants.WEB_SESSION_USER_KEY);
154
155 Defense.notNull(webSessionUserClass, "webSessionUserClass");
156
157 return new AccessValidatorImpl(componentSource, locator, logger, manager, webSessionUserClass);
158 }
159
160 /**
161 * Contributes "AccessControl" filter which checks for access rights of requests.
162 */
163 public void contributePageRenderRequestHandler(OrderedConfiguration<PageRenderRequestFilter> configuration,
164 final @ChenilleKitAccess PageRenderRequestFilter accessFilter)
165 {
166 configuration.add("AccessControl", accessFilter, "before:*");
167 }
168
169 /**
170 * Contribute "AccessControl" filter to determine if the event can be processed and the user
171 * has enough rights to do so.
172 */
173 public void contributeComponentEventRequestHandler(OrderedConfiguration<ComponentEventRequestFilter> configuration,
174 @ChenilleKitAccess ComponentEventRequestFilter accessFilter)
175 {
176 configuration.add("AccessControl", accessFilter, "before:*");
177 }
178
179 /**
180 * @param configuration
181 */
182 public static void contributeFactoryDefaults(MappedConfiguration<String, String> configuration)
183 {
184 Properties prop = new Properties();
185 try
186 {
187 prop.load(ChenilleKitAccessModule.class.getResourceAsStream("/chenillekit-access.properties"));
188 }
189 catch (IOException e)
190 {
191 throw new RuntimeException(e);
192 }
193
194 Set<Object> keys = prop.keySet();
195 for (Object key : keys)
196 {
197 Object value = prop.get(key);
198 configuration.add(key.toString(), value.toString());
199 }
200 }
201
202 /**
203 * User management filter, the login method on the user should be called when the user logs in. If the user does not
204 * yet exist (which is possible when logging in using some SSO solution, then the user should be created).
205 *
206 * @param webSessionUserService login info service
207 * @param appServerLoginService assure login to the appserver can be handled correctly
208 * @return request filter
209 */
210 // public RequestFilter buildWebSessionUserFilter( final WebSessionUserService webSessionUserService,
211 // final AppServerLoginService appServerLoginService )
212 // {
213 // return new RequestFilter()
214 // {
215 // public boolean service( Request request, Response response, RequestHandler handler )
216 // throws IOException
217 // {
218 // Session session = request.getSession( false );
219 // WebSessionUser wsu = null;
220 // if ( null != session ) wsu = (WebSessionUser) session.getAttribute( ChenilleKitAccessConstants.WEB_SESSION_USER_KEY );
221 // appServerLoginService.appServerLogin( wsu );
222 // webSessionUserService.setUser( wsu );
223 //
224 // // The reponsibility of a filter is to invoke the corresponding method
225 // // in the handler. When you chain multiple filters together, each filter
226 // // received a handler that is a bridge to the next filter.
227 // boolean res = handler.service( request, response );
228 //
229 // wsu = webSessionUserService.getUser();
230 // session = request.getSession( wsu != null );
231 // if ( null != session ) session.setAttribute( ChenilleKitAccessConstants.WEB_SESSION_USER_KEY, wsu );
232 // return res;
233 // }
234 // };
235 // }
236
237 /**
238 * This is a contribution to the RequestHandler service configuration. This is how we extend Tapestry using the
239 * timing filter. A common use for this kind of filter is transaction management or security.
240 *
241 * @param configuration configuration to add to
242 * @param webSessionUserFilter filter info
243 */
244 // public void contributeRequestHandler( OrderedConfiguration<RequestFilter> configuration,
245 // @InjectService( "WebSessionUserFilter" ) RequestFilter webSessionUserFilter )
246 // {
247 // // Each contribution to an ordered configuration has a name, When necessary, you may
248 // // set constraints to precisely control the invocation order of the contributed filter
249 // // within the pipeline.
250 // configuration.add( "WebSessionUser", webSessionUserFilter );
251 // }
252
253 }