Skip to content

Commit 9b10ea7

Browse files
Add /audit-log route
1 parent 80ee2b0 commit 9b10ea7

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of Packagist.
5+
*
6+
* (c) Jordi Boggiano <[email protected]>
7+
* Nils Adermann <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
namespace App\Controller;
14+
15+
use App\Entity\AuditRecordRepository;
16+
use Pagerfanta\Doctrine\ORM\QueryAdapter;
17+
use Pagerfanta\Pagerfanta;
18+
use Symfony\Component\HttpFoundation\Request;
19+
use Symfony\Component\HttpFoundation\Response;
20+
use Symfony\Component\Routing\Attribute\Route;
21+
use Symfony\Component\Security\Http\Attribute\IsGranted;
22+
23+
class AuditLogController extends Controller
24+
{
25+
#[IsGranted('ROLE_USER')]
26+
#[Route(path: '/audit-log', name: 'view_audit_logs')]
27+
public function viewAuditLogs(Request $req, AuditRecordRepository $auditRecordRepository): Response
28+
{
29+
$query = $auditRecordRepository->createQueryBuilder('a')
30+
->orderBy('a.id', 'DESC');
31+
32+
$auditLogs = new Pagerfanta(new QueryAdapter($query, false));
33+
$auditLogs->setNormalizeOutOfRangePages(true);
34+
$auditLogs->setMaxPerPage(20);
35+
$auditLogs->setCurrentPage(max(1, $req->query->getInt('page', 1)));
36+
37+
return $this->render('audit_log/view_audit_logs.html.twig', [
38+
'auditLogs' => $auditLogs,
39+
]);
40+
}
41+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{% extends "layout.html.twig" %}
2+
3+
{% block title %}
4+
Packagist - Audit Logs
5+
{% endblock %}
6+
7+
{% block content %}
8+
<h2 class="title">Audit Logs</h2>
9+
10+
{% if auditLogs|length %}
11+
<table class="table table-striped">
12+
<thead>
13+
<tr>
14+
<th>Date & Time</th>
15+
<th>Type</th>
16+
<th>Vendor</th>
17+
</tr>
18+
</thead>
19+
<tbody>
20+
{% for log in auditLogs %}
21+
<tr>
22+
<td>{{ log.datetime|date('Y-m-d H:i:s') }} UTC</td>
23+
<td data-test="audit-log-type">{{ log.type.value }}</td>
24+
<td>{{ log.vendor ?? '-' }}</td>
25+
</tr>
26+
{% endfor %}
27+
</tbody>
28+
</table>
29+
30+
{% if auditLogs.haveToPaginate() %}
31+
{{ pagerfanta(auditLogs, 'twitter_bootstrap', {'proximity': 2}) }}
32+
{% endif %}
33+
{% else %}
34+
<div class="alert alert-info">
35+
<p>No audit logs found.</p>
36+
</div>
37+
{% endif %}
38+
{% endblock %}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of Packagist.
5+
*
6+
* (c) Jordi Boggiano <[email protected]>
7+
* Nils Adermann <[email protected]>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
namespace App\Tests\Controller;
14+
15+
use App\Entity\AuditRecord;
16+
use App\Tests\IntegrationTestCase;
17+
18+
class AuditLogControllerTest extends IntegrationTestCase
19+
{
20+
public function testViewAuditLogs(): void
21+
{
22+
$user = self::createUser('testuser', '[email protected]', roles: ['ROLE_ADMIN']);
23+
$package = self::createPackage('vendor1/package1', 'https://github.com/vendor1/package1', maintainers: [$user]);
24+
25+
$this->store($user, $package);
26+
27+
$auditLog1 = AuditRecord::canonicalUrlChange($package, $user, 'https://github.com/vendor1/package1-new');
28+
$auditLog2 = AuditRecord::packageDeleted($package, $user);
29+
30+
$this->store($auditLog1, $auditLog2);
31+
32+
$this->client->loginUser($user);
33+
$crawler = $this->client->request('GET', '/audit-log');
34+
static::assertResponseIsSuccessful();
35+
36+
$rows = $crawler->filter('[data-test=audit-log-type]');
37+
static::assertGreaterThanOrEqual(3, $rows->count(), 'Should have at least 3 audit log entries');
38+
static::assertSame([
39+
'package_deleted',
40+
'canonical_url_change',
41+
'package_created',
42+
], $rows->each(fn ($element) => trim($element->text())));
43+
}
44+
}

tests/IntegrationTestCase.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ protected static function createUser(string $username = 'test', string $email =
111111
$user->setApiToken($apiToken);
112112
$user->setSafeApiToken($safeApiToken);
113113
$user->setGithubId($githubId);
114+
$user->setRoles($roles);
114115

115116
return $user;
116117
}

0 commit comments

Comments
 (0)