]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/support-scripts/overdrive-api-checker.pl
lp1863252 toward geosort
[Evergreen.git] / Open-ILS / src / support-scripts / overdrive-api-checker.pl
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use LWP::UserAgent;
6 use HTTP::Request;
7 use JSON;
8 use Getopt::Long;
9 use MIME::Base64;
10 use Data::Dumper;
11
12 my $account_id;
13 my ($basic_token, $get_token, $client_key, $client_secret);
14 my ($api_endpoint, $content);
15 my $oauth_endpoint = 'https://oauth.overdrive.com/token';
16 my $oauth_only; 
17 my ($patron_auth, $barcode, $password, $websiteid, $authorizationname); 
18 my ($verbose, $help);
19 my ($authtoken, $auth_content);
20
21 GetOptions(
22     'account=s'        => \$account_id,     # OverDrive API account ID
23     'get-token'        => \$get_token,      # generate basic client token
24     'key=s'            => \$client_key,     # OverDrive client key
25     'secret=s'         => \$client_secret,  # OverDrive client secret
26     'token=s'          => \$basic_token,    # basic client token for OAuth requests
27     'endpoint=s'       => \$api_endpoint,   # main API endpoint
28     'content=s'        => \$content,        # main request content (optional)
29     'oauth-endpoint=s' => \$oauth_endpoint, # API endpoint for OAuth requests
30     'oauth-only'       => \$oauth_only,     # only attempt OAuth request, then stop
31     'patron-auth'      => \$patron_auth,    # perform patron authentication
32     'barcode=s'        => \$barcode,        # patron barcode
33     'password=s'       => \$password,        # patron password
34     'websiteid=s'      => \$websiteid,      # OverDrive website ID
35     'authorizationname=s' => \$authorizationname, # OverDrive ILS name
36     'verbose'          => \$verbose,        # verbose output
37     'help'             => \$help            # show help message and exit
38 );
39
40 if ($help) {
41     print <<"HELP";
42 USAGE:
43     $0 --get-token --key <client-key> --secret <client-secret>
44     $0 --account <account_id> --token <basic_token> [ --endpoint https://api.overdrive.com/v1/libraries/1234 [ --content <content> ] ]
45     $0 --account <account_id> --token <basic_token> --oauth-only
46     $0 --account <account_id> --token <basic_token> --patron-auth [ --endpoint https://oauth-patron.overdrive.com/patrontoken ] --barcode <barcode> [ --password <password> ] --websiteid <websiteid> --authorizationname <authorizationname>
47
48 OPTIONS:
49     --get-token
50         Generate OverDrive API basic token.
51     --key
52         Client key supplied by OverDrive.  Required with --get-token.
53     --secret
54         Client secret supplied by OverDrive.  Required with --get-token.
55     --token
56         Your OverDrive API basic token (clientKey:clientSecret, Base64-encoded).
57         Required unless using --get-token.
58     --account
59         Your OverDrive API account ID (e.g. 1234).  Not required for generating
60         a basic token; required for everything else.
61     --oauth-endpoint
62         OverDrive API endpoint for OAuth token requests.
63         Default: https://oauth.overdrive.com/token.
64     --endpoint
65         OverDrive API endpoint that you wish to test.
66         Default: https://api.overdrive.com/v1/libraries/<account>
67     --content
68         JSON content of main API request.  Required only if you have specified
69         an endpoint that expects JSON message content.
70     --oauth-only
71         Only request an OAuth token; do not attempt further API requests.
72     --patron-auth
73         Submit a patron authentication request.
74     --barcode
75         Patron barcode.  Required with --patron-auth.
76     --password
77         Patron password.  Required with --patron-auth if your library requires
78         password for patron authentication.
79     --websiteid
80         Website ID supplied by OverDrive.  Required with --patron-auth.
81     --authorizationname
82         ILS name supplied by OverDrive.  Required with --patron-auth.
83     --verbose
84         Print full HTTP requests and responses.
85     --help
86         Print this help message.
87
88 EXAMPLES:
89
90     To generate your basic token, given a client key and client secret supplied
91     by OverDrive:
92
93     $0 --get-token --key <client-key> --secret <client-secret>
94
95     To send a basic API request (this is useful for validating your client
96     credentials and determining whether the OverDrive API is currently
97     available):
98
99     $0 --account <account_id> --token <basic_token>
100
101     To send a request to a specific API endpoint:
102
103     $0 --account <account_id> --token <basic_token> \
104     --endpoint <endpoint> --content <content>
105
106     To test OverDrive API authentication for a specific patron:
107
108     $0 --account <account_id> --token <basic_token> \
109     --patron-auth --barcode <barcode> --password <password> \
110     --websiteid <websiteid> --authorizationname <authorizationname>
111
112 HELP
113     exit;
114 }
115
116 if ($get_token) {
117     die "No client key provided" unless ($client_key);
118     die "No client secret provided" unless ($client_secret);
119     $basic_token = encode_base64("$client_key:$client_secret");
120     print "Your basic token is: $basic_token\n";
121     exit unless ($api_endpoint || $oauth_only || $patron_auth);
122 }
123
124 die "No basic token provided" unless ($basic_token);
125 die "No account ID provided" unless ($account_id);
126
127 my $ua = new LWP::UserAgent;
128
129 # First, we use our basic token to request an access (bearer) token from the OAuth endpoint.
130
131 if (!$patron_auth) {
132
133     # construct the HTTP request
134     my $auth_req = HTTP::Request->new( POST => $oauth_endpoint );
135     $auth_req->header('Authorization' => "Basic $basic_token");
136     $auth_req->content_type('application/x-www-form-urlencoded;charset=UTF-8');
137     $auth_req->content('grant_type=client_credentials');
138
139     # send the request and handle the response
140     my $auth_resp = $ua->request($auth_req);
141     if (!$auth_resp->is_success) {
142         die "Error on auth request: " . $auth_resp->status_line . "\n";
143     }
144     $auth_content = decode_json($auth_resp->decoded_content);
145     $authtoken = $auth_content->{access_token};
146
147     print "$authtoken\n" if ($oauth_only || $verbose);
148     exit if ($oauth_only);
149     sleep 1;
150 }
151
152 # Now that we have our bearer token, we can make our main API request.
153 if (!$api_endpoint) {
154     if ($patron_auth) {
155         $api_endpoint = "https://oauth-patron.overdrive.com/patrontoken";
156     } else {
157         $api_endpoint = "https://api.overdrive.com/v1/libraries/$account_id";
158     }
159 }
160
161 # Determine method and initialize HTTP request object
162 my $method = ($patron_auth) ? 'POST' : 'GET';
163 my $api_req = HTTP::Request->new( $method => $api_endpoint );
164
165 # Flesh out our request.
166 if ($patron_auth) {
167     $api_req->header('Authorization' => "Basic $basic_token");
168     $api_req->content_type("application/x-www-form-urlencoded;charset=UTF-8");
169     if ($password) {
170         $api_req->content("grant_type=password&username=$barcode&password=$password&scope=websiteid:$websiteid authorizationname:$authorizationname");
171     } else {
172         $api_req->content("grant_type=password&username=$barcode&password=1234&password_required=false&scope=websiteid:$websiteid authorizationname:$authorizationname");
173     }
174 } else {
175     $api_req->header('Authorization' => "bearer $authtoken");
176     $api_req->content_type('application/json');
177     $api_req->content($content) if ($content);
178 }
179 print Dumper $api_req if ($verbose);
180
181 # Send API request and handle response.
182 my $api_resp = $ua->request($api_req);
183 if (!$api_resp->is_success) {
184     print "Error on API request: " . $api_resp->status_line . "\n";
185     print Dumper $api_resp if ($verbose);
186     die;
187 }
188 print "Success: " . $api_resp->status_line . "\n";
189 print $api_resp->decoded_content . "\n" if ($verbose);
190