File Coverage

blib/lib/EWS/Client.pm
Criterion Covered Total %
statement 25 47 53.1
branch 0 14 0.0
condition 0 3 0.0
subroutine 9 15 60.0
pod n/a
total 34 79 43.0


line stmt bran cond sub pod time code
1             package EWS::Client;
2             BEGIN {
3 1     1   17137 $EWS::Client::VERSION = '1.200001';
4             }
5 1     1   490 use Moose;
  1         411664  
  1         10  
6              
7             with qw/
8             EWS::Client::Role::SOAP
9             EWS::Client::Role::GetItem
10             EWS::Client::Role::FindItem
11             EWS::Client::Role::FindFolder
12             EWS::Client::Role::GetFolder
13             EWS::Client::Role::ExpandDL
14             /;
15 1     1   7369 use EWS::Client::Contacts;
  1         3  
  1         65  
16 1     1   606 use EWS::Client::Calendar;
  1         3  
  1         46  
17 1     1   682 use EWS::Client::Folder;
  1         3  
  1         34  
18 1     1   519 use EWS::Client::DistributionList;
  1         3  
  1         38  
19 1     1   576 use URI::Escape ();
  1         1112  
  1         25  
20 1     1   505 use Log::Report;
  1         65941  
  1         5  
21              
22             has username => (
23             is => 'rw',
24             isa => 'Str',
25             required => 1,
26             );
27              
28             has password => (
29             is => 'rw',
30             isa => 'Str',
31             required => 1,
32             );
33              
34             has server => (
35             is => 'ro',
36             isa => 'Str',
37             required => 1,
38             );
39              
40             has contacts => (
41             is => 'ro',
42             isa => 'EWS::Client::Contacts',
43             lazy_build => 1,
44             );
45              
46             sub _build_contacts {
47 0     0     my $self = shift;
48 0           return EWS::Client::Contacts->new({ client => $self });
49             }
50              
51             has calendar => (
52             is => 'ro',
53             isa => 'EWS::Client::Calendar',
54             lazy_build => 1,
55             );
56              
57             sub _build_calendar {
58 0     0     my $self = shift;
59 0           return EWS::Client::Calendar->new({ client => $self });
60             }
61              
62             has folders => (
63             is => 'ro',
64             isa => 'EWS::Client::Folder',
65             lazy_build => 1,
66             );
67              
68             sub _build_folders {
69 0     0     my $self = shift;
70 0           return EWS::Client::Folder->new({ client => $self });
71             }
72              
73             has distribution_list => (
74             is => 'ro',
75             isa => 'EWS::Client::DistributionList',
76             lazy_build => 1,
77             );
78              
79             sub _build_distribution_list {
80 0     0     my $self = shift;
81 0           return EWS::Client::DistributionList->new({ client => $self });
82             }
83              
84             sub BUILDARGS {
85 0     0     my ($class, @rest) = @_;
86 0 0         my $params = (scalar @rest == 1 ? $rest[0] : {@rest});
87              
88             # collect EWS password from environment as last resort
89 0   0       $params->{password} ||= $ENV{EWS_PASS};
90              
91 0           return $params;
92             }
93              
94             sub BUILD {
95 0     0     my ($self, $params) = @_;
96              
97 0 0         if ($self->use_negotiated_auth) {
98             die "please install LWP::Authen::Ntlm"
99 0 0         unless eval { require LWP::Authen::Ntlm && $LWP::Authen::Ntlm::VERSION };
  0 0          
100             die "please install Authen::NTLM"
101 0 0         unless eval { require Authen::NTLM && $Authen::NTLM::VERSION };
  0 0          
102              
103             # change email style username to win-domain style
104 0 0         if ($self->username =~ m/(.+)@(.+)/) {
105 0           $self->username( $2 .'\\'. $1 );
106             }
107             }
108             else {
109             # URI escape the username and password
110 0           $self->password( URI::Escape::uri_escape($self->password) );
111 0           $self->username( URI::Escape::uri_escape($self->username) );
112             }
113             }
114              
115             __PACKAGE__->meta->make_immutable;
116 1     1   530 no Moose;
  1         2  
  1         7  
117             1;
118              
119             =head1 NAME
120              
121             EWS::Client - Microsoft Exchange Web Services Client
122              
123             =head1 SYNOPSIS
124              
125             Set up your Exchange Web Services client.
126              
127             use EWS::Client;
128             use DateTime;
129            
130             my $ews = EWS::Client->new({
131             server => 'exchangeserver.example.com',
132             username => 'oliver',
133             password => 's3krit', # or set in $ENV{EWS_PASS}
134             });
135              
136             Then perform operations on the Exchange server:
137              
138             my $entries = $ews->calendar->retrieve({
139             start => DateTime->now(),
140             end => DateTime->now->add( months => 1 ),
141             });
142            
143             print "I retrieved ". $entries->count ." items\n";
144            
145             while ($entries->has_next) {
146             print $entries->next->Subject, "\n";
147             }
148            
149             my $contacts = $ews->contacts->retrieve;
150              
151             =head1 DESCRIPTION
152              
153             This module acts as a client to the Microsoft Exchange Web Services API. From
154             here you can access calendar and contact entries in a nicely abstracted
155             fashion. Query results are generally available in an iterator and convenience
156             methods exist to access the properties of each entry.
157              
158             =head1 AUTHENTICATION
159              
160             Depending on the configuration of the Microsoft Exchange server, you can use
161             either HTTP Basic Access Auth, or NTLM Negotiated Auth, from this module. The
162             default is HTTP Basic Access Auth, so if using NTLM, the following additional
163             option to C<new()> is required:
164              
165             use_negotiated_auth => 1,
166              
167             =head1 METHODS
168              
169             =head2 EWS::Client->new( \%arguments )
170              
171             Instantiates a new EWS client. There won't be any connection to the server
172             until you call one of the calendar or contacts retrieval methods.
173              
174             =over 4
175              
176             =item C<server> => Fully Qualified Domain Name (required)
177              
178             The host name of the Exchange server to which the module should connect.
179              
180             =item C<username> => String (required)
181              
182             The account username under which the module will connect to Exchange.
183              
184             For Basic Access Auth this value will be URI encoded by the module, meaning
185             you don't have to worry about escaping any special characters. For NTLM
186             Negotiated Auth, pass a C<user@domain> format username and it will
187             automatically be converted into Windows' C<domain\user> format for you.
188              
189             =item C<password> => String OR via C<$ENV{EWS_PASS}> (required)
190              
191             The password of the account under which the module will connect to Exchange.
192              
193             For Basic Access Auth this value will be URI encoded by the module. You can
194             also provide the password via the C<EWS_PASS> environment variable.
195              
196             =item C<use_negotiated_auth> => True or False value
197              
198             The module will assume you wish to use HTTP Basic Access Auth, in which case
199             you should enable that in your Exchange server. However for negotiated methods
200             such as NTLM set this to a True value.
201              
202             =item C<schema_path> => String (optional)
203              
204             A folder on your file system which contains the WSDL and two further Schema
205             files (messages, and types) which describe the Exchange 2007 Web Services SOAP
206             API. They are shipped with this module so your providing this is optional.
207              
208             =item C<server_version> => String (optional)
209              
210             In each request to the server is specified the API version we expect to use.
211             By default this is set to C<Exchange2007_SP1> but you have the opportunity to
212             set it to C<Exchange2007> if you wish using this option.
213              
214             =back
215              
216             =head2 $ews->calendar()
217              
218             Retrieves the L<EWS::Client::Calendar> object which allows search and
219             retrieval of calendar entries and their various properties. See that linked
220             manual page for more details.
221              
222             =head2 $ews->contacts()
223              
224             Retrieves the L<EWS::Client::Contacts> object which allows retrieval of
225             contact entries and their telephone numbers. See that linked manual page for
226             more details.
227              
228             =head2 $ews->folders()
229              
230             Retrieves the L<EWS::Client::Folder> object which allows retrieval of
231             mailbox folder entries and their sizes. See that linked manual page for
232             more details.
233              
234             =head2 $ews->dls()
235              
236             Retrieves the L<EWS::Client::DistributionList> object which allows retrieval of
237             distribution list entries and their email addresses and names. See that linked
238             manual page for more details.
239              
240             =head1 KNOWN ISSUES
241              
242             =over 4
243              
244             =item * No handling of time zone information, sorry.
245              
246             =item * The C<SOAPAction> Header might be wrong for Exchange 2010.
247              
248             =back
249              
250             =head1 THANKS
251              
252             To Greg Shaw for sending patches for NTLM Authentication support and User
253             Impersonation.
254              
255             =head1 AUTHOR
256              
257             Oliver Gorwits <oliver@cpan.org>
258              
259             =head1 COPYRIGHT AND LICENSE
260              
261             This software is copyright (c) 2014 by University of Oxford.
262              
263             This is free software; you can redistribute it and/or modify it under
264             the same terms as the Perl 5 programming language system itself.
265              
266             =cut
267