Passed
Pull Request — master (#2)
by Tim
07:11
created

Logpeek::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 7
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\logpeek\Controller;
6
7
use Exception;
8
use SimpleSAML\Assert\Assert;
9
use SimpleSAML\Configuration;
10
use SimpleSAML\Module\logpeek\File;
11
use SimpleSAML\Module\logpeek\Syslog;
12
use SimpleSAML\Session;
13
use SimpleSAML\Utils;
14
use SimpleSAML\XHTML\Template;
15
use Symfony\Component\HttpFoundation\Request;
16
17
use function array_reverse;
18
use function intval;
19
use function count;
20
use function date;
21
use function preg_match;
22
use function strstr;
23
24
/**
25
 * Controller class for the logpeek module.
26
 *
27
 * This class serves the different views available in the module.
28
 *
29
 * @package simplesamlphp/simplesamlphp-module-logpeek
30
 */
31
class Logpeek
32
{
33
    /** @var \SimpleSAML\Configuration */
34
    protected Configuration $config;
35
36
    /** @var \SimpleSAML\Configuration */
37
    protected Configuration $moduleConfig;
38
39
    /** @var \SimpleSAML\Session */
40
    protected Session $session;
41
42
    /** @var \SimpleSAML\Utils\Auth */
43
    protected $authUtils;
44
45
46
    /**
47
     * Controller constructor.
48
     *
49
     * It initializes the global configuration and session for the controllers implemented here.
50
     *
51
     * @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
52
     * @param \SimpleSAML\Session $session The session to use by the controllers.
53
     *
54
     * @throws \Exception
55
     */
56
    public function __construct(
57
        Configuration $config,
58
        Session $session
59
    ) {
60
        $this->config = $config;
61
        $this->moduleConfig = Configuration::getConfig('module_logpeek.php');
62
        $this->session = $session;
63
    }
64
65
66
    /**
67
     * Inject the \SimpleSAML\Utils\Auth dependency.
68
     *
69
     * @param \SimpleSAML\Utils\Auth $authUtils
70
     */
71
    public function setAuthUtils(Utils\Auth $authUtils): void
72
    {
73
        $this->authUtils = $authUtils;
74
    }
75
76
77
    /**
78
     * Main index controller.
79
     *
80
     * @param \Symfony\Component\HttpFoundation\Request $request The current request.
81
     *
82
     * @return \SimpleSAML\XHTML\Template
83
     */
84
    public function main(Request $request): Template
85
    {
86
        $this->authUtils::requireAdmin();
0 ignored issues
show
Bug Best Practice introduced by
The method SimpleSAML\Utils\Auth::requireAdmin() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

86
        $this->authUtils::/** @scrutinizer ignore-call */ 
87
                          requireAdmin();
Loading history...
87
88
        $logfile = $this->moduleConfig->getValue('logfile', '/var/log/simplesamlphp.log');
89
        $blockSize = $this->moduleConfig->getValue('blocksz', 8192);
90
91
        $myLog = new File\ReverseRead($logfile, $blockSize);
92
93
        $results = [];
94
        if ($request->query->has('tag') === true) {
95
            /** @psalm-var string $tag */
96
            $tag = $request->query->get('tag');
97
            Assert::notNull($tag);
98
99
            $results = $this->logFilter($myLog, $tag, $this->moduleConfig->getValue('lines', 500));
100
        }
101
102
        $fileModYear = intval(date("Y", $myLog->getFileMtime()));
103
        $firstLine = $myLog->getFirstLine();
104
        $firstTimeEpoch = Syslog\ParseLine::getUnixTime($firstLine ?: '', $fileModYear);
105
        $lastLine = $myLog->getLastLine();
106
        $lastTimeEpoch = Syslog\ParseLine::getUnixTime($lastLine ?: '', $fileModYear);
107
        $fileSize = $myLog->getFileSize();
108
109
        $t = new Template($this->config, 'logpeek:logpeek.twig');
110
        $t->data['results'] = $results;
111
        $t->data['trackid'] = $this->session->getTrackID();
112
        $t->data['timestart'] = date(DATE_RFC822, $firstTimeEpoch ?: time());
113
        $t->data['endtime'] = date(DATE_RFC822, $lastTimeEpoch ?: time());
114
        $t->data['filesize'] = $fileSize;
115
116
        return $t;
117
    }
118
119
120
    /**
121
     * @param \SimpleSAML\Module\logpeek\File\ReverseRead $objFile
122
     * @param string $tag
123
     * @param int $cut
124
     * @return array
125
     */
126
    private function logFilter(File\ReverseRead $objFile, string $tag, int $cut): array
127
    {
128
        if (!preg_match('/^[a-f0-9]{10}$/D', $tag)) {
129
            throw new Exception('Invalid search tag');
130
        }
131
132
        $i = 0;
133
        $results = [];
134
        $line = $objFile->getPreviousLine();
135
        while ($line !== false && ($i++ < $cut)) {
136
            if (strstr($line, '[' . $tag . ']')) {
137
                $results[] = $line;
138
            }
139
            $line = $objFile->getPreviousLine();
140
        }
141
142
        $results[] = 'Searched ' . $i . ' lines backward. ' . count($results) . ' lines found.';
143
        $results = array_reverse($results);
144
        return $results;
145
    }
146
}
147