File Coverage

blib/lib/Net/Duo/Admin.pm
Criterion Covered Total %
statement 57 58 98.2
branch 8 10 80.0
condition n/a
subroutine 12 12 100.0
pod 6 6 100.0
total 83 86 96.5


line stmt bran cond sub pod time code
1             # Perl interface for the Duo Admin API.
2             #
3             # This Perl module collection provides a Perl interface to the Admin API
4             # integration for the Duo multifactor authentication service
5             # (https://www.duosecurity.com/). It differs from the Perl API sample code in
6             # that it wraps all the returned data structures in objects with method calls,
7             # abstracts some of the API details, and throws rich exceptions rather than
8             # requiring the caller deal with JSON data structures directly.
9              
10             package Net::Duo::Admin 1.01;
11              
12 6     6   12402 use 5.014;
  6         23  
13 6     6   30 use strict;
  6         144  
  6         131  
14 6     6   27 use warnings;
  6         10  
  6         175  
15              
16 6     6   693 use parent qw(Net::Duo);
  6         296  
  6         32  
17              
18 6     6   4021 use Net::Duo::Admin::Integration;
  6         17  
  6         188  
19 6     6   652 use Net::Duo::Admin::User;
  6         12  
  6         3018  
20              
21             ##############################################################################
22             # Admin API methods
23             ##############################################################################
24              
25             # Retrieve all integrations associated with a Duo account.
26             #
27             # $self - The Net::Duo::Admin object
28             #
29             # Returns: List of Net::Duo::Admin::Integration objects
30             # Throws: Net::Duo::Exception on failure
31             sub integrations {
32 1     1 1 87 my ($self) = @_;
33              
34             # Make the Duo call and get the decoded result.
35 1         9 my $result = $self->call_json('GET', '/admin/v1/integrations');
36              
37             # Convert the returned integrations into Net::Duo::Admin::Integration
38             # objects.
39 1         2 my @integrations;
40 1         3 for my $integration (@{$result}) {
  1         4  
41 1         11 my $object = Net::Duo::Admin::Integration->new($self, $integration);
42 1         4 push(@integrations, $object);
43             }
44 1         7 return @integrations;
45             }
46              
47             # Retrieve logs of administrative actions. At most 1000 entries are returned,
48             # so the caller may need to call this repeatedly with different mintime
49             # parameters to retrieve all of the logs.
50             #
51             # $self - The Net::Duo::Admin object
52             # $mintime - Only return records with a timestamp after this (optional)
53             #
54             # Returns: A list of log entries, each of which is a hash reference with keys:
55             # timestamp - Time of event in seconds since epoch
56             # username - Admin username or API for changes via API
57             # action - The action taken
58             # object - The object on which the action was performed
59             # description - The details of what was changed
60             # Throws: Net::Duo::Exception on failure
61             sub logs_administrator {
62 2     2 1 14 my ($self, $mintime) = @_;
63              
64             # Make the Duo call and get the decoded result.
65 2 100       7 my $args = defined($mintime) ? { mintime => $mintime } : {};
66 2         5 my $uri = '/admin/v1/logs/administrator';
67 2         11 my $result = $self->call_json('GET', $uri, $args);
68              
69             # Return the result as a list.
70 2         5 return @{$result};
  2         10  
71             }
72              
73             # Retrieve authentication logs. At most 1000 entries are returned, so the
74             # caller may need to call this repeatedly with different mintime parameters to
75             # retrieve all of the logs.
76             #
77             # $self - The Net::Duo::Admin object
78             # $mintime - Only return records with a timestamp after this (optional)
79             #
80             # Returns: A list of log entries, each of which is a hash reference with keys:
81             # timestamp - Time of event in seconds since epoch
82             # username - The authenticating username
83             # factor - The authentication factor
84             # result - The result of the authentication
85             # ip - IP address from which the request originated
86             # integration - Integration name attempting the authentication
87             # Throws: Net::Duo::Exception on failure
88             sub logs_authentication {
89 2     2 1 12 my ($self, $mintime) = @_;
90              
91             # Make the Duo call and get the decoded result.
92 2 100       10 my $args = defined($mintime) ? { mintime => $mintime } : {};
93 2         5 my $uri = '/admin/v1/logs/authentication';
94 2         8 my $result = $self->call_json('GET', $uri, $args);
95              
96             # Return the result as a list.
97 2         4 return @{$result};
  2         11  
98             }
99              
100             # Retrieve telephony logs. At most 1000 entries are returned, so the caller
101             # may need to call this repeatedly with different mintime parameters to
102             # retrieve all of the logs.
103             #
104             # $self - The Net::Duo::Admin object
105             # $mintime - Only return records with a timestamp after this (optional)
106             #
107             # Returns: A list of log entries, each of which is a hash reference with keys:
108             # timestamp - Time of event in seconds since epoch
109             # context - How this telephony event was initiated
110             # type - The event type
111             # phone - The phone number for this event
112             # credits - How many telephony credits this event cost
113             # Throws: Net::Duo::Exception on failure
114             sub logs_telephony {
115 2     2 1 12 my ($self, $mintime) = @_;
116              
117             # Make the Duo call and get the decoded result.
118 2 100       8 my $args = defined($mintime) ? { mintime => $mintime } : {};
119 2         4 my $uri = '/admin/v1/logs/telephony';
120 2         7 my $result = $self->call_json('GET', $uri, $args);
121              
122             # Return the result as a list.
123 2         3 return @{$result};
  2         12  
124             }
125              
126             # Retrieve a single user by username. An empty reply indicates that no user
127             # by that username exists.
128             #
129             # $self - The Net::Duo::Admin object
130             # $username - Username whose record to retrieve
131             #
132             # Returns: A single Net::Duo::User object or undef
133             # Throws: Net::Duo::Exception on failure
134             sub user {
135 1     1 1 87 my ($self, $username) = @_;
136              
137             # Make the Duo call and get the decoded result.
138 1         4 my $args = { username => $username };
139 1         5 my $result = $self->call_json('GET', '/admin/v1/users', $args);
140              
141             # Convert the returned user into a Net::Duo::Admin::User object.
142 1 50       3 if (@{$result}) {
  1         4  
143 1         9 return Net::Duo::Admin::User->new($self, $result->[0]);
144             } else {
145 0         0 return;
146             }
147             }
148              
149             # Retrieve all users associated with a Duo account.
150             #
151             # $self - The Net::Duo::Admin object
152             # $username - Retrieve the record for only this user (optional)
153             #
154             # Returns: List of Net::Duo::User objects if no parameter is given
155             # A single Net::Duo::User object if $username is given and found
156             # undef if $username is given and not found
157             # Throws: Net::Duo::Exception on failure
158             sub users {
159 1     1 1 69 my ($self, $username) = @_;
160              
161             # Make the Duo call and get the decoded result.
162 1 50       4 my $args = $username ? { username => $username } : undef;
163 1         8 my $result = $self->call_json('GET', '/admin/v1/users', $args);
164              
165             # Convert the returned users into Net::Duo::Admin::User objects.
166 1         3 my @users;
167 1         2 for my $user (@{$result}) {
  1         3  
168 1         16 push(@users, Net::Duo::Admin::User->new($self, $user));
169             }
170 1         10 return @users;
171             }
172              
173             1;
174             __END__