package CatalystX::SimpleLogin::Form::Login; use HTML::FormHandler::Moose; use Try::Tiny; use namespace::autoclean; extends 'HTML::FormHandler'; use MooseX::Types::Moose qw/ HashRef /; use MooseX::Types::Common::String qw/ NonEmptySimpleStr /; has '+name' => ( default => 'login_form' ); has authenticate_args => ( is => 'ro', isa => HashRef, predicate => 'has_authenticate_args', ); has authenticate_realm => ( is => 'ro', isa => NonEmptySimpleStr, predicate => 'has_authenticate_realm', ); has 'login_error_message' => ( is => 'ro', isa => NonEmptySimpleStr, required => 1, default => 'Wrong username or password', ); foreach my $type (qw/ username password /) { has sprintf("authenticate_%s_field_name", $type) => ( is => 'ro', isa => NonEmptySimpleStr, default => $type ); # FIXME - be able to change field names in rendered form also! } has_field 'username' => ( type => 'Text', tabindex => 1 ); has_field 'password' => ( type => 'Password', tabindex => 2 ); has_field 'remember' => ( type => 'Checkbox', tabindex => 3 ); has_field 'submit' => ( type => 'Submit', value => 'Login', tabindex => 4 ); sub validate { my $self = shift; # as HTML::Formhandler doesn't handle exceptions thrown by user provided # validate methods and fails to clear the 'posted' attribute we need to # catch them unless ( try { $self->ctx->authenticate( { (map { my $param_name = sprintf("authenticate_%s_field_name", $_); ($self->can($param_name) ? $self->$param_name() : $_) => $self->values->{$_}; } grep { ! /remember/ } keys %{ $self->values }), ($self->has_authenticate_args ? %{ $self->authenticate_args } : ()), }, ($self->has_authenticate_realm ? $self->authenticate_realm : ()), ); } catch { $self->ctx->log->error("$_"); return 0; } ) { $self->add_auth_errors; # the return value of this method is ignored by HTML::FormHandler # 0.40064, only errors added to the form itself or its fields control # the forms' 'validated' attribute return 0; } return 1; } sub add_auth_errors { my $self = shift; $self->field( 'password' )->add_error( $self->login_error_message ); } __PACKAGE__->meta->make_immutable; =head1 NAME CatalystX::SimpleLogin::Form::Login - validation for the login form =head1 DESCRIPTION A L form for the login form. =head1 FIELDS =over =item username =item password =item remember =item submit =back =head1 METHODS =over =item validate =item add_auth_errors =back =head1 SEE ALSO =over =item L =back =head1 CUSTOMIZATION By default, the params passed to authenticate() are 'username' and 'password'. If you need to use different names, then you'll need to set the correct value(s) via login_form_args in the configuration. The keys are 'authenticate_username_field_name' and/or 'authenticate_password_field_name'. __PACKAGE__->config( 'Controller::Login' => { login_form_args => { authenticate_username_field_name => 'name', authenticate_password_field_name => 'password2', }, }, ); You can also change the way that the form is displayed by setting attributes. In MyApp.pm: __PACKAGE__->config( 'Controller::Login' => { login_form_args => { login_error_message => 'Login failed', field_list => [ '+submit' => { value => 'Login' }, ] } }, ); Additional fields can be added: field_list => [ 'foo' => ( type => 'MyField' ), 'bar' => { type => 'Text' }, ] Additional arguments to the authenticate call can be added: If your user table has a column C and you want only those with Cto be able to log .in __PACKAGE__->config( 'Controller::Login' => { login_form_args => { authenticate_args => { status => 1 }, }, }, }; =head1 AUTHORS See L for authors. =head1 LICENSE See L for license. =cut