|
4 | 4 |
|
5 | 5 | namespace Icinga\Module\X509\Controllers; |
6 | 6 |
|
7 | | -use Icinga\Data\Filter\FilterExpression; |
8 | 7 | use Icinga\Exception\ConfigurationError; |
9 | 8 | use Icinga\Module\X509\CertificatesTable; |
10 | 9 | use Icinga\Module\X509\Controller; |
11 | | -use Icinga\Module\X509\FilterAdapter; |
12 | | -use Icinga\Module\X509\SortAdapter; |
13 | | -use Icinga\Module\X509\SqlFilter; |
14 | | -use ipl\Web\Control\PaginationControl; |
15 | | -use ipl\Sql; |
16 | | -use ipl\Web\Url; |
| 10 | +use Icinga\Module\X509\Model\X509Certificate; |
| 11 | +use Icinga\Module\X509\Web\Control\SearchBar\ObjectSuggestions; |
| 12 | +use ipl\Orm\Query; |
| 13 | +use ipl\Web\Control\LimitControl; |
| 14 | +use ipl\Web\Control\SortControl; |
17 | 15 |
|
18 | 16 | class CertificatesController extends Controller |
19 | 17 | { |
20 | 18 | public function indexAction() |
21 | 19 | { |
22 | | - $this |
23 | | - ->initTabs() |
24 | | - ->setTitle($this->translate('Certificates')); |
| 20 | + $this->addTitleTab($this->translate('Certificates')); |
| 21 | + $this->getTabs()->enableDataExports(); |
25 | 22 |
|
26 | 23 | try { |
27 | 24 | $conn = $this->getDb(); |
28 | 25 | } catch (ConfigurationError $_) { |
29 | 26 | $this->render('missing-resource', null, true); |
| 27 | + |
30 | 28 | return; |
31 | 29 | } |
32 | 30 |
|
33 | | - $select = (new Sql\Select()) |
34 | | - ->from('x509_certificate c') |
35 | | - ->columns([ |
36 | | - 'c.id', 'c.subject', 'c.issuer', 'c.version', 'c.self_signed', 'c.ca', 'c.trusted', |
37 | | - 'c.pubkey_algo', 'c.pubkey_bits', 'c.signature_algo', 'c.signature_hash_algo', |
38 | | - 'c.valid_from', 'c.valid_to', |
39 | | - ]); |
40 | | - |
41 | | - $this->view->paginator = new PaginationControl(new Sql\Cursor($conn, $select), Url::fromRequest()); |
42 | | - $this->view->paginator->apply(); |
43 | | - |
44 | | - $sortAndFilterColumns = [ |
45 | | - 'subject' => $this->translate('Certificate'), |
46 | | - 'issuer' => $this->translate('Issuer'), |
47 | | - 'version' => $this->translate('Version'), |
48 | | - 'self_signed' => $this->translate('Is Self-Signed'), |
49 | | - 'ca' => $this->translate('Is Certificate Authority'), |
50 | | - 'trusted' => $this->translate('Is Trusted'), |
51 | | - 'pubkey_algo' => $this->translate('Public Key Algorithm'), |
52 | | - 'pubkey_bits' => $this->translate('Public Key Strength'), |
53 | | - 'signature_algo' => $this->translate('Signature Algorithm'), |
| 31 | + $certificates = X509Certificate::on($conn); |
| 32 | + |
| 33 | + $sortColumns = [ |
| 34 | + 'subject' => $this->translate('Certificate'), |
| 35 | + 'issuer' => $this->translate('Issuer'), |
| 36 | + 'version' => $this->translate('Version'), |
| 37 | + 'self_signed' => $this->translate('Is Self-Signed'), |
| 38 | + 'ca' => $this->translate('Is Certificate Authority'), |
| 39 | + 'trusted' => $this->translate('Is Trusted'), |
| 40 | + 'pubkey_algo' => $this->translate('Public Key Algorithm'), |
| 41 | + 'pubkey_bits' => $this->translate('Public Key Strength'), |
| 42 | + 'signature_algo' => $this->translate('Signature Algorithm'), |
54 | 43 | 'signature_hash_algo' => $this->translate('Signature Hash Algorithm'), |
55 | | - 'valid_from' => $this->translate('Valid From'), |
56 | | - 'valid_to' => $this->translate('Valid To'), |
57 | | - 'duration' => $this->translate('Duration'), |
58 | | - 'expires' => $this->translate('Expiration') |
| 44 | + 'valid_from' => $this->translate('Valid From'), |
| 45 | + 'valid_to' => $this->translate('Valid To'), |
| 46 | + 'duration' => $this->translate('Duration'), |
| 47 | + 'expires' => $this->translate('Expiration') |
59 | 48 | ]; |
60 | 49 |
|
61 | | - $this->setupSortControl( |
62 | | - $sortAndFilterColumns, |
63 | | - new SortAdapter($select, function ($field) { |
64 | | - if ($field === 'duration') { |
65 | | - return '(valid_to - valid_from)'; |
66 | | - } elseif ($field === 'expires') { |
67 | | - return 'CASE WHEN UNIX_TIMESTAMP() > valid_to' |
68 | | - . ' THEN 0 ELSE (valid_to - UNIX_TIMESTAMP()) / 86400 END'; |
69 | | - } |
70 | | - }) |
71 | | - ); |
| 50 | + $limitControl = $this->createLimitControl(); |
| 51 | + $paginator = $this->createPaginationControl($certificates); |
| 52 | + $sortControl = $this->createSortControl($certificates, $sortColumns); |
72 | 53 |
|
73 | | - $this->setupLimitControl(); |
| 54 | + $searchBar = $this->createSearchBar($certificates, [ |
| 55 | + $limitControl->getLimitParam(), |
| 56 | + $sortControl->getSortParam() |
| 57 | + ]); |
74 | 58 |
|
75 | | - $filterAdapter = new FilterAdapter(); |
76 | | - $this->setupFilterControl( |
77 | | - $filterAdapter, |
78 | | - $sortAndFilterColumns, |
79 | | - ['subject', 'issuer'], |
80 | | - ['format'] |
81 | | - ); |
| 59 | + if ($searchBar->hasBeenSent() && ! $searchBar->isValid()) { |
| 60 | + if ($searchBar->hasBeenSubmitted()) { |
| 61 | + $filter = $this->getFilter(); |
| 62 | + } else { |
| 63 | + $this->addControl($searchBar); |
| 64 | + $this->sendMultipartUpdate(); |
82 | 65 |
|
83 | | - (new SqlFilter($conn))->apply($select, $filterAdapter->getFilter(), function (FilterExpression $filter) { |
84 | | - switch ($filter->getColumn()) { |
85 | | - case 'issuer_hash': |
86 | | - $value = $filter->getExpression(); |
87 | | - |
88 | | - if (is_array($value)) { |
89 | | - $value = array_map('hex2bin', $value); |
90 | | - } else { |
91 | | - $value = hex2bin($value); |
92 | | - } |
93 | | - |
94 | | - return $filter->setExpression($value); |
95 | | - case 'duration': |
96 | | - return $filter->setColumn('(valid_to - valid_from)'); |
97 | | - case 'expires': |
98 | | - return $filter->setColumn( |
99 | | - 'CASE WHEN UNIX_TIMESTAMP() > valid_to THEN 0 ELSE (valid_to - UNIX_TIMESTAMP()) / 86400 END' |
100 | | - ); |
101 | | - case 'valid_from': |
102 | | - case 'valid_to': |
103 | | - $expr = $filter->getExpression(); |
104 | | - if (! is_numeric($expr)) { |
105 | | - return $filter->setExpression(strtotime($expr)); |
106 | | - } |
107 | | - |
108 | | - // expression doesn't need changing |
109 | | - default: |
110 | | - return false; |
| 66 | + return; |
111 | 67 | } |
112 | | - }); |
| 68 | + } else { |
| 69 | + $filter = $searchBar->getFilter(); |
| 70 | + } |
113 | 71 |
|
114 | | - $this->handleFormatRequest($conn, $select, function (\PDOStatement $stmt) { |
115 | | - foreach ($stmt as $cert) { |
| 72 | + $certificates->peekAhead($this->view->compact); |
| 73 | + |
| 74 | + $certificates->filter($filter); |
| 75 | + |
| 76 | + $this->addControl($paginator); |
| 77 | + $this->addControl($sortControl); |
| 78 | + $this->addControl($limitControl); |
| 79 | + $this->addControl($searchBar); |
| 80 | + |
| 81 | + $this->handleFormatRequest($certificates, function (Query $certificates) { |
| 82 | + /** @var X509Certificate $cert */ |
| 83 | + foreach ($certificates as $cert) { |
116 | 84 | $cert['valid_from'] = (new \DateTime()) |
117 | 85 | ->setTimestamp($cert['valid_from']) |
118 | 86 | ->format('l F jS, Y H:i:s e'); |
119 | 87 | $cert['valid_to'] = (new \DateTime()) |
120 | 88 | ->setTimestamp($cert['valid_to']) |
121 | 89 | ->format('l F jS, Y H:i:s e'); |
122 | 90 |
|
123 | | - yield $cert; |
| 91 | + yield array_intersect_key(iterator_to_array($cert), array_flip($cert->getExportableColumns())); |
124 | 92 | } |
125 | 93 | }); |
126 | 94 |
|
127 | | - $this->view->certificatesTable = (new CertificatesTable())->setData($conn->select($select)); |
| 95 | + $this->addContent((new CertificatesTable())->setData($certificates)); |
| 96 | + |
| 97 | + if (! $searchBar->hasBeenSubmitted() && $searchBar->hasBeenSent()) { |
| 98 | + $this->sendMultipartUpdate(); // Updates the browser search bar |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | + public function completeAction() |
| 103 | + { |
| 104 | + $this->getDocument()->add( |
| 105 | + (new ObjectSuggestions()) |
| 106 | + ->setModel(X509Certificate::class) |
| 107 | + ->forRequest($this->getServerRequest()) |
| 108 | + ); |
| 109 | + } |
| 110 | + |
| 111 | + public function searchEditorAction() |
| 112 | + { |
| 113 | + $editor = $this->createSearchEditor(X509Certificate::on($this->getDb()), [ |
| 114 | + LimitControl::DEFAULT_LIMIT_PARAM, |
| 115 | + SortControl::DEFAULT_SORT_PARAM |
| 116 | + ]); |
| 117 | + |
| 118 | + $this->getDocument()->add($editor); |
| 119 | + $this->setTitle(t('Adjust Filter')); |
128 | 120 | } |
129 | 121 | } |
0 commit comments