]> BookStack Code Mirror - bookstack/blob - tests/Actions/AuditLogTest.php
Cleaned testing service provider usage
[bookstack] / tests / Actions / AuditLogTest.php
1 <?php
2
3 namespace Tests\Actions;
4
5 use BookStack\Actions\Activity;
6 use BookStack\Actions\ActivityLogger;
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 use Tests\TestCase;
15
16 class AuditLogTest extends TestCase
17 {
18     /** @var ActivityLogger */
19     protected $activityService;
20
21     protected function setUp(): void
22     {
23         parent::setUp();
24         $this->activityService = app(ActivityLogger::class);
25     }
26
27     public function test_only_accessible_with_right_permissions()
28     {
29         $viewer = $this->getViewer();
30         $this->actingAs($viewer);
31
32         $resp = $this->get('/settings/audit');
33         $this->assertPermissionError($resp);
34
35         $this->giveUserPermissions($viewer, ['settings-manage']);
36         $resp = $this->get('/settings/audit');
37         $this->assertPermissionError($resp);
38
39         $this->giveUserPermissions($viewer, ['users-manage']);
40         $resp = $this->get('/settings/audit');
41         $resp->assertStatus(200);
42         $resp->assertSeeText('Audit Log');
43     }
44
45     public function test_shows_activity()
46     {
47         $admin = $this->getAdmin();
48         $this->actingAs($admin);
49         $page = Page::query()->first();
50         $this->activityService->add(ActivityType::PAGE_CREATE, $page);
51         $activity = Activity::query()->orderBy('id', 'desc')->first();
52
53         $resp = $this->get('settings/audit');
54         $resp->assertSeeText($page->name);
55         $resp->assertSeeText('page_create');
56         $resp->assertSeeText($activity->created_at->toDateTimeString());
57         $this->withHtml($resp)->assertElementContains('.table-user-item', $admin->name);
58     }
59
60     public function test_shows_name_for_deleted_items()
61     {
62         $this->actingAs($this->getAdmin());
63         $page = Page::query()->first();
64         $pageName = $page->name;
65         $this->activityService->add(ActivityType::PAGE_CREATE, $page);
66
67         app(PageRepo::class)->destroy($page);
68         app(TrashCan::class)->empty();
69
70         $resp = $this->get('settings/audit');
71         $resp->assertSeeText('Deleted Item');
72         $resp->assertSeeText('Name: ' . $pageName);
73     }
74
75     public function test_shows_activity_for_deleted_users()
76     {
77         $viewer = $this->getViewer();
78         $this->actingAs($viewer);
79         $page = Page::query()->first();
80         $this->activityService->add(ActivityType::PAGE_CREATE, $page);
81
82         $this->actingAs($this->getAdmin());
83         app(UserRepo::class)->destroy($viewer);
84
85         $resp = $this->get('settings/audit');
86         $resp->assertSeeText("[ID: {$viewer->id}] Deleted User");
87     }
88
89     public function test_filters_by_key()
90     {
91         $this->actingAs($this->getAdmin());
92         $page = Page::query()->first();
93         $this->activityService->add(ActivityType::PAGE_CREATE, $page);
94
95         $resp = $this->get('settings/audit');
96         $resp->assertSeeText($page->name);
97
98         $resp = $this->get('settings/audit?event=page_delete');
99         $resp->assertDontSeeText($page->name);
100     }
101
102     public function test_date_filters()
103     {
104         $this->actingAs($this->getAdmin());
105         $page = Page::query()->first();
106         $this->activityService->add(ActivityType::PAGE_CREATE, $page);
107
108         $yesterday = (Carbon::now()->subDay()->format('Y-m-d'));
109         $tomorrow = (Carbon::now()->addDay()->format('Y-m-d'));
110
111         $resp = $this->get('settings/audit?date_from=' . $yesterday);
112         $resp->assertSeeText($page->name);
113
114         $resp = $this->get('settings/audit?date_from=' . $tomorrow);
115         $resp->assertDontSeeText($page->name);
116
117         $resp = $this->get('settings/audit?date_to=' . $tomorrow);
118         $resp->assertSeeText($page->name);
119
120         $resp = $this->get('settings/audit?date_to=' . $yesterday);
121         $resp->assertDontSeeText($page->name);
122     }
123
124     public function test_user_filter()
125     {
126         $admin = $this->getAdmin();
127         $editor = $this->getEditor();
128         $this->actingAs($admin);
129         $page = Page::query()->first();
130         $this->activityService->add(ActivityType::PAGE_CREATE, $page);
131
132         $this->actingAs($editor);
133         $chapter = Chapter::query()->first();
134         $this->activityService->add(ActivityType::CHAPTER_UPDATE, $chapter);
135
136         $resp = $this->actingAs($admin)->get('settings/audit?user=' . $admin->id);
137         $resp->assertSeeText($page->name);
138         $resp->assertDontSeeText($chapter->name);
139
140         $resp = $this->actingAs($admin)->get('settings/audit?user=' . $editor->id);
141         $resp->assertSeeText($chapter->name);
142         $resp->assertDontSeeText($page->name);
143     }
144
145     public function test_ip_address_logged_and_visible()
146     {
147         config()->set('app.proxies', '*');
148         $editor = $this->getEditor();
149         /** @var Page $page */
150         $page = Page::query()->first();
151
152         $this->actingAs($editor)->put($page->getUrl(), [
153             'name' => 'Updated page',
154             'html' => '<p>Updated content</p>',
155         ], [
156             'X-Forwarded-For' => '192.123.45.1',
157         ])->assertRedirect($page->refresh()->getUrl());
158
159         $this->assertDatabaseHas('activities', [
160             'type'      => ActivityType::PAGE_UPDATE,
161             'ip'        => '192.123.45.1',
162             'user_id'   => $editor->id,
163             'entity_id' => $page->id,
164         ]);
165
166         $resp = $this->asAdmin()->get('/settings/audit');
167         $resp->assertSee('192.123.45.1');
168     }
169
170     public function test_ip_address_is_searchable()
171     {
172         config()->set('app.proxies', '*');
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         ])->assertRedirect($page->refresh()->getUrl());
183
184         $this->actingAs($editor)->put($page->getUrl(), [
185             'name' => 'Updated page',
186             'html' => '<p>Updated content</p>',
187         ], [
188             'X-Forwarded-For' => '192.122.45.1',
189         ])->assertRedirect($page->refresh()->getUrl());
190
191         $resp = $this->asAdmin()->get('/settings/audit?&ip=192.123');
192         $resp->assertSee('192.123.45.1');
193         $resp->assertDontSee('192.122.45.1');
194     }
195
196     public function test_ip_address_not_logged_in_demo_mode()
197     {
198         config()->set('app.proxies', '*');
199         config()->set('app.env', 'demo');
200         $editor = $this->getEditor();
201         /** @var Page $page */
202         $page = Page::query()->first();
203
204         $this->actingAs($editor)->put($page->getUrl(), [
205             'name' => 'Updated page',
206             'html' => '<p>Updated content</p>',
207         ], [
208             'X-Forwarded-For' => '192.123.45.1',
209             'REMOTE_ADDR'     => '192.123.45.2',
210         ])->assertRedirect($page->refresh()->getUrl());
211
212         $this->assertDatabaseHas('activities', [
213             'type'      => ActivityType::PAGE_UPDATE,
214             'ip'        => '127.0.0.1',
215             'user_id'   => $editor->id,
216             'entity_id' => $page->id,
217         ]);
218     }
219
220     public function test_ip_address_respects_precision_setting()
221     {
222         config()->set('app.proxies', '*');
223         config()->set('app.ip_address_precision', 2);
224         $editor = $this->getEditor();
225         /** @var Page $page */
226         $page = Page::query()->first();
227
228         $this->actingAs($editor)->put($page->getUrl(), [
229             'name' => 'Updated page',
230             'html' => '<p>Updated content</p>',
231         ], [
232             'X-Forwarded-For' => '192.123.45.1',
233         ])->assertRedirect($page->refresh()->getUrl());
234
235         $this->assertDatabaseHas('activities', [
236             'type'      => ActivityType::PAGE_UPDATE,
237             'ip'        => '192.123.x.x',
238             'user_id'   => $editor->id,
239             'entity_id' => $page->id,
240         ]);
241     }
242 }