diff --git a/.gitignore b/.gitignore index a7c43f5..e392ac3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ *.bak -paia-session.json -paia.json +*.json .build App-PAIA-* diff --git a/lib/App/PAIA.pm b/lib/App/PAIA.pm index 4fafadf..8e94764 100644 --- a/lib/App/PAIA.pm +++ b/lib/App/PAIA.pm @@ -17,7 +17,7 @@ sub global_opt_spec { ['quiet|q' => "don't print PAIA response"], ["username|u=s" => "username for login"], ["password|p=s" => "password for login"], - ['token|t=s' => "explicit access_token"], + ['access_token|token|t=s' => "explicit access_token"], ["patron|o=s" => "explicit patron identifier"], ["scope|e=s" => "comma-separated list of scopes for login"], ["help|h|?" => "show help", { shortcircuit => 1 } ], diff --git a/lib/App/PAIA/Command.pm b/lib/App/PAIA/Command.pm index 3ea35d4..d658b66 100644 --- a/lib/App/PAIA/Command.pm +++ b/lib/App/PAIA/Command.pm @@ -11,6 +11,8 @@ use App::PAIA::File; use URI::Escape; use URI; +# TODO: move option handling to App::PAIA + # Implements lazy accessors just like Mo, Moo, Moose... sub has { my ($name, %options) = @_; @@ -41,14 +43,6 @@ sub explicit_option { // $self->config->get($name); # config file } -sub token { # TODO: make option - my ($self) = @_; - - $self->app->global_options->{'token'} - // $self->session->get('access_token') - // $self->config->get('access_token'); -} - has config => ( default => sub { App::PAIA::File->new( @@ -109,15 +103,19 @@ has core => ( has base => ( default => sub { $_[0]->option('base') }, - coerce => sub { my ($b) = @_; $b =~ s!/$!!; $b; }, + coerce => sub { my ($b) = @_; $b =~ s!/$!!; $b; } ); has patron => ( - default => sub { $_[0]->option('patron') }, + default => sub { $_[0]->option('patron') } ); has scope => ( - default => sub { $_[0]->option('scope') }, + default => sub { $_[0]->option('scope') } +); + +has token => ( + default => sub { $_[0]->option('access_token') } ); has username => ( @@ -132,16 +130,19 @@ has password => ( } ); +sub expired { + my ($self) = @_; + + my $expires = $self->session->get('expires_at'); + return $expires ? $expires <= time : 0; +} + sub not_authentificated { my ($self, $scope) = @_; my $token = $self->token // return "missing access token"; - if ( my $expires = $self->session->get('expires_at') ) { - if ($expires <= time) { - return "access token expired"; - } - } + return "access token expired" if $self->expired; if ($scope and $self->scope and !$self->has_scope($scope)) { return "current scope '{$self->scope}' does not include $scope!\n"; @@ -191,6 +192,11 @@ sub request { sub login { my ($self, $scope) = @_; + if ($self->session->purge) { + $self->session->file(undef); + $self->logger->("deleted session file"); + } + my $auth = $self->auth or $self->usage_error("missing PAIA auth server URL"); # take credentials from command line or config file only diff --git a/lib/App/PAIA/Command/logout.pm b/lib/App/PAIA/Command/logout.pm index 4c18fab..f8196bd 100644 --- a/lib/App/PAIA/Command/logout.pm +++ b/lib/App/PAIA/Command/logout.pm @@ -10,19 +10,18 @@ use App::PAIA::JSON; sub _execute { my ($self, $opt, $args) = @_; - my $auth = $self->auth // $self->usage_error("missing PAIA auth URL"); - - my $response = $self->request( - "POST", "$auth/logout", { patron => $self->patron } - ); - print encode_json($response); - - if (defined $self->session->file) { - $self->session; - unlink $self->session->file; - $self->logger->("deleted session file"); + if ($self->expired) { + $self->logger("session expired, skip logout"); # TODO: force on request + } else { + my $auth = $self->auth // $self->usage_error("missing PAIA auth URL"); + my $response = $self->request( + "POST", "$auth/logout", { patron => $self->patron } + ); + print encode_json($response); } + $self->session->purge && $self->logger->("deleted session file"); + return; } diff --git a/lib/App/PAIA/File.pm b/lib/App/PAIA/File.pm index 4619851..173c70c 100644 --- a/lib/App/PAIA/File.pm +++ b/lib/App/PAIA/File.pm @@ -22,7 +22,7 @@ sub new { } sub file { - $_[0]->{file}; + @_ > 1 ? ($_[0]->{file} = $_[1]) : $_[0]->{file}; } sub get { @@ -73,6 +73,13 @@ sub store { $self->{logger}->("saved $type file $file"); } +sub purge { + my ($self) = @_; + + return unless defined $self->file && -e $self->file; + unlink $self->file; +} + 1; =head1 DESCRIPTION