mirror of
https://github.com/Kovah/LinkAce.git
synced 2025-03-14 19:59:38 +01:00
Adjust api model authorization
This commit is contained in:
parent
f0421b7222
commit
0f0e266101
@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\ChecksOrdering;
|
||||
use App\Http\Requests\Models\ListStoreRequest;
|
||||
use App\Http\Requests\Models\ListUpdateRequest;
|
||||
use App\Models\Api\ApiLinkList;
|
||||
use App\Models\LinkList;
|
||||
use App\Repositories\ListRepository;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@ -17,8 +18,8 @@ class ListController extends Controller
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->allowedOrderBy = LinkList::$allowOrderBy;
|
||||
$this->authorizeResource(LinkList::class . 'Api', 'list');
|
||||
$this->allowedOrderBy = ApiLinkList::$allowOrderBy;
|
||||
$this->authorizeResource(ApiLinkList::class, 'list');
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers\API;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Models\NoteStoreRequest;
|
||||
use App\Http\Requests\Models\NoteUpdateRequest;
|
||||
use App\Models\Api\ApiNote;
|
||||
use App\Models\Note;
|
||||
use App\Repositories\NoteRepository;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@ -14,7 +15,7 @@ class NoteController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Note::class . 'Api', 'note');
|
||||
$this->authorizeResource(ApiNote::class, 'note');
|
||||
}
|
||||
|
||||
public function store(NoteStoreRequest $request): JsonResponse
|
||||
|
@ -6,6 +6,7 @@ use App\Http\Controllers\Controller;
|
||||
use App\Http\Controllers\Traits\ChecksOrdering;
|
||||
use App\Http\Requests\Models\TagStoreRequest;
|
||||
use App\Http\Requests\Models\TagUpdateRequest;
|
||||
use App\Models\Api\ApiTag;
|
||||
use App\Models\Tag;
|
||||
use App\Repositories\TagRepository;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
@ -17,8 +18,8 @@ class TagController extends Controller
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->allowedOrderBy = Tag::$allowOrderBy;
|
||||
$this->authorizeResource(Tag::class . 'Api', 'tag');
|
||||
$this->allowedOrderBy = ApiTag::$allowOrderBy;
|
||||
$this->authorizeResource(ApiTag::class, 'tag');
|
||||
}
|
||||
|
||||
public function index(Request $request): JsonResponse
|
||||
|
@ -6,5 +6,5 @@ use App\Models\Link;
|
||||
|
||||
class ApiLink extends Link
|
||||
{
|
||||
protected $table = 'links';
|
||||
public $table = 'links';
|
||||
}
|
||||
|
10
app/Models/Api/ApiLinkList.php
Normal file
10
app/Models/Api/ApiLinkList.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Api;
|
||||
|
||||
use App\Models\LinkList;
|
||||
|
||||
class ApiLinkList extends LinkList
|
||||
{
|
||||
public $table = 'lists';
|
||||
}
|
10
app/Models/Api/ApiNote.php
Normal file
10
app/Models/Api/ApiNote.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Api;
|
||||
|
||||
use App\Models\Note;
|
||||
|
||||
class ApiNote extends Note
|
||||
{
|
||||
public $table = 'notes';
|
||||
}
|
10
app/Models/Api/ApiTag.php
Normal file
10
app/Models/Api/ApiTag.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Api;
|
||||
|
||||
use App\Models\Tag;
|
||||
|
||||
class ApiTag extends Tag
|
||||
{
|
||||
public $table = 'tags';
|
||||
}
|
@ -3,7 +3,6 @@
|
||||
namespace App\Policies\Api;
|
||||
|
||||
use App\Enums\ApiToken;
|
||||
use App\Enums\ModelAttribute;
|
||||
use App\Models\Api\ApiLink;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
@ -11,6 +10,11 @@ use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
class ApiLinkPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
use AuthorizesUserApiActions;
|
||||
|
||||
protected string $readAbility = ApiToken::ABILITY_LINKS_READ;
|
||||
protected string $updateAbility = ApiToken::ABILITY_LINKS_UPDATE;
|
||||
protected string $deleteAbility = ApiToken::ABILITY_LINKS_DELETE;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
@ -22,7 +26,7 @@ class ApiLinkPolicy
|
||||
|
||||
public function view(User $user, ApiLink $link): bool
|
||||
{
|
||||
return $this->userCanAccessLink($user, $link);
|
||||
return $this->userCanAccessModel($user, $link);
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
@ -32,7 +36,7 @@ class ApiLinkPolicy
|
||||
|
||||
public function update(User $user, ApiLink $link): bool
|
||||
{
|
||||
return $this->userCanUpdateLink($user, $link);
|
||||
return $this->userCanUpdateModel($user, $link);
|
||||
}
|
||||
|
||||
public function delete(User $user, ApiLink $link): bool
|
||||
@ -49,33 +53,4 @@ class ApiLinkPolicy
|
||||
{
|
||||
return $link->user->is($user);
|
||||
}
|
||||
|
||||
// Link must be either owned by user, or be not private
|
||||
protected function userCanAccessLink(User $user, ApiLink $link): bool
|
||||
{
|
||||
if ($link->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
if ($user->isSystemUser()) {
|
||||
if ($link->visibility === ModelAttribute::VISIBILITY_PRIVATE) {
|
||||
return $user->tokenCan(ApiToken::ABILITY_LINKS_READ) && $user->tokenCan(ApiToken::ABILITY_SYSTEM_ACCESS_PRIVATE);
|
||||
}
|
||||
return $user->tokenCan(ApiToken::ABILITY_LINKS_READ);
|
||||
}
|
||||
return $link->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
|
||||
protected function userCanUpdateLink(User $user, ApiLink $link): bool
|
||||
{
|
||||
if ($link->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
if ($user->isSystemUser()) {
|
||||
if ($link->visibility === ModelAttribute::VISIBILITY_PRIVATE) {
|
||||
return $user->tokenCan(ApiToken::ABILITY_LINKS_UPDATE) && $user->tokenCan(ApiToken::ABILITY_SYSTEM_ACCESS_PRIVATE);
|
||||
}
|
||||
return $user->tokenCan(ApiToken::ABILITY_LINKS_UPDATE);
|
||||
}
|
||||
return $link->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
39
app/Policies/Api/AuthorizesUserApiActions.php
Normal file
39
app/Policies/Api/AuthorizesUserApiActions.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies\Api;
|
||||
|
||||
use App\Enums\ApiToken;
|
||||
use App\Enums\ModelAttribute;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
trait AuthorizesUserApiActions
|
||||
{
|
||||
protected function userCanAccessModel(User $user, Model $model): bool
|
||||
{
|
||||
if ($model->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
if ($user->isSystemUser()) {
|
||||
if ($model->visibility === ModelAttribute::VISIBILITY_PRIVATE) {
|
||||
return $user->tokenCan($this->readAbility) && $user->tokenCan(ApiToken::ABILITY_SYSTEM_ACCESS_PRIVATE);
|
||||
}
|
||||
return $user->tokenCan($this->readAbility);
|
||||
}
|
||||
return $model->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
|
||||
protected function userCanUpdateModel(User $user, Model $model): bool
|
||||
{
|
||||
if ($model->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
if ($user->isSystemUser()) {
|
||||
if ($model->visibility === ModelAttribute::VISIBILITY_PRIVATE) {
|
||||
return $user->tokenCan($this->updateAbility) && $user->tokenCan(ApiToken::ABILITY_SYSTEM_ACCESS_PRIVATE);
|
||||
}
|
||||
return $user->tokenCan($this->updateAbility);
|
||||
}
|
||||
return $model->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
}
|
@ -2,23 +2,28 @@
|
||||
|
||||
namespace App\Policies\Api;
|
||||
|
||||
use App\Enums\ModelAttribute;
|
||||
use App\Models\LinkList;
|
||||
use App\Enums\ApiToken;
|
||||
use App\Models\Api\ApiLinkList;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class LinkListApiPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
use AuthorizesUserApiActions;
|
||||
|
||||
protected string $readAbility = ApiToken::ABILITY_LISTS_READ;
|
||||
protected string $updateAbility = ApiToken::ABILITY_LISTS_UPDATE;
|
||||
protected string $deleteAbility = ApiToken::ABILITY_LISTS_DELETE;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function view(User $user, LinkList $list): bool
|
||||
public function view(User $user, ApiLinkList $list): bool
|
||||
{
|
||||
return $this->userCanAccessList($user, $list);
|
||||
return $this->userCanAccessModel($user, $list);
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
@ -26,32 +31,23 @@ class LinkListApiPolicy
|
||||
return true;
|
||||
}
|
||||
|
||||
public function update(User $user, LinkList $list): bool
|
||||
public function update(User $user, ApiLinkList $list): bool
|
||||
{
|
||||
return $this->userCanAccessList($user, $list);
|
||||
return $this->userCanUpdateModel($user, $list);
|
||||
}
|
||||
|
||||
public function delete(User $user, LinkList $list): bool
|
||||
public function delete(User $user, ApiLinkList $list): bool
|
||||
{
|
||||
return $list->user->is($user);
|
||||
}
|
||||
|
||||
public function restore(User $user, LinkList $list): bool
|
||||
public function restore(User $user, ApiLinkList $list): bool
|
||||
{
|
||||
return $list->user->is($user);
|
||||
}
|
||||
|
||||
public function forceDelete(User $user, LinkList $list): bool
|
||||
public function forceDelete(User $user, ApiLinkList $list): bool
|
||||
{
|
||||
return $list->user->is($user);
|
||||
}
|
||||
|
||||
// Link must be either owned by user, or be not private
|
||||
protected function userCanAccessList(User $user, LinkList $list): bool
|
||||
{
|
||||
if ($list->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
return $list->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Policies\Api;
|
||||
|
||||
use App\Enums\ModelAttribute;
|
||||
use App\Enums\ApiToken;
|
||||
use App\Models\Note;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
@ -10,6 +10,11 @@ use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
class NoteApiPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
use AuthorizesUserApiActions;
|
||||
|
||||
protected string $readAbility = ApiToken::ABILITY_NOTES_READ;
|
||||
protected string $updateAbility = ApiToken::ABILITY_NOTES_UPDATE;
|
||||
protected string $deleteAbility = ApiToken::ABILITY_NOTES_DELETE;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
@ -45,13 +50,4 @@ class NoteApiPolicy
|
||||
{
|
||||
return $note->user->is($user);
|
||||
}
|
||||
|
||||
// Link must be either owned by user, or be not private
|
||||
protected function userCanAccessNote(User $user, Note $note): bool
|
||||
{
|
||||
if ($note->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
return $note->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Policies\Api;
|
||||
|
||||
use App\Enums\ModelAttribute;
|
||||
use App\Enums\ApiToken;
|
||||
use App\Models\Tag;
|
||||
use App\Models\User;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
@ -10,6 +10,11 @@ use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
class TagApiPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
use AuthorizesUserApiActions;
|
||||
|
||||
protected string $readAbility = ApiToken::ABILITY_TAGS_READ;
|
||||
protected string $updateAbility = ApiToken::ABILITY_TAGS_UPDATE;
|
||||
protected string $deleteAbility = ApiToken::ABILITY_TAGS_DELETE;
|
||||
|
||||
public function viewAny(User $user): bool
|
||||
{
|
||||
@ -18,7 +23,7 @@ class TagApiPolicy
|
||||
|
||||
public function view(User $user, Tag $tag): bool
|
||||
{
|
||||
return $this->userCanAccessTag($user, $tag);
|
||||
return $this->userCanAccessModel($user, $tag);
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
@ -28,7 +33,7 @@ class TagApiPolicy
|
||||
|
||||
public function update(User $user, Tag $tag): bool
|
||||
{
|
||||
return $this->userCanAccessTag($user, $tag);
|
||||
return $this->userCanUpdateModel($user, $tag);
|
||||
}
|
||||
|
||||
public function delete(User $user, Tag $tag): bool
|
||||
@ -45,13 +50,4 @@ class TagApiPolicy
|
||||
{
|
||||
return $tag->user->is($user);
|
||||
}
|
||||
|
||||
// Link must be either owned by user, or be not private
|
||||
protected function userCanAccessTag(User $user, Tag $tag): bool
|
||||
{
|
||||
if ($tag->user_id === $user->id) {
|
||||
return true;
|
||||
}
|
||||
return $tag->visibility !== ModelAttribute::VISIBILITY_PRIVATE;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,9 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Api\ApiLink;
|
||||
use App\Models\Api\ApiLinkList;
|
||||
use App\Models\Api\ApiNote;
|
||||
use App\Models\Api\ApiTag;
|
||||
use App\Models\Link;
|
||||
use App\Models\LinkList;
|
||||
use App\Models\Note;
|
||||
@ -33,9 +36,9 @@ class AuthServiceProvider extends ServiceProvider
|
||||
Tag::class => TagPolicy::class,
|
||||
PersonalAccessToken::class => ApiTokenPolicy::class,
|
||||
ApiLink::class => ApiLinkPolicy::class,
|
||||
LinkList::class . 'Api' => LinkListApiPolicy::class,
|
||||
Note::class . 'Api' => NoteApiPolicy::class,
|
||||
Tag::class . 'Api' => TagApiPolicy::class,
|
||||
ApiLinkList::class => LinkListApiPolicy::class,
|
||||
ApiNote::class => NoteApiPolicy::class,
|
||||
ApiTag::class => TagApiPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -4,6 +4,7 @@ namespace Tests;
|
||||
|
||||
use App\Settings\SystemSettings;
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
@ -13,6 +14,7 @@ abstract class TestCase extends BaseTestCase
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
Http::preventStrayRequests();
|
||||
|
||||
if (Schema::hasTable('settings')) {
|
||||
SystemSettings::fake([
|
||||
|
Loading…
x
Reference in New Issue
Block a user