You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Carl Crowder <ca...@taptu.com> on 2008/07/29 13:41:59 UTC

Access control with dispatchers and annotations

Hi,

I'm trying to create an access control system using a dispatcher as
described on the wiki page.

I'm following this:
http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess
So that I can use an annotation to declare which pages need a logged-in
user.

It checks the meta-data in the component model for a key called
"private" but it is not being added in my code. As far as I can tell,
there is no place where annotations on the type get converted into
meta-data. Am I missing something? Or do I need to implement my own
ClassTransformWorker to do this?

Thanks,
Carl


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations

Posted by Carl Crowder <ca...@taptu.com>.
Cheers for all the replies - I've taken Moritz's approach in the end :)

I've updated the wiki page to reflect this.

Carl

Moritz Gmelin wrote:
> Hi,
> 
> I think there is a bug in the Wiki. Try this instead
> 
>         Component page = componentSource.getPage(pageName);
>         Private prvAnnot = page.getClass().getAnnotation(
>             Private.class);
> 
> 
> when your Annotation is called Private of course.
> You'll get the annotation if it was present on the page or NULL otherwise.
> 
> M.
> 
> 
> Am 29.07.2008 um 13:41 schrieb Carl Crowder:
> 
>> Hi,
>>
>> I'm trying to create an access control system using a dispatcher as
>> described on the wiki page.
>>
>> I'm following this:
>> http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess
>> So that I can use an annotation to declare which pages need a logged-in
>> user.
>>
>> It checks the meta-data in the component model for a key called
>> "private" but it is not being added in my code. As far as I can tell,
>> there is no place where annotations on the type get converted into
>> meta-data. Am I missing something? Or do I need to implement my own
>> ClassTransformWorker to do this?
>>
>> Thanks,
>> Carl
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org
> 
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations

Posted by ph...@digiatlas.org.
I've been trying to use the same code.

The problem lies apparently in the fact that the class returned by  
getAnnotation is not Private but a proxy...

...
page anno class=$Proxy40
...


Quoting Moritz Gmelin <mo...@gmx.de>:

> Hi,
>
> I think there is a bug in the Wiki. Try this instead
>
> 		Component page = componentSource.getPage(pageName);
> 		Private prvAnnot = page.getClass().getAnnotation(
> 			Private.class);
>
>
> when your Annotation is called Private of course.
> You'll get the annotation if it was present on the page or NULL  otherwise.
>
> M.
>
>
> Am 29.07.2008 um 13:41 schrieb Carl Crowder:
>
>> Hi,
>>
>> I'm trying to create an access control system using a dispatcher as
>> described on the wiki page.
>>
>> I'm following this:
>> http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess
>> So that I can use an annotation to declare which pages need a logged- in
>> user.
>>
>> It checks the meta-data in the component model for a key called
>> "private" but it is not being added in my code. As far as I can tell,
>> there is no place where annotations on the type get converted into
>> meta-data. Am I missing something? Or do I need to implement my own
>> ClassTransformWorker to do this?
>>
>> Thanks,
>> Carl
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>> For additional commands, e-mail: users-help@tapestry.apache.org




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Serving a JNLP

Posted by Carl Crowder <ca...@taptu.com>.
Wait, never mind. I have had my head in XML mode, I forgot about
StreamResponses and this page:
http://wiki.apache.org/tapestry/Tapestry5HowToStreamAnExistingBinaryFile

Sorry!

Carl Crowder wrote:
> Hi again,
> 
> My app needs to serve JNLP files, and these files are dynamically
> generated. I'm doing this by simply having the tapestry page render a
> template as normal, but using the JNLP element as the page root. I then
> set the content type on the page to be the JNLP MIME-type.
> 
> This all works fine and it serves a page which I can then run with WebStart.
> 
> The only problem is the tapestry page is called "app", so the file you
> download is also called "app". This is fine when running the app from
> within a browser, because of the MIME-type. However I want to allow
> users to save the file on their computer to run the app offline. If you
> save the file it gets saved as just "app" so, on Windows at least,
> double clicking doesn't automatically run WebStart.
> 
> I want to have the file returned be called "app.jnlp" to overcome this.
> 
> Firstly, is the way I'm doing this the best way to serve dynamically
> generated JNLPs?
> 
> Secondly, how can I set the page name (or file returned name) to be
> "app.jnlp"? I thought about having a dummy page called "app" which just
> had a single "jnlp" component which did the work, so "app.jnlp" would
> work I think, but that seems like a massive hack.
> 
> Any help would be greatly appreciated :)
> 
> Carl
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Serving a JNLP

Posted by Carl Crowder <ca...@taptu.com>.
Hi again,

My app needs to serve JNLP files, and these files are dynamically
generated. I'm doing this by simply having the tapestry page render a
template as normal, but using the JNLP element as the page root. I then
set the content type on the page to be the JNLP MIME-type.

This all works fine and it serves a page which I can then run with WebStart.

The only problem is the tapestry page is called "app", so the file you
download is also called "app". This is fine when running the app from
within a browser, because of the MIME-type. However I want to allow
users to save the file on their computer to run the app offline. If you
save the file it gets saved as just "app" so, on Windows at least,
double clicking doesn't automatically run WebStart.

I want to have the file returned be called "app.jnlp" to overcome this.

Firstly, is the way I'm doing this the best way to serve dynamically
generated JNLPs?

Secondly, how can I set the page name (or file returned name) to be
"app.jnlp"? I thought about having a dummy page called "app" which just
had a single "jnlp" component which did the work, so "app.jnlp" would
work I think, but that seems like a massive hack.

Any help would be greatly appreciated :)

Carl

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations

Posted by Moritz Gmelin <mo...@gmx.de>.
Hi,

I think there is a bug in the Wiki. Try this instead

		Component page = componentSource.getPage(pageName);
		Private prvAnnot = page.getClass().getAnnotation(
			Private.class);


when your Annotation is called Private of course.
You'll get the annotation if it was present on the page or NULL  
otherwise.

M.


Am 29.07.2008 um 13:41 schrieb Carl Crowder:

> Hi,
>
> I'm trying to create an access control system using a dispatcher as
> described on the wiki page.
>
> I'm following this:
> http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess
> So that I can use an annotation to declare which pages need a logged- 
> in
> user.
>
> It checks the meta-data in the component model for a key called
> "private" but it is not being added in my code. As far as I can tell,
> there is no place where annotations on the type get converted into
> meta-data. Am I missing something? Or do I need to implement my own
> ClassTransformWorker to do this?
>
> Thanks,
> Carl
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations - problem

Posted by "Martijn Brinkers (List)" <ma...@gmail.com>.
Could you try to move all non-page classes/interfaces out of the pages
package (same applies to components). So move Private.java to some
package other than in components, mixins, base, pages

Martijn 



On Wed, 2008-07-30 at 10:41 +0100, photos@digiatlas.org wrote:
> I too have been trying to implement what is on the wiki.
> 
> This is really doing my head in (not helped by the fact the wiki  
> solution http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess  
> does not have all the "bits" of code necessary for a newbie like  
> myself to get it working. For instance, it's missing the package  
> imports and is also missing a necessary try-catch block at the end of  
> checkAccess()).
> 
> I've had no success after a day or more working on it - even with the  
> updated code recently provided. It just does not work and seems either  
> to be a mistake on my part in how Annotations work (they are new to  
> me, I admit, having not used them before), or a serious problem with  
> the way the code works (the ClassLoaders? It seems the standard  
> classloader is loading Private while the tapestry pages are via its  
> own classloader - I don't know how getAnnotation() works, so I'm  
> wildly guessing and probably wrong)
> 
> Below is the code I have. I'd appreciate a pointer on what I've done wrong.
> 
> The output is as follows:
> 
> [DEBUG] AppModule.TimingFilter Invoking method  
> uk.bl.dlportal.services.AppModule.buildTimingFilter(Logger) (at  
> AppModule.java:97).
> 1
> PAGE CLASS = class uk.bl.dlportal.pages.Administration
> PAGE ANNO = null
> PAGE ANNOS = @uk.bl.dlportal.pages.util.Private()
> [INFO] AppModule.TimingFilter Request time: 4784 ms
> [INFO] AppModule.TimingFilter Request time: 0 ms
> 
> 
> ----------------- AccessController.java --
> 
> package uk.bl.dlportal.pages.util;
> 
> import java.io.IOException;
> 
> import org.apache.tapestry5.runtime.Component;
> import org.apache.tapestry5.services.ApplicationStateManager;
> import org.apache.tapestry5.services.ComponentClassResolver;
> import org.apache.tapestry5.services.ComponentSource;
> import org.apache.tapestry5.services.Dispatcher;
> import org.apache.tapestry5.services.Request;
> import org.apache.tapestry5.services.Response;
> 
> import uk.bl.dlportal.entities.User;
> 
> public class AccessController implements Dispatcher
> {
> 	private final static String LOGIN_PAGE = "/index";
> 
> 	private ApplicationStateManager asm;
> 	private final ComponentClassResolver resolver;
> 	private final ComponentSource componentSource;
> 
> 
> 	/**
> 	 * Receive all the services needed as constructor arguments. When we bind
> 	 * this service, T5 IoC will provide all the services !
> 	 */
> 	public AccessController(ApplicationStateManager asm,
> 			ComponentClassResolver resolver, ComponentSource componentSource)
> 	{
> 		this.asm = asm;
> 		this.resolver = resolver;
> 		this.componentSource = componentSource;
> 	}
> 
> 
> 	public boolean dispatch(Request request, Response response)
> 			throws IOException
> 	{
> 		System.out.println("1");
> 		/*
> 		 * We need to get the Tapestry page requested by the user. So we parse
> 		 * the path extracted from the request
> 		 */
> 		String path = request.getPath();
> 		if (path.equals(""))
> 			return false;
> 
> 		int nextslashx = path.length();
> 		String pageName;
> 
> 		while (true)
> 		{
> 			pageName = path.substring(1, nextslashx);
> 			if (!pageName.endsWith("/") && resolver.isPageName(pageName))
> 				break;
> 			nextslashx = path.lastIndexOf('/', nextslashx - 1);
> 			if (nextslashx <= 1)
> 				return false;
> 		}
> 		return checkAccess(pageName, request, response);
> 	}
> 
> 
> 	/**
> 	 * Check the rights of the user for the page requested
> 	 */
> 	public boolean checkAccess(String pageName, Request request,
> 			Response response)
> 	{
> 
> 		boolean canAccess = true;
> 
> 		/* Is the requested page private ? */
> 		Component page = componentSource.getPage(pageName);
> 
> 		System.out.println("PAGE CLASS = "+page.getClass());
> 		System.out.println("PAGE ANNO =  
> "+page.getClass().getAnnotation(Private.class));
> 		System.out.println("PAGE ANNOS = "+page.getClass().getAnnotations()[0]);
> 
> 		boolean privatePage = page.getClass().getAnnotation(Private.class) != null;
> 
> 		if (privatePage)
> 		{
> 			canAccess = false;
> 			/* Is the user already authenticated ? */
> 			if (asm.exists(User.class))
> 			{
> 				User userSession = asm.get(User.class);
> 				canAccess = userSession != null;
> 			}
> 
> 			/*
> 			if (asm.exists(UserSessionImpl.class))
> 			{
> 				UserSessionImpl userSession = asm.get(UserSessionImpl.class);
> 				canAccess = userSession.isUserLoggedIn();
> 			}
> 			*/
> 		}
> 
> 
> 		if (!canAccess)
> 		{
> 			try
> 			{
> 				response.sendRedirect(request.getContextPath() + LOGIN_PAGE);
> 			} catch (IOException e)
> 			{
> 				// TODO Auto-generated catch block
> 				e.printStackTrace();
> 			}
> 			return true; // Make sure to leave the chain
> 		}
> 		return false;
> 	}
> 
> }
> 
> 
> -------------------- AppModule.java --
> 
> ...
> 	public static void bind(ServiceBinder binder)
> 	{
> 		// binder.bind(MyServiceInterface.class, MyServiceImpl.class);
> 
> 		// Make bind() calls on the binder object to define most IoC services.
> 		// Use service builder methods (example below) when the implementation
> 		// is provided inline, or requires more initialization than simply
> 		// invoking the constructor.
> 
> 		binder.bind(AccessController.class).withId("AccessController");
> 
> 	}
> 
> 
> 	public void contributeMasterDispatcher(
> 			OrderedConfiguration<Dispatcher> configuration,
> 			@InjectService("AccessController") Dispatcher accessController)
> 	{
> 		configuration.add("AccessController", accessController,
> 				"before:PageRender");
> 	}
> ...
> 
> 
> ---------------- Private.java --
> 
> package uk.bl.dlportal.pages.util;
> 
> import java.lang.annotation.Documented;
> import java.lang.annotation.ElementType;
> import java.lang.annotation.Retention;
> import java.lang.annotation.RetentionPolicy;
> import java.lang.annotation.Target;
> 
> @Target(ElementType.TYPE)
> @Retention(RetentionPolicy.RUNTIME)
> @Documented
> public @interface Private
> {
> }
> 
> 
> ------------------ Administration.java -- (the page I'm testing this on)
> 
> package uk.bl.dlportal.pages;
> 
> import org.apache.tapestry5.annotations.ApplicationState;
> 
> import uk.bl.dlportal.entities.User;
> import uk.bl.dlportal.pages.util.Private;
> 
> /**
>   * Admin page of application dlportal.
>   */
> @Private
> public class Administration
> {
> ....
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations - problem

Posted by Weisu <we...@gmail.com>.
Hi, I think I have found your problem. I tried to implemented your code and
found this line caused the problem. After I commented out this line
everything works.
		/* Is the requested page private ? */
		Component page = componentSource.getPage(pageName);

		System.out.println("PAGE CLASS = "+page.getClass());
		System.out.println("PAGE ANNO =  
"+page.getClass().getAnnotation(Private.class));
//		System.out.println("PAGE ANNOS = "+page.getClass().getAnnotations()[0]);

		boolean privatePage = page.getClass().getAnnotation(Private.class) !=
null;


Weisu


photos-4 wrote:
> 
> I too have been trying to implement what is on the wiki.
> 
> This is really doing my head in (not helped by the fact the wiki  
> solution http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess  
> does not have all the "bits" of code necessary for a newbie like  
> myself to get it working. For instance, it's missing the package  
> imports and is also missing a necessary try-catch block at the end of  
> checkAccess()).
> 
> I've had no success after a day or more working on it - even with the  
> updated code recently provided. It just does not work and seems either  
> to be a mistake on my part in how Annotations work (they are new to  
> me, I admit, having not used them before), or a serious problem with  
> the way the code works (the ClassLoaders? It seems the standard  
> classloader is loading Private while the tapestry pages are via its  
> own classloader - I don't know how getAnnotation() works, so I'm  
> wildly guessing and probably wrong)
> 
> Below is the code I have. I'd appreciate a pointer on what I've done
> wrong.
> 
> The output is as follows:
> 
> [DEBUG] AppModule.TimingFilter Invoking method  
> uk.bl.dlportal.services.AppModule.buildTimingFilter(Logger) (at  
> AppModule.java:97).
> 1
> PAGE CLASS = class uk.bl.dlportal.pages.Administration
> PAGE ANNO = null
> PAGE ANNOS = @uk.bl.dlportal.pages.util.Private()
> [INFO] AppModule.TimingFilter Request time: 4784 ms
> [INFO] AppModule.TimingFilter Request time: 0 ms
> 
> 
> ----------------- AccessController.java --
> 
> package uk.bl.dlportal.pages.util;
> 
> import java.io.IOException;
> 
> import org.apache.tapestry5.runtime.Component;
> import org.apache.tapestry5.services.ApplicationStateManager;
> import org.apache.tapestry5.services.ComponentClassResolver;
> import org.apache.tapestry5.services.ComponentSource;
> import org.apache.tapestry5.services.Dispatcher;
> import org.apache.tapestry5.services.Request;
> import org.apache.tapestry5.services.Response;
> 
> import uk.bl.dlportal.entities.User;
> 
> public class AccessController implements Dispatcher
> {
> 	private final static String LOGIN_PAGE = "/index";
> 
> 	private ApplicationStateManager asm;
> 	private final ComponentClassResolver resolver;
> 	private final ComponentSource componentSource;
> 
> 
> 	/**
> 	 * Receive all the services needed as constructor arguments. When we bind
> 	 * this service, T5 IoC will provide all the services !
> 	 */
> 	public AccessController(ApplicationStateManager asm,
> 			ComponentClassResolver resolver, ComponentSource componentSource)
> 	{
> 		this.asm = asm;
> 		this.resolver = resolver;
> 		this.componentSource = componentSource;
> 	}
> 
> 
> 	public boolean dispatch(Request request, Response response)
> 			throws IOException
> 	{
> 		System.out.println("1");
> 		/*
> 		 * We need to get the Tapestry page requested by the user. So we parse
> 		 * the path extracted from the request
> 		 */
> 		String path = request.getPath();
> 		if (path.equals(""))
> 			return false;
> 
> 		int nextslashx = path.length();
> 		String pageName;
> 
> 		while (true)
> 		{
> 			pageName = path.substring(1, nextslashx);
> 			if (!pageName.endsWith("/") && resolver.isPageName(pageName))
> 				break;
> 			nextslashx = path.lastIndexOf('/', nextslashx - 1);
> 			if (nextslashx <= 1)
> 				return false;
> 		}
> 		return checkAccess(pageName, request, response);
> 	}
> 
> 
> 	/**
> 	 * Check the rights of the user for the page requested
> 	 */
> 	public boolean checkAccess(String pageName, Request request,
> 			Response response)
> 	{
> 
> 		boolean canAccess = true;
> 
> 		/* Is the requested page private ? */
> 		Component page = componentSource.getPage(pageName);
> 
> 		System.out.println("PAGE CLASS = "+page.getClass());
> 		System.out.println("PAGE ANNO =  
> "+page.getClass().getAnnotation(Private.class));
> 		System.out.println("PAGE ANNOS = "+page.getClass().getAnnotations()[0]);
> 
> 		boolean privatePage = page.getClass().getAnnotation(Private.class) !=
> null;
> 
> 		if (privatePage)
> 		{
> 			canAccess = false;
> 			/* Is the user already authenticated ? */
> 			if (asm.exists(User.class))
> 			{
> 				User userSession = asm.get(User.class);
> 				canAccess = userSession != null;
> 			}
> 
> 			/*
> 			if (asm.exists(UserSessionImpl.class))
> 			{
> 				UserSessionImpl userSession = asm.get(UserSessionImpl.class);
> 				canAccess = userSession.isUserLoggedIn();
> 			}
> 			*/
> 		}
> 
> 
> 		if (!canAccess)
> 		{
> 			try
> 			{
> 				response.sendRedirect(request.getContextPath() + LOGIN_PAGE);
> 			} catch (IOException e)
> 			{
> 				// TODO Auto-generated catch block
> 				e.printStackTrace();
> 			}
> 			return true; // Make sure to leave the chain
> 		}
> 		return false;
> 	}
> 
> }
> 
> 
> -------------------- AppModule.java --
> 
> ...
> 	public static void bind(ServiceBinder binder)
> 	{
> 		// binder.bind(MyServiceInterface.class, MyServiceImpl.class);
> 
> 		// Make bind() calls on the binder object to define most IoC services.
> 		// Use service builder methods (example below) when the implementation
> 		// is provided inline, or requires more initialization than simply
> 		// invoking the constructor.
> 
> 		binder.bind(AccessController.class).withId("AccessController");
> 
> 	}
> 
> 
> 	public void contributeMasterDispatcher(
> 			OrderedConfiguration<Dispatcher> configuration,
> 			@InjectService("AccessController") Dispatcher accessController)
> 	{
> 		configuration.add("AccessController", accessController,
> 				"before:PageRender");
> 	}
> ...
> 
> 
> ---------------- Private.java --
> 
> package uk.bl.dlportal.pages.util;
> 
> import java.lang.annotation.Documented;
> import java.lang.annotation.ElementType;
> import java.lang.annotation.Retention;
> import java.lang.annotation.RetentionPolicy;
> import java.lang.annotation.Target;
> 
> @Target(ElementType.TYPE)
> @Retention(RetentionPolicy.RUNTIME)
> @Documented
> public @interface Private
> {
> }
> 
> 
> ------------------ Administration.java -- (the page I'm testing this on)
> 
> package uk.bl.dlportal.pages;
> 
> import org.apache.tapestry5.annotations.ApplicationState;
> 
> import uk.bl.dlportal.entities.User;
> import uk.bl.dlportal.pages.util.Private;
> 
> /**
>   * Admin page of application dlportal.
>   */
> @Private
> public class Administration
> {
> ....
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
> 
> 
> 

-- 
View this message in context: http://www.nabble.com/Access-control-with-dispatchers-and-annotations-tp18710376p18768093.html
Sent from the Tapestry - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations - problem

Posted by ph...@digiatlas.org.
I too have been trying to implement what is on the wiki.

This is really doing my head in (not helped by the fact the wiki  
solution http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess  
does not have all the "bits" of code necessary for a newbie like  
myself to get it working. For instance, it's missing the package  
imports and is also missing a necessary try-catch block at the end of  
checkAccess()).

I've had no success after a day or more working on it - even with the  
updated code recently provided. It just does not work and seems either  
to be a mistake on my part in how Annotations work (they are new to  
me, I admit, having not used them before), or a serious problem with  
the way the code works (the ClassLoaders? It seems the standard  
classloader is loading Private while the tapestry pages are via its  
own classloader - I don't know how getAnnotation() works, so I'm  
wildly guessing and probably wrong)

Below is the code I have. I'd appreciate a pointer on what I've done wrong.

The output is as follows:

[DEBUG] AppModule.TimingFilter Invoking method  
uk.bl.dlportal.services.AppModule.buildTimingFilter(Logger) (at  
AppModule.java:97).
1
PAGE CLASS = class uk.bl.dlportal.pages.Administration
PAGE ANNO = null
PAGE ANNOS = @uk.bl.dlportal.pages.util.Private()
[INFO] AppModule.TimingFilter Request time: 4784 ms
[INFO] AppModule.TimingFilter Request time: 0 ms


----------------- AccessController.java --

package uk.bl.dlportal.pages.util;

import java.io.IOException;

import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.ApplicationStateManager;
import org.apache.tapestry5.services.ComponentClassResolver;
import org.apache.tapestry5.services.ComponentSource;
import org.apache.tapestry5.services.Dispatcher;
import org.apache.tapestry5.services.Request;
import org.apache.tapestry5.services.Response;

import uk.bl.dlportal.entities.User;

public class AccessController implements Dispatcher
{
	private final static String LOGIN_PAGE = "/index";

	private ApplicationStateManager asm;
	private final ComponentClassResolver resolver;
	private final ComponentSource componentSource;


	/**
	 * Receive all the services needed as constructor arguments. When we bind
	 * this service, T5 IoC will provide all the services !
	 */
	public AccessController(ApplicationStateManager asm,
			ComponentClassResolver resolver, ComponentSource componentSource)
	{
		this.asm = asm;
		this.resolver = resolver;
		this.componentSource = componentSource;
	}


	public boolean dispatch(Request request, Response response)
			throws IOException
	{
		System.out.println("1");
		/*
		 * We need to get the Tapestry page requested by the user. So we parse
		 * the path extracted from the request
		 */
		String path = request.getPath();
		if (path.equals(""))
			return false;

		int nextslashx = path.length();
		String pageName;

		while (true)
		{
			pageName = path.substring(1, nextslashx);
			if (!pageName.endsWith("/") && resolver.isPageName(pageName))
				break;
			nextslashx = path.lastIndexOf('/', nextslashx - 1);
			if (nextslashx <= 1)
				return false;
		}
		return checkAccess(pageName, request, response);
	}


	/**
	 * Check the rights of the user for the page requested
	 */
	public boolean checkAccess(String pageName, Request request,
			Response response)
	{

		boolean canAccess = true;

		/* Is the requested page private ? */
		Component page = componentSource.getPage(pageName);

		System.out.println("PAGE CLASS = "+page.getClass());
		System.out.println("PAGE ANNO =  
"+page.getClass().getAnnotation(Private.class));
		System.out.println("PAGE ANNOS = "+page.getClass().getAnnotations()[0]);

		boolean privatePage = page.getClass().getAnnotation(Private.class) != null;

		if (privatePage)
		{
			canAccess = false;
			/* Is the user already authenticated ? */
			if (asm.exists(User.class))
			{
				User userSession = asm.get(User.class);
				canAccess = userSession != null;
			}

			/*
			if (asm.exists(UserSessionImpl.class))
			{
				UserSessionImpl userSession = asm.get(UserSessionImpl.class);
				canAccess = userSession.isUserLoggedIn();
			}
			*/
		}


		if (!canAccess)
		{
			try
			{
				response.sendRedirect(request.getContextPath() + LOGIN_PAGE);
			} catch (IOException e)
			{
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return true; // Make sure to leave the chain
		}
		return false;
	}

}


-------------------- AppModule.java --

...
	public static void bind(ServiceBinder binder)
	{
		// binder.bind(MyServiceInterface.class, MyServiceImpl.class);

		// Make bind() calls on the binder object to define most IoC services.
		// Use service builder methods (example below) when the implementation
		// is provided inline, or requires more initialization than simply
		// invoking the constructor.

		binder.bind(AccessController.class).withId("AccessController");

	}


	public void contributeMasterDispatcher(
			OrderedConfiguration<Dispatcher> configuration,
			@InjectService("AccessController") Dispatcher accessController)
	{
		configuration.add("AccessController", accessController,
				"before:PageRender");
	}
...


---------------- Private.java --

package uk.bl.dlportal.pages.util;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Private
{
}


------------------ Administration.java -- (the page I'm testing this on)

package uk.bl.dlportal.pages;

import org.apache.tapestry5.annotations.ApplicationState;

import uk.bl.dlportal.entities.User;
import uk.bl.dlportal.pages.util.Private;

/**
  * Admin page of application dlportal.
  */
@Private
public class Administration
{
....



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations

Posted by Massimo Lusetti <ml...@gmail.com>.
On Tue, Jul 29, 2008 at 3:54 PM, Sven Homburg <ho...@googlemail.com> wrote:

> massimo,
>
> i ask me sometimes, now i ask you ;-)
> why do you use the the Restriced annotation not directly
> your code RestrictedWorker class seach for Restriced class an injected
> some metas into the page/component
> after that the AccessValidatorImpl ask for the private meta ???
> why not directly work the annotation ?

The first reason is cause i've looked at Howard's code and it is done
that way so i've taken that path. I'll tell you the second reason when
i will finish the method level protection code :)

Regards
-- 
Massimo
http://meridio.blogspot.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Access control with dispatchers and annotations

Posted by Sven Homburg <ho...@googlemail.com>.
massimo,

i ask me sometimes, now i ask you ;-)
why do you use the the Restriced annotation not directly
your code RestrictedWorker class seach for Restriced class an injected
some metas into the page/component
after that the AccessValidatorImpl ask for the private meta ???
why not directly work the annotation ?

2008/7/29 Massimo Lusetti <ml...@gmail.com>

> On Tue, Jul 29, 2008 at 1:41 PM, Carl Crowder <ca...@taptu.com>
> wrote:
>
> > Hi,
> >
> > I'm trying to create an access control system using a dispatcher as
> > described on the wiki page.
> >
> > I'm following this:
> > http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess
> > So that I can use an annotation to declare which pages need a logged-in
> > user.
> >
> > It checks the meta-data in the component model for a key called
> > "private" but it is not being added in my code. As far as I can tell,
> > there is no place where annotations on the type get converted into
> > meta-data. Am I missing something? Or do I need to implement my own
> > ClassTransformWorker to do this?
>
> Take a look at chenillekit-access module, it does just that. Look for
> chenillekit project on googlecode.
>
> Regards
> --
> Massimo
> http://meridio.blogspot.com
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>


-- 
with regards
Sven Homburg
http://tapestry5-components.googlecode.com
http://chenillekit.googlecode.com

Re: Access control with dispatchers and annotations

Posted by Massimo Lusetti <ml...@gmail.com>.
On Tue, Jul 29, 2008 at 1:41 PM, Carl Crowder <ca...@taptu.com> wrote:

> Hi,
>
> I'm trying to create an access control system using a dispatcher as
> described on the wiki page.
>
> I'm following this:
> http://wiki.apache.org/tapestry/Tapestry5HowToControlAccess
> So that I can use an annotation to declare which pages need a logged-in
> user.
>
> It checks the meta-data in the component model for a key called
> "private" but it is not being added in my code. As far as I can tell,
> there is no place where annotations on the type get converted into
> meta-data. Am I missing something? Or do I need to implement my own
> ClassTransformWorker to do this?

Take a look at chenillekit-access module, it does just that. Look for
chenillekit project on googlecode.

Regards
-- 
Massimo
http://meridio.blogspot.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org