forked from BookStackApp/BookStack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApiAuthTest.php
More file actions
149 lines (119 loc) · 5.22 KB
/
ApiAuthTest.php
File metadata and controls
149 lines (119 loc) · 5.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
namespace Tests\Api;
use BookStack\Auth\Permissions\RolePermission;
use BookStack\Auth\User;
use Carbon\Carbon;
use Tests\TestCase;
class ApiAuthTest extends TestCase
{
use TestsApi;
protected $endpoint = '/api/books';
public function test_requests_succeed_with_default_auth()
{
$viewer = $this->getViewer();
$this->giveUserPermissions($viewer, ['access-api']);
$resp = $this->get($this->endpoint);
$resp->assertStatus(401);
$this->actingAs($viewer, 'standard');
$resp = $this->get($this->endpoint);
$resp->assertStatus(200);
}
public function test_no_token_throws_error()
{
$resp = $this->get($this->endpoint);
$resp->assertStatus(401);
$resp->assertJson($this->errorResponse('No authorization token found on the request', 401));
}
public function test_bad_token_format_throws_error()
{
$resp = $this->get($this->endpoint, ['Authorization' => 'Token abc123']);
$resp->assertStatus(401);
$resp->assertJson($this->errorResponse('An authorization token was found on the request but the format appeared incorrect', 401));
}
public function test_token_with_non_existing_id_throws_error()
{
$resp = $this->get($this->endpoint, ['Authorization' => 'Token abc:123']);
$resp->assertStatus(401);
$resp->assertJson($this->errorResponse('No matching API token was found for the provided authorization token', 401));
}
public function test_token_with_bad_secret_value_throws_error()
{
$resp = $this->get($this->endpoint, ['Authorization' => "Token {$this->apiTokenId}:123"]);
$resp->assertStatus(401);
$resp->assertJson($this->errorResponse('The secret provided for the given used API token is incorrect', 401));
}
public function test_api_access_permission_required_to_access_api()
{
$resp = $this->get($this->endpoint, $this->apiAuthHeader());
$resp->assertStatus(200);
auth()->logout();
$accessApiPermission = RolePermission::getByName('access-api');
$editorRole = $this->getEditor()->roles()->first();
$editorRole->detachPermission($accessApiPermission);
$resp = $this->get($this->endpoint, $this->apiAuthHeader());
$resp->assertStatus(403);
$resp->assertJson($this->errorResponse('The owner of the used API token does not have permission to make API calls', 403));
}
public function test_api_access_permission_required_to_access_api_with_session_auth()
{
$editor = $this->getEditor();
$this->actingAs($editor, 'standard');
$resp = $this->get($this->endpoint);
$resp->assertStatus(200);
auth('standard')->logout();
$accessApiPermission = RolePermission::getByName('access-api');
$editorRole = $this->getEditor()->roles()->first();
$editorRole->detachPermission($accessApiPermission);
$editor = User::query()->where('id', '=', $editor->id)->first();
$this->actingAs($editor, 'standard');
$resp = $this->get($this->endpoint);
$resp->assertStatus(403);
$resp->assertJson($this->errorResponse('The owner of the used API token does not have permission to make API calls', 403));
}
public function test_token_expiry_checked()
{
$editor = $this->getEditor();
$token = $editor->apiTokens()->first();
$resp = $this->get($this->endpoint, $this->apiAuthHeader());
$resp->assertStatus(200);
auth()->logout();
$token->expires_at = Carbon::now()->subDay()->format('Y-m-d');
$token->save();
$resp = $this->get($this->endpoint, $this->apiAuthHeader());
$resp->assertJson($this->errorResponse('The authorization token used has expired', 403));
}
public function test_email_confirmation_checked_using_api_auth()
{
$editor = $this->getEditor();
$editor->email_confirmed = false;
$editor->save();
// Set settings and get user instance
$this->setSettings(['registration-enabled' => 'true', 'registration-confirmation' => 'true']);
$resp = $this->get($this->endpoint, $this->apiAuthHeader());
$resp->assertStatus(401);
$resp->assertJson($this->errorResponse('The email address for the account in use needs to be confirmed', 401));
}
public function test_rate_limit_headers_active_on_requests()
{
$resp = $this->actingAsApiEditor()->get($this->endpoint);
$resp->assertHeader('x-ratelimit-limit', 180);
$resp->assertHeader('x-ratelimit-remaining', 179);
$resp = $this->actingAsApiEditor()->get($this->endpoint);
$resp->assertHeader('x-ratelimit-remaining', 178);
}
public function test_rate_limit_hit_gives_json_error()
{
config()->set(['api.requests_per_minute' => 1]);
$resp = $this->actingAsApiEditor()->get($this->endpoint);
$resp->assertStatus(200);
$resp = $this->actingAsApiEditor()->get($this->endpoint);
$resp->assertStatus(429);
$resp->assertHeader('x-ratelimit-remaining', 0);
$resp->assertHeader('retry-after');
$resp->assertJson([
'error' => [
'code' => 429,
],
]);
}
}