[cgiapp] app authorization patterns, best practices?

2012-03-23 Thread B. Estrade
Greetings, all. I've been working with CApp for a while, and I really
like it.

I have some questions regarding best practices when implementing
role based access control (RBAC). I have been playing with
CApp::Authentication and Authorization, and they both do basically
what I need.

Here's the skeleton I came up with - 

https://gist.github.com/33d23edf8fa2c0f48dc0

My question is really, what's the best way to go about separating
functionality in a CApp based application?

A practical case I am looking at right now is that I have form that
is used to manage user data. There are 3 roles - User, Manager, and
Admin. Each one has the types of permissions you'd expect (User can
manage himself, Manager can manage his Users, Admin can do anything).

I was thinking of the best way to build this form and control actions
cleanly and compose this form using 3 different runmodes that are
increasingly restrictive.

For example, the User form calls the "user" runmode, and returns the
form content. The "manager" runmode takes the output of "user" and
adds some stuff to it. The "admin" runmode might take the result of
the "manager" runmode - which would also include what the "user"
runmode provides...and so on.

Ultimately, my goal is to get away from nasty frog boiling "if" blocks
controlling authorization and rely on composable functions (i.e.,
runmodes or modules) that will cleanly give me what I would like using
the runmode level protection that CApp::Authorization provides you.

I've searched around and banged my head against this pretty hard, so
any thoughts or resources would be appreciated. For all I know, this
might be a bad idea. But I am really just looking for the best way to
create an access controlled system as cleanly as possible.

Thank you,
Brett

ps: I noticed that even if POST_LOGIN_RUNMODE is protected via
CApp::Authentication, the check seems to be ignored immediately after
login. I am not sure if this is a known issue or that there are some
callbacks happening in the wrong order. This will happen in the gist I
linked above.

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] app authorization patterns, best practices?

2012-03-28 Thread B. Estrade
On Sat, Mar 24, 2012 at 10:32:59AM +1100, Ron Savage wrote:
> Hi Brett
> 
> On 24/03/12 05:30, B. Estrade wrote:
> > https://gist.github.com/33d23edf8fa2c0f48dc0
> 
> The return stmt in your groupmap code seems overly complex:
> 
> #!/usr/bin/env perl
> 
> use strict;
> use warnings;
> #use no autovivification;
> 
> # ---
> 
> sub check
> {
>   my($user, $group) = @_;
>   my(%user2group)   =
>   (
>   user1 => {all => 1, manager => 1, admin => 1},
>   user2 => {all => 1, manager => 1},
>   user3 => {all => 1},
>   );
> 
>   return $user2group{$user}{$group};
> 
> }
> 
> # ---
> 
> for my $user (qw/user1 user2 user3 nobody/)
> {
>   print "User: $user. ";
> 
>   for my $group (qw/all manager admin nothing/)
>   {
>   print "Group: $group. Check: ", check($user, $group) || 0, '. ';
>   }
> 
>   print "\n";
> }

Very nice, thank you. And, yes, I am considering the class-based
approach. It's just that the last guy did that, too - and it's not too
pretty :)

Brett

> 
> 
> -- 
> Ron Savage
> http://savage.net.au/
> Ph: 0421 920 622
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] app authorization patterns, best practices?

2012-03-28 Thread B. Estrade
On Fri, Mar 23, 2012 at 8:05 PM, Jerry Kaidor  wrote:
>
>> I have some questions regarding best practices when implementing
>> role based access control (RBAC). I have been playing with
>> CApp::Authentication and Authorization, and they both do basically
>> what I need.
>
> *** Me too.  I have three sub-businesses.  Let's call them A, B, C.  I
> want to have access to all of it, but I want my managers to only have
> access to
> their particular piece.
>
>    Here's more or less how I did it.  BTW, it recently broke for unknown
> reason, and I havent' gotten around to troubleshooting.
>
>   CApp:Authentication has a notion of "drivers".  I wrote a multi-DB
> driver that can look in a set of authentication databases.  I have a
> "users"
> mysql database at my global level, and another "users" database in each
> subbusiness.  When somebody attempts to log in, the multi-auth driver
> tries each database in turn.  If it successfully authenticates against the
> "global" database, that user has privs for all the sub-businesses.
>
>   Each line in the "users" database has a set of "permissions" flags,
> which correspond to things seeming to permission as I coded.  In line
> with the code are statements in the form if( getpriv( user, business
> )){}.  That way, I have a permissions system with much finer
> granularity than Capp::Authorization, which I do not use at all.
>
>                               - Jerry Kaidor ( je...@tr2.com )
>
>

Jerry,

I didn't think about using the driver in this way - thank you for the idea.

Another thing I am looking at doing is setting up contexts. What this
does is that it allows the user to  assume a particular set of roles
given what they are doing if they are assigned mutually exclusive
roles globally. Basically, each context is a set of compatible roles
that are active at any given time. The user is permitted to switch
among contexts as they wish, activating and deactivating roles as
needed.  I know it's another level of complexity, but still part of
the RBAC thing - I'll look more at the drivers aspect. Thanks, again.

Brett

>
>
>
>>
>> Here's the skeleton I came up with -
>>
>>       https://gist.github.com/33d23edf8fa2c0f48dc0
>>
>> My question is really, what's the best way to go about separating
>> functionality in a CApp based application?
>>
>> A practical case I am looking at right now is that I have form that
>> is used to manage user data. There are 3 roles - User, Manager, and
>> Admin. Each one has the types of permissions you'd expect (User can
>> manage himself, Manager can manage his Users, Admin can do anything).
>>
>> I was thinking of the best way to build this form and control actions
>> cleanly and compose this form using 3 different runmodes that are
>> increasingly restrictive.
>>
>> For example, the User form calls the "user" runmode, and returns the
>> form content. The "manager" runmode takes the output of "user" and
>> adds some stuff to it. The "admin" runmode might take the result of
>> the "manager" runmode - which would also include what the "user"
>> runmode provides...and so on.
>>
>> Ultimately, my goal is to get away from nasty frog boiling "if" blocks
>> controlling authorization and rely on composable functions (i.e.,
>> runmodes or modules) that will cleanly give me what I would like using
>> the runmode level protection that CApp::Authorization provides you.
>>
>> I've searched around and banged my head against this pretty hard, so
>> any thoughts or resources would be appreciated. For all I know, this
>> might be a bad idea. But I am really just looking for the best way to
>> create an access controlled system as cleanly as possible.
>>
>> Thank you,
>> Brett
>>
>> ps: I noticed that even if POST_LOGIN_RUNMODE is protected via
>> CApp::Authentication, the check seems to be ignored immediately after
>> login. I am not sure if this is a known issue or that there are some
>> callbacks happening in the wrong order. This will happen in the gist I
>> linked above.
>>
>> #  CGI::Application community mailing list  
>> ##                                                            ##
>> ##  To unsubscribe, or change your message delivery options,  ##
>> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
>> ##                                                            ##
>> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
>> ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
>> ##                                                            ##
>> 
>>
>
>
>
> #  CGI::Application community mailing list  
> ##                                                            ##
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
> ##                                                            ##
> ##  Web archive:   http://www.erlba

Re: [cgiapp] app authorization patterns, best practices?

2012-03-29 Thread B. Estrade
On Thu, Mar 29, 2012 at 09:37:33AM +1100, Ron Savage wrote:
> Hi
> 
> There are 2 modules on CPAN which might help:
> 
> https://metacpan.org/module/Entities
> 
> https://metacpan.org/module/Abilities

Thank you, Ron.

I'll give them a looksee, then will let you know if I find them
helpful.

Brett

> 
> I did not try them yet myself.
> 
> On 29/03/12 00:40, B. Estrade wrote:
> > On Fri, Mar 23, 2012 at 8:05 PM, Jerry Kaidor  wrote:
> >>
> >>> I have some questions regarding best practices when implementing
> >>> role based access control (RBAC). I have been playing with
> >>> CApp::Authentication and Authorization, and they both do basically
> >>> what I need.
> >>
> >> *** Me too.  I have three sub-businesses.  Let's call them A, B, C.  I
> >> want to have access to all of it, but I want my managers to only have
> >> access to
> >> their particular piece.
> >>
> >> Here's more or less how I did it.  BTW, it recently broke for unknown
> >> reason, and I havent' gotten around to troubleshooting.
> >>
> >>CApp:Authentication has a notion of "drivers".  I wrote a multi-DB
> >> driver that can look in a set of authentication databases.  I have a
> >> "users"
> >> mysql database at my global level, and another "users" database in each
> >> subbusiness.  When somebody attempts to log in, the multi-auth driver
> >> tries each database in turn.  If it successfully authenticates against the
> >> "global" database, that user has privs for all the sub-businesses.
> >>
> >>Each line in the "users" database has a set of "permissions" flags,
> >> which correspond to things seeming to permission as I coded.  In line
> >> with the code are statements in the form if( getpriv( user, business
> >> )){}.  That way, I have a permissions system with much finer
> >> granularity than Capp::Authorization, which I do not use at all.
> >>
> >>- Jerry Kaidor ( je...@tr2.com )
> >>
> >>
> >
> > Jerry,
> >
> > I didn't think about using the driver in this way - thank you for the idea.
> >
> > Another thing I am looking at doing is setting up contexts. What this
> > does is that it allows the user to  assume a particular set of roles
> > given what they are doing if they are assigned mutually exclusive
> > roles globally. Basically, each context is a set of compatible roles
> > that are active at any given time. The user is permitted to switch
> > among contexts as they wish, activating and deactivating roles as
> > needed.  I know it's another level of complexity, but still part of
> > the RBAC thing - I'll look more at the drivers aspect. Thanks, again.
> >
> > Brett
> >
> >>
> >>
> >>
> >>>
> >>> Here's the skeleton I came up with -
> >>>
> >>>https://gist.github.com/33d23edf8fa2c0f48dc0
> >>>
> >>> My question is really, what's the best way to go about separating
> >>> functionality in a CApp based application?
> >>>
> >>> A practical case I am looking at right now is that I have form that
> >>> is used to manage user data. There are 3 roles - User, Manager, and
> >>> Admin. Each one has the types of permissions you'd expect (User can
> >>> manage himself, Manager can manage his Users, Admin can do anything).
> >>>
> >>> I was thinking of the best way to build this form and control actions
> >>> cleanly and compose this form using 3 different runmodes that are
> >>> increasingly restrictive.
> >>>
> >>> For example, the User form calls the "user" runmode, and returns the
> >>> form content. The "manager" runmode takes the output of "user" and
> >>> adds some stuff to it. The "admin" runmode might take the result of
> >>> the "manager" runmode - which would also include what the "user"
> >>> runmode provides...and so on.
> >>>
> >>> Ultimately, my goal is to get away from nasty frog boiling "if" blocks
> >>> controlling authorization and rely on composable functions (i.e.,
> >>> runmodes or modules) that will cleanly give me what I would like using
> >>> the runmode level protection that CApp::Authoriza

Re: [cgiapp] CAP::Session causing errors under FastCGI and Plack?

2012-04-04 Thread B. Estrade
On Wed, Apr 04, 2012 at 03:13:13PM +1000, Cees Hek wrote:
> On Wed, Apr 4, 2012 at 1:51 PM, Jason Crome  wrote:
> > I keep banging my head against the wall trying to figure this out. ?I 
> > expect that I am doing something else wrong, but whenever I comment out the 
> > session initialization logic, my app runs (as well as it can without 
> > sessions, that is).
> >
> > I am getting this error under FCGI and PSGI:
> > "[Dispatch] ERROR for request '/': Unknown error: Error executing class 
> > callback in init stage: Calling session_config after the session has 
> > already been created at 
> > /Users/crome/perl5/perlbrew/perls/perl-5.14.2/lib/site_perl/5.14.2/CGI/Application/Plugin/Session.pm
> >  line 79."
> 
> Hi Jason,
> 
> Does this happen every time?  Or does the first request succeed and
> then subsequent requests fail?  Does it have any problems when you run
> it as a plain old CGI?

It's interesting that you mention this. I was recently made aware of
an issue caused when using CGI.pm under speedy. Perl's lexical scoping
got entangled with speedy's persistence, and cause scoping to be as
intended on the first run, but subsequent runs would fail.

Brett

> 
> The big question for me is:  Are you getting a new CGI::Application
> object on every request, or is the object from the previous request
> being re-used?  If the object is being re-used, then it is not being
> cleared out properly and hence the CAP::Session module thinks the
> session has already been loaded when cgiapp_init calls session_config.
> 
> CAP::Session looks to see if $self->{__CAP__SESSION_OBJ} exists to
> determine if a session has already been loaded.  At the start of your
> cgiapp_init method, look to see if it exists already which should
> point you in the right direction to figuring out what is going on.
> 
> Cheers,
> 
> Cees
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Announce: CGI::Snapp::Dispatch V 1.00 etc, with PSGI support

2012-04-12 Thread B. Estrade
On Thu, Apr 12, 2012 at 01:29:37PM +1000, Ron Savage wrote:
> Hi Folks
> 
> I've uploaded to CPAN:
> 
> o CGI::Snapp::Dispatch V 1.00.
> 
> This distro includes CGI::Snapp::Dispatch::Regexp.
> 
> Both modules support usage in a PSGI environment.
> 
> This module is a partner for CGI::Snapp, and together they are almost 
> drop-in replacements for CGI::Application, CGI::Application::Dispatch, 
> CGI::Application::Dispatch::Regexp and CGI::Application::Dispatch::PSGI.
> 
> The default for logging is to not create a logger, as per CGI::Snapp V 
> 1.01 below.
> 
> There are 63 tests.
> 
> PSGI is supported without needing a module called 
> CGI::Snapp::Dispatch::PSGI.
> 
> o CGI::Snapp V 1.01.
> 
> This has a new mutator _psgi() for use by CGI::Snapp::Dispatch.
> 
> Also, the default for logging is now to not create a logger.
> 
> PSGI is supported without needing a module called CGI::Snapp::PSGI.
> 
> o CGI::Snapp::Plugin::Forward V 1.01.
> 
> The tests explicitly create a logger since CGI::Snapp V 1.01 now does not.
> 
> o CGI::Snapp::Plugin::Redirect V 1.01.
> 
> The tests explicitly create a logger since CGI::Snapp V 1.01 now does not.

Ron,

Congratulations and nice work. I am sorry to be dense, but as long as
I've been following Snapp and as many of the docs that I seem to have
read, I am still trying to figure out exactly what Snapp gives us over
CAP.

I ask because I am at the start of a major project that is making
critical use of CAP and CAP::Dispatch.  If I am going to switch, now's
the time, but I need to justify it to myself.

Thank you,
Brett

> 
> 
> -- 
> Ron Savage
> http://savage.net.au/
> Ph: 0421 920 622
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Announce: CGI::Snapp::Dispatch V 1.00 etc, with PSGI support

2012-04-13 Thread B. Estrade
On Fri, Apr 13, 2012 at 06:48:34AM -0400, Nic Zero  wrote:
> I too have recently rewritten CGI::App and most of its core plugins.
> That was not my original plan.?? You may remember recently I was
> recommending people make use of class-level initialisation and
> only do object-level initialisation (ie per cgiapp instance) for those
> things that can't be shared.?? However, when I looked into it more
> deeply (as part of a separate task) I found that support for this
> within plugins is quite sketchy and unreliable.?? CGI::App itself
> doesn't really support the idea in any clear way.?? I also thought
> that rearranging the code inside CGI::App would help me and
> others understand the flow better.?? So I started to refactor.?? But
> then I encountered code that is convoluted, for example a six-
> line subroutine that was much clearer in one line.?? So I started
> to rewrite.?? And then I decided the whole thing would be easier to
> code against as well as easier to read if I made my Stash plugin
> be used within CGI::App itself (much like Catalyst & Mojolicious).
> So then I realised I was departing from being CGI::App
> compatible.
> 
> That's where that story ends.?? As soon as you've broken
> compatibility you've distanced yourself from the CGI::App
> community and your one-man project is dead.?? My time wasn't
> wasted cos I then refactored again so that the good bits are
> separate extensions that can be used with CGI::App or
> Mojolicious.?? [They're close to being published; tests need to
> be improved and documentation needs to catch up.]

..ah, yes..the community - that's the compelling part about CAP for
me. I like this list a lot, for example.

> 
> I thought that my micro-framework would still fill a niche: those
> cases where you want the functionality of Catalyst but with a
> 1 MB du footprint.?? Unfortunately those smart people over at
> Mojolicious had a fabulous 2011 and can do much more than
> my framework and still sit inside 1 MB.
> 
> So if you're still reading, my strong recommendations are:
> * Respect CGI::App for what it is.?? If you need more, go see
> Mojolicious::Lite and Mojolicious itself.
> * Ignore people like Ron & me who are tempted to do rewrites
> that will never have the community that CGI::App grew.?? Two
> years from now both of our frameworks will still contain more
> bugs and fewer working examples than CGI::App.

I am less inclined to use something other than CAP proper, but
Mojolicious looks interesting. Something about how much it hides is a
little unerving to me, though.

I have routes set up fine using CAP::Dispatch (which also supports the
HTTP methods for the clean URIs. Beyond setting up the routes, I am
not sure what Mojo gives me since I still have to implement my backend
to push and pull data. It is a lot cleaner looking, but one thing that
stands out to me are those templates in Mojo - out of the box, they
seem way to powerful (I am a fan of super dumb templates).

> * Ron, if you do continue with Snapp, try borrowing some of
> the smart ideas from Mojolicious::Lite, but
> * like me, I suspect you'll fall in love with Mojolicious and
> Snapp will just be an amusing memory.

Thanks, everyone. And thanks, Ron, for your efforts - I don't think
any effort to improve things or to learn is time wasted. Most OSS
projects out there are "one man" or "one off".  I have a few myself =).

Brett

> 
> Happy coding,
> Nic
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Debugging while using CAP::Dispatch...

2012-04-19 Thread B. Estrade
I am having some time trying to figure out errors with this kind of
output:

Can't locate object method "error" via package "Can't locate
object method "error has occured" via package...

What is the best way to get useful information to the browswer when
something goes awry?

Brett

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Debugging while using CAP::Dispatch...

2012-04-20 Thread B. Estrade
On Fri, Apr 20, 2012 at 08:57:53AM +1000, Ron Savage wrote:
> Hi Brett
> 
> On 20/04/12 08:47, B. Estrade wrote:
> > I am having some time trying to figure out errors with this kind of
> > output:
> >
> > Can't locate object method "error" via package "Can't locate
> > object method "error has occured" via package...
> >
> > What is the best way to get useful information to the browswer when
> > something goes awry?
> 
> Those msgs mean there is a mis-match between the calling code and the 
> parameter list of the method you're calling (or think you're calling).

Hmm...it seems that it's a side effect of CAP::Dispatch - is there a
way to get the precise error?

Brett

> 
> -- 
> Ron Savage
> http://savage.net.au/
> Ph: 0421 920 622
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] app authorization patterns, best practices?

2012-04-24 Thread B. Estrade
I am finally at the point where I am writing a driver, so I have a
stupid question.

Do I need to place this into the main module's parent directory in
order to have Authen/z use them?

Thanks,
Brett

On Wed, Mar 28, 2012 at 09:26:14AM -0700, Jerry Kaidor wrote:
> Hello,
> 
>I just emailed you the source of the MULTI_DBI driver.  I do not
> pretend that this is the best way to do it, or even that it is very
> good;  I am far from expert at object oriented Perl, and sweated blood
> to get it to work at all.  And a month or two ago it stopped working
> suddenly, and I haven't had time to troubleshoot it.
> 
>It authenticates against multiple "user" databases, all with the same
> format.  One is designated as "global", and the others are sub-business
> specific.   The driver authenticates by username and password, and
> records which database it authenticated against in the session->param
> structure.
> 
>   - Jerry Kaidor
> 
> 
> 
> 
> 
> 
> 
> > On Fri, Mar 23, 2012 at 8:05 PM, Jerry Kaidor  wrote:
> >>
> >>> I have some questions regarding best practices when implementing
> >>> role based access control (RBAC). I have been playing with
> >>> CApp::Authentication and Authorization, and they both do basically
> >>> what I need.
> >>
> >> *** Me too.  I have three sub-businesses.  Let's call them A, B, C.  I
> >> want to have access to all of it, but I want my managers to only have
> >> access to
> >> their particular piece.
> >>
> >>    Here's more or less how I did it.  BTW, it recently broke for unknown
> >> reason, and I havent' gotten around to troubleshooting.
> >>
> >>   CApp:Authentication has a notion of "drivers".  I wrote a multi-DB
> >> driver that can look in a set of authentication databases.  I have a
> >> "users"
> >> mysql database at my global level, and another "users" database in each
> >> subbusiness.  When somebody attempts to log in, the multi-auth driver
> >> tries each database in turn.  If it successfully authenticates against
> >> the
> >> "global" database, that user has privs for all the sub-businesses.
> >>
> >>   Each line in the "users" database has a set of "permissions" flags,
> >> which correspond to things seeming to permission as I coded.  In line
> >> with the code are statements in the form if( getpriv( user, business
> >> )){}.  That way, I have a permissions system with much finer
> >> granularity than Capp::Authorization, which I do not use at all.
> >>
> >>                               - Jerry Kaidor ( je...@tr2.com )
> >>
> >>
> >
> > Jerry,
> >
> > I didn't think about using the driver in this way - thank you for the
> > idea.
> >
> > Another thing I am looking at doing is setting up contexts. What this
> > does is that it allows the user to  assume a particular set of roles
> > given what they are doing if they are assigned mutually exclusive
> > roles globally. Basically, each context is a set of compatible roles
> > that are active at any given time. The user is permitted to switch
> > among contexts as they wish, activating and deactivating roles as
> > needed.  I know it's another level of complexity, but still part of
> > the RBAC thing - I'll look more at the drivers aspect. Thanks, again.
> >
> > Brett
> >
> >>
> >>
> >>
> >>>
> >>> Here's the skeleton I came up with -
> >>>
> >>>       https://gist.github.com/33d23edf8fa2c0f48dc0
> >>>
> >>> My question is really, what's the best way to go about separating
> >>> functionality in a CApp based application?
> >>>
> >>> A practical case I am looking at right now is that I have form that
> >>> is used to manage user data. There are 3 roles - User, Manager, and
> >>> Admin. Each one has the types of permissions you'd expect (User can
> >>> manage himself, Manager can manage his Users, Admin can do anything).
> >>>
> >>> I was thinking of the best way to build this form and control actions
> >>> cleanly and compose this form using 3 different runmodes that are
> >>> increasingly restrictive.
> >>>
> >>> For example, the User form calls the "user" runmode, and returns the
> >>> form content. The "manager" runmode takes the output of "user" and
> >>> adds some stuff to it. The "admin" runmode might take the result of
> >>> the "manager" runmode - which would also include what the "user"
> >>> runmode provides...and so on.
> >>>
> >>> Ultimately, my goal is to get away from nasty frog boiling "if" blocks
> >>> controlling authorization and rely on composable functions (i.e.,
> >>> runmodes or modules) that will cleanly give me what I would like using
> >>> the runmode level protection that CApp::Authorization provides you.
> >>>
> >>> I've searched around and banged my head against this pretty hard, so
> >>> any thoughts or resources would be appreciated. For all I know, this
> >>> might be a bad idea. But I am really just looking for the best way to
> >>> create an access controlled system as cleanly as possible.
> >>>
> >>> Thank you,
> >>> Brett
> >>>
> >>> ps: I noticed that even if POST

Re: [cgiapp] app authorization patterns, best practices?

2012-04-25 Thread B. Estrade
On Wed, Apr 25, 2012 at 03:51:08AM -0400, Nic Zero  wrote:
> No, the main modules don't rely on the drivers being in a close relative 
> path, they just need to be on perl's @INC path.  Take a look at the code of 
> the main modules; it's fairly easy to read and you'll see that it tries 
> multiple path patterns to find your drivers.  Best give your drivers the same 
> name prefix as existing drivers though.

Thanks, yeah. I was looking at the source when it was suggested to me
that I just emulate the namespace path in one of my @INC paths. 

IOW,

I have in - 
/path/to/my/lib/CGI/Application/Plugin/Authentication/Driver/MyDriver.pm

Now I can configure it to use: DRIVER => ['MyDriver', {arg1=>foo,...}], 

Thank you,
Brett

> Nic
> 
> 
> 
> 
> From: B. Estrade 
> To: CGI Application 
> Sent: Tuesday, April 24, 2012 at 7:04 pm
> Subject: Re: [cgiapp] app authorization patterns, best practices?
> 
> I am finally at the point where I am writing a driver, so I have a
> 
> stupid question.
> 
> 
> 
> Do I need to place this into the main module's parent directory in
> 
> order to have Authen/z use them?
> 
> 
> 
> Thanks,
> 
> Brett
> 
> 
> 
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] CAP Dispatch and encoded backslashes

2012-06-06 Thread B. Estrade
I am having an issue with CAP Dispatch that seems to be rearing its
ugly head when I send, as part of the route, serialized JSON data.
The issue is that I have a value with a backslash in it.

I am pretty sure the URL parsing done by Dispatch is splitting on this
backslash, but I though that it wouldn't be a problem since it's being
sent as an encoded string.

When I don't include this one field, it works; when I do, I get a 404
thrown by Dispatch.

Any ways around this?

Thanks,
Brett

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] CAP Dispatch and encoded backslashes

2012-06-06 Thread B. Estrade
On Thu, Jun 07, 2012 at 01:17:12PM +1000, Ron Savage wrote:
> Hi Brett
> 
> On 07/06/12 05:37, B. Estrade wrote:
> > I am having an issue with CAP Dispatch that seems to be rearing its
> > ugly head when I send, as part of the route, serialized JSON data.
> > The issue is that I have a value with a backslash in it.
> >
> > I am pretty sure the URL parsing done by Dispatch is splitting on this
> > backslash, but I though that it wouldn't be a problem since it's being
> > sent as an encoded string.
> >
> > When I don't include this one field, it works; when I do, I get a 404
> > thrown by Dispatch.
> 
> The documentation says:
> To get the name of the application module the path is split on 
> backslahes (C).
> 
> Clearly (?) it means slash (/), not backslash (\).

You are right, it's not the backslash, it's the forward slash. I saw
that part in the docs, but I was not sure how to include that in the
serialized string; I assumed if it was uri encoded it'd be fine.

Thanks for pointing out the error in my email

Brett

> 
> Which do you mean?
> 
> -- 
> Ron Savage
> http://savage.net.au/
> Ph: 0421 920 622
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] CAP Dispatch and encoded backslashes

2012-06-07 Thread B. Estrade
On Thu, Jun 07, 2012 at 03:45:15PM +1000, Ron Savage wrote:
> Hi Brett
> 
> On 07/06/12 13:42, B. Estrade wrote:
> > On Thu, Jun 07, 2012 at 01:17:12PM +1000, Ron Savage wrote:
> >> Hi Brett
> >>
> >> On 07/06/12 05:37, B. Estrade wrote:
> >>> I am having an issue with CAP Dispatch that seems to be rearing its
> >>> ugly head when I send, as part of the route, serialized JSON data.
> >>> The issue is that I have a value with a backslash in it.
> >>>
> >>> I am pretty sure the URL parsing done by Dispatch is splitting on this
> >>> backslash, but I though that it wouldn't be a problem since it's being
> >>> sent as an encoded string.
> >>>
> >>> When I don't include this one field, it works; when I do, I get a 404
> >>> thrown by Dispatch.
> >>
> >> The documentation says:
> >> To get the name of the application module the path is split on
> >> backslahes (C).
> >>
> >> Clearly (?) it means slash (/), not backslash (\).
> >
> > You are right, it's not the backslash, it's the forward slash. I saw
> > that part in the docs, but I was not sure how to include that in the
> > serialized string; I assumed if it was uri encoded it'd be fine.
> 
> So the next question is: Does the problematic / get converted to %2f? If 
> so, I'd expect CAD to ignore it. If not, why not?
> 
> I'm thinking that if not, you'll have to use JS attached to the submit 
> button to capture the value and encode it yourself.

It is encoded, and I am using YUI 3's Y.IO to submit a POST request. 

The whole, serialized JSON encoded is:

%7B%22id%22%3A%228734%22%2C%22name%22%3A%22heello%20the%20dog%22%2C%22email%22%3A%22estrabd%40gmail.com%22%2C%22phone%22%3A%22123456%20%22%2C%22phoneext%22%3A%2278%22%2C%22status%22%3A%22inactive%22%2C%22locale%22%3A%22local%22%2C%22isexempt%22%3Anull%2C%22timezone%22%3A%22American%2FChicago%22%2C%22isdevadmin%22%3Anull%2C%22last_modified%22%3A%222012-06-07%2009%3A36%3A05%22%2C%22adminlvl%22%3A%22-1%22%2C%22vendcode%22%3Anull%2C%22username%22%3A%22iamthefrog%40gmail.com%22%2C%22endday%22%3Anull%2C%22administaffid%22%3A%22-1%22%2C%22startday%22%3Anull%7D

You'll note the offending character at "American%2FChicago".

Thanks,
Brett

> 
> -- 
> Ron Savage
> http://savage.net.au/
> Ph: 0421 920 622
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] CAP Dispatch and encoded backslashes

2012-06-07 Thread B. Estrade
This issue may be rendered moot. I have discovered that I am
unitentionally relying on GET-like behavior to pass data during a
PATCH method request.

I suppose this leads me to ask, is the data in a PATCH request
handled the same way it is in a POST?

Thank you,
Brett

On Thu, Jun 07, 2012 at 09:41:30AM -0500, B. Estrade wrote:
> On Thu, Jun 07, 2012 at 03:45:15PM +1000, Ron Savage wrote:
> > Hi Brett
> > 
> > On 07/06/12 13:42, B. Estrade wrote:
> > > On Thu, Jun 07, 2012 at 01:17:12PM +1000, Ron Savage wrote:
> > >> Hi Brett
> > >>
> > >> On 07/06/12 05:37, B. Estrade wrote:
> > >>> I am having an issue with CAP Dispatch that seems to be rearing its
> > >>> ugly head when I send, as part of the route, serialized JSON data.
> > >>> The issue is that I have a value with a backslash in it.
> > >>>
> > >>> I am pretty sure the URL parsing done by Dispatch is splitting on this
> > >>> backslash, but I though that it wouldn't be a problem since it's being
> > >>> sent as an encoded string.
> > >>>
> > >>> When I don't include this one field, it works; when I do, I get a 404
> > >>> thrown by Dispatch.
> > >>
> > >> The documentation says:
> > >> To get the name of the application module the path is split on
> > >> backslahes (C).
> > >>
> > >> Clearly (?) it means slash (/), not backslash (\).
> > >
> > > You are right, it's not the backslash, it's the forward slash. I saw
> > > that part in the docs, but I was not sure how to include that in the
> > > serialized string; I assumed if it was uri encoded it'd be fine.
> > 
> > So the next question is: Does the problematic / get converted to %2f? If 
> > so, I'd expect CAD to ignore it. If not, why not?
> > 
> > I'm thinking that if not, you'll have to use JS attached to the submit 
> > button to capture the value and encode it yourself.
> 
> It is encoded, and I am using YUI 3's Y.IO to submit a POST request. 
> 
> The whole, serialized JSON encoded is:
> 
> %7B%22id%22%3A%228734%22%2C%22name%22%3A%22heello%20the%20dog%22%2C%22email%22%3A%22estrabd%40gmail.com%22%2C%22phone%22%3A%22123456%20%22%2C%22phoneext%22%3A%2278%22%2C%22status%22%3A%22inactive%22%2C%22locale%22%3A%22local%22%2C%22isexempt%22%3Anull%2C%22timezone%22%3A%22American%2FChicago%22%2C%22isdevadmin%22%3Anull%2C%22last_modified%22%3A%222012-06-07%2009%3A36%3A05%22%2C%22adminlvl%22%3A%22-1%22%2C%22vendcode%22%3Anull%2C%22username%22%3A%22iamthefrog%40gmail.com%22%2C%22endday%22%3Anull%2C%22administaffid%22%3A%22-1%22%2C%22startday%22%3Anull%7D
> 
> You'll note the offending character at "American%2FChicago".
> 
> Thanks,
> Brett
> 
> > 
> > -- 
> > Ron Savage
> > http://savage.net.au/
> > Ph: 0421 920 622
> > 
> > #  CGI::Application community mailing list  
> > ####
> > ##  To unsubscribe, or change your message delivery options,  ##
> > ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> > ####
> > ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> > ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> > ####
> > 
> > 
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




[cgiapp] Authz with Authen, something is backwards here...

2012-06-13 Thread B. Estrade
I am finding that if I have a runmode that is protected via
authentication and authorization, the authen doesn't happen before the
authz is validated.

In otherwords, I want a authen to happen first; if it fails, redirect
to the login. If authen is okay, proceseed to authz.

Right now I have this unsettling bit of code in my authz driver's
authorize_user method:

sub authorize_user {
my $self = shift;my ($username, $required_permission) = @_;
return 1 if (!$username or $required_permission);



I figure that if there is no $username, then authen has failed. But,
because of the ordering of calls, it appears that if this is the case,
I have to succeed authorize_user and rely on authen to redirect the
login - this seems backwards. Authen should fail before anything is
checked with authz. What am I doing wrong?

Thank you,
Brett 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Authz with Authen, something is backwards here...

2012-06-13 Thread B. Estrade
On Wed, Jun 13, 2012 at 02:58:28PM -0500, B. Estrade wrote:
> I am finding that if I have a runmode that is protected via
> authentication and authorization, the authen doesn't happen before the
> authz is validated.
> 
> In otherwords, I want a authen to happen first; if it fails, redirect
> to the login. If authen is okay, proceseed to authz.
> 
> Right now I have this unsettling bit of code in my authz driver's
> authorize_user method:
> 
> sub authorize_user {
> my $self = shift;my ($username, $required_permission) = @_;
> return 1 if (!$username or $required_permission);
> 

I mean:

sub authorize_user {
my $self = shift;
my ($username, $required_permission) = @_;
return 1 if (!$username);



> 
> 
> I figure that if there is no $username, then authen has failed. But,
> because of the ordering of calls, it appears that if this is the case,
> I have to succeed authorize_user and rely on authen to redirect the
> login - this seems backwards. Authen should fail before anything is
> checked with authz. What am I doing wrong?
> 
> Thank you,
> Brett 
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Authz with Authen, something is backwards here...

2012-06-14 Thread B. Estrade
On Thu, Jun 14, 2012 at 10:12:40AM +1000, Cees Hek wrote:
> Hi Brett,
> 
> Authorization is not purely related to authentication.  For example
> you could authorize access based on an IP Address, or based on the
> time of the day.  So we can't automatically decline a request just
> because they are not logged in.

You're right. I know there is integration on the level that the
default call for a $username to the
Authorization::Driver::X::authorize_user will look for an
authenticated username.

> 
> But as you say, your authentication checks should have caught this
> before it got this far.  Perhaps there is a problem with the order in
> which you configured things which will influence the order in which
> the authen and authz callbacks get triggered.

I guess this is where I need to look.  Thank you,

Brett

> 
> Cheers,
> 
> Cees
> 
> On Thu, Jun 14, 2012 at 6:03 AM, B. Estrade  wrote:
> > On Wed, Jun 13, 2012 at 02:58:28PM -0500, B. Estrade wrote:
> >> I am finding that if I have a runmode that is protected via
> >> authentication and authorization, the authen doesn't happen before the
> >> authz is validated.
> >>
> >> In otherwords, I want a authen to happen first; if it fails, redirect
> >> to the login. If authen is okay, proceseed to authz.
> >>
> >> Right now I have this unsettling bit of code in my authz driver's
> >> authorize_user method:
> >>
> >> sub authorize_user {
> >>     my $self = shift;    my ($username, $required_permission) = @_;
> >>     return 1 if (!$username or $required_permission);
> >>
> >
> > I mean:
> >
> > sub authorize_user {
> >    my $self = shift;
> >    my ($username, $required_permission) = @_;
> >    return 1 if (!$username);
> >
> > 
> >
> >> 
> >>
> >> I figure that if there is no $username, then authen has failed. But,
> >> because of the ordering of calls, it appears that if this is the case,
> >> I have to succeed authorize_user and rely on authen to redirect the
> >> login - this seems backwards. Authen should fail before anything is
> >> checked with authz. What am I doing wrong?
> >>
> >> Thank you,
> >> Brett
> >>
> >> #  CGI::Application community mailing list  
> >> ##                                                            ##
> >> ##  To unsubscribe, or change your message delivery options,  ##
> >> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
> >> ##                                                            ##
> >> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> >> ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
> >> ##                                                            ##
> >> 
> >>
> >
> > #  CGI::Application community mailing list  
> > ##                                                            ##
> > ##  To unsubscribe, or change your message delivery options,  ##
> > ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
> > ##                                                            ##
> > ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> > ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
> > ##                                                            ##
> > 
> >
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 
> 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] Authz with Authen, something is backwards here...

2012-06-14 Thread B. Estrade
I've been trying to figure out how to affect the order in which these
prerun hooks are processed, and it's escaping me. For now, I just have
to settle to let the runmodes that have no real authz restrictions to
not even be protected (e.g., landing pages) and to just be okay with
those authz pages that are protected with authz to throw my 401
warning.  I am not really sure what other sort of strategy is good. I
don't want a logged in user to get redirect to the login just because
of an auth violation. I suppose I could redirect them to one of the
non-authz'd runmodes. Thoughts?

On Thu, Jun 14, 2012 at 09:44:32AM -0500, B. Estrade wrote:
> On Thu, Jun 14, 2012 at 10:12:40AM +1000, Cees Hek wrote:
> > Hi Brett,
> > 
> > Authorization is not purely related to authentication.  For example
> > you could authorize access based on an IP Address, or based on the
> > time of the day.  So we can't automatically decline a request just
> > because they are not logged in.
> 
> You're right. I know there is integration on the level that the
> default call for a $username to the
> Authorization::Driver::X::authorize_user will look for an
> authenticated username.
> 
> > 
> > But as you say, your authentication checks should have caught this
> > before it got this far.  Perhaps there is a problem with the order in
> > which you configured things which will influence the order in which
> > the authen and authz callbacks get triggered.
> 
> I guess this is where I need to look.  Thank you,
> 
> Brett
> 
> > 
> > Cheers,
> > 
> > Cees
> > 
> > On Thu, Jun 14, 2012 at 6:03 AM, B. Estrade  wrote:
> > > On Wed, Jun 13, 2012 at 02:58:28PM -0500, B. Estrade wrote:
> > >> I am finding that if I have a runmode that is protected via
> > >> authentication and authorization, the authen doesn't happen before the
> > >> authz is validated.
> > >>
> > >> In otherwords, I want a authen to happen first; if it fails, redirect
> > >> to the login. If authen is okay, proceseed to authz.
> > >>
> > >> Right now I have this unsettling bit of code in my authz driver's
> > >> authorize_user method:
> > >>
> > >> sub authorize_user {
> > >>     my $self = shift;    my ($username, $required_permission) = @_;
> > >>     return 1 if (!$username or $required_permission);
> > >>
> > >
> > > I mean:
> > >
> > > sub authorize_user {
> > >    my $self = shift;
> > >    my ($username, $required_permission) = @_;
> > >    return 1 if (!$username);
> > >
> > > 
> > >
> > >> 
> > >>
> > >> I figure that if there is no $username, then authen has failed. But,
> > >> because of the ordering of calls, it appears that if this is the case,
> > >> I have to succeed authorize_user and rely on authen to redirect the
> > >> login - this seems backwards. Authen should fail before anything is
> > >> checked with authz. What am I doing wrong?
> > >>
> > >> Thank you,
> > >> Brett
> > >>
> > >> #  CGI::Application community mailing list  
> > >> ##                                                            ##
> > >> ##  To unsubscribe, or change your message delivery options,  ##
> > >> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
> > >> ##                                                            ##
> > >> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> > >> ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
> > >> ##                                                            ##
> > >> 
> > >>
> > >
> > > #  CGI::Application community mailing list  
> > > ##                                                            ##
> > > ##  To unsubscribe, or change your message delivery options,  ##
> > > ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp    ##
> > > ##                                                            ##
> > > ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> > > ##  Wiki:          http://cgiapp.erlbaum.net/                 ##
> > > ##                                                            ##
> > > 
> > >
> > 
&g

[cgiapp] uploads

2012-08-10 Thread B. Estrade
What is the idiomatic way for dealing with uploads via CAP?

I am using CGI::Simple.

Thank you,
Brett

-- 
Register Now for cPanel Conference
Oct 8-10, 2012, Houston, Texas
http://conference.cpanel.net/

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] CGI::Application status update from the maintainer

2012-09-05 Thread B. Estrade
Thank you, Mark. Responses are inlined.
 
On Tue, Aug 28, 2012 at 11:27:04PM -0400, Mark Stosberg wrote:
> 
> Hello Everyone.
> 
> I'll start with a apology about not being as present as I intended.
> Messages from this list were not coming directly to my Inbox for some
> time, and it took me longer than I wanted to get that addressed.
> Starting today, messages should be going back in my Inbox again, and I
> will attempt be more responsive here.
> 
> I'm still alive and well, and use and support CGI::Application every day
> at work. I'm also now the primary maintainer of CGI.pm. While it's only
> a part of the CGI::Application framework, it has substantially more
> lines of code, as well as more bugs and bug traffic. More of my
> maintenance time has been spent maintaining that lately.
> 
> I appreciate the fork that Ron Savage recently published, because it's
> good to explore options, and it's easiest to evaluate options if they
> are complete. I also agree with the spirit of it. It's time for the next
> generation of the framework, one that breaks compatibility in some
> places to move the whole forward.
> 
> I started writing my own fork over a year ago in hopes of having
> something to share around the time for YAPC 2011. While I needed to put
> that on hold for a while, It's now on the verge of the initial release.
> It was interesting to find Ron's fork which had been developed
> independently and in parallel, to see where we agreed and where we
> differed.

It strikes me that CAP is more of a "way" or standard than any
particular implementation, even though I think it could certainly be
standardized or have that one true reference implementation.

> 
> Here are the key points I have mind for the update I'll be publishing
> soon:
> 
> - A new name space, to avoid confusion and problems with API changes.
> 
> - A "::Compat" addition that allows people to keep using a maximal
>amount of the old API if they need to. (Including a certain amount of
>plugins)

Or maybe just do something like how perl5 turns on new version based
features (e.g., use CGI::Application q/1.2.3/;).

> 
> - PSGI-native. I'm excited that Perl web frameworks are converging here.
>We'll be able to take advantage of PSGI "Middleware" that was designed
>with other frameworks in mind. Many things that were CGI::App plugins
>before are now better done done as PSGI "Middleware". As a plugin
>author, you get the benefit of having more users who may be using
>other frameworks. The difference with CGI::App will be that PSGI will
>the *only* code path supported.

Nice.

I would like to warn that traditional persistent environments will
continue to remain relevant, and I think it's a mistake to discount
this.

Additionally, from what I have seen from the other frameworks, nothing
solves anything in principle beyond what CAP does. Some make it easier
to define runmodes or to set up dispatching, but you still need to
properly create a proper MVC separation and set of supporting modules.
It's the same amount of work no matter what you use.

> 
> - Uses Any::Moose / Mouse. I endorse the Moose API and Mouse brings
>much of that API to lower resource environments, like the CGI
>environment where CGI::Application has always performed well.
> 
>It's already possible to write a CGI::App subclass based on Moose or
>Mouse, but like with PSGI, I think it's in our best interest to
>upgrade to first class support.

I am not sure what this buys anyone, to be frank. I know that using
these object layering might incite some sort of religious war.
Ultimately, this decision is clearly in the hands of those who do the
work.  I have my reservations about moving away from Perlish idioms
and towards the oop flavors of the week. Any core might be well served
by avoiding any sort of meta object sugar over the long haul. 

I think my overall point is that CAP and what it provides is timeless.
The pendulum swings both ways, and it would be nice to see CAP focus
on improving its strengths and not trying to do what the other kids
might be doing.

> 
>Just as "PSGI Middleware" presents a new opportunity for code re-use,
>Moose/Mouse "roles" present another alternative to "plugins" that can
>be shared between frameworks. For example, methods for logging,
>database access and "config" data are all good candidates to be
>implemented as roles.
> 
> - Templating APIs removed from core, for now. We'll get a new templating
>API, although the details are still TBD.
> 
> - Plans to replace CGI.pm with request and response objects. As the
>CGI.pm maintainer, I could devote another full post to reasons why I
>don't to be using it in another 5 or 10 years. Details here are still
>to be determined as well.
> 
>Immediately we would see the "query()" method replaced with a "req"
>method to represent a "request" object. HTTP has "requests" and
>"responses". The idea of a "query object" i

Re: [cgiapp] CGI::Application status update from the maintainer

2012-09-06 Thread B. Estrade
Snipped

On Thu, Sep 06, 2012 at 09:12:40AM +1000, Ron Savage wrote:
> Hi Brett
> > It would be really nice to merge in some bare bones Authentication and
> > Authorization support - maybe ever by more fully developing CAP's lifecycle.
> 
> Likewise. It's a pity a standard(!) way of doing this with CAP doesn't 
> seem to have evolved /with the approval of all/.
> 
> > Here are some items I would like to see addressed.
> >
> > 1. scalability - it is unnecessarily awkward to have more than 2
> > levels of subclassing currently.
> 
> This statement worries me. Could you please expand.
> 
> Also, did you look at CGI::Snapp::Demo::Four::Wrapper, which easily 
> wraps CGI::Snapp::Demo::Four. It's specifically a (simple) demo of 
> sub-classing.
> 
> > Direct subclass of CAP uses cgi_init; child of subclass uses setup;
> > anything else must call SUPER::setup.
> 
> How does this differ from any other class which uses sub-classing? The 
> parent method is either completely overridden or called /and/ partially 
> overridden. Or am I missing something?

What I mean is that there are 2 methods that basically do the same
thing.  If you have MyApp (ISA CGI::Application), you would initialize
runmodes and whatnot via cgiapp_init.  Say you subclass MyApp to get
MyApp::Foo, but want to keep what is going on in MyApp::cgiapp_init;
but you have your own specific MyApp::Foo runmodes. You'd most cleanly
do this by defining MyApp::Foo::setup. Now, what if you want to
subclass MyApp::Foo into MyApp::Foo::Derp, but you have some Derp
specific runmodes.  You end up having to redefine cgiapp_init or
setup; in either case, you're going to have to make an explicit call
to SUPER::cgiapp_init or SUPER::setup. 

You're limited to 2 generations below CAP if you want to subclass
without explicitly calling on SUPER because you have 2 explicit
methods -cgiapp_init and setup.  I am suggesting a way to provide any
number of generations without having to call on SUPER.

Here is my real world use case.  I split my applications into 2 parts;
one amounts to the UI payload delivery, basically HTML that makes all
calls asynchronously. The other is strictly non-UI and handles only
asynchronous requests (i.e., the "REST" API). And I typically have
this hierarchy:

1. WebCommon.pm (ISA CGI::Application; implements Authentication and common run 
modes)
2. WebApp.pm (ISA WebCommon; base class for the UI delivery or initial "view")
3. WebAPI.pm (ISA WebCommon; base class for the "REST" API)

>From there, I may have another or even another 2 levels of WebApps or
WebAPIs. In WebCommon.pm, I define cgiapp_init; in WebApps.pm and
WebAPI.pm, I define a setup. Beyond that, I redefine setup with a call
to $self->SUPER::setup - not something I really like doing.

> 
> > 3. a more fully developed plugin/event system; I think this goes along
> > with #2 (i.e., a few more hooks), but in addition to this I have
> > always thought it would be useful to have some sort of mechanism
> > through which plugins might be able to query one another.  A good
> > example (and actually the main motivation for #2 and #3) are the CAP
> > Authorization and Authentication plugins.  The short list of troubles
> > I have had with using these two are:
> >
> >   * when used together, Authorization is called before Authentication,
> >   making it awkward to handle authorization errors of unauthenticated
> >   guests (or maybe Authz assumes an authenticated session);
> >
> >   * default behavior of Authz is to query directly the Authorization
> >   plugin instance for a username; this works fine in that situation,
> >   but there is no clear way for plugin A to make information available
> >   to plugin B;
> 
> There's no doubt they are awkward. I'd argue the underlying CAP 
> structure is sound, and just this part need a bug re-think.
> 
> > 4. more flexibility with the query object...err response object; I've
> > run into some hoops to jump through when I wanted to use CGI::Simple
> > and be able to upload capabilities on or off in a sub class.
> 
> It'd help if you could expand on this issue.

I want to use CGI::Simple, but do not want to enable uploads app-wide.
I have a subclass (WebAPI::UploadApp, say) where I do want to enable
uploads.

In WebCommon.pm, I have to do this:

our $cgi; #= CGI::Simple->new;
sub cgiapp_get_query {
use CGI::Simple ();
$cgi = CGI::Simple->new();
return $cgi;
}

Then in order to override that CGI::Simple to enable uploads, in
WebAPI::UploadApp, I have to do this:

sub cgiapp_get_query {  
  
my $self = shift;   
  
use CGI::Simple (); 
  
$CGI::Simple::DISABLE_UPLOADS = 0;  
  
$sel

Re: [cgiapp] CGI::Application status update from the maintainer

2012-09-07 Thread B. Estrade
Thank you, Rhesa. This is helpful.

My last common on cgiapp_init and setup will be this. It's not simply
how deeply inheritance can be, it's the fact that there are 2 explicit
API methods for initializing an instance beyond what is provided for
in the ancestor.  For me, it'd make more sense to do a way with setup
altogether and use a method similar to the init hook you mentioned
below.  I am sure MMWV, but I will take your advice below. Thanks for
the help.

Brett

On Thu, Sep 6, 2012 at 12:04 PM, Rhesa Rozendaal  wrote:
> On 09/06/2012 04:48 PM, B. Estrade wrote:
>
>> You're limited to 2 generations below CAP if you want to subclass
>> without explicitly calling on SUPER because you have 2 explicit
>> methods -cgiapp_init and setup.  I am suggesting a way to provide any
>> number of generations without having to call on SUPER.
>
> You're not limited to 2 levels of inheritance. The grandchild's SUPER
> calls the child's method, and the child's SUPER calls the parent's
> method. It'll work the same even when you add a grandchild. (At some
> point I'd start asking myself if inheritance is really the way I'd want
> to structure my application).
>
>
>> Here is my real world use case.  I split my applications into 2 parts;
>> one amounts to the UI payload delivery, basically HTML that makes all
>> calls asynchronously. The other is strictly non-UI and handles only
>> asynchronous requests (i.e., the "REST" API). And I typically have
>> this hierarchy:
>>
>> 1. WebCommon.pm (ISA CGI::Application; implements Authentication and common 
>> run modes)
>> 2. WebApp.pm (ISA WebCommon; base class for the UI delivery or initial 
>> "view")
>> 3. WebAPI.pm (ISA WebCommon; base class for the "REST" API)
>>
>>>From there, I may have another or even another 2 levels of WebApps or
>> WebAPIs. In WebCommon.pm, I define cgiapp_init; in WebApps.pm and
>> WebAPI.pm, I define a setup. Beyond that, I redefine setup with a call
>> to $self->SUPER::setup - not something I really like doing.
>
>
> You'd be better off setting up your runmodes in an init hook. That's the
> way I do it in CA::Plugin::RunmodeDeclare.
>
> package WebCommon;
> use base 'CGI::Application';
>
> __PACKAGE__->add_callback( init => sub {
>  $_[0]->run_modes([ ... ]);
> });
>
> package WebAPI;
> use base 'WebCommon';
>
> __PACKAGE__->add_callback( init => sub {
>  $_[0]->run_modes([ ... ]);
> });
>
> package WebAPI::Stuff;
> use base 'WebAPI';
>
> __PACKAGE__->add_callback( init => sub {
>  $_[0]->run_modes([ ... ]);
> });
>
>
>
> Then WebAPI has all the run modes of WebCommon, as well as its own run
> modes. And WebAPI::Stuff has those of WebAPI and its own.
>
> However, I'd ask myself if I really want to have all those parent run
> modes in the child app.
>
>
>> I want to use CGI::Simple, but do not want to enable uploads app-wide.
>> I have a subclass (WebAPI::UploadApp, say) where I do want to enable
>> uploads.
>>
>> In WebCommon.pm, I have to do this:
>>
>> our $cgi; #= CGI::Simple->new;
>
> Don't do this. You need a query object that's an attribute of the
> current CA object. A package variable is going to have too wide a scope.
>
>> sub cgiapp_get_query {
>>  use CGI::Simple ();
>>  $cgi = CGI::Simple->new();
>>  return $cgi;
>> }
>
> This is better written as:
>
> sub cgiapp_get_query {
>  use CGI::Simple;
>  return CGI::Simple->new;
> }
>
>> Then in order to override that CGI::Simple to enable uploads, in
>> WebAPI::UploadApp, I have to do this:
>>
>> sub cgiapp_get_query {
>>  my $self = shift;
>>  use CGI::Simple ();
>>  $CGI::Simple::DISABLE_UPLOADS = 0;
>>  $self::SUPER::cgi = CGI::Simple->new();
>>  return $self::SUPER::cgi;
>> }
>
> That code makes little sense. cgiapp_get_query is supposed to return a
> CGI compatible object. It's not supposed to change variables in another
> package.
>
> This is what you should do instead:
>
> sub cgiapp_get_query {
>  local $CGI::Simple::DISABLE_UPLOADS = 0;
>  return $_[0]->SUPER::cgiapp_get_query;
> }
>
>
>> Granted, there is probably a more correct, cleaner, or better way to do
>> this; if so, I am all ears.
>
> The only ugly thing about that

Re: [cgiapp] CGI::Application status update from the maintainer

2012-09-10 Thread B. Estrade
Thank you, Mark.

I accept what you so at face value and will seek to educate myself
more. Below I address the questions you asked me.

On Sat, Sep 08, 2012 at 06:10:55PM -0400, Mark Stosberg wrote:
> 

snip..

> >
> > It would be really nice to merge in some bare bones Authentication and
> > Authorization support - maybe ever by more fully developing CAP's lifecycle.
> 
> More detailed suggestions would be welcome here, but I'm hestitent. Are
> there examples of other frames that do something here in a way that's
> appealing?

Not that I know of; I must admit I am a one trick pony wrt frameworks.
CAP is all I use and know.

> 
> I would generally plan to keep the core small, but would welcome more
> full-featured stacks to be shipped that were based on it, as Titanium
> did for CGI::Application.

My motivation for this is based on our needs. We use CAP to write not
just authenticated applications, but those with role based
authorization.  I have had moderate success using Authen and Authz,
but in order to do what was necessary to Authen before Authz or to
properly scale out the RBAC restrictions, I had to ditch both and
implement my own callbacks during the prerun stage.  I suppose both
plugins got be over the learning curve, and after I was able to
implement authentication and authorization without the plugins.

Anyway, my main reason for recommending these 2 in particular as
bona fide life cycle events is that the mirror Apache's life cycle. I
think this reflects the value of these two stages.  The first
(authentication) is simply for verifying to some degree that the actor
on the system is who they claim to be; the authorization is to ensure
that this authentication actor has authorized to execute the targeted
run mode. Both are prerun type of stages, but first classing them
would be nice. 

I am not sure I can persuade you to formalize these two stages in
particular, but I hope that you consider this. I believe that
authentication and RBAC style authorization is only going to become
more important, and if nothing these stages would provide a clue to
application programmers that CAP is very much suitable for industrial
strenght web applications.

> 
> One project that strikes me as interesting here is "Abilities".
> It addresses the problem space by using a "role". It is framework
> independent, but is intended to be used as part of web applications.
> 
>  https://metacpan.org/module/Abilities

Thank you.

> 
> This is an example of the kind of code I would like to make more easily
> available to CGI::App based projects.
> 
> > I am a recent addition to this community, and prefer CAP well over the
> > other alternatives.
> 
> That's good to hear, and welcome. Could you say more about why you
> prefer it and how you use it?

I prefer it because it provided me with a significant epiphany after
doing CGI the hard way for too long.  It's also more or less what we
standardize on internally at cPanel.

We use it to write internal applications and external facing APIs that
require both authentication and authorization. One of our primary
requirements is also raw speed, so even .05 seconds matters to us.
This is the basis for my distaste for any sort of MOP layer.  However,
I concede that in a persistent environment, start up times are
amortized over the long term and in this way any cost eventually goes
to 0. 

> 
> > 1. scalability - it is unnecessarily awkward to have more than 2
> > levels of subclassing currently.
> >
> > Direct subclass of CAP uses cgi_init; child of subclass uses setup;
> > anything else must call SUPER::setup.
> 
> Another option I use sometimes is to use the callback system:
> 
> # Register an action to happen at the init stage.
> __PACKAGE__->add_callback('init', sub {
> 
> });

Nice.

> 
> Note that the Moose API also helps here as well, as it allows you to say
> this:
> 
>  # Add some additional functionality after 'setup' runs in the parent
>  after 'setup' => sub {
>  my $self = shift;
>  };
> 

Thank you. Yeah, that syntax makes me cring actually :).

However, this out of the box seems to provide the basis for a very
well structured plugin system.

>  
> https://metacpan.org/module/Moose::Manual::MethodModifiers#BEFORE-and-AFTER-modifiers
> 
> The Moose API also provides "BUILD", which like our callback system is
> called for every class in the inheritance hierarchy. So another way to
> add some "initialization" functionality would be to put this in your
> Moose/Mouse based child class:
> 
>  # Another way to add extra functionality when setting up classes.
>  sub BUILD {
>  my $self = shift;
>  }
> 
> > 2. a more fully developed lifecycle model - similar to the one that
> > Apache itself uses.  In particular, it would be really helpful to have
> > explicit  phases for state (e.g., Session munging), authentication,
> > and authorization.  I imagine those 3 in particular to be extremely
> > helpful for building things like r

Re: [cgiapp] CGI::Application status update from the maintainer

2012-09-18 Thread B. Estrade
On Tue, Sep 18, 2012 at 12:19:46PM -0500, Bill Stephenson wrote:
> On Sep 15, 2012, at 10:58 AM, Mark Stosberg wrote:
> 
> > Most web clients support JSON now, which allows for more complex
> > structures than the simple key/value pair that CGI.pm uses.
> 
> 
> Mark, I think this is relevant to what I'm advocating here. 
> 
> That JSON support is accomplished with javascript parsing a string of JSON 
> data that is stored in the localStorage key/value format. I think that's a 
> very clever use of the localStorage feature because it extends the 
> functionality without adding complexity. 
> 
> Here's an interesting article on that:
> 
> https://hacks.mozilla.org/2012/03/there-is-no-simple-solution-for-local-storage/
> 
> That article points out the value of the simplicity in having the 
> localStorage function and the key/value format, and also how the IndexedDB 
> feature is not so simple. So, I'm not at all alone in seeing the benefits of 
> these simple to use functions and this format. That simplicity is really 
> quite ingenious, and I think this is what's important to keep in mind. 
> 
> What developers are doing with localStorage and JSON on the client side is 
> really not any different in concept than storing a string of JSON  data with 
> CGI.pm's save function on the server side. I think that sounds pretty handy.
> 
> Here's a quote from the author about that:
> 
> "This local storage solution has a few very tempting features for web 
> developers:
> 
>   ? It is dead simple
>   ? It uses strings for storage instead of complex databases (and you can 
> store more complex data using JSON encoding) ..."
> 
> In that article the author, Chris Heilmann, also discusses how unforeseen 
> uses of the localStorage feature have revealed issues with how it is 
> implemented. He offers several ideas on how to deal with those issues and he 
> concludes his findings with "We need to fix this".
> 
> It seems to me that we are in a somewhat similar situation, but are leaning 
> towards a "We need to ditch this" conclusion. 
> 
> As I've said, my reasons for advocating for this feature are selfish. I am 
> not qualified to help implement it so how can they be anything but selfish? 
> But, that does not mean others will not also benefit. I think the example of 
> creative and clever usage discussed above helps to demonstrate that.
> 
> While I may not be able to help implement the feature, I might be able to 
> help with example code and documentation, and I'd be more than willing to try.
> 
> Kindest Regards,

It is unclear to me exactly what feature you're advocating, even
though I went back and read the previous threads.

I'd like to point out that while it doesn't matter what the client or
the server do, the defacto standard is to send key/value pairs to the
server no matter what the HTTP method is.  CGI.pm will happly parse a
k/v string sent via POST just as it would sent via GET; however, if
you send just JSON to the server, you must manually parse whatever is
in the POSTDATA field. That's my experience anyway.

It'd be nice to have something on the server that recognized the JSON
as natively as a k/v query string, particularly for non-GET methods.

Also, YUI 3 has some interesting local storage options.

Brett

> 
> Bill
> 
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 
> 

-- 
Register Now for cPanel Conference
Oct 8-10, 2012, Houston, Texas
http://conference.cpanel.net/

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] draft version of "PSGI::Application" and load_tmpl replacement

2012-11-06 Thread B. Estrade
I had originally suggested adding authentication and authorization
stages in the life cycle of the application, and after looking at
things it seems that your very close to having a general system that
could make it easy to not only add hooks to callbacks, but to add and
manage callbacks themselves.

So, I guess what I am suggesting is not to add authentication and 
authorization, but to make it easy for me as a programmer to add them
as a top level CLASS_CALLBACK myself.

You start with the rather arbitrary (but rational):

my %CLASS_CALLBACKS = (
#   hook name  package sub
init  => { 'PSGI::Application' => [ 'init'] },
prerun=> { 'PSGI::Application' => [ 'prerun'  ] },
postrun   => { 'PSGI::Application' => [ 'postrun' ] },
teardown  => { 'PSGI::Application' => [ 'teardown'] },
load_tmpl => { },
error => { },
);

You call init in BUILD, but then explicitly run down the callback list in 
the run() method. What I am wondering is if you could bridge the gap to the 
other side that would allow one to munge around with the *ordered contents 
of %CLASS_CALLBACKS.

my %CLASS_CALLBACKS = (
#   hook name  package sub
init  => { 'PSGI::Application' => [ 'init'] },
prerun=> { 'PSGI::Application' => [ 'prerun'  ] },

# for example, add
authentication  => { 'My::PSGI::Application' => [ 'authentication'  ] },
authorization   => { 'My::PSGI::Application' => [ 'authorization'  ] },

postrun   => { 'PSGI::Application' => [ 'postrun' ] },
teardown  => { 'PSGI::Application' => [ 'teardown'] },
load_tmpl => { },
error => { },
);

Instead of me having to reimplement the run() method to provide for custom
top level callbacks, would it be possible to craft run() so that it took
%CLASS_CALLBACKS as ordered (e.g., if %CLASS_CALLBACKS was tied with 
Tie::Hash::Indexed) ?

Right now, it seems like I'd have to reimplement the run(), when all I really 
wanted
to do was insert top level callback classes wrt the order in which they are run.

Thank you,
Brett

On Tue, Nov 06, 2012 at 01:36:07PM -0500, Mark Stosberg wrote:
> On 11/06/2012 12:27 PM, Kurt Lidl wrote:
> > On 11/6/2012 12:24 PM, Mark Stosberg wrote:
> > 
>  * Hash keys for new() must now be upper-case now.
> >>>
> >>> Ridiculous. Lower case hash keys are the norm throughout Perl.
> >>>
> >>> Upper case is SHOUTING.
> >>
> >> I agree that lower case hash keys are the norm and upper case hash keys
> >> are shouting. The choice here weas a nod to compatibility with
> >> CGI::Application, which internally was case-insensitive, but by
> >> convention, everyone has been using the upper-case keys.
> >>
> >> I'm open to reconsidering this point as well, as I would prefer
> >> lower case going forward myself. Perhaps the upper-case support can be
> >> pushed into a ::Compat transitional module.
> > 
> > I'd vote for lower-casing them, if you're looking for feedback.
> 
> I am looking for feedback. Thanks for the opinion.
> 
>Mark
> 
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

-- 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] authentication and authorization callbacks

2012-11-06 Thread B. Estrade
On Tue, Nov 06, 2012 at 03:32:13PM -0500, Mark Stosberg wrote:
> 
> > You call init in BUILD, but then explicitly run down the callback list in 
> > the run() method. What I am wondering is if you could bridge the gap to the 
> > other side that would allow one to munge around with the *ordered contents 
> > of %CLASS_CALLBACKS.
> > 
> > my %CLASS_CALLBACKS = (
> > #   hook name  package sub
> > init  => { 'PSGI::Application' => [ 'init'] },
> > prerun=> { 'PSGI::Application' => [ 'prerun'  ] },
> > 
> > # for example, add
> > authentication  => { 'My::PSGI::Application' => [ 'authentication'  ] },
> > authorization   => { 'My::PSGI::Application' => [ 'authorization'  ] },
> > 
> > postrun   => { 'PSGI::Application' => [ 'postrun' ] },
> > teardown  => { 'PSGI::Application' => [ 'teardown'] },
> > load_tmpl => { },
> > error => { },
> > );
> > 
> > Instead of me having to reimplement the run() method to provide for custom
> > top level callbacks, would it be possible to craft run() so that it took
> > %CLASS_CALLBACKS as ordered (e.g., if %CLASS_CALLBACKS was tied with 
> > Tie::Hash::Indexed) ?
> > 
> > Right now, it seems like I'd have to reimplement the run(), when all I 
> > really wanted
> > to do was insert top level callback classes wrt the order in which they are 
> > run.
> 
> Brett, I think this existing functionality would provide what you want:
> 
>  PSGI::Application->new_hook('authorization');
>  PSGI::Application->add_callback('authorization', \&callback);

Kind of, but what it doesn't allow me to do is affect the order in
which the lifecycle hooks are executed.  I think that I would also
have to make a ->call_hook('authorization'), when what I really want
to do is not only create the 'authorization' hook, but add it as a
bona-fide lifecycle event like 'init', 'prerun', etc and choose at
what point after 'init' is executed.

> 
> That would register a hook named 'authorization', and register a
> callback to fire the same as it would as if it were in the built-in hash.
> 
> Or have I misunderstood the request?

You're close.

> 
> If need-be, we could make %CLASS_CALLBACKS, replaceable, but I want to
> be first be clear that there's a need.

That's really a subjective call, and not mine to make. I think that
ultimately it'd be nice to be make the run() method general enough to
where you can have a custom hook executed there in an order of your
choosing, without having to call ->call_hook('foo') explicitly in your
PAP instance.

So, maybe something like this:

 PSGI::Application->new_hook('authorization','before','prerun');
 PSGI::Application->add_callback('authorization', \&callback);

Then run() would know due to some ordered notion of the default hooks
that ->call_hook('authorization') would effectively get called
'before' the 'prerun' hook.

I think of the hooks as stacks that contain registered callback
methods. You get 'init', 'prerun', etc for free. And yes, you can
create your own "stack" and registered callbacks to them. However,
sometimes it would be really convenient if you could insert your own
custom hook into the list of those that are implicitly called - it
might particularly make it easier for plugins to better manage when
and what they execute.

Ultimately, I just want a way to create my own top level hook 
and not have to ->call_hook when I could just slide it into the
lifecycle of events itself.

Thanks for your consideration.

Brett

> 
>Mark
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

-- 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####




Re: [cgiapp] authentication and authorization callbacks

2012-11-07 Thread B. Estrade
On Tue, Nov 06, 2012 at 09:37:21PM -0500, Mark Stosberg wrote:
> >> Brett, I think this existing functionality would provide what you want:
> >>
> >>   PSGI::Application->new_hook('authorization');
> >>   PSGI::Application->add_callback('authorization', \&callback);
> >
> > Kind of, but what it doesn't allow me to do is affect the order in
> > which the lifecycle hooks are executed.  I think that I would also
> > have to make a ->call_hook('authorization'), when what I really want
> > to do is not only create the 'authorization' hook, but add it as a
> > bona-fide lifecycle event like 'init', 'prerun', etc and choose at
> > what point after 'init' is executed.
> 
> I see the difference. You still want the ability to decide where within
> "run" the hook point is fired from.
> 
> > So, maybe something like this:
> >
> >   PSGI::Application->new_hook('authorization','before','prerun');
> >   PSGI::Application->add_callback('authorization', \&callback);
> 
> Then you need one more piece:
> 
>before 'prerun' => sub {
>my ($self,@args) = @_;
>$self->call_hook('authorization', @args);
>}
> 
> "before" is a method modifier provided by Moose and Mouse. Since
> PSGI::Application uses Any::Moose, it will always be available for use.
> 
> The pieces can be wrapped up in an Authorization plugin for those who
> want to use it.
> 
> Once that's done, there's no more calling "call_hook()" explicitly, just
> use the authorization plugin.

A win for the MOP it seems :)...and a nice feeling idiom to boot.
Thank you,

Brett

> 
>  Mark
> 
> #  CGI::Application community mailing list  
> ####
> ##  To unsubscribe, or change your message delivery options,  ##
> ##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
> ####
> ##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
> ##  Wiki:  http://cgiapp.erlbaum.net/ ##
> ####
> 
> 

-- 

#  CGI::Application community mailing list  
####
##  To unsubscribe, or change your message delivery options,  ##
##  visit:  http://www.erlbaum.net/mailman/listinfo/cgiapp##
####
##  Web archive:   http://www.erlbaum.net/pipermail/cgiapp/   ##
##  Wiki:  http://cgiapp.erlbaum.net/ ##
####