Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve API client usability #1368

Merged
merged 70 commits into from
Sep 17, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
8c81604
Support API tokens per user
qwerty287 Jun 12, 2022
5e1d798
Do not require Accept and Content-Type headers
qwerty287 Jun 12, 2022
b5ca08b
Fix 500 on user creation
qwerty287 Jun 12, 2022
40fee32
Recompile
qwerty287 Jun 26, 2022
7ec4a68
Merge remote-tracking branch 'origin/master' into api-tokens
qwerty287 Jun 26, 2022
0ac74e4
Fix some reviews
qwerty287 Jun 29, 2022
20bf192
Undo Content-Type and Accept change
qwerty287 Jun 29, 2022
b47d039
Merge branch 'master' into api-tokens
qwerty287 Jun 29, 2022
ae2f277
Fix phpstan
qwerty287 Jun 29, 2022
595dc9c
Fix phpstan
qwerty287 Jun 29, 2022
4e15114
Fix phpstan 3
qwerty287 Jun 29, 2022
534bd12
merge from master
ildyria Jul 16, 2022
10c385c
add support for disabling the token completely rather than letting it…
ildyria Jul 16, 2022
b0057c3
disable-enable FK
ildyria Jul 16, 2022
00633aa
add tests
ildyria Jul 16, 2022
2491549
remove unused variable
ildyria Jul 16, 2022
55555d5
Merge branch 'master' into api-tokens
qwerty287 Jul 17, 2022
12a6014
Translate and add strings
qwerty287 Jul 17, 2022
28a706e
Fix security issue during migration that gives admin perms to api_key
qwerty287 Jul 18, 2022
3c558f9
Fix locale
qwerty287 Jul 20, 2022
cc265d4
Sync frontend
qwerty287 Jul 20, 2022
c51d0ef
Merge remote-tracking branch 'origin/master' into api-tokens
qwerty287 Jul 26, 2022
c3b1c0a
Merge remote-tracking branch 'origin/master' into api-tokens
qwerty287 Aug 2, 2022
0319237
Suggestions
qwerty287 Aug 5, 2022
ad270aa
Apply suggestions from code review
qwerty287 Aug 5, 2022
0c06d82
Apply suggestions
qwerty287 Aug 5, 2022
8412834
Recompile frontend
qwerty287 Aug 5, 2022
e1db64e
Fix perms
qwerty287 Aug 5, 2022
ba67ad3
Fix lint
qwerty287 Aug 5, 2022
d1e5264
Improve check
qwerty287 Aug 5, 2022
3a2c02e
Simplify middleware
nagmat84 Aug 5, 2022
5376b31
Assert JSON
qwerty287 Aug 6, 2022
1a34f13
fix format
qwerty287 Aug 6, 2022
35c5af0
Apply fixes from PHP-CS-Fixer (#1444)
github-actions[bot] Aug 6, 2022
d8ccc6e
Hash tokens
qwerty287 Aug 6, 2022
b42fa6d
Sync frontend
qwerty287 Aug 6, 2022
91c2096
Tmp commit to find out why it's failing
qwerty287 Aug 6, 2022
fb41b63
Second try to find failure
qwerty287 Aug 6, 2022
7611838
I'm pretty stupid at all
qwerty287 Aug 6, 2022
5bf6e60
Fix db errors
qwerty287 Aug 6, 2022
c974d1a
Merge branch 'master' into api-tokens
qwerty287 Sep 4, 2022
b5d4345
Fix phpstan
qwerty287 Sep 4, 2022
36072ba
Fix phpstan 2
qwerty287 Sep 4, 2022
d80094a
Fix phpstan 3
qwerty287 Sep 4, 2022
3e10d93
Fix test
qwerty287 Sep 4, 2022
3f57646
merge master
ildyria Sep 8, 2022
b79293f
Add tests and fix issues as guest
qwerty287 Sep 8, 2022
2424663
sync frontend
qwerty287 Sep 8, 2022
018d96b
fix phpdoc
qwerty287 Sep 8, 2022
4ff6f18
Update locales and sync frontedn
qwerty287 Sep 9, 2022
ed3e2f8
Fix duplicated keys
qwerty287 Sep 9, 2022
1d3d535
Sync frontend
qwerty287 Sep 9, 2022
daf9238
Add getAuthenticatedUser test
qwerty287 Sep 9, 2022
871eb59
Don't send token with user, fix locales, synced frontend
nagmat84 Sep 9, 2022
6c19699
Make PHPStan happy about something toally unrelated
nagmat84 Sep 9, 2022
5cf7730
Sync frontend
qwerty287 Sep 10, 2022
d222def
fix sync
qwerty287 Sep 10, 2022
8e9cde1
Remove HasUserMiddleware
nagmat84 Sep 10, 2022
61c866d
Fix tests
qwerty287 Sep 10, 2022
c5d2ff6
Added custom guard to handle session or token
nagmat84 Sep 10, 2022
16ecce3
Avoid unintended login as admin
nagmat84 Sep 11, 2022
e0ee662
Keep token-based authentication stateless + Fix tests
nagmat84 Sep 11, 2022
d6b8c95
Added test for logout
nagmat84 Sep 11, 2022
26b4bd4
Don't drop table
qwerty287 Sep 15, 2022
039d72f
Recompile frontend
qwerty287 Sep 15, 2022
9cd9f7c
Revert "Recompile frontend"
qwerty287 Sep 15, 2022
eaa3a17
Only migrate if not exists
qwerty287 Sep 15, 2022
b8916b8
Merge remote-tracking branch 'origin/master' into api-tokens
qwerty287 Sep 15, 2022
fc3fd82
Sync frontend to master
qwerty287 Sep 15, 2022
35bac96
Undo change
qwerty287 Sep 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/Actions/User/Create.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public function do(string $username, string $password, bool $mayUpload, bool $is
$user->is_locked = $isLocked;
$user->username = $username;
$user->password = bcrypt($password);
$user->token = strtr(base64_encode(random_bytes(16)), '+/', '-_');
} catch (\InvalidArgumentException $e) {
throw new InvalidPropertyException('Could not hash password', $e);
}
Expand Down
25 changes: 25 additions & 0 deletions app/Http/Controllers/Administration/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,29 @@ public function getEmail(): array
'email' => AccessControl::user()->email,
];
}

/**
* Returns the currently authenticated user.
*
* @return User
*/
public function getCurrent(): User
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
{
return AccessControl::user();
}

/**
* Reset the token of the currently authenticated user.
*
* @return User
*/
public function resetToken(): array
{
AccessControl::user()->token = strtr(base64_encode(random_bytes(16)), '+/', '-_');
AccessControl::user()->save();

return [
'token' => AccessControl::user()->token,
];
}
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
}
2 changes: 1 addition & 1 deletion app/Http/Middleware/AcceptContentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class AcceptContentType
public function handle(Request $request, \Closure $next, string $contentType): mixed
{
if ($contentType === self::JSON) {
if (!$request->expectsJson()) {
if (!$request->acceptsJson()) {
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
throw new UnexpectedContentType(self::JSON);
}
} elseif ($contentType === self::HTML) {
Expand Down
8 changes: 5 additions & 3 deletions app/Http/Middleware/ContentType.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ class ContentType
*/
public function handle(Request $request, \Closure $next, string $contentType): mixed
{
if ($contentType === self::JSON) {
$any = empty($request->getContentType()) || $request->getContentType() === '*/*';

if ($contentType === self::JSON && !$any) {
if (!$request->isJson()) {
throw new UnexpectedContentType(self::JSON);
}
} elseif ($contentType === self::MULTIPART) {
} elseif ($contentType === self::MULTIPART && !$any) {
if ($request->getContentType() !== 'form') {
throw new UnexpectedContentType(self::MULTIPART);
}
} else {
} elseif (!$any) {
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
throw new LycheeInvalidArgumentException('$contentType must either be "' . self::JSON . '" or "' . self::MULTIPART . '"');
}

Expand Down
34 changes: 17 additions & 17 deletions app/Http/Middleware/VerifyCsrfToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace App\Http\Middleware;

use App\Models\Configs;
use App\Facades\AccessControl;
use App\Models\User;
use Closure;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
use Illuminate\Session\TokenMismatchException;

Expand Down Expand Up @@ -36,26 +38,24 @@ class VerifyCsrfToken extends Middleware
public function handle($request, Closure $next)
{
if ($request->is('api/*')) {
/**
* default value is ''
* we force it in case of the migration has not been done.
*/
$apiKey = Configs::get_value('api_key', '');

/*
* if apiKey is the empty string we directly return the parent handle.
*/
if ($apiKey && $apiKey == '') {
$token = $request->header('Authorization');
if (!$token) {
return parent::handle($request, $next);
}

/*
* We are currently checking for Authorization.
* Do we also want to check if there is a POST value with the apiKey ?
*/
if ($apiKey && $request->header('Authorization') === $apiKey) {
return $next($request);
/** @var User $user */
$user = User::query()->where('token', '=', $token)->get();
if ($user instanceof Collection) {
$user = $user->get(0);
}
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved

if ($user === null) {
return parent::handle($request, $next);
}

AccessControl::log_as_id($user->id);

return $next($request);
}

return parent::handle($request, $next);
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/ChineseSimplified.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => '设置 OpenStreetMap 图层提供者',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => '智能相册',
'SHARED_ALBUMS' => '已共享的相册',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/ChineseTraditional.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => '設置OpenStreetMap圖層提供者',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => '智能相簿',
'SHARED_ALBUMS' => '共享的相簿',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Czech.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public function get_locale(): array
'SAVE_RISK' => 'Uložit změny, rizika jsou mi známa!',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Chytrá alba',
'SHARED_ALBUMS' => 'Sdílená alba',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Dutch.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Slimme albums',
'SHARED_ALBUMS' => 'Shared albums',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/English.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Smart albums',
'SHARED_ALBUMS' => 'Shared albums',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/French.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Selectioner le fournisseur de données cartographiques',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Smart Albums',
'SHARED_ALBUMS' => 'Albums partagés',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/German.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Speichere Provider für OpenStreetMap Karten',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'API-Schlüssel anzeigen',
'RESET' => 'Zurücksetzen',

'SAVE_RISK' => 'Änderungen speichern, ich kenne das Risiko!',

Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Greek.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Έξυπνα λευκώματα',
'SHARED_ALBUMS' => 'Κοινόχρηστα λευκώματα',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Italian.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Album smart',
'SHARED_ALBUMS' => 'Album condivisi',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/NorwegianBokmal.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Lagre leverandør for OpenStreetMap fliser',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Automatiske album',
'SHARED_ALBUMS' => 'Delte album',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Polish.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Inteligentne albumy',
'SHARED_ALBUMS' => 'Udostępnione albumy',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Portuguese.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Escolher OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Smart álbums',
'SHARED_ALBUMS' => 'Álbums partilhados',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Russian.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Метаальбомы',
'SHARED_ALBUMS' => 'Общие альбомы',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Slovak.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public function get_locale(): array
'SAVE_RISK' => 'Zmeny uložiť, riziko je známe!',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Inteligentné albumy',
'SHARED_ALBUMS' => 'Zdieľané albumy',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Spanish.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Álbumes inteligentes',
'SHARED_ALBUMS' => 'Álbumes compartidos',
Expand Down
2 changes: 2 additions & 0 deletions app/Locale/Swedish.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'VIEW_TOKEN' => 'View API token',
'RESET' => 'Reset',

'SMART_ALBUMS' => 'Smarta album',
'SHARED_ALBUMS' => 'Shared albums',
Expand Down
1 change: 1 addition & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
* @property string|null $email
* @property bool $may_upload
* @property bool $is_locked
* @property string $token
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though the token is public information (is it?) I wonder, if we should it to the hidden array such that it is not sent to the client when the user object is converted into JSON.

* @property string|null $remember_token
* @property Collection<BaseAlbumImpl> $albums
* @property DatabaseNotificationCollection|DatabaseNotification[] $notifications
Expand Down
64 changes: 64 additions & 0 deletions database/migrations/2022_06_12_075709_add_token_to_user_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

use App\Models\Configs;
use App\Models\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class AddTokenToUserTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*
* @throws Exception
*/
public function up(): void
{
$key_length = 16;

$old_key = Configs::get_value('api_key', '');
if (!$old_key) {
$old_key = strtr(base64_encode(random_bytes($key_length)), '+/', '-_');
}
ildyria marked this conversation as resolved.
Show resolved Hide resolved

Configs::where('key', '=', 'api_key')->delete();

Schema::table('users', function (Blueprint $table) {
$table->char('token', 100)->unique()->after('email')->default('needs-to-be-set');
});

foreach (User::all() as $user) {
if ($user->id === 0) {
$user->token = $old_key;
} else {
$user->token = strtr(base64_encode(random_bytes($key_length)), '+/', '-_');
}
$user->save();
}
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
DB::table('configs')->insert([
[
'key' => 'api_key',
'value' => User::query()->findOrFail(0)->token,
'confidentiality' => 0,
'cat' => 'config',
qwerty287 marked this conversation as resolved.
Show resolved Hide resolved
],
]);

Schema::table('users', function (Blueprint $table) {
$table->dropColumn('token');
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ongoing problem. SQLite does not support dropping columns yet. Dropping a column is mimic by re-creating a table without that column. But this throws away all foreign key constraints.

For the time being, we must abstain from dropping columns. But luckily this is only in the downwards path, not the upwards path. Otherwise we had to add it to the list in #1321.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #1368 (comment)

The ongoing problem. SQLite does not support dropping columns yet. Dropping a column is mimic by re-creating a table without that column. But this throws away all foreign key constraints.

For the time being, we must abstain from dropping columns. But luckily this is only in the downwards path, not the upwards path. Otherwise we had to add it to the list in #1321.

}
}
2 changes: 1 addition & 1 deletion public/Lychee-front
2 changes: 1 addition & 1 deletion public/dist/leaflet.markercluster.js.map

Large diffs are not rendered by default.

Loading