From 2337f282aeb7717ca0f70272a42ab33b7e045e93 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Thu, 8 Jun 2017 11:09:04 -0700 Subject: [PATCH] LP#169625: Support script for working with OverDrive API Adds a script, overdrive-api-checker.pl, for testing the OverDrive API from the command line. USAGE: Open-ILS/src/support-scripts/overdrive-api-checker.pl --get-token --key --secret Open-ILS/src/support-scripts/overdrive-api-checker.pl --account --token [ --endpoint https://api.overdrive.com/v1/libraries/1234 [ --content ] ] Open-ILS/src/support-scripts/overdrive-api-checker.pl --account --token --oauth-only Open-ILS/src/support-scripts/overdrive-api-checker.pl --account --token --patron-auth [ --endpoint https://oauth-patron.overdrive.com/patrontoken ] --barcode [ --password ] --websiteid --authorizationname OPTIONS: --get-token Generate OverDrive API basic token. --key Client key supplied by OverDrive. Required with --get-token. --secret Client secret supplied by OverDrive. Required with --get-token. --token Your OverDrive API basic token (clientKey:clientSecret, Base64-encoded). Required unless using --get-token. --account Your OverDrive API account ID (e.g. 1234). Not required for generating a basic token; required for everything else. --oauth-endpoint OverDrive API endpoint for OAuth token requests. Default: https://oauth.overdrive.com/token. --endpoint OverDrive API endpoint that you wish to test. Default: https://api.overdrive.com/v1/libraries/ --content JSON content of main API request. Required only if you have specified an endpoint that expects JSON message content. --oauth-only Only request an OAuth token; do not attempt further API requests. --patron-auth Submit a patron authentication request. --barcode Patron barcode. Required with --patron-auth. --password Patron password. Required with --patron-auth if your library requires password for patron authentication. --websiteid Website ID supplied by OverDrive. Required with --patron-auth. --authorizationname ILS name supplied by OverDrive. Required with --patron-auth. --verbose Print full HTTP requests and responses. --help Print this help message. EXAMPLES: To generate your basic token, given a client key and client secret supplied by OverDrive: Open-ILS/src/support-scripts/overdrive-api-checker.pl --get-token --key --secret To send a basic API request (this is useful for validating your client credentials and determining whether the OverDrive API is currently available): Open-ILS/src/support-scripts/overdrive-api-checker.pl --account --token To send a request to a specific API endpoint: Open-ILS/src/support-scripts/overdrive-api-checker.pl --account --token --endpoint --content To test OverDrive API authentication for a specific patron: Open-ILS/src/support-scripts/overdrive-api-checker.pl --account --token --patron-auth --barcode --password --websiteid --authorizationname Signed-off-by: Jeff Davis Signed-off-by: Martha Driscoll Signed-off-by: Galen Charlton --- .../support-scripts/overdrive-api-checker.pl | 190 ++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100755 Open-ILS/src/support-scripts/overdrive-api-checker.pl diff --git a/Open-ILS/src/support-scripts/overdrive-api-checker.pl b/Open-ILS/src/support-scripts/overdrive-api-checker.pl new file mode 100755 index 0000000000..32a63abdf9 --- /dev/null +++ b/Open-ILS/src/support-scripts/overdrive-api-checker.pl @@ -0,0 +1,190 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use LWP::UserAgent; +use HTTP::Request; +use JSON; +use Getopt::Long; +use MIME::Base64; +use Data::Dumper; + +my $account_id; +my ($basic_token, $get_token, $client_key, $client_secret); +my ($api_endpoint, $content); +my $oauth_endpoint = 'https://oauth.overdrive.com/token'; +my $oauth_only; +my ($patron_auth, $barcode, $password, $websiteid, $authorizationname); +my ($verbose, $help); +my ($authtoken, $auth_content); + +GetOptions( + 'account=s' => \$account_id, # OverDrive API account ID + 'get-token' => \$get_token, # generate basic client token + 'key=s' => \$client_key, # OverDrive client key + 'secret=s' => \$client_secret, # OverDrive client secret + 'token=s' => \$basic_token, # basic client token for OAuth requests + 'endpoint=s' => \$api_endpoint, # main API endpoint + 'content=s' => \$content, # main request content (optional) + 'oauth-endpoint=s' => \$oauth_endpoint, # API endpoint for OAuth requests + 'oauth-only' => \$oauth_only, # only attempt OAuth request, then stop + 'patron-auth' => \$patron_auth, # perform patron authentication + 'barcode=s' => \$barcode, # patron barcode + 'password=s' => \$password, # patron password + 'websiteid=s' => \$websiteid, # OverDrive website ID + 'authorizationname=s' => \$authorizationname, # OverDrive ILS name + 'verbose' => \$verbose, # verbose output + 'help' => \$help # show help message and exit +); + +if ($help) { + print <<"HELP"; +USAGE: + $0 --get-token --key --secret + $0 --account --token [ --endpoint https://api.overdrive.com/v1/libraries/1234 [ --content ] ] + $0 --account --token --oauth-only + $0 --account --token --patron-auth [ --endpoint https://oauth-patron.overdrive.com/patrontoken ] --barcode [ --password ] --websiteid --authorizationname + +OPTIONS: + --get-token + Generate OverDrive API basic token. + --key + Client key supplied by OverDrive. Required with --get-token. + --secret + Client secret supplied by OverDrive. Required with --get-token. + --token + Your OverDrive API basic token (clientKey:clientSecret, Base64-encoded). + Required unless using --get-token. + --account + Your OverDrive API account ID (e.g. 1234). Not required for generating + a basic token; required for everything else. + --oauth-endpoint + OverDrive API endpoint for OAuth token requests. + Default: https://oauth.overdrive.com/token. + --endpoint + OverDrive API endpoint that you wish to test. + Default: https://api.overdrive.com/v1/libraries/ + --content + JSON content of main API request. Required only if you have specified + an endpoint that expects JSON message content. + --oauth-only + Only request an OAuth token; do not attempt further API requests. + --patron-auth + Submit a patron authentication request. + --barcode + Patron barcode. Required with --patron-auth. + --password + Patron password. Required with --patron-auth if your library requires + password for patron authentication. + --websiteid + Website ID supplied by OverDrive. Required with --patron-auth. + --authorizationname + ILS name supplied by OverDrive. Required with --patron-auth. + --verbose + Print full HTTP requests and responses. + --help + Print this help message. + +EXAMPLES: + + To generate your basic token, given a client key and client secret supplied + by OverDrive: + + $0 --get-token --key --secret + + To send a basic API request (this is useful for validating your client + credentials and determining whether the OverDrive API is currently + available): + + $0 --account --token + + To send a request to a specific API endpoint: + + $0 --account --token \ + --endpoint --content + + To test OverDrive API authentication for a specific patron: + + $0 --account --token \ + --patron-auth --barcode --password \ + --websiteid --authorizationname + +HELP + exit; +} + +if ($get_token) { + die "No client key provided" unless ($client_key); + die "No client secret provided" unless ($client_secret); + $basic_token = encode_base64("$client_key:$client_secret"); + print "Your basic token is: $basic_token\n"; + exit unless ($api_endpoint || $oauth_only || $patron_auth); +} + +die "No basic token provided" unless ($basic_token); +die "No account ID provided" unless ($account_id); + +my $ua = new LWP::UserAgent; + +# First, we use our basic token to request an access (bearer) token from the OAuth endpoint. + +if (!$patron_auth) { + + # construct the HTTP request + my $auth_req = HTTP::Request->new( POST => $oauth_endpoint ); + $auth_req->header('Authorization' => "Basic $basic_token"); + $auth_req->content_type('application/x-www-form-urlencoded;charset=UTF-8'); + $auth_req->content('grant_type=client_credentials'); + + # send the request and handle the response + my $auth_resp = $ua->request($auth_req); + if (!$auth_resp->is_success) { + die "Error on auth request: " . $auth_resp->status_line . "\n"; + } + $auth_content = decode_json($auth_resp->decoded_content); + $authtoken = $auth_content->{access_token}; + + print "$authtoken\n" if ($oauth_only || $verbose); + exit if ($oauth_only); + sleep 1; +} + +# Now that we have our bearer token, we can make our main API request. +if (!$api_endpoint) { + if ($patron_auth) { + $api_endpoint = "https://oauth-patron.overdrive.com/patrontoken"; + } else { + $api_endpoint = "https://api.overdrive.com/v1/libraries/$account_id"; + } +} + +# Determine method and initialize HTTP request object +my $method = ($patron_auth) ? 'POST' : 'GET'; +my $api_req = HTTP::Request->new( $method => $api_endpoint ); + +# Flesh out our request. +if ($patron_auth) { + $api_req->header('Authorization' => "Basic $basic_token"); + $api_req->content_type("application/x-www-form-urlencoded;charset=UTF-8"); + if ($password) { + $api_req->content("grant_type=password&username=$barcode&password=$password&scope=websiteid:$websiteid authorizationname:$authorizationname"); + } else { + $api_req->content("grant_type=password&username=$barcode&password=1234&password_required=false&scope=websiteid:$websiteid authorizationname:$authorizationname"); + } +} else { + $api_req->header('Authorization' => "bearer $authtoken"); + $api_req->content_type('application/json'); + $api_req->content($content) if ($content); +} +print Dumper $api_req if ($verbose); + +# Send API request and handle response. +my $api_resp = $ua->request($api_req); +if (!$api_resp->is_success) { + print "Error on API request: " . $api_resp->status_line . "\n"; + print Dumper $api_resp if ($verbose); + die; +} +print "Success: " . $api_resp->status_line . "\n"; +print $api_resp->decoded_content . "\n" if ($verbose); + -- 2.43.2