]> BookStack Code Mirror - bookstack/blob - tests/User/UserApiTokenTest.php
Fix Crowdin name in the language_request issue template
[bookstack] / tests / User / UserApiTokenTest.php
1 <?php
2
3 namespace Tests\User;
4
5 use BookStack\Actions\ActivityType;
6 use BookStack\Api\ApiToken;
7 use Carbon\Carbon;
8 use Tests\TestCase;
9
10 class UserApiTokenTest extends TestCase
11 {
12     protected $testTokenData = [
13         'name'       => 'My test API token',
14         'expires_at' => '2050-04-01',
15     ];
16
17     public function test_tokens_section_not_visible_without_access_api_permission()
18     {
19         $user = $this->getViewer();
20
21         $resp = $this->actingAs($user)->get($user->getEditUrl());
22         $resp->assertDontSeeText('API Tokens');
23
24         $this->giveUserPermissions($user, ['access-api']);
25
26         $resp = $this->actingAs($user)->get($user->getEditUrl());
27         $resp->assertSeeText('API Tokens');
28         $resp->assertSeeText('Create Token');
29     }
30
31     public function test_those_with_manage_users_can_view_other_user_tokens_but_not_create()
32     {
33         $viewer = $this->getViewer();
34         $editor = $this->getEditor();
35         $this->giveUserPermissions($viewer, ['users-manage']);
36
37         $resp = $this->actingAs($viewer)->get($editor->getEditUrl());
38         $resp->assertSeeText('API Tokens');
39         $resp->assertDontSeeText('Create Token');
40     }
41
42     public function test_create_api_token()
43     {
44         $editor = $this->getEditor();
45
46         $resp = $this->asAdmin()->get($editor->getEditUrl('/create-api-token'));
47         $resp->assertStatus(200);
48         $resp->assertSee('Create API Token');
49         $resp->assertSee('Token Secret');
50
51         $resp = $this->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
52         $token = ApiToken::query()->latest()->first();
53         $resp->assertRedirect($editor->getEditUrl('/api-tokens/' . $token->id));
54         $this->assertDatabaseHas('api_tokens', [
55             'user_id'    => $editor->id,
56             'name'       => $this->testTokenData['name'],
57             'expires_at' => $this->testTokenData['expires_at'],
58         ]);
59
60         // Check secret token
61         $this->assertSessionHas('api-token-secret:' . $token->id);
62         $secret = session('api-token-secret:' . $token->id);
63         $this->assertDatabaseMissing('api_tokens', [
64             'secret' => $secret,
65         ]);
66         $this->assertTrue(\Hash::check($secret, $token->secret));
67
68         $this->assertTrue(strlen($token->token_id) === 32);
69         $this->assertTrue(strlen($secret) === 32);
70
71         $this->assertSessionHas('success');
72         $this->assertActivityExists(ActivityType::API_TOKEN_CREATE);
73     }
74
75     public function test_create_with_no_expiry_sets_expiry_hundred_years_away()
76     {
77         $editor = $this->getEditor();
78         $this->asAdmin()->post($editor->getEditUrl('/create-api-token'), ['name' => 'No expiry token', 'expires_at' => '']);
79         $token = ApiToken::query()->latest()->first();
80
81         $over = Carbon::now()->addYears(101);
82         $under = Carbon::now()->addYears(99);
83         $this->assertTrue(
84             ($token->expires_at < $over && $token->expires_at > $under),
85             'Token expiry set at 100 years in future'
86         );
87     }
88
89     public function test_created_token_displays_on_profile_page()
90     {
91         $editor = $this->getEditor();
92         $this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
93         $token = ApiToken::query()->latest()->first();
94
95         $resp = $this->get($editor->getEditUrl());
96         $resp->assertElementExists('#api_tokens');
97         $resp->assertElementContains('#api_tokens', $token->name);
98         $resp->assertElementContains('#api_tokens', $token->token_id);
99         $resp->assertElementContains('#api_tokens', $token->expires_at->format('Y-m-d'));
100     }
101
102     public function test_secret_shown_once_after_creation()
103     {
104         $editor = $this->getEditor();
105         $resp = $this->asAdmin()->followingRedirects()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
106         $resp->assertSeeText('Token Secret');
107
108         $token = ApiToken::query()->latest()->first();
109         $this->assertNull(session('api-token-secret:' . $token->id));
110
111         $resp = $this->get($editor->getEditUrl('/api-tokens/' . $token->id));
112         $resp->assertDontSeeText('Client Secret');
113     }
114
115     public function test_token_update()
116     {
117         $editor = $this->getEditor();
118         $this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
119         $token = ApiToken::query()->latest()->first();
120         $updateData = [
121             'name'       => 'My updated token',
122             'expires_at' => '2011-01-01',
123         ];
124
125         $resp = $this->put($editor->getEditUrl('/api-tokens/' . $token->id), $updateData);
126         $resp->assertRedirect($editor->getEditUrl('/api-tokens/' . $token->id));
127
128         $this->assertDatabaseHas('api_tokens', array_merge($updateData, ['id' => $token->id]));
129         $this->assertSessionHas('success');
130         $this->assertActivityExists(ActivityType::API_TOKEN_UPDATE);
131     }
132
133     public function test_token_update_with_blank_expiry_sets_to_hundred_years_away()
134     {
135         $editor = $this->getEditor();
136         $this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
137         $token = ApiToken::query()->latest()->first();
138
139         $resp = $this->put($editor->getEditUrl('/api-tokens/' . $token->id), [
140             'name'       => 'My updated token',
141             'expires_at' => '',
142         ]);
143         $token->refresh();
144
145         $over = Carbon::now()->addYears(101);
146         $under = Carbon::now()->addYears(99);
147         $this->assertTrue(
148             ($token->expires_at < $over && $token->expires_at > $under),
149             'Token expiry set at 100 years in future'
150         );
151     }
152
153     public function test_token_delete()
154     {
155         $editor = $this->getEditor();
156         $this->asAdmin()->post($editor->getEditUrl('/create-api-token'), $this->testTokenData);
157         $token = ApiToken::query()->latest()->first();
158
159         $tokenUrl = $editor->getEditUrl('/api-tokens/' . $token->id);
160
161         $resp = $this->get($tokenUrl . '/delete');
162         $resp->assertSeeText('Delete Token');
163         $resp->assertSeeText($token->name);
164         $resp->assertElementExists('form[action="' . $tokenUrl . '"]');
165
166         $resp = $this->delete($tokenUrl);
167         $resp->assertRedirect($editor->getEditUrl('#api_tokens'));
168         $this->assertDatabaseMissing('api_tokens', ['id' => $token->id]);
169         $this->assertActivityExists(ActivityType::API_TOKEN_DELETE);
170     }
171
172     public function test_user_manage_can_delete_token_without_api_permission_themselves()
173     {
174         $viewer = $this->getViewer();
175         $editor = $this->getEditor();
176         $this->giveUserPermissions($editor, ['users-manage']);
177
178         $this->asAdmin()->post($viewer->getEditUrl('/create-api-token'), $this->testTokenData);
179         $token = ApiToken::query()->latest()->first();
180
181         $resp = $this->actingAs($editor)->get($viewer->getEditUrl('/api-tokens/' . $token->id));
182         $resp->assertStatus(200);
183         $resp->assertSeeText('Delete Token');
184
185         $resp = $this->actingAs($editor)->delete($viewer->getEditUrl('/api-tokens/' . $token->id));
186         $resp->assertRedirect($viewer->getEditUrl('#api_tokens'));
187         $this->assertDatabaseMissing('api_tokens', ['id' => $token->id]);
188     }
189 }
Morty Proxy This is a proxified and sanitized view of the page, visit original site.