summaryrefslogtreecommitdiffstats
path: root/application/controllers/CertificatesController.php
blob: c145b03ab3bb1ee1e59054ae4f2c98b360b667fb (plain)
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
<?php
// Icinga Web 2 X.509 Module | (c) 2018 Icinga GmbH | GPLv2

namespace Icinga\Module\X509\Controllers;

use Icinga\Data\Filter\FilterExpression;
use Icinga\Exception\ConfigurationError;
use Icinga\Module\X509\CertificatesTable;
use Icinga\Module\X509\Controller;
use Icinga\Module\X509\FilterAdapter;
use Icinga\Module\X509\SortAdapter;
use Icinga\Module\X509\SqlFilter;
use ipl\Web\Control\PaginationControl;
use ipl\Sql;
use ipl\Web\Url;

class CertificatesController extends Controller
{
    public function indexAction()
    {
        $this
            ->initTabs()
            ->setTitle($this->translate('Certificates'));

        try {
            $conn = $this->getDb();
        } catch (ConfigurationError $_) {
            $this->render('missing-resource', null, true);
            return;
        }

        $select = (new Sql\Select())
            ->from('x509_certificate c')
            ->columns([
                'c.id', 'c.subject', 'c.issuer', 'c.version', 'c.self_signed', 'c.ca', 'c.trusted',
                'c.pubkey_algo',  'c.pubkey_bits', 'c.signature_algo', 'c.signature_hash_algo',
                'c.valid_from', 'c.valid_to',
            ]);

        $this->view->paginator = new PaginationControl(new Sql\Cursor($conn, $select), Url::fromRequest());
        $this->view->paginator->apply();

        $sortAndFilterColumns = [
            'subject' => $this->translate('Certificate'),
            'issuer' => $this->translate('Issuer'),
            'version' => $this->translate('Version'),
            'self_signed' => $this->translate('Is Self-Signed'),
            'ca' => $this->translate('Is Certificate Authority'),
            'trusted' => $this->translate('Is Trusted'),
            'pubkey_algo' => $this->translate('Public Key Algorithm'),
            'pubkey_bits' => $this->translate('Public Key Strength'),
            'signature_algo' => $this->translate('Signature Algorithm'),
            'signature_hash_algo' => $this->translate('Signature Hash Algorithm'),
            'valid_from' => $this->translate('Valid From'),
            'valid_to' => $this->translate('Valid To'),
            'duration' => $this->translate('Duration'),
            'expires' => $this->translate('Expiration')
        ];

        $this->setupSortControl(
            $sortAndFilterColumns,
            new SortAdapter($select, function ($field) {
                if ($field === 'duration') {
                    return '(valid_to - valid_from)';
                } elseif ($field === 'expires') {
                    return 'CASE WHEN UNIX_TIMESTAMP() > valid_to'
                        . ' THEN 0 ELSE (valid_to - UNIX_TIMESTAMP()) / 86400 END';
                }
            })
        );

        $this->setupLimitControl();

        $filterAdapter = new FilterAdapter();
        $this->setupFilterControl(
            $filterAdapter,
            $sortAndFilterColumns,
            ['subject', 'issuer'],
            ['format']
        );
        SqlFilter::apply($select, $filterAdapter->getFilter(), function (FilterExpression $filter) {
            switch ($filter->getColumn()) {
                case 'issuer_hash':
                    $value = $filter->getExpression();

                    if (is_array($value)) {
                        $value = array_map('hex2bin', $value);
                    } else {
                        $value = hex2bin($value);
                    }

                    return $filter->setExpression($value);
                case 'duration':
                    return $filter->setColumn('(valid_to - valid_from)');
                case 'expires':
                    return $filter->setColumn(
                        'CASE WHEN UNIX_TIMESTAMP() > valid_to THEN 0 ELSE (valid_to - UNIX_TIMESTAMP()) / 86400 END'
                    );
                case 'valid_from':
                case 'valid_to':
                    $expr = $filter->getExpression();
                    if (! is_numeric($expr)) {
                        return $filter->setExpression(strtotime($expr));
                    }

                    // expression doesn't need changing
                default:
                    return false;
            }
        });

        $this->handleFormatRequest($conn, $select, function (\PDOStatement $stmt) {
            foreach ($stmt as $cert) {
                $cert['valid_from'] = (new \DateTime())
                    ->setTimestamp($cert['valid_from'])
                    ->format('l F jS, Y H:i:s e');
                $cert['valid_to'] = (new \DateTime())
                    ->setTimestamp($cert['valid_to'])
                    ->format('l F jS, Y H:i:s e');

                yield $cert;
            }
        });

        $this->view->certificatesTable = (new CertificatesTable())->setData($conn->select($select));
    }
}