Add proper permissions for role application routes, allow admins to access application api
This commit is contained in:
parent
b6abeb0994
commit
9c7b49e2b9
|
@ -1,76 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Controllers\Api\Application;
|
|
||||||
|
|
||||||
use Illuminate\Http\JsonResponse;
|
|
||||||
use Pterodactyl\Http\Requests\Admin\RoleFormRequest;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\AdminRolesRepository;
|
|
||||||
|
|
||||||
class RoleController extends ApplicationApiController
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var \Pterodactyl\Repositories\Eloquent\AdminRolesRepository
|
|
||||||
*/
|
|
||||||
private $repository;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RolesController constructor.
|
|
||||||
*
|
|
||||||
* @param \Pterodactyl\Repositories\Eloquent\AdminRolesRepository $repository
|
|
||||||
*/
|
|
||||||
public function __construct(AdminRolesRepository $repository)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$this->repository = $repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of all roles.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
return new JsonResponse($this->repository->all());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new role.
|
|
||||||
*
|
|
||||||
* @param \Pterodactyl\Http\Requests\Admin\RoleFormRequest $request
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
public function create(RoleFormRequest $request)
|
|
||||||
{
|
|
||||||
$role = $this->repository->create($request->normalize());
|
|
||||||
|
|
||||||
return new JsonResponse($role);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates a role.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
|
|
||||||
*/
|
|
||||||
public function update()
|
|
||||||
{
|
|
||||||
return response('', 204);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a role.
|
|
||||||
*
|
|
||||||
* @param int $role_id
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
|
|
||||||
*/
|
|
||||||
public function delete(int $role_id)
|
|
||||||
{
|
|
||||||
$this->repository->delete($role_id);
|
|
||||||
|
|
||||||
return response('', 204);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Controllers\Api\Application\Roles;
|
||||||
|
|
||||||
|
use Illuminate\Http\JsonResponse;
|
||||||
|
use Pterodactyl\Models\AdminRole;
|
||||||
|
use Pterodactyl\Repositories\Eloquent\AdminRolesRepository;
|
||||||
|
use Pterodactyl\Transformers\Api\Application\AdminRoleTransformer;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Roles\StoreRoleRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Roles\DeleteRoleRequest;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\Roles\UpdateRoleRequest;
|
||||||
|
use Pterodactyl\Http\Controllers\Api\Application\ApplicationApiController;
|
||||||
|
|
||||||
|
class RoleController extends ApplicationApiController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Repositories\Eloquent\AdminRolesRepository
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RolesController constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Repositories\Eloquent\AdminRolesRepository $repository
|
||||||
|
*/
|
||||||
|
public function __construct(AdminRolesRepository $repository)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of all roles.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest $request
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function index(GetRolesRequest $request)
|
||||||
|
{
|
||||||
|
return $this->fractal->collection(AdminRole::all())
|
||||||
|
->transformWith($this->getTransformer(AdminRoleTransformer::class))
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a single role.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\GetRolesRequest $request
|
||||||
|
* @param \Pterodactyl\Models\AdminRole $role
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function view(GetRolesRequest $request, AdminRole $role): array
|
||||||
|
{
|
||||||
|
return $this->fractal->item($role)
|
||||||
|
->transformWith($this->getTransformer(AdminRoleTransformer::class))
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new role.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\StoreRoleRequest $request
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function store(StoreRoleRequest $request)
|
||||||
|
{
|
||||||
|
$role = AdminRole::query()->create($request->validated());
|
||||||
|
|
||||||
|
return $this->fractal->item($role)
|
||||||
|
->transformWith($this->getTransformer(AdminRoleTransformer::class))
|
||||||
|
->respond(JsonResponse::HTTP_CREATED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates a role.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\UpdateRoleRequest $request
|
||||||
|
* @param \Pterodactyl\Models\AdminRole $role
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function update(UpdateRoleRequest $request, AdminRole $role)
|
||||||
|
{
|
||||||
|
$role->update($request->validated());
|
||||||
|
|
||||||
|
return $this->fractal->item($role)
|
||||||
|
->transformWith($this->getTransformer(AdminRoleTransformer::class))
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a role.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Http\Requests\Api\Application\Roles\DeleteRoleRequest $request
|
||||||
|
* @param \Pterodactyl\Models\AdminRole $role
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function delete(DeleteRoleRequest $request, AdminRole $role)
|
||||||
|
{
|
||||||
|
$this->repository->delete($role->id);
|
||||||
|
|
||||||
|
return new JsonResponse([], JsonResponse::HTTP_NO_CONTENT);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Pterodactyl - Panel
|
|
||||||
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
|
||||||
*
|
|
||||||
* This software is licensed under the terms of the MIT license.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Pterodactyl\Http\Requests\Admin;
|
|
||||||
|
|
||||||
use Pterodactyl\Models\AdminRole;
|
|
||||||
|
|
||||||
class RoleFormRequest extends AdminFormRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Setup the validation rules to use for these requests.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function rules()
|
|
||||||
{
|
|
||||||
if ($this->method() === 'PATCH') {
|
|
||||||
return AdminRole::getRulesForUpdate($this->route()->parameter('mount')->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return AdminRole::getRules();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -50,6 +50,10 @@ abstract class ApplicationApiRequest extends FormRequest
|
||||||
throw new PterodactylException('An ACL resource must be defined on API requests.');
|
throw new PterodactylException('An ACL resource must be defined on API requests.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! is_null($this->user())) {
|
||||||
|
return $this->user()->root_admin;
|
||||||
|
}
|
||||||
|
|
||||||
return AdminAcl::check($this->key(), $this->resource, $this->permission);
|
return AdminAcl::check($this->key(), $this->resource, $this->permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\AdminRole;
|
||||||
|
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
|
||||||
|
class DeleteRoleRequest extends ApplicationApiRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $resource = AdminAcl::RESOURCE_ROLES;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $permission = AdminAcl::WRITE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the requested role exists on the Panel.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function resourceExists(): bool
|
||||||
|
{
|
||||||
|
$role = $this->route()->parameter('role');
|
||||||
|
|
||||||
|
return $role instanceof AdminRole && $role->exists;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\AdminRole;
|
||||||
|
|
||||||
|
class GetRoleRequest extends GetRolesRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the requested role exists on the Panel.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function resourceExists(): bool
|
||||||
|
{
|
||||||
|
$role = $this->route()->parameter('role');
|
||||||
|
|
||||||
|
return $role instanceof AdminRole && $role->exists;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||||
|
|
||||||
|
use Pterodactyl\Services\Acl\Api\AdminAcl as Acl;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
|
||||||
|
class GetRolesRequest extends ApplicationApiRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $resource = Acl::RESOURCE_ROLES;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $permission = Acl::READ;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\AdminRole;
|
||||||
|
use Pterodactyl\Services\Acl\Api\AdminAcl;
|
||||||
|
use Pterodactyl\Http\Requests\Api\Application\ApplicationApiRequest;
|
||||||
|
|
||||||
|
class StoreRoleRequest extends ApplicationApiRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $resource = AdminAcl::RESOURCE_ROLES;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $permission = AdminAcl::WRITE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ?
|
||||||
|
*
|
||||||
|
* @param array|null $rules
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(array $rules = null): array
|
||||||
|
{
|
||||||
|
return $rules ?? AdminRole::getRules();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Http\Requests\Api\Application\Roles;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\AdminRole;
|
||||||
|
|
||||||
|
class UpdateRoleRequest extends StoreRoleRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* ?
|
||||||
|
*
|
||||||
|
* @param array|null $rules
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules(array $rules = null): array
|
||||||
|
{
|
||||||
|
return $rules ?? AdminRole::getRulesForUpdate($this->route()->parameter('role')->id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ class ApiKey extends Model
|
||||||
'r_' . AdminAcl::RESOURCE_NESTS => 'int',
|
'r_' . AdminAcl::RESOURCE_NESTS => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_NODES => 'int',
|
'r_' . AdminAcl::RESOURCE_NODES => 'int',
|
||||||
'r_' . AdminAcl::RESOURCE_SERVERS => 'int',
|
'r_' . AdminAcl::RESOURCE_SERVERS => 'int',
|
||||||
|
'r_' . AdminAcl::RESOURCE_ROLES => 'int',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,6 +111,7 @@ class ApiKey extends Model
|
||||||
'r_' . AdminAcl::RESOURCE_NESTS => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_NESTS => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_NODES => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_NODES => 'integer|min:0|max:3',
|
||||||
'r_' . AdminAcl::RESOURCE_SERVERS => 'integer|min:0|max:3',
|
'r_' . AdminAcl::RESOURCE_SERVERS => 'integer|min:0|max:3',
|
||||||
|
'r_' . AdminAcl::RESOURCE_ROLES => 'integer|min:0|max:3',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,6 +34,7 @@ class AdminAcl
|
||||||
const RESOURCE_EGGS = 'eggs';
|
const RESOURCE_EGGS = 'eggs';
|
||||||
const RESOURCE_DATABASE_HOSTS = 'database_hosts';
|
const RESOURCE_DATABASE_HOSTS = 'database_hosts';
|
||||||
const RESOURCE_SERVER_DATABASES = 'server_databases';
|
const RESOURCE_SERVER_DATABASES = 'server_databases';
|
||||||
|
const RESOURCE_ROLES = 'roles';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if an API key has permission to perform a specific read/write operation.
|
* Determine if an API key has permission to perform a specific read/write operation.
|
||||||
|
@ -69,7 +70,6 @@ class AdminAcl
|
||||||
* Return a list of all resource constants defined in this ACL.
|
* Return a list of all resource constants defined in this ACL.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \ReflectionException
|
|
||||||
*/
|
*/
|
||||||
public static function getResourceList(): array
|
public static function getResourceList(): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Transformers\Api\Application;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\AdminRole;
|
||||||
|
|
||||||
|
class AdminRoleTransformer extends BaseTransformer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return the resource name for the JSONAPI output.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getResourceName(): string
|
||||||
|
{
|
||||||
|
return AdminRole::RESOURCE_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a transformed User model that can be consumed by external services.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\AdminRole $role
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function transform(AdminRole $role): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $role->id,
|
||||||
|
'name' => $role->name,
|
||||||
|
'description' => $role->description,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ export default (name: string, description?: string): Promise<Role> => {
|
||||||
http.post('/api/application/roles', {
|
http.post('/api/application/roles', {
|
||||||
name, description,
|
name, description,
|
||||||
})
|
})
|
||||||
.then(({ data }) => resolve(data))
|
.then(({ data }) => resolve(data.attributes))
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import http from '@/api/http';
|
import http from '@/api/http';
|
||||||
|
import { rawDataToAdminRole } from '@/api/transformers';
|
||||||
|
|
||||||
export interface Role {
|
export interface Role {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
description: string | null;
|
description: string | null;
|
||||||
sortId: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (): Promise<Role[]> => {
|
export default (): Promise<Role[]> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
http.get('/api/application/roles')
|
http.get('/api/application/roles')
|
||||||
.then(({ data }) => resolve(data || []))
|
.then(({ data }) => resolve((data.data || []).map(rawDataToAdminRole)))
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { Role } from '@/api/admin/roles/getRoles';
|
||||||
import { Allocation } from '@/api/server/getServer';
|
import { Allocation } from '@/api/server/getServer';
|
||||||
import { FractalResponseData } from '@/api/http';
|
import { FractalResponseData } from '@/api/http';
|
||||||
import { FileObject } from '@/api/server/files/loadDirectory';
|
import { FileObject } from '@/api/server/files/loadDirectory';
|
||||||
|
@ -74,3 +75,9 @@ export const rawDataToServerEggVariable = ({ attributes }: FractalResponseData):
|
||||||
isEditable: attributes.is_editable,
|
isEditable: attributes.is_editable,
|
||||||
rules: attributes.rules.split('|'),
|
rules: attributes.rules.split('|'),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const rawDataToAdminRole = ({ attributes }: FractalResponseData): Role => ({
|
||||||
|
id: attributes.id,
|
||||||
|
name: attributes.name,
|
||||||
|
description: attributes.description,
|
||||||
|
});
|
||||||
|
|
|
@ -131,9 +131,10 @@ Route::group(['prefix' => '/nests'], function () {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group(['prefix' => '/roles'], function () {
|
Route::group(['prefix' => '/roles'], function () {
|
||||||
Route::get('/', 'RoleController@index')->name('api.application.roles');
|
Route::get('/', 'Roles\RoleController@index');
|
||||||
|
Route::get('/{role}', 'Roles\RoleController@view');
|
||||||
|
|
||||||
Route::post('/', 'RoleController@create');
|
Route::post('/', 'Roles\oleController@store');
|
||||||
|
|
||||||
Route::delete('/{role}', 'RoleController@delete');
|
Route::delete('/{role}', 'Roles\RoleController@delete');
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue