Skip to content

Commit

Permalink
Improve API client usability (LycheeOrg#1368)
Browse files Browse the repository at this point in the history
* Support API tokens per user

* Do not require Accept and Content-Type headers

* Fix 500 on user creation

* Recompile

* Fix some reviews

* Undo Content-Type and Accept change

* Fix phpstan

* Fix phpstan

* Fix phpstan 3

* add support for disabling the token completely rather than letting it set as a random value

* disable-enable FK

* add tests

* remove unused variable

* Translate and add strings

* Fix security issue during migration that gives admin perms to api_key

* Fix locale

* Sync frontend

* Suggestions

* Apply suggestions from code review

Co-authored-by: Matthias Nagel <matthias.h.nagel@posteo.de>

* Apply suggestions

* Recompile frontend

* Fix perms

* Fix lint

* Improve check

* Simplify middleware

* Assert JSON

* fix format

* Apply fixes from PHP-CS-Fixer (LycheeOrg#1444)

* add JetBrain Open Source Community Support (LycheeOrg#1442)

* add JetBrain Open Source Community Support

Co-authored-by: Matthias Nagel <matthias.h.nagel@posteo.de>
Co-authored-by: Martin Stone <1611702+d7415@users.noreply.github.com>

* Make VideoHandler support optional (LycheeOrg#1439)

* Make VideoHandler support optional

* Changes recommended by nagmat84

* Add a testcase for video upload without ffmpeg

* Fix new testcase

* Fix a typo

* Update tests/Feature/PhotosAddHandlerTestAbstract.php

Co-authored-by: Matthias Nagel <matthias.h.nagel@posteo.de>

* Check for error message that FFmpeg is disabled

* Fixed Google Motion Photo test

Co-authored-by: Matthias Nagel <matthias.h.nagel@posteo.de>

* Apply fixes from PHP-CS-Fixer

Co-authored-by: Benoît Viguier <ildyria@users.noreply.github.com>
Co-authored-by: Matthias Nagel <matthias.h.nagel@posteo.de>
Co-authored-by: Martin Stone <1611702+d7415@users.noreply.github.com>
Co-authored-by: Kamil Iskra <kamil.01482@iskra.name>
Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
Co-authored-by: github-actions[bot] <action@github.com>

* Hash tokens

* Sync frontend

* Tmp commit to find out why it's failing

* Second try to find failure

* I'm pretty stupid at all

* Fix db errors

* Fix phpstan

* Fix phpstan 2

* Fix phpstan 3

* Fix test

* Add tests and fix issues as guest

* sync frontend

* fix phpdoc

* Update locales and sync frontedn

* Fix duplicated keys

* Sync frontend

* Add getAuthenticatedUser test

* Don't send token with user, fix locales, synced frontend

* Make PHPStan happy about something toally unrelated

* Sync frontend

* fix sync

* Remove HasUserMiddleware

* Fix tests

* Added custom guard to handle session or token

* Avoid unintended login as admin

* Keep token-based authentication stateless + Fix tests

* Added test for logout

* Don't drop table

* Recompile frontend

* Revert "Recompile frontend"

This reverts commit 039d72f.

* Only migrate if not exists

* Sync frontend to master

* Undo change

Co-authored-by: ildyria <beviguier@gmail.com>
Co-authored-by: Matthias Nagel <matthias.h.nagel@posteo.de>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Benoît Viguier <ildyria@users.noreply.github.com>
Co-authored-by: Martin Stone <1611702+d7415@users.noreply.github.com>
Co-authored-by: Kamil Iskra <kamil.01482@iskra.name>
Co-authored-by: github-actions[bot] <action@github.com>
  • Loading branch information
8 people committed Sep 17, 2022
1 parent ed4240e commit 8c0bcb4
Show file tree
Hide file tree
Showing 36 changed files with 1,136 additions and 89 deletions.
13 changes: 13 additions & 0 deletions app/Exceptions/BadRequestHeaderException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Exceptions;

use Symfony\Component\HttpFoundation\Response;

class BadRequestHeaderException extends LycheeBaseException
{
public function __construct(string $msg, \Throwable $previous = null)
{
parent::__construct(Response::HTTP_BAD_REQUEST, $msg, $previous);
}
}
51 changes: 51 additions & 0 deletions app/Http/Controllers/Administration/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use App\Http\Requests\User\SetEmailRequest;
use App\Http\Requests\User\SetUserSettingsRequest;
use App\Models\User;
use Carbon\Exceptions\InvalidFormatException;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Auth;
Expand Down Expand Up @@ -67,6 +68,8 @@ public function save(SetUserSettingsRequest $request, Save $save): void
* @return void
*
* @throws ModelDBException
* @throws UnauthenticatedException
* @throws InvalidFormatException
*/
public function delete(DeleteUserRequest $request): void
{
Expand Down Expand Up @@ -139,4 +142,52 @@ public function getEmail(): array
'email' => $user->email,
];
}

/**
* Returns the currently authenticated user or `null` if no user
* is authenticated.
*
* @return User|null
*/
public function getAuthenticatedUser(): ?User
{
/** @var User|null */
return Auth::user();
}

/**
* Reset the token of the currently authenticated user.
*
* @return array{'token': string}
*
* @throws UnauthenticatedException
* @throws ModelDBException
* @throws \Exception
*/
public function resetToken(): array
{
/** @var User $user */
$user = Auth::user() ?? throw new UnauthenticatedException();
$token = strtr(base64_encode(random_bytes(16)), '+/', '-_');
$user->token = hash('SHA512', $token);
$user->save();

return ['token' => $token];
}

/**
* Disable the token of the currently authenticated user.
*
* @return void
*
* @throws UnauthenticatedException
* @throws ModelDBException
*/
public function unsetToken(): void
{
/** @var User $user */
$user = Auth::user() ?? throw new UnauthenticatedException();
$user->token = null;
$user->save();
}
}
1 change: 0 additions & 1 deletion app/Http/Controllers/IndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use App\ModelFunctions\ConfigFunctions;
use App\ModelFunctions\SymLinkFunctions;
use App\Models\Configs;
use App\Models\Page;
use Illuminate\Contracts\Container\BindingResolutionException;
use Illuminate\Routing\Controller;
use Illuminate\View\View;
Expand Down
7 changes: 0 additions & 7 deletions app/Http/Controllers/SessionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,6 @@ public function init(): array
*/
public function login(LoginRequest $request): void
{
// No login
if (AdminAuthentication::loginAsAdminIfNotRegistered()) {
Logs::warning(__METHOD__, __LINE__, 'DEFAULT LOGIN!');

return;
}

if (AdminAuthentication::loginAsAdmin($request->username(), $request->password(), $request->ip())) {
return;
}
Expand Down
33 changes: 8 additions & 25 deletions app/Http/Middleware/VerifyCsrfToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Http\Middleware;

use App\Models\Configs;
use App\Services\Auth\SessionOrTokenGuard;
use Closure;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
use Illuminate\Http\Request;
Expand All @@ -22,10 +22,11 @@ class VerifyCsrfToken extends Middleware
];

/**
* The goal of this function is to allow to bypass the CSRF token requirement
* if an Authorization value is provided in the header and matches the apiKey.
* Attempts to verify the CSRF token unless an API token is provided.
*
* FIXME: Do we want to hash this API key ? Might actually be a good idea...
* Note, if the API token is given but invalid (i.e. refers to a
* non-existing user), then {@link \App\Services\Auth\SessionOrTokenGuard}
* bails out.
*
* @param Request $request
* @param Closure $next
Expand All @@ -36,27 +37,9 @@ class VerifyCsrfToken extends Middleware
*/
public function handle($request, Closure $next): mixed
{
if ($request->is('api/*')) {
/**
* default value is ''
* we force it in case of the migration has not been done.
*/
$apiKey = Configs::getValueAsString('api_key');

/*
* if apiKey is the empty string we directly return the parent handle.
*/
if ($apiKey === '') {
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 ($request->header('Authorization') === $apiKey) {
return $next($request);
}
$token = $request->get(SessionOrTokenGuard::TOKEN_COLUMN_NAME);
if (is_string($token) && $token !== '') {
return $next($request);
}

return parent::handle($request, $next);
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/ChineseSimplified.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => '设置 OpenStreetMap 图层提供者',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => '智能相册',
'SHARED_ALBUMS' => '已共享的相册',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/ChineseTraditional.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => '設置OpenStreetMap圖層提供者',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => '智能相簿',
'SHARED_ALBUMS' => '共享的相簿',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Czech.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public function get_locale(): array
'SAVE_RISK' => 'Uložit změny, rizika jsou mi známa!',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Chytrá alba',
'SHARED_ALBUMS' => 'Sdílená alba',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Dutch.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Slimme albums',
'SHARED_ALBUMS' => 'Shared albums',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/English.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Smart albums',
'SHARED_ALBUMS' => 'Shared albums',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/French.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Selectioner le fournisseur de données cartographiques',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Smart Albums',
'SHARED_ALBUMS' => 'Albums partagés',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/German.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Speichere Provider für OpenStreetMap Karten',
'FULL_SETTINGS' => 'Alle Einstellungen',
'UPDATE' => 'Update',
'RESET' => 'Zurücksetzen',
'DISABLE_TOKEN_TOOLTIP' => 'Deaktivieren',
'ENABLE_TOKEN' => 'API-Schlüssel aktivieren',
'DISABLED_TOKEN_STATUS_MSG' => 'Deaktiviert',
'TOKEN_BUTTON' => 'API-Schlüssel ...',
'TOKEN_NOT_AVAILABLE' => 'Sie haben diesen Schlüssel bereits angesehen.',
'TOKEN_WAIT' => 'Warten ...',

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

Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Greek.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Έξυπνα λευκώματα',
'SHARED_ALBUMS' => 'Κοινόχρηστα λευκώματα',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Italian.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Album smart',
'SHARED_ALBUMS' => 'Album condivisi',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/NorwegianBokmal.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Lagre leverandør for OpenStreetMap fliser',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Automatiske album',
'SHARED_ALBUMS' => 'Delte album',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Polish.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Inteligentne albumy',
'SHARED_ALBUMS' => 'Udostępnione albumy',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Portuguese.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Escolher OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Smart álbums',
'SHARED_ALBUMS' => 'Álbums partilhados',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Russian.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Метаальбомы',
'SHARED_ALBUMS' => 'Общие альбомы',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Slovak.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ public function get_locale(): array
'SAVE_RISK' => 'Zmeny uložiť, riziko je známe!',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Inteligentné albumy',
'SHARED_ALBUMS' => 'Zdieľané albumy',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Spanish.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Álbumes inteligentes',
'SHARED_ALBUMS' => 'Álbumes compartidos',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Swedish.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Set OpenStreetMap tiles provider',
'FULL_SETTINGS' => 'Full Settings',
'UPDATE' => 'Update',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Smarta album',
'SHARED_ALBUMS' => 'Shared albums',
Expand Down
7 changes: 7 additions & 0 deletions app/Locale/Vietnamese.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ public function get_locale(): array
'SET_MAP_PROVIDER' => 'Cài đặt nhà cung cấp ô bản đồ OpenStreetMap',
'FULL_SETTINGS' => 'Toàn bộ cài đặt',
'UPDATE' => 'Cập nhật',
'RESET' => 'Reset',
'DISABLE_TOKEN_TOOLTIP' => 'Disable',
'ENABLE_TOKEN' => 'Enable API token',
'DISABLED_TOKEN_STATUS_MSG' => 'Disabled',
'TOKEN_BUTTON' => 'API Token ...',
'TOKEN_NOT_AVAILABLE' => 'You have already viewed this token.',
'TOKEN_WAIT' => 'Wait ...',

'SMART_ALBUMS' => 'Những album thông minh',
'SHARED_ALBUMS' => 'Những album được chia sẻ',
Expand Down
Loading

0 comments on commit 8c0bcb4

Please sign in to comment.