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