]> BookStack Code Mirror - bookstack/blob - tests/AuditLogTest.php
Added test for logical-theme-system command registration
[bookstack] / tests / AuditLogTest.php
1 <?php
2
3 namespace Tests;
4
5 use BookStack\Actions\Activity;
6 use BookStack\Actions\ActivityService;
7 use BookStack\Actions\ActivityType;
8 use BookStack\Auth\UserRepo;
9 use BookStack\Entities\Models\Chapter;
10 use BookStack\Entities\Models\Page;
11 use BookStack\Entities\Repos\PageRepo;
12 use BookStack\Entities\Tools\TrashCan;
13 use Carbon\Carbon;
14
15 class AuditLogTest extends TestCase
16 {
17     /** @var ActivityService */
18     protected $activityService;
19
20     protected function setUp(): void
21     {
22         parent::setUp();
23         $this->activityService = app(ActivityService::class);
24     }
25
26     public function test_only_accessible_with_right_permissions()
27     {
28         $viewer = $this->getViewer();
29         $this->actingAs($viewer);
30
31         $resp = $this->get('/settings/audit');
32         $this->assertPermissionError($resp);
33
34         $this->giveUserPermissions($viewer, ['settings-manage']);
35         $resp = $this->get('/settings/audit');
36         $this->assertPermissionError($resp);
37
38         $this->giveUserPermissions($viewer, ['users-manage']);
39         $resp = $this->get('/settings/audit');
40         $resp->assertStatus(200);
41         $resp->assertSeeText('Audit Log');
42     }
43
44     public function test_shows_activity()
45     {
46         $admin = $this->getAdmin();
47         $this->actingAs($admin);
48         $page = Page::query()->first();
49         $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE);
50         $activity = Activity::query()->orderBy('id', 'desc')->first();
51
52         $resp = $this->get('settings/audit');
53         $resp->assertSeeText($page->name);
54         $resp->assertSeeText('page_create');
55         $resp->assertSeeText($activity->created_at->toDateTimeString());
56         $resp->assertElementContains('.table-user-item', $admin->name);
57     }
58
59     public function test_shows_name_for_deleted_items()
60     {
61         $this->actingAs($this->getAdmin());
62         $page = Page::query()->first();
63         $pageName = $page->name;
64         $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE);
65
66         app(PageRepo::class)->destroy($page);
67         app(TrashCan::class)->empty();
68
69         $resp = $this->get('settings/audit');
70         $resp->assertSeeText('Deleted Item');
71         $resp->assertSeeText('Name: ' . $pageName);
72     }
73
74     public function test_shows_activity_for_deleted_users()
75     {
76         $viewer = $this->getViewer();
77         $this->actingAs($viewer);
78         $page = Page::query()->first();
79         $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE);
80
81         $this->actingAs($this->getAdmin());
82         app(UserRepo::class)->destroy($viewer);
83
84         $resp = $this->get('settings/audit');
85         $resp->assertSeeText("[ID: {$viewer->id}] Deleted User");
86     }
87
88     public function test_filters_by_key()
89     {
90         $this->actingAs($this->getAdmin());
91         $page = Page::query()->first();
92         $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE);
93
94         $resp = $this->get('settings/audit');
95         $resp->assertSeeText($page->name);
96
97         $resp = $this->get('settings/audit?event=page_delete');
98         $resp->assertDontSeeText($page->name);
99     }
100
101     public function test_date_filters()
102     {
103         $this->actingAs($this->getAdmin());
104         $page = Page::query()->first();
105         $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE);
106
107         $yesterday = (Carbon::now()->subDay()->format('Y-m-d'));
108         $tomorrow = (Carbon::now()->addDay()->format('Y-m-d'));
109
110         $resp = $this->get('settings/audit?date_from=' . $yesterday);
111         $resp->assertSeeText($page->name);
112
113         $resp = $this->get('settings/audit?date_from=' . $tomorrow);
114         $resp->assertDontSeeText($page->name);
115
116         $resp = $this->get('settings/audit?date_to=' . $tomorrow);
117         $resp->assertSeeText($page->name);
118
119         $resp = $this->get('settings/audit?date_to=' . $yesterday);
120         $resp->assertDontSeeText($page->name);
121     }
122
123     public function test_user_filter()
124     {
125         $admin = $this->getAdmin();
126         $editor = $this->getEditor();
127         $this->actingAs($admin);
128         $page = Page::query()->first();
129         $this->activityService->addForEntity($page, ActivityType::PAGE_CREATE);
130
131         $this->actingAs($editor);
132         $chapter = Chapter::query()->first();
133         $this->activityService->addForEntity($chapter, ActivityType::CHAPTER_UPDATE);
134
135         $resp = $this->actingAs($admin)->get('settings/audit?user=' . $admin->id);
136         $resp->assertSeeText($page->name);
137         $resp->assertDontSeeText($chapter->name);
138
139         $resp = $this->actingAs($admin)->get('settings/audit?user=' . $editor->id);
140         $resp->assertSeeText($chapter->name);
141         $resp->assertDontSeeText($page->name);
142     }
143
144     public function test_ip_address_logged_and_visible()
145     {
146         config()->set('app.proxies', '*');
147         $editor = $this->getEditor();
148         /** @var Page $page */
149         $page = Page::query()->first();
150
151         $this->actingAs($editor)->put($page->getUrl(), [
152             'name' => 'Updated page',
153             'html' => '<p>Updated content</p>',
154         ], [
155             'X-Forwarded-For' => '192.123.45.1',
156         ])->assertRedirect($page->refresh()->getUrl());
157
158         $this->assertDatabaseHas('activities', [
159             'type'      => ActivityType::PAGE_UPDATE,
160             'ip'        => '192.123.45.1',
161             'user_id'   => $editor->id,
162             'entity_id' => $page->id,
163         ]);
164
165         $resp = $this->asAdmin()->get('/settings/audit');
166         $resp->assertSee('192.123.45.1');
167     }
168
169     public function test_ip_address_not_logged_in_demo_mode()
170     {
171         config()->set('app.proxies', '*');
172         config()->set('app.env', 'demo');
173         $editor = $this->getEditor();
174         /** @var Page $page */
175         $page = Page::query()->first();
176
177         $this->actingAs($editor)->put($page->getUrl(), [
178             'name' => 'Updated page',
179             'html' => '<p>Updated content</p>',
180         ], [
181             'X-Forwarded-For' => '192.123.45.1',
182             'REMOTE_ADDR'     => '192.123.45.2',
183         ])->assertRedirect($page->refresh()->getUrl());
184
185         $this->assertDatabaseHas('activities', [
186             'type'      => ActivityType::PAGE_UPDATE,
187             'ip'        => '127.0.0.1',
188             'user_id'   => $editor->id,
189             'entity_id' => $page->id,
190         ]);
191     }
192 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.