forked from The-Shadowserver-Foundation/api_utils
-
Notifications
You must be signed in to change notification settings - Fork 0
/
call-api.pl
126 lines (95 loc) · 2.31 KB
/
call-api.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env perl
=head1 NAME
call-api.pl : Shadowserver Foundation API Utility
=head1 DESCRIPTION
This script requires your API details to be stored in ~/.shadowserver.api
with the following contents:
--
[api]
key = 123456798
secret = MySecret
uri = https://transform.shadowserver.org/api2/
--
This script may be called with two or three arguments:
call-api.pl <method> <request> [pretty|binary]
The request must be a valid JSON object.
Simple usage:
$ ./call-api.pl test/ping '{}'
{"pong":"2020-10-26 23:06:37"}
Pretty output:
$ ./call-api.pl test/ping '{}' pretty
{
"pong": "2020-10-26 23:06:42"
}
=cut
use Config::Simple;
use JSON;
use Digest::SHA qw(hmac_sha256_hex);
use LWP::UserAgent;
use HTTP::Request;
use URI;
use strict;
my $config = eval { new Config::Simple($ENV{'HOME'} . "/.shadowserver.api") };
my $TIMEOUT = 45;
=item api_call( $method, \%request )
Call the specified api method with a request dictionary.
=cut
sub api_call
{
my ($method, $request) = @_;
my $url = $config->param("api.uri") . $method;
$request->{'apikey'} = $config->param('api.key');
my $request_string = encode_json($request);
my $hmac2 = hmac_sha256_hex($request_string, $config->param('api.secret'));
my $ua = new LWP::UserAgent();
$ua->timeout($TIMEOUT);
my $ua_request = new HTTP::Request('POST', $url, [ 'HMAC2' => $hmac2 ] );
$ua_request->content($request_string);
my $response = $ua->request($ua_request);
return $response->content;
}
unless (caller) # main
{
if (scalar @ARGV < 2)
{
print STDERR "Usage: call-api.pl method json [pretty|binary]\n";
exit(1);
}
my $api_request = eval { decode_json($ARGV[1]) };
if ($@)
{
print STDERR "JSON Exception: $@\n";
exit(1);
}
if (!defined($config) || $config->param('api.key') eq '')
{
print STDERR "Exception: api.key not defined in " . $ENV{'HOME'}
. "/.shadowserver.api\n";
exit(1);
}
my $res = eval { api_call($ARGV[0], $api_request) };
if ($@)
{
print STDERR "API Exception: $@\n";
exit(1);
}
if (scalar @ARGV > 2)
{
if ($ARGV[2] eq "pretty")
{
eval { print to_json(decode_json($res), { pretty => 1}), "\n" };
exit(0) unless ($@);
}
elsif ($ARGV[2] eq "binary")
{
binmode(STDOUT);
write(STDOUT, $res);
exit(0);
}
else
{
die('Unknown option ' . $ARGV[2]);
}
}
print $res, "\n";
}