Add SFTP management to server front-end
This commit is contained in:
parent
b6e83b8e32
commit
52229d5d2e
6 changed files with 196 additions and 8 deletions
|
@ -24,16 +24,21 @@
|
||||||
namespace Pterodactyl\Http\Controllers\Server;
|
namespace Pterodactyl\Http\Controllers\Server;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
|
use Debugbar;
|
||||||
|
use Uuid;
|
||||||
|
use Alert;
|
||||||
|
use Log;
|
||||||
|
|
||||||
use Pterodactyl\Models\Server;
|
use Pterodactyl\Models\Server;
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
use Pterodactyl\Models\Download;
|
use Pterodactyl\Models\Download;
|
||||||
use Pterodactyl\Models\Allocation;
|
use Pterodactyl\Models\Allocation;
|
||||||
use Debugbar;
|
|
||||||
use Uuid;
|
|
||||||
use Alert;
|
|
||||||
|
|
||||||
use Pterodactyl\Exceptions\DisplayException;
|
use Pterodactyl\Exceptions\DisplayException;
|
||||||
use Pterodactyl\Repositories;
|
use Pterodactyl\Exceptions\DisplayValidationException;
|
||||||
|
use Pterodactyl\Repositories\Daemon\FileRepository;
|
||||||
|
use Pterodactyl\Repositories\ServerRepository;
|
||||||
|
|
||||||
use Pterodactyl\Http\Controllers\Controller;
|
use Pterodactyl\Http\Controllers\Controller;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
@ -127,7 +132,7 @@ class ServerController extends Controller
|
||||||
$this->authorize('edit-files', $server);
|
$this->authorize('edit-files', $server);
|
||||||
|
|
||||||
$fileInfo = (object) pathinfo($file);
|
$fileInfo = (object) pathinfo($file);
|
||||||
$controller = new Repositories\Daemon\FileRepository($uuid);
|
$controller = new FileRepository($uuid);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$fileContent = $controller->returnFileContents($file);
|
$fileContent = $controller->returnFileContents($file);
|
||||||
|
@ -184,4 +189,39 @@ class ServerController extends Controller
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders server settings page.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function getSettings(Request $request, $uuid)
|
||||||
|
{
|
||||||
|
$server = Server::getByUUID($uuid);
|
||||||
|
return view('server.settings', [
|
||||||
|
'server' => $server,
|
||||||
|
'node' => Node::find($server->node)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function postSettingsSFTP(Request $request, $uuid)
|
||||||
|
{
|
||||||
|
$server = Server::getByUUID($uuid);
|
||||||
|
$this->authorize('reset-sftp', $server);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$repo = new ServerRepository;
|
||||||
|
$repo->updateSFTPPassword($server->id, $request->input('sftp_pass'));
|
||||||
|
Alert::success('Successfully updated this servers SFTP password.')->flash();
|
||||||
|
} catch (DisplayValidationException $ex) {
|
||||||
|
return redirect()->route('server.settings', $uuid)->withErrors(json_decode($ex->getMessage()));
|
||||||
|
} catch (DisplayException $ex) {
|
||||||
|
Alert::danger($ex->getMessage())->flash();
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
Log::error($ex);
|
||||||
|
Alert::danger('An unknown error occured while attempting to update this server\'s SFTP settings.')->flash();
|
||||||
|
}
|
||||||
|
return redirect()->route('server.settings', $uuid);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,17 @@ class ServerRoutes {
|
||||||
'uses' => 'Server\ServerController@getIndex'
|
'uses' => 'Server\ServerController@getIndex'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
$router->get('/settings', [
|
||||||
|
'as' => 'server.settings',
|
||||||
|
'uses' => 'Server\ServerController@getSettings'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$router->post('/settings/sftp', [
|
||||||
|
'as' => 'server.settings.sftp',
|
||||||
|
'uses' => 'Server\ServerController@postSettingsSFTP'
|
||||||
|
]);
|
||||||
|
|
||||||
// File Manager Routes
|
// File Manager Routes
|
||||||
$router->get('/files', [
|
$router->get('/files', [
|
||||||
'as' => 'files.index',
|
'as' => 'files.index',
|
||||||
|
|
|
@ -98,8 +98,8 @@ class Node extends Model
|
||||||
// @TODO: Better solution to disabling verification. Security risk.
|
// @TODO: Better solution to disabling verification. Security risk.
|
||||||
self::$guzzle[$node] = new Client([
|
self::$guzzle[$node] = new Client([
|
||||||
'base_uri' => sprintf('%s://%s:%s/', $nodeData->scheme, $nodeData->fqdn, $nodeData->daemonListen),
|
'base_uri' => sprintf('%s://%s:%s/', $nodeData->scheme, $nodeData->fqdn, $nodeData->daemonListen),
|
||||||
'timeout' => 10.0,
|
'timeout' => 5.0,
|
||||||
'connect_timeout' => 5.0,
|
'connect_timeout' => 3.0,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return self::$guzzle[$node];
|
return self::$guzzle[$node];
|
||||||
|
|
|
@ -724,4 +724,39 @@ class ServerRepository
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function updateSFTPPassword($id, $password)
|
||||||
|
{
|
||||||
|
$server = Models\Server::findOrFail($id);
|
||||||
|
$node = Models\Node::findOrFail($server->node);
|
||||||
|
|
||||||
|
$validator = Validator::make([
|
||||||
|
'password' => $password,
|
||||||
|
], [
|
||||||
|
'password' => 'required|regex:/^((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})$/'
|
||||||
|
]);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new DisplayValidationException(json_encode($validator->errors()));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$client = Models\Node::guzzleRequest($server->node);
|
||||||
|
$client->request('POST', '/server/password', [
|
||||||
|
'headers' => [
|
||||||
|
'X-Access-Token' => $node->daemonSecret,
|
||||||
|
'X-Access-Server' => $server->uuid
|
||||||
|
],
|
||||||
|
'json' => [
|
||||||
|
'password' => $password,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
} catch (\GuzzleHttp\Exception\TransferException $ex) {
|
||||||
|
throw new DisplayException('There was an error while attmping to contact the remote service to change the password.');
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
throw $ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,13 @@
|
||||||
<a href="/server/{{ $server->uuidShort }}/" class="list-group-item server-index">{{ trans('pagination.sidebar.overview') }}</a>
|
<a href="/server/{{ $server->uuidShort }}/" class="list-group-item server-index">{{ trans('pagination.sidebar.overview') }}</a>
|
||||||
@can('list-files', $server)<a href="/server/{{ $server->uuidShort }}/files" class="list-group-item server-files">{{ trans('pagination.sidebar.files') }}</a>@endcan
|
@can('list-files', $server)<a href="/server/{{ $server->uuidShort }}/files" class="list-group-item server-files">{{ trans('pagination.sidebar.files') }}</a>@endcan
|
||||||
@can('list-subusers', $server)<a href="/server/{{ $server->uuidShort }}/users" class="list-group-item server-users">{{ trans('pagination.sidebar.subusers') }}</a>@endcan
|
@can('list-subusers', $server)<a href="/server/{{ $server->uuidShort }}/users" class="list-group-item server-users">{{ trans('pagination.sidebar.subusers') }}</a>@endcan
|
||||||
@can('view-manage', $server)<a href="/server/{{ $server->uuidShort }}/settings" class="list-group-item server-settings">{{ trans('pagination.sidebar.manage') }}</a>@endcan
|
@can('view-sftp', $server)
|
||||||
|
<a href="/server/{{ $server->uuidShort }}/settings" class="list-group-item server-settings">{{ trans('pagination.sidebar.manage') }}</a>
|
||||||
|
@else
|
||||||
|
@can('view-startup', $server)
|
||||||
|
<a href="/server/{{ $server->uuidShort }}/settings" class="list-group-item server-settings">{{ trans('pagination.sidebar.manage') }}</a>
|
||||||
|
@endcan
|
||||||
|
@endcan
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@show
|
@show
|
||||||
|
|
96
resources/views/server/settings.blade.php
Normal file
96
resources/views/server/settings.blade.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
{{--
|
||||||
|
Copyright (c) 2015 - 2016 Dane Everitt <dane@daneeveritt.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
--}}
|
||||||
|
@extends('layouts.master')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Server Settings
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h3 class="nopad">Server Settings</h3><hr />
|
||||||
|
<ul class="nav nav-tabs tabs_with_panel" id="config_tabs">
|
||||||
|
@can('view-sftp', $server)<li class="active"><a href="#tab_sftp" data-toggle="tab">SFTP Settings</a></li>@endcan
|
||||||
|
@can('view-startup', $server)<li><a href="#tab_startup" data-toggle="tab">Startup Configuration</a></li>@endcan
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
@can('view-sftp', $server)
|
||||||
|
<div class="tab-pane active" id="tab_sftp">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label class="control-label">SFTP Connection Address:</label>
|
||||||
|
<div>
|
||||||
|
<input type="text" readonly="readonly" class="form-control" value="{{ $node->fqdn }}:{{ $node->daemonSFTP }}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label class="control-label">SFTP Username:</label>
|
||||||
|
<div>
|
||||||
|
<input type="text" readonly="readonly" class="form-control" value="{{ $server->username }}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@can('reset-sftp', $server)
|
||||||
|
<form action="{{ route('server.settings.sftp', $server->uuidShort) }}" method="POST">
|
||||||
|
<div class="row">
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label class="control-label">New SFTP Password:</label>
|
||||||
|
<div>
|
||||||
|
<input type="password" name="sftp_pass" class="form-control" />
|
||||||
|
<p class="text-muted"><small>Passwords must meet the following requirements: at least one uppercase character, one lowercase character, one digit, and be at least 8 characters in length. <a href="#" data-action="generate-password">Click here</a> to generate one to use.</small></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group col-md-6">
|
||||||
|
<label class="control-label"> </label>
|
||||||
|
<div>
|
||||||
|
{!! csrf_field() !!}
|
||||||
|
<input type="submit" class="btn btn-sm btn-primary" value="Update Password" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
@endcan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endcan
|
||||||
|
@can('view-startup', $server)
|
||||||
|
<div class="tab-pane" id="tab_startup">
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
Startup
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endcan
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('.server-settings').addClass('active');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endsection
|
Loading…
Reference in a new issue