diff options
-rw-r--r-- | perllib/Catalyst/Authentication/Store/FixMyStreetUser.pm | 54 | ||||
-rw-r--r-- | perllib/FixMyStreet/App.pm | 21 | ||||
-rw-r--r-- | t/app/controller/token.t | 4 | ||||
-rw-r--r-- | t/app/model/user.t | 16 |
4 files changed, 77 insertions, 18 deletions
diff --git a/perllib/Catalyst/Authentication/Store/FixMyStreetUser.pm b/perllib/Catalyst/Authentication/Store/FixMyStreetUser.pm new file mode 100644 index 000000000..240f4b1de --- /dev/null +++ b/perllib/Catalyst/Authentication/Store/FixMyStreetUser.pm @@ -0,0 +1,54 @@ +package Catalyst::Authentication::Store::FixMyStreetUser; + +use Moose; +use namespace::autoclean; +extends 'Catalyst::Authentication::Store::DBIx::Class::User'; + +use Carp; +use Try::Tiny; + +sub AUTOLOAD { + my $self = shift; + (my $method) = (our $AUTOLOAD =~ /([^:]+)$/); + return if $method eq "DESTROY"; + + if (my $code = $self->_user->can($method)) { + return $self->_user->$code(@_); + } + elsif (my $accessor = + try { $self->_user->result_source->column_info($method)->{accessor} }) { + return $self->_user->$accessor(@_); + } else { + croak sprintf("Can't locate object method '%s'", $method); + } +} + +__PACKAGE__->meta->make_immutable(inline_constructor => 0); + +1; +__END__ + +=head1 NAME + +Catalyst::Authentication::Store::FixMyStreetUser - The backing user +class for the Catalyst::Authentication::Store::DBIx::Class storage +module, adjusted to die on unknown lookups. + +=head1 DESCRIPTION + +The Catalyst::Authentication::Store::FixMyStreetUser class implements user +storage connected to an underlying DBIx::Class schema object. + +=head1 SUBROUTINES / METHODS + +=head2 AUTOLOAD + +Delegates method calls to the underlying user row. +Unlike the default, dies if an unknown method is called. + +=head1 LICENSE + +Copyright (c) 2007-2019. All rights reserved. This program is free software; +you can redistribute it and/or modify it under the same terms as Perl itself. + +=cut diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm index 36f736cd2..e9c3fac8d 100644 --- a/perllib/FixMyStreet/App.pm +++ b/perllib/FixMyStreet/App.pm @@ -34,6 +34,12 @@ extends 'Catalyst'; our $VERSION = '0.01'; +my $store = { # Catalyst::Authentication::Store::DBIx::Class + class => 'DBIx::Class', + user_model => 'DB::User', + store_user_class => 'Catalyst::Authentication::Store::FixMyStreetUser', +}; + __PACKAGE__->config( # Use REQUEST_URI, not PATH_INFO, to infer path. This fixes an issue @@ -83,20 +89,14 @@ __PACKAGE__->config( }, ], }, - store => { # Catalyst::Authentication::Store::DBIx::Class - class => 'DBIx::Class', - user_model => 'DB::User', - }, + store => $store, }, no_password => { # use post confirm etc credential => { # Catalyst::Authentication::Credential::Password class => 'Password', password_type => 'none', }, - store => { # Catalyst::Authentication::Store::DBIx::Class - class => 'DBIx::Class', - user_model => 'DB::User', - }, + store => $store, }, access_token => { use_session => 0, @@ -106,10 +106,7 @@ __PACKAGE__->config( # This means the token has to be 18 characters long (as generated by AuthToken) token_lookup => { like => "%access_token,T18:TOKEN,%" }, }, - store => { - class => 'DBIx::Class', - user_model => 'DB::User', - }, + store => $store, }, }, ); diff --git a/t/app/controller/token.t b/t/app/controller/token.t index 858838865..f7dec1a31 100644 --- a/t/app/controller/token.t +++ b/t/app/controller/token.t @@ -1,5 +1,4 @@ use FixMyStreet::TestMech; -use FixMyStreet::App; my $mech = FixMyStreet::TestMech->new; my $user = $mech->create_user_ok('bob@example.com', name => 'Bob'); @@ -8,7 +7,6 @@ subtest 'Zurich special case for C::Tokens->problem_confirm' => sub { FixMyStreet::override_config { ALLOWED_COBRANDS => ['zurich'], }, sub { - my $c = FixMyStreet::App->new; my $zurich = $mech->create_body_ok( 1, 'Zurich' ); my ($report) = $mech->create_problems_for_body( 1, $zurich->id, @@ -19,7 +17,7 @@ subtest 'Zurich special case for C::Tokens->problem_confirm' => sub { }); is $report->get_extra_metadata('email_confirmed'), undef, 'email_confirmed not yet set (sanity)'; - my $token = $c->model('DB::Token')->create({ scope => 'problem', data => $report->id }); + my $token = FixMyStreet::DB->resultset('Token')->create({ scope => 'problem', data => $report->id }); $mech->get_ok('/P/' . $token->token); $report->discard_changes; diff --git a/t/app/model/user.t b/t/app/model/user.t index 5a9c898a2..cbc0fe6cf 100644 --- a/t/app/model/user.t +++ b/t/app/model/user.t @@ -1,5 +1,8 @@ use FixMyStreet::TestMech; use FixMyStreet::DB; +use Catalyst::Test 'FixMyStreet::App'; +use HTTP::Request::Common; +use Test::Exception; my $mech = FixMyStreet::TestMech->new(); $mech->log_in_ok('test@example.com'); @@ -63,9 +66,16 @@ FixMyStreet::override_config { $mech->content_like(qr/may_show_name[^>c]*>/); }; -END { - done_testing(); -} +subtest 'Check non-existent methods on user object die' => sub { + my $c = ctx_request(POST '/auth', { username => 'test@example.com', password_sign_in => 'secret' }); + throws_ok( + sub { $c->user->is_super_user }, + qr/Can't locate object method 'is_super_user'/, + 'attempt to call non-existent method' + ); +}; + +done_testing(); sub create_update { my ($problem, %params) = @_; |