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