Passed
Pull Request — master (#3)
by Tim
02:48
created

Logpeek::setModuleConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
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\Config;
11
use SimpleSAML\Module\logpeek\File;
12
use SimpleSAML\Module\logpeek\Syslog;
13
use SimpleSAML\Session;
14
use SimpleSAML\Utils;
15
use SimpleSAML\XHTML\Template;
16
use Symfony\Component\HttpFoundation\Request;
17
18
use function array_reverse;
19
use function intval;
20
use function count;
21
use function date;
22
use function preg_match;
23
use function strstr;
24
25
/**
26
 * Controller class for the logpeek module.
27
 *
28
 * This class serves the different views available in the module.
29
 *
30
 * @package simplesamlphp/simplesamlphp-module-logpeek
31
 */
32
class Logpeek
33
{
34
    /** @var \SimpleSAML\Configuration */
35
    protected Configuration $config;
36
37
    /** @var \SimpleSAML\Module\logpeek\Config\Logpeek */
38
    protected Config\Logpeek $moduleConfig;
39
40
    /** @var \SimpleSAML\Session */
41
    protected Session $session;
42
43
    /** @var \SimpleSAML\Utils\Auth */
44
    protected $authUtils;
45
46
47
    /**
48
     * Controller constructor.
49
     *
50
     * It initializes the global configuration and session for the controllers implemented here.
51
     *
52
     * @param \SimpleSAML\Configuration $config The configuration to use by the controllers.
53
     * @param \SimpleSAML\Session $session The session to use by the controllers.
54
     * @param \SimpleSAML\Module\logpeek\Config\Logpeek $moduleConfig The configuration for this module
55
     *
56
     * @throws \Exception
57
     */
58
    public function __construct(
59
        Configuration $config,
60
        Session $session,
61
        Config\Logpeek $moduleConfig
0 ignored issues
show
Unused Code introduced by
The parameter $moduleConfig is not used and could be removed. ( Ignorable by Annotation )

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

61
        /** @scrutinizer ignore-unused */ Config\Logpeek $moduleConfig

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
62
    ) {
63
        $this->authUtils = new Utils\Auth();
64
        $this->config = $config;
65
        $this->moduleConfig = Config\Logpeek::fromYaml();
66
        $this->session = $session;
67
    }
68
69
70
    /**
71
     * Inject the \SimpleSAML\Utils\Auth dependency.
72
     *
73
     * @param \SimpleSAML\Utils\Auth $authUtils
74
     */
75
    public function setAuthUtils(Utils\Auth $authUtils): void
76
    {
77
        $this->authUtils = $authUtils;
78
    }
79
80
81
    /**
82
     * Inject the \SimpleSAML\Module\logpeek\Config\Logpeek dependency.
83
     *
84
     * @param \SimpleSAML\Module\logpeek\Config\Logpeek $moduleConfig
85
     */
86
    public function setModuleConfig(Config\Logpeek $moduleConfig): void
87
    {
88
        $this->moduleConfig = $moduleConfig;
89
    }
90
91
92
    /**
93
     * Main index controller.
94
     *
95
     * @param \Symfony\Component\HttpFoundation\Request $request The current request.
96
     *
97
     * @return \SimpleSAML\XHTML\Template
98
     */
99
    public function main(Request $request): Template
100
    {
101
        $this->authUtils->requireAdmin();
102
103
        $logFile = $this->moduleConfig->getLogFile();
104
        $blockSize = $this->moduleConfig->getBlockSize();
105
        $myLog = new File\ReverseRead($logFile, $blockSize);
106
107
        $results = [];
108
        if ($request->query->has('tag') === true) {
109
            /** @psalm-var string $tag */
110
            $tag = $request->query->get('tag');
111
            Assert::notNull($tag);
112
113
            $results = $this->logFilter($myLog, $tag, $this->moduleConfig->getLines());
114
        }
115
116
        $fileModYear = intval(date("Y", $myLog->getFileMtime()));
117
        $firstLine = $myLog->getFirstLine();
118
        $firstTimeEpoch = Syslog\ParseLine::getUnixTime($firstLine ?: '', $fileModYear);
119
        $lastLine = $myLog->getLastLine();
120
        $lastTimeEpoch = Syslog\ParseLine::getUnixTime($lastLine ?: '', $fileModYear);
121
        $fileSize = $myLog->getFileSize();
122
123
        $t = new Template($this->config, 'logpeek:logpeek.twig');
124
        $t->data['results'] = $results;
125
        $t->data['trackid'] = $this->session->getTrackID();
126
        $t->data['timestart'] = date(DATE_RFC822, $firstTimeEpoch ?: time());
127
        $t->data['endtime'] = date(DATE_RFC822, $lastTimeEpoch ?: time());
128
        $t->data['filesize'] = $fileSize;
129
130
        return $t;
131
    }
132
133
134
    /**
135
     * @param \SimpleSAML\Module\logpeek\File\ReverseRead $objFile
136
     * @param string $tag
137
     * @param int $cut
138
     * @return array
139
     */
140
    private function logFilter(File\ReverseRead $objFile, string $tag, int $cut): array
141
    {
142
        if (!preg_match('/^(TR[a-f0-9{8}]|CL[a-f0-9]{8}|[a-f0-9]{10})$/D', $tag)) {
143
            throw new Exception('Invalid search tag');
144
        }
145
146
        $i = 0;
147
        $results = [];
148
        $line = $objFile->getPreviousLine();
149
        while ($line !== false && ($i++ < $cut)) {
150
            if (strstr($line, '[' . $tag . ']')) {
151
                $results[] = $line;
152
            }
153
            $line = $objFile->getPreviousLine();
154
        }
155
156
        $results[] = 'Searched ' . $i . ' lines backward. ' . count($results) . ' lines found.';
157
        $results = array_reverse($results);
158
        return $results;
159
    }
160
}
161