Implement application API Keys
This commit is contained in:
parent
f9fc3f4370
commit
c3b9738364
13 changed files with 454 additions and 3 deletions
|
@ -15,6 +15,14 @@ interface ApiKeyRepositoryInterface extends RepositoryInterface
|
|||
*/
|
||||
public function getAccountKeys(User $user): Collection;
|
||||
|
||||
/**
|
||||
* Get all of the application API keys that exist for a specific user.
|
||||
*
|
||||
* @param \Pterodactyl\Models\User $user
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getApplicationKeys(User $user): Collection;
|
||||
|
||||
/**
|
||||
* Delete an account API key from the panel for a specific user.
|
||||
*
|
||||
|
@ -23,4 +31,13 @@ interface ApiKeyRepositoryInterface extends RepositoryInterface
|
|||
* @return int
|
||||
*/
|
||||
public function deleteAccountKey(User $user, string $identifier): int;
|
||||
|
||||
/**
|
||||
* Delete an application API key from the panel for a specific user.
|
||||
*
|
||||
* @param \Pterodactyl\Models\User $user
|
||||
* @param string $identifier
|
||||
* @return int
|
||||
*/
|
||||
public function deleteApplicationKey(User $user, string $identifier): int;
|
||||
}
|
||||
|
|
117
app/Http/Controllers/Admin/ApplicationApiController.php
Normal file
117
app/Http/Controllers/Admin/ApplicationApiController.php
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Controllers\Admin;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Prologue\Alerts\AlertsMessageBag;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Controllers\Controller;
|
||||
use Pterodactyl\Services\Api\KeyCreationService;
|
||||
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
|
||||
use Pterodactyl\Http\Requests\Admin\Api\StoreApplicationApiKeyRequest;
|
||||
|
||||
class ApplicationApiController extends Controller
|
||||
{
|
||||
/**
|
||||
* @var \Prologue\Alerts\AlertsMessageBag
|
||||
*/
|
||||
private $alert;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Services\Api\KeyCreationService
|
||||
*/
|
||||
private $keyCreationService;
|
||||
|
||||
/**
|
||||
* @var \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* ApplicationApiController constructor.
|
||||
*
|
||||
* @param \Prologue\Alerts\AlertsMessageBag $alert
|
||||
* @param \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface $repository
|
||||
* @param \Pterodactyl\Services\Api\KeyCreationService $keyCreationService
|
||||
*/
|
||||
public function __construct(
|
||||
AlertsMessageBag $alert,
|
||||
ApiKeyRepositoryInterface $repository,
|
||||
KeyCreationService $keyCreationService
|
||||
) {
|
||||
$this->alert = $alert;
|
||||
$this->keyCreationService = $keyCreationService;
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render view showing all of a user's application API keys.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(Request $request): View
|
||||
{
|
||||
return view('admin.api.index', [
|
||||
'keys' => $this->repository->getApplicationKeys($request->user()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render view allowing an admin to create a new application API key.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
$resources = AdminAcl::getResourceList();
|
||||
sort($resources);
|
||||
|
||||
return view('admin.api.new', [
|
||||
'resources' => $resources,
|
||||
'permissions' => [
|
||||
'r' => AdminAcl::READ,
|
||||
'rw' => AdminAcl::READ | AdminAcl::WRITE,
|
||||
'n' => AdminAcl::NONE,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the new key and redirect the user back to the application key listing.
|
||||
*
|
||||
* @param \Pterodactyl\Http\Requests\Admin\Api\StoreApplicationApiKeyRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||
*/
|
||||
public function store(StoreApplicationApiKeyRequest $request): RedirectResponse
|
||||
{
|
||||
$this->keyCreationService->setKeyType(ApiKey::TYPE_APPLICATION)->handle([
|
||||
'memo' => $request->input('memo'),
|
||||
'user_id' => $request->user()->id,
|
||||
], $request->getKeyPermissions());
|
||||
|
||||
$this->alert->success('A new application API key has been generated for your account.')->flash();
|
||||
|
||||
return redirect()->route('admin.api.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an application API key from the database.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $identifier
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function delete(Request $request, string $identifier): Response
|
||||
{
|
||||
$this->repository->deleteApplicationKey($request->user(), $identifier);
|
||||
|
||||
return response('', 204);
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@ use Pterodactyl\Http\Middleware\RedirectIfAuthenticated;
|
|||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||
use Pterodactyl\Http\Middleware\Api\Admin\AuthenticateKey;
|
||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||
use Pterodactyl\Http\Middleware\Api\Admin\AuthenticateUser;
|
||||
use Pterodactyl\Http\Middleware\Api\Admin\SetSessionDriver;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Pterodactyl\Http\Middleware\Server\AuthenticateAsSubuser;
|
||||
|
@ -66,10 +67,11 @@ class Kernel extends HttpKernel
|
|||
RequireTwoFactorAuthentication::class,
|
||||
],
|
||||
'api' => [
|
||||
'throttle:60,1',
|
||||
'throttle:120,1',
|
||||
SubstituteBindings::class,
|
||||
SetSessionDriver::class,
|
||||
AuthenticateKey::class,
|
||||
AuthenticateUser::class,
|
||||
AuthenticateIPAccess::class,
|
||||
],
|
||||
'daemon' => [
|
||||
|
|
27
app/Http/Middleware/Api/Admin/AuthenticateUser.php
Normal file
27
app/Http/Middleware/Api/Admin/AuthenticateUser.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Middleware\Api\Admin;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
|
||||
class AuthenticateUser
|
||||
{
|
||||
/**
|
||||
* Authenticate that the currently authenticated user is an administrator
|
||||
* and should be allowed to proceede through the application API.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (is_null($request->user()) || ! $request->user()->root_admin) {
|
||||
throw new AccessDeniedHttpException;
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Pterodactyl\Http\Requests\Admin\Api;
|
||||
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||
use Pterodactyl\Http\Requests\Admin\AdminFormRequest;
|
||||
|
||||
class StoreApplicationApiKeyRequest extends AdminFormRequest
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$modelRules = ApiKey::getCreateRules();
|
||||
|
||||
return collect(AdminAcl::getResourceList())->mapWithKeys(function ($resource) use ($modelRules) {
|
||||
return [AdminAcl::COLUMN_IDENTIFER . $resource => $modelRules['r_' . $resource]];
|
||||
})->merge(['memo' => $modelRules['memo']])->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function attributes()
|
||||
{
|
||||
return [
|
||||
'memo' => 'Description',
|
||||
];
|
||||
}
|
||||
|
||||
public function getKeyPermissions(): array
|
||||
{
|
||||
return collect($this->validated())->filter(function ($value, $key) {
|
||||
return substr($key, 0, strlen(AdminAcl::COLUMN_IDENTIFER)) === AdminAcl::COLUMN_IDENTIFER;
|
||||
})->toArray();
|
||||
}
|
||||
}
|
|
@ -32,6 +32,19 @@ class ApiKeyRepository extends EloquentRepository implements ApiKeyRepositoryInt
|
|||
->get($this->getColumns());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all of the application API keys that exist for a specific user.
|
||||
*
|
||||
* @param \Pterodactyl\Models\User $user
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function getApplicationKeys(User $user): Collection
|
||||
{
|
||||
return $this->getBuilder()->where('user_id', $user->id)
|
||||
->where('key_type', ApiKey::TYPE_APPLICATION)
|
||||
->get($this->getColumns());
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an account API key from the panel for a specific user.
|
||||
*
|
||||
|
@ -46,4 +59,19 @@ class ApiKeyRepository extends EloquentRepository implements ApiKeyRepositoryInt
|
|||
->where('identifier', $identifier)
|
||||
->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an application API key from the panel for a specific user.
|
||||
*
|
||||
* @param \Pterodactyl\Models\User $user
|
||||
* @param string $identifier
|
||||
* @return int
|
||||
*/
|
||||
public function deleteApplicationKey(User $user, string $identifier): int
|
||||
{
|
||||
return $this->getBuilder()->where('user_id', $user->id)
|
||||
->where('key_type', ApiKey::TYPE_APPLICATION)
|
||||
->where('identifier', $identifier)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Pterodactyl\Services\Acl\Api;
|
||||
|
||||
use ReflectionClass;
|
||||
use Pterodactyl\Models\ApiKey;
|
||||
|
||||
class AdminAcl
|
||||
|
@ -22,7 +23,7 @@ class AdminAcl
|
|||
|
||||
/**
|
||||
* Resources that are available on the API and can contain a permissions
|
||||
* set for each key. These are stored in the database as permission_{resource}.
|
||||
* set for each key. These are stored in the database as r_{resource}.
|
||||
*/
|
||||
const RESOURCE_SERVERS = 'servers';
|
||||
const RESOURCE_NODES = 'nodes';
|
||||
|
@ -63,4 +64,18 @@ class AdminAcl
|
|||
{
|
||||
return self::can(data_get($key, self::COLUMN_IDENTIFER . $resource, self::NONE), $action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all resource constants defined in this ACL.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getResourceList(): array
|
||||
{
|
||||
$reflect = new ReflectionClass(__CLASS__);
|
||||
|
||||
return collect($reflect->getConstants())->filter(function ($value, $key) {
|
||||
return substr($key, 0, 9) === 'RESOURCE_';
|
||||
})->values()->toArray();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue