Hetula-Client

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

META.json
META.yml
Makefile.PL
README
README.md
bin/hetula-client
dist.ini
lib/Hetula/Client.pm
t/00-load.t
t/01-usage.t
t/credentials
t/ssns.txt
t/ssnsWithContext.txt

bin/hetula-client  view on Meta::CPAN


use IO::Prompter {
  prompt_password => [-timeout=>120, -echo=>'*'],
  prompt_string   => [-timeout=>120],
};


my %args;
Getopt::Long::GetOptions(
  'a|action:s'          => \$args{action},
  'c|credentials:s'     => \$args{credentials},
  'l|list'              => \$args{listActions},
  'o|organization:s'    => \$args{organization},
  'p|password:s'        => \$args{password},
  'u|username:s'        => \$args{username},
  'url=s'               => \$args{baseURL},
  'a|action:s'          => \$args{action},
  'version'             => sub { Getopt::Long::VersionMessage() },
  'h|help'              => sub {
  print <<HELP;

bin/hetula-client  view on Meta::CPAN

For more information, see
  perldoc Hetula::Client

  -a --action String
      Instead of using the built-in menu, trigger a single action from the
      commandline.
      Give the action name with the necessary parameters,
      eg. ssnsBatchAddFromFile(/tmp/ssns.txt,/tmp/ssns.results.txt)
          userDisableAccount(username)

  -c --credentials File
      Where to read the username and password, is more secure than passing them
      as commandline arguments directly.
      These credentials overload any other parameters given.
      The credentials file must consist of up to 4 lines, with each line
      specifying the following commandline argument replacements:
        username
        password
        organization
        url

  -l --list
      List actions that can be invoked with --action

  -o --organization String
      Code of the Hetula organization we are operating on behalf.
  
  -p --password String
      Login to Hetula with this. Avoid using this, will be asked securely if
      not supplied. Use --credentials instead.

  -u --username String
      Login to Hetula with this.

  --url String
      base url of the Hetula instance to connect to.
      ex. https://hetula.example.com

  -v level
        Verbose output to the STDOUT,

bin/hetula-client  view on Meta::CPAN

  exit 0;
},
) or die("Error in command line arguments: $! $@"); #EO Getopt::Long::GetOptions()


if ($args{listActions}) {
  listActions();
  exit 0;
}

Hetula::Client::slurpCredentials($args{credentials}, \%args) if $args{credentials};

Hetula::Client::_detectKohaEnvironment(\%args); #If using Koha, try to get the configurations from Koha's config


$args{username}     = prompt_string(  "Hetula username:").''     unless $args{username};
$args{password}     = prompt_password("Hetula password:").''     unless $args{password};
$args{organization} = prompt_string(  "Hetula organization:").'' unless $args{organization};
$args{baseURL}      = prompt_string(  "Hetula base URL:").''     unless $args{baseURL};

my $hc = Hetula::Client->new({

lib/Hetula/Client.pm  view on Meta::CPAN


##External modules
use Mojo::UserAgent;
use Storable;
use Regexp::Common;
use Data::Printer;

=head3 new

 @param1 {HASHRef} baseURL => https://hetula.example.com
                   credentials => filepath, Where to load the credentials file.
                                  see slurpCredentials() for more info.

=cut

sub new($class, $params) {
  slurpCredentials($params->{credentials}, $params) if ($params->{credentials});
  _detectKohaEnvironment($params);
  die("Hetula::Client::BadParam - parameter 'baseURL' is missing") unless $params->{baseURL};
  die("Hetula::Client::BadParam - parameter 'baseURL' '$params->{baseURL}' is not a valid URI") unless $params->{baseURL} =~ /$RE{URI}{HTTP}{-scheme=>qr!https?!}/;

  my $s = bless(Storable::dclone($params), $class);

  $s->{ua} = Mojo::UserAgent->new() unless $s->{ua};
  return $s;
}

=head2 API Access methods

=head3 login

See Hetula API doc for endpoint POST /api/v1/auth

 @param1 {HASHRef} username => String || undef if given via credentials during construction,
                   password => String || undef if given via credentials during construction,
                   organization => String || undef if given via credentials during construction,

=cut

sub login($s, $params={}) {
  $params->{username} = $s->{username} unless $params->{username};
  $params->{password} = $s->{password} unless $params->{password};
  $params->{organization} = $s->{organization} unless $params->{organization};

  my $tx = $s->ua->post( $s->baseURL().'/api/v1/auth', {Accept => '*/*'}, json => $params );
  my $json = _handleResponse($tx);

lib/Hetula/Client.pm  view on Meta::CPAN

  die("Hetula::Client::BadParameter - parameter 'id' or 'username' is missing") unless ($id);
  my $tx = $s->ua->delete( $s->baseURL()."/api/v1/users/$id/password", {Accept => '*/*'} );
  return _handleResponse($tx);
}

=head2 HELPERS

=head3 slurpCredentials
@static

Reads the contents of a credentials file.

The credentials file must consist of up to 4 lines, with each line
specifying the following commandline argument replacements:
  username
  password
  organization
  url

 @param1 {String} Path to the credentials file
 @param2 {HASHRef} Optional, HASHRef where to inject the found credentials

=cut

sub slurpCredentials($credentialsFile, $injectHere=undef) {
  open(my $FH, '<:encoding(UTF-8)', $credentialsFile) or die("Couldn't read '$credentialsFile': $!");
  my $username     = <$FH>; if ($username)     { chomp($username);     $injectHere->{username}     = $username     if $username && $injectHere; }
  my $password     = <$FH>; if ($password)     { chomp($password);     $injectHere->{password}     = $password     if $password && $injectHere; }
  my $organization = <$FH>; if ($organization) { chomp($organization); $injectHere->{organization} = $organization if $organization && $injectHere; }
  my $baseURL      = <$FH>; if ($baseURL)      { chomp($baseURL);      $injectHere->{baseURL}      = $baseURL      if $baseURL && $injectHere; }
  return ($username, $password, $organization, $baseURL);
}

=head2 ATTRIBUTES

=head3 ua

t/01-usage.t  view on Meta::CPAN

use File::Slurp;
use File::Temp;

use Hetula::Client;


#$ENV{HETULA_DEBUG} = 1;
#$ENV{MOJO_INSECURE} = 1;
$ENV{MOJO_LOG_LEVEL} = 'info';

## Get credentials to use. Alternatively one can temporarily test with real credentials this predesigned test suite.
my $realCredentials = 0;
my $credentialsFile = "$FindBin::Bin/credentials";
my @credentials = File::Slurp::read_file($credentialsFile, chomp => 1);

my $username     = $credentials[0];
my $password     = $credentials[1];
my $organization = $credentials[2];
my $baseURL      = $credentials[3];
if ($realCredentials) { #test with real credentials here
  $username     = '';
  $password     = '';
  $organization = '';
  $baseURL      = '';
}
## Credentials dealt with.


my $hc = Hetula::Client->new({baseURL => $baseURL});
mockServer($hc) unless $realCredentials;


my $resp = $hc->login({username => 'master', password => 'blaster', organization => $organization});
ok($resp->{error}, "Login failed - Using bad credentials, got error '$resp->{error}'");


$resp = $hc->login({username => $username, password => $password, organization => $organization});
ok(! $resp->{error}, "Login success");


$resp = $hc->loginActive();
ok(! $resp->{error}, "Login active");


t/01-usage.t  view on Meta::CPAN



$resp = $hc->userDisableAccount({username => $username});
ok(! $resp->{error}, "User disable account succeeded");


$resp = $hc->userChangePassword({username => $username, password => $password});
ok(! $resp->{error}, "User change password succeeded");


subtest "New Hetula::Client with a credentials file", sub {
  plan tests => 1;
  my $hc = Hetula::Client->new({baseURL => $baseURL, credentials => $credentialsFile});
  mockServer($hc) unless $realCredentials;

  $resp = $hc->login();
  ok(! $resp->{error}, "Login success");
};


subtest "ssnsBatchAddFromFile()", sub {
  plan tests => 11;
  my ($FH, $tempFilename) = File::Temp::tempfile();



( run in 0.260 second using v1.01-cache-2.11-cpan-4d50c553e7e )