File: DevOps.pm

package info (click to toggle)
lemonldap-ng 2.21.2%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 28,024 kB
  • sloc: perl: 77,414; javascript: 25,284; xml: 6,473; makefile: 1,303; sh: 453; sql: 159; python: 53; php: 26
file content (128 lines) | stat: -rw-r--r-- 4,296 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package Lemonldap::NG::Handler::Lib::DevOps;

use strict;
use Lemonldap::NG::Common::UserAgent;
use Lemonldap::NG::Common::Util qw(isHiddenAttr);
use JSON qw(from_json);

our $VERSION = '2.19.0';
our $_ua;

sub ua {
    my ($class) = @_;
    return $_ua if $_ua;
    $_ua = Lemonldap::NG::Common::UserAgent->new( {
            lwpOpts    => $class->tsv->{lwpOpts},
            lwpSslOpts => $class->tsv->{lwpSslOpts}
        }
    );
    return $_ua;
}

sub checkMaintenanceMode {
    my ( $class, $req ) = @_;
    my $vhost = $class->resolveAlias($req);

    unless ($vhost) {
        $class->logger->error('No VHost provided');
        return $class->Lemonldap::NG::Handler::Main::checkMaintenanceMode($req);
    }

    $class->logger->info("DevOps request from $vhost");
    $class->tsv->{lastVhostUpdate} //= {};
    $class->_loadVhostConfig( $req, $vhost )
      unless (
        $class->tsv->{defaultCondition}->{$vhost}
        and (
            time() - $class->tsv->{lastVhostUpdate}->{$vhost} <
            $class->checkTime )
      );

    return $class->Lemonldap::NG::Handler::Main::checkMaintenanceMode($req);
}

sub _loadVhostConfig {
    my ( $class, $req, $vhost ) = @_;
    my ( $json, $rUrl, $rVhost );
    if ( $class->tsv->{useSafeJail} ) {
        if ( $req->env->{RULES_URL} || $class->tsv->{devOpsRulesUrl}->{$vhost} )
        {
            $rUrl = $req->{env}->{RULES_URL}
              || $class->tsv->{devOpsRulesUrl}->{$vhost};
            $rVhost = ( $rUrl =~ m#^https?://([^/]*).*# )[0];
            $rVhost =~ s/:\d+$//;
        }
        else {
            $rUrl =
              ( $class->localConfig->{loopBackUrl}
                  || "http://127.0.0.1:" . $req->{env}->{SERVER_PORT} )
              . '/rules.json';
            $rVhost = $vhost;
        }

        $class->logger->debug("Try to retrieve rules file from $rUrl");
        my $get = HTTP::Request->new( GET => $rUrl );
        $class->logger->debug("Set Host header with $rVhost");
        $get->header( Host => $rVhost );
        my $resp = $class->ua->request($get);
        if ( $resp->is_success ) {
            $class->logger->debug('Response is success');
            eval { $json = from_json( $resp->content, { allow_nonref => 1 } ); };
            if ($@) {
                $class->logger->debug('Bad json file received');
                $class->logger->error(
"Bad rules file retrieved from $rUrl for $vhost, skipping ($@)"
                );
            }
            else {
                $class->logger->debug('Good json file received');
                $class->logger->info(
                    "Compiling rules retrieved from $rUrl for $vhost");
            }
        }
        else {
            $class->logger->error(
                "Unable to retrieve rules file from $rUrl -> "
                  . $resp->status_line );
            $class->logger->info("Default rule and header are employed");
        }
    }
    else {
        $class->logger->error(
q"I refuse to compile 'rules.json' when useSafeJail isn't activated! Yes I know, I'm a coward..."
        );
    }
    $json->{rules} ||= { default => 1 };
    $json->{headers} //= { 'Auth-User' => '$uid' };

    # Removed hidden session attributes
    foreach ( keys %{ $json->{headers} } ) {
        my $header = $json->{headers}->{$_};
        $header =~ s/^\$//;
        if ( isHiddenAttr( $class->localConfig, $header ) ) {
            delete $json->{headers}->{$_};
            $class->auditLog(
                $req,
                message => (
"DevOps handler: $vhost tried to retrieve a hidden attribute -> $header"
                ),
                code      => "HANDLER_DEVOPS_HIDDEN_ATTRIBUTE_REQUESTED",
                vhost     => $vhost,
                attribute => $header,
            );
        }
    }

    $class->logger->debug("DevOps handler called by $vhost");
    $class->locationRulesInit( undef, { $vhost => $json->{rules} } );
    $class->headersInit( undef, { $vhost => $json->{headers} } );
    $class->tsv->{lastVhostUpdate}->{$vhost} = time;
    $class->tsv->{https}->{$vhost} = uc $req->env->{HTTPS_REDIRECT} eq 'ON'
      if exists $req->env->{HTTPS_REDIRECT};
    $class->tsv->{port}->{$vhost} = $req->env->{PORT_REDIRECT}
      if exists $req->env->{PORT_REDIRECT};

    return;
}

1;