File Coverage

blib/lib/Lemonldap/NG/Handler/Specific/ZimbraPreAuth.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             ##@file
2             # Zimbra preauthentication
3              
4             ##@class
5             # Zimbra preauthentication
6             #
7             # It will build Zimbra preauth URL
8              
9             # This specific handler is intended to be called directly by Apache
10              
11             package Lemonldap::NG::Handler::Specific::ZimbraPreAuth;
12              
13 1     1   6891 use strict;
  1         2  
  1         34  
14 1     1   470 use Lemonldap::NG::Handler::SharedConf qw(:all);
  0            
  0            
15             use base qw(Lemonldap::NG::Handler::SharedConf);
16             use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
17             use Lemonldap::NG::Handler::Main::Headers;
18             use Lemonldap::NG::Handler::Main::Logger;
19              
20             our $VERSION = '1.0.0';
21              
22             # Shared variables
23             our ( $zimbraPreAuthKey, $zimbraAccountKey, $zimbraBy, $zimbraUrl,
24             $zimbraSsoUrl, $timeout );
25              
26             ## @imethod protected void globalInit(hashRef args)
27             # Overload globalInit to launch this class defaultValuesInit
28             # @param $args reference to the configuration hash
29             sub globalInit {
30             my $class = shift;
31             __PACKAGE__->defaultValuesInit(@_);
32             $class->SUPER::globalInit(@_);
33             }
34              
35             ## @imethod protected void defaultValuesInit(hashRef args)
36             # Overload defaultValuesInit
37             # @param $args reference to the configuration hash
38             sub defaultValuesInit {
39             my ( $class, $args ) = splice @_;
40              
41             # Catch Zimbra parameters
42             $zimbraPreAuthKey = $args->{'zimbraPreAuthKey'} || $zimbraPreAuthKey;
43             $zimbraAccountKey =
44             $args->{'zimbraAccountKey'}
45             || $zimbraAccountKey
46             || 'uid';
47             $zimbraBy = $args->{'zimbraBy'} || $zimbraBy || 'id';
48             $zimbraUrl = $args->{'zimbraUrl'} || $zimbraUrl || '/service/preauth';
49             $zimbraSsoUrl = $args->{'zimbraSsoUrl'} || $zimbraSsoUrl || '^/zimbrasso$';
50             $timeout = $args->{'timeout'} || $timeout || '0';
51              
52             # Display found values in debug mode
53             Lemonldap::NG::Handler::Main::Logger->lmLog(
54             "zimbraPreAuthKey: $zimbraPreAuthKey", 'debug' );
55             Lemonldap::NG::Handler::Main::Logger->lmLog(
56             "zimbraAccountKey: $zimbraAccountKey", 'debug' );
57             Lemonldap::NG::Handler::Main::Logger->lmLog( "zimbraBy: $zimbraBy",
58             'debug' );
59             Lemonldap::NG::Handler::Main::Logger->lmLog( "zimbraUrl: $zimbraUrl",
60             'debug' );
61             Lemonldap::NG::Handler::Main::Logger->lmLog( "zimbraSsoUrl: $zimbraSsoUrl",
62             'debug' );
63             Lemonldap::NG::Handler::Main::Logger->lmLog( "timeout: $timeout", 'debug' );
64              
65             # Delete Zimbra parameters
66             delete $args->{'zimbraPreAuthKey'};
67             delete $args->{'zimbraAccountKey'};
68             delete $args->{'zimbraBy'};
69             delete $args->{'zimbraUrl'};
70             delete $args->{'zimbraSsoUrl'};
71             delete $args->{'timeout'};
72              
73             # Call main subroutine
74             return $class->SUPER::defaultValuesInit($args);
75             }
76              
77             ## @rmethod Apache2::Const run(Apache2::RequestRec r)
78             # Overload main run method
79             # @param r Current request
80             # @return Apache2::Const value (OK, FORBIDDEN, REDIRECT or SERVER_ERROR)
81             sub run {
82             my $class = shift;
83             my $r = $_[0];
84             my $ret = $class->SUPER::run(@_);
85              
86             # Continue only if user is authorized
87             return $ret unless ( $ret == OK );
88              
89             # Get current URI
90             my $args = $r->args;
91             my $uri = $r->uri . ( $args ? "?$args" : "" );
92              
93             # Return if we are not on a Zimbra SSO URI
94             return OK unless ( $uri =~ $zimbraSsoUrl );
95              
96             # Check mandatory parameters
97             return $class->abort("No Zimbra preauth key configured")
98             unless ($zimbraPreAuthKey);
99              
100             # Build URL
101             my $zimbra_url = $class->_buildZimbraPreAuthUrl(
102             $zimbraPreAuthKey, $zimbraUrl,
103             $datas->{$zimbraAccountKey}, $zimbraBy
104             );
105              
106             # Header location
107             Lemonldap::NG::Handler::Main::Headers->lmSetHeaderOut( $r,
108             'Location' => $zimbra_url );
109              
110             # Return REDIRECT
111             return REDIRECT;
112             }
113              
114             ## @method private string _buildZimbraPreAuthUrl(string key, string url, string account, string by)
115             # Build Zimbra PreAuth URL
116             # @param key PreAuthKey
117             # @param url URL
118             # @param account User account
119             # @param by Account type
120             # @return Zimbra PreAuth URL
121             sub _buildZimbraPreAuthUrl {
122             my ( $class, $key, $url, $account, $by ) = splice @_;
123              
124             # Expiration time is calculated with _utime and timeout
125             my $expires = $timeout ? ( $datas->{_utime} + $timeout ) * 1000 : $timeout;
126              
127             # Timestamp
128             my $timestamp = time() * 1000;
129              
130             # Compute preauth value
131             my $computed_value =
132             hmac_sha1_hex( "$account|$by|$expires|$timestamp", $key );
133              
134             Lemonldap::NG::Handler::Main::Logger->lmLog(
135             "Compute value $account|$by|$expires|$timestamp into $computed_value",
136             'debug' );
137              
138             # Build PreAuth URL
139             my $zimbra_url =
140             "$url?account=$account&by=$by×tamp=$timestamp&expires=$expires&preauth=$computed_value";
141              
142             Lemonldap::NG::Handler::Main::Logger->lmLog(
143             "Build Zimbra URL: $zimbra_url", 'debug' );
144              
145             return $zimbra_url;
146             }
147              
148             __PACKAGE__->init( {} );
149              
150             1;
151              
152             __END__