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