[cgiapp] Re: CAP:Authentication with an enum credential
Mark Rajcok
mrajcok at gmail.com
Sun Apr 26 16:30:09 EDT 2009
On Mon, Apr 20, 2009 at 9:13 PM, Mark Rajcok <mrajcok at gmail.com> wrote:
> On Wed, Apr 15, 2009 at 9:15 AM, Mark Stosberg <mark at summersault.com>wrote:
>
>> On Tue, 14 Apr 2009 01:06:38 -0400
>> Mark Rajcok <mrajcok at gmail.com> wrote:
>>
>> > I'm using CAP:Authentication and I have a u_state field in my Users
>> table.
>> > The u_state field is a MySQL enum, and can be set to created, active,
>> > restricted, or disabled.
>> >
>> > I'm trying to figure out how I can display a "Sorry, your account has
>> been
>> > disabled" error page if a user with u_state=disabled tries to log in.
>> >
>> > I looked at (and tried using) custom filters with CAP:Authentication,
>> but
>> > something like the following isn't supported syntax-wise:
>> > CONSTRAINTS => { 'stateFilter:u_state' =>
>> "(created,active,restricted)"
>> > }
>> >
>> > Any suggestions?
>>
>> I think you are right, Mark. I think you may need to write your own driver
>> for
>> this.
>>
>> You can copy the DBI driver and modify it, or write one from scratch,
>> which has
>> the possibility of being simpler and less abstracted because it is
>> designed
>> just for your case.
>>
>> You could also ask Cees if he's interested in patch for "enum()" support
>> in
>> CGI::Application::Plugin::Authentication.
>>
>> Mark
>>
>
> Not exactly efficient (because I make another query of the database for
> every successful login), but here's what I'm doing for now:
>
> Added a callback to $self->authen->config(
> POST_LOGIN_CALLBACK => \&_post_login,
>
> sub _post_login { # we only get here if we authenticated
> my $self = shift;
> my $sql = 'select count(*) from user where u_username = ? and u_state =
> "disabled"';
> if($self->dbh->selectrow_arrayref($sql, undef,
> $self->authen->username)->[0]) {
> $self->authen->logout;
> my $page = $self->custom_error(
> type=>'forbidden', msg=>'Your account has been disabled.');
> print $self->query->header, $page;
> exit # prevent any other/normal CAP processing
> }
> # else the callback returns and the user is logged in
> }
>
> custom_error() is essentially and error run mode that I wrote.
>
> In essence, I'm using CAP::Authentication for normal username+password
> authentication, then I have this additional method to check the account
> state.
>
The above works when the user logs in. It does not work if the user does
not log in -- i.e., if the user comes back to the website using a session
cookie.
To handle both cases, I removed POST_LOGIN_CALLBACK and added a
cgiapp_prerun() method. If the page requires authentication, then I check
the account state.
#------------------------------------------------------------------------------
sub cgiapp_prerun { # overrides
my $self = shift;
$self->_check_account_state if
$self->authen->is_protected_runmode($self->get_current_runmode())
}
#------------------------------------------------------------------------------
sub _check_account_state {
my $self = shift;
my $sql = 'select count(*) from user where u_username = ? and u_state =
"disabled"';
if($self->dbh->selectrow_arrayref($sql,undef,
$self->authen->username)->[0]) {
$self->authen->logout;
my $page = $self->custom_error(type=>'forbidden', msg=>'Your account
has been disabled.');
print $self->query->header, $page;
exit
}
}
More information about the cgiapp
mailing list