diff --git a/app/Http/Controllers/Api/Client/Servers/ServerController.php b/app/Http/Controllers/Api/Client/Servers/ServerController.php index ffb5a1bde..4cf91416d 100644 --- a/app/Http/Controllers/Api/Client/Servers/ServerController.php +++ b/app/Http/Controllers/Api/Client/Servers/ServerController.php @@ -3,12 +3,31 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers; use Pterodactyl\Models\Server; +use Pterodactyl\Repositories\Eloquent\SubuserRepository; use Pterodactyl\Transformers\Api\Client\ServerTransformer; +use Pterodactyl\Exceptions\Repository\RecordNotFoundException; use Pterodactyl\Http\Controllers\Api\Client\ClientApiController; use Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest; class ServerController extends ClientApiController { + /** + * @var \Pterodactyl\Repositories\Eloquent\SubuserRepository + */ + private $repository; + + /** + * ServerController constructor. + * + * @param \Pterodactyl\Repositories\Eloquent\SubuserRepository $repository + */ + public function __construct(SubuserRepository $repository) + { + parent::__construct(); + + $this->repository = $repository; + } + /** * Transform an individual server into a response that can be consumed by a * client using the API. @@ -19,8 +38,21 @@ class ServerController extends ClientApiController */ public function index(GetServerRequest $request, Server $server): array { + try { + $permissions = $this->repository->findFirstWhere([ + 'server_id' => $server->id, + 'user_id' => $request->user()->id, + ])->permissions; + } catch (RecordNotFoundException $exception) { + $permissions = []; + } + return $this->fractal->item($server) ->transformWith($this->getTransformer(ServerTransformer::class)) + ->addMeta([ + 'is_server_owner' => $request->user()->id === $server->owner_id, + 'user_permissions' => $permissions, + ]) ->toArray(); } } diff --git a/app/Models/Permission.php b/app/Models/Permission.php index dd3292d8b..11db34545 100644 --- a/app/Models/Permission.php +++ b/app/Models/Permission.php @@ -286,28 +286,4 @@ class Permission extends Validable return collect(self::$deprecatedPermissions); } - - /** - * Find permission by permission node. - * - * @param \Illuminate\Database\Query\Builder $query - * @param string $permission - * @return \Illuminate\Database\Query\Builder - */ - public function scopePermission($query, $permission) - { - return $query->where('permission', $permission); - } - - /** - * Filter permission by server. - * - * @param \Illuminate\Database\Query\Builder $query - * @param \Pterodactyl\Models\Server $server - * @return \Illuminate\Database\Query\Builder - */ - public function scopeServer($query, Server $server) - { - return $query->where('server_id', $server->id); - } } diff --git a/app/Models/Subuser.php b/app/Models/Subuser.php index 15f315f53..e5e8e318e 100644 --- a/app/Models/Subuser.php +++ b/app/Models/Subuser.php @@ -8,12 +8,12 @@ use Illuminate\Notifications\Notifiable; * @property int $id * @property int $user_id * @property int $server_id + * @property array $permissions * @property \Carbon\Carbon $created_at * @property \Carbon\Carbon $updated_at * * @property \Pterodactyl\Models\User $user * @property \Pterodactyl\Models\Server $server - * @property \Pterodactyl\Models\Permission[]|\Illuminate\Database\Eloquent\Collection $permissions */ class Subuser extends Validable { @@ -45,8 +45,9 @@ class Subuser extends Validable * @var array */ protected $casts = [ - 'user_id' => 'integer', - 'server_id' => 'integer', + 'user_id' => 'int', + 'server_id' => 'int', + 'permissions' => 'array', ]; /** @@ -55,6 +56,8 @@ class Subuser extends Validable public static $validationRules = [ 'user_id' => 'required|numeric|exists:users,id', 'server_id' => 'required|numeric|exists:servers,id', + 'permissions' => 'nullable|array', + 'permissions.*' => 'string', ]; /** diff --git a/app/Providers/RepositoryServiceProvider.php b/app/Providers/RepositoryServiceProvider.php index 99fccf823..6ee5a8d5c 100644 --- a/app/Providers/RepositoryServiceProvider.php +++ b/app/Providers/RepositoryServiceProvider.php @@ -21,7 +21,6 @@ use Pterodactyl\Repositories\Eloquent\SettingsRepository; use Pterodactyl\Repositories\Wings\DaemonPowerRepository; use Pterodactyl\Repositories\Eloquent\DaemonKeyRepository; use Pterodactyl\Repositories\Eloquent\AllocationRepository; -use Pterodactyl\Repositories\Eloquent\PermissionRepository; use Pterodactyl\Repositories\Wings\DaemonCommandRepository; use Pterodactyl\Contracts\Repository\EggRepositoryInterface; use Pterodactyl\Repositories\Eloquent\EggVariableRepository; @@ -43,7 +42,6 @@ use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface; use Pterodactyl\Repositories\Wings\DaemonConfigurationRepository; use Pterodactyl\Contracts\Repository\DaemonKeyRepositoryInterface; use Pterodactyl\Contracts\Repository\AllocationRepositoryInterface; -use Pterodactyl\Contracts\Repository\PermissionRepositoryInterface; use Pterodactyl\Contracts\Repository\Daemon\FileRepositoryInterface; use Pterodactyl\Contracts\Repository\EggVariableRepositoryInterface; use Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface; @@ -73,7 +71,6 @@ class RepositoryServiceProvider extends ServiceProvider $this->app->bind(NestRepositoryInterface::class, NestRepository::class); $this->app->bind(NodeRepositoryInterface::class, NodeRepository::class); $this->app->bind(PackRepositoryInterface::class, PackRepository::class); - $this->app->bind(PermissionRepositoryInterface::class, PermissionRepository::class); $this->app->bind(ScheduleRepositoryInterface::class, ScheduleRepository::class); $this->app->bind(ServerRepositoryInterface::class, ServerRepository::class); $this->app->bind(ServerVariableRepositoryInterface::class, ServerVariableRepository::class); diff --git a/app/Repositories/Eloquent/PermissionRepository.php b/app/Repositories/Eloquent/PermissionRepository.php index ad2fa6386..e2d0b8cb5 100644 --- a/app/Repositories/Eloquent/PermissionRepository.php +++ b/app/Repositories/Eloquent/PermissionRepository.php @@ -2,7 +2,7 @@ namespace Pterodactyl\Repositories\Eloquent; -use Pterodactyl\Models\Permission; +use Exception; use Pterodactyl\Contracts\Repository\PermissionRepositoryInterface; class PermissionRepository extends EloquentRepository implements PermissionRepositoryInterface @@ -11,9 +11,10 @@ class PermissionRepository extends EloquentRepository implements PermissionRepos * Return the model backing this repository. * * @return string + * @throws \Exception */ public function model() { - return Permission::class; + throw new Exception('This functionality is not implemented.'); } } diff --git a/database/migrations/2020_03_22_163911_merge_permissions_table_into_subusers.php b/database/migrations/2020_03_22_163911_merge_permissions_table_into_subusers.php new file mode 100644 index 000000000..1568ef726 --- /dev/null +++ b/database/migrations/2020_03_22_163911_merge_permissions_table_into_subusers.php @@ -0,0 +1,57 @@ +json('permissions')->nullable()->after('server_id'); + }); + + DB::statement(' + UPDATE subusers as s + LEFT JOIN ( + SELECT subuser_id, JSON_ARRAYAGG(permission) as permissions + FROM permissions + GROUP BY subuser_id + ) as p ON p.subuser_id = s.id + SET s.permissions = p.permissions + '); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + foreach (DB::select('SELECT id, permissions FROM subusers') as $datum) { + $values = []; + foreach(json_decode($datum->permissions, true) as $permission) { + $values[] = $datum->id; + $values[] = $permission; + } + + if (!empty($values)) { + $string = 'VALUES ' . implode(', ', array_fill(0, count($values) / 2, '(?, ?)')); + + DB::insert('INSERT INTO permissions(`subuser_id`, `permission`) ' . $string, $values); + } + } + + Schema::table('subusers', function (Blueprint $table) { + $table->dropColumn('permissions'); + }); + } +} diff --git a/database/migrations/2020_03_22_164814_drop_permissions_table.php b/database/migrations/2020_03_22_164814_drop_permissions_table.php new file mode 100644 index 000000000..da9d677a8 --- /dev/null +++ b/database/migrations/2020_03_22_164814_drop_permissions_table.php @@ -0,0 +1,34 @@ +increments('id'); + $table->unsignedInteger('subuser_id'); + $table->string('permission'); + + $table->foreign('subuser_id')->references('id')->on('subusers')->onDelete('cascade'); + }); + } +}