Skip to content

Commit 5233d6e

Browse files
committed
Add database password change support and fix column name
1 parent 0d61c50 commit 5233d6e

File tree

11 files changed

+188
-9
lines changed

11 files changed

+188
-9
lines changed

app/Http/Controllers/Admin/DatabaseController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function getIndex(Request $request)
5656
'servers.id as a_serverId',
5757
'servers.name as a_serverName'
5858
)->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
59-
->join('servers', 'databases.server', '=', 'servers.id')
59+
->join('servers', 'databases.server_id', '=', 'servers.id')
6060
->paginate(20),
6161
'dbh' => Models\DatabaseServer::select(
6262
'database_servers.*',

app/Http/Controllers/Admin/ServersController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public function getView(Request $request, $id)
9999
->where('server_variables.server_id', $server->id)
100100
->get(),
101101
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
102-
->where('server', $server->id)
102+
->where('server_id', $server->id)
103103
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
104104
->get(),
105105
'db_servers' => Models\DatabaseServer::all()

app/Http/Controllers/Server/AjaxController.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
use Log;
2727
use Debugbar;
28+
use Pterodactyl\Models;
2829
use Pterodactyl\Models\Server;
2930
use Pterodactyl\Models\Node;
3031

@@ -223,4 +224,28 @@ public function postSetConnection(Request $request, $uuid)
223224
}
224225
}
225226

227+
public function postResetDatabasePassword(Request $request, $uuid)
228+
{
229+
$server = Models\Server::getByUUID($uuid);
230+
$database = Models\Database::where('id', $request->input('database'))->where('server_id', $server->id)->firstOrFail();
231+
232+
$this->authorize('reset-db-password', $server);
233+
try {
234+
235+
$repo = new Repositories\DatabaseRepository;
236+
$password = str_random(16);
237+
$repo->modifyPassword($request->input('database'), $password);
238+
return response($password);
239+
} catch (\Pterodactyl\Exceptions\DisplayException $ex) {
240+
return response()->json([
241+
'error' => $ex->getMessage(),
242+
], 503);
243+
} catch(\Exception $ex) {
244+
Log::error($ex);
245+
return response()->json([
246+
'error' => 'An unhandled error occured while attempting to modify this database\'s password.'
247+
], 503);
248+
}
249+
}
250+
226251
}

app/Http/Controllers/Server/ServerController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ public function getSettings(Request $request, $uuid)
229229
return view('server.settings', [
230230
'server' => $server,
231231
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
232-
->where('server', $server->id)
232+
->where('server_id', $server->id)
233233
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
234234
->get(),
235235
'node' => Models\Node::find($server->node),

app/Http/Routes/ServerRoutes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,11 @@ public function map(Router $router) {
152152
$router->post('set-connection', [
153153
'uses' => 'Server\AjaxController@postSetConnection'
154154
]);
155+
156+
$router->post('settings/reset-database-password', [
157+
'as' => 'server.ajax.reset-database-password',
158+
'uses' => 'Server\AjaxController@postResetDatabasePassword'
159+
]);
155160
});
156161

157162
// Assorted AJAX Routes

app/Models/DatabaseServer.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class DatabaseServer extends Model
5656
*/
5757
protected $casts = [
5858
'id' => 'integer',
59+
'server_id' => 'integer',
60+
'db_server' => 'integer'
5961
];
6062

6163
}

app/Policies/ServerPolicy.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,13 @@ public function createTask(User $user, Server $server)
546546
return $user->permissions()->server($server)->permission('create-task')->exists();
547547
}
548548

549+
public function resetDbPassword(User $user, Server $server)
550+
{
551+
if ($this->isOwner($user, $server)) {
552+
return true;
553+
}
554+
555+
return $user->permissions()->server($server)->permission('create-task')->exists();
556+
}
557+
549558
}

app/Repositories/DatabaseRepository.php

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function create($server, $options)
6060
try {
6161
$db = new Models\Database;
6262
$db->fill([
63-
'server' => $server->id,
63+
'server_id' => $server->id,
6464
'db_server' => $options['db_server'],
6565
'database' => $server->uuidShort . '_' . $options['database'],
6666
'username' => $server->uuidShort . '_' . str_random(7),
@@ -103,6 +103,54 @@ public function create($server, $options)
103103
}
104104
}
105105

106+
/**
107+
* Updates the password for a given database.
108+
* @param int $database The ID of the database to modify.
109+
* @param string $password The new password to use for the database.
110+
* @return bool
111+
*/
112+
public function modifyPassword($database, $password)
113+
{
114+
$db = Models\Database::findOrFail($database);
115+
$dbr = Models\DatabaseServer::findOrFail($db->db_server);
116+
117+
DB::beginTransaction();
118+
try {
119+
120+
$db->password = Crypt::encrypt($password);
121+
$db->save();
122+
123+
$capsule = new Capsule;
124+
$capsule->addConnection([
125+
'driver' => 'mysql',
126+
'host' => $dbr->host,
127+
'port' => $dbr->port,
128+
'database' => 'mysql',
129+
'username' => $dbr->username,
130+
'password' => Crypt::decrypt($dbr->password),
131+
'charset' => 'utf8',
132+
'collation' => 'utf8_unicode_ci',
133+
'prefix' => '',
134+
'options' => [
135+
\PDO::ATTR_TIMEOUT => 3,
136+
]
137+
]);
138+
139+
$capsule->setAsGlobal();
140+
Capsule::statement(sprintf(
141+
'ALTER USER \'%s\'@\'%s\' IDENTIFIED BY \'%s\'',
142+
$db->username,
143+
$db->remote,
144+
$password
145+
));
146+
147+
DB::commit();
148+
} catch(\Exception $ex) {
149+
DB::rollback();
150+
throw $ex;
151+
}
152+
}
153+
106154
/**
107155
* Drops a database from the associated MySQL Server
108156
* @param int $database The ID of the database to drop.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Illuminate\Database\Schema\Blueprint;
4+
use Illuminate\Database\Migrations\Migration;
5+
6+
class FixColumnNameForDatabases extends Migration
7+
{
8+
/**
9+
* Run the migrations.
10+
*
11+
* @return void
12+
*/
13+
public function up()
14+
{
15+
Schema::table('databases', function (Blueprint $table) {
16+
$table->renameColumn('server', 'server_id');
17+
});
18+
}
19+
20+
/**
21+
* Reverse the migrations.
22+
*
23+
* @return void
24+
*/
25+
public function down()
26+
{
27+
Schema::table('databases', function (Blueprint $table) {
28+
$table->renameColumn('server_id', 'server');
29+
});
30+
}
31+
}

resources/views/admin/servers/view.blade.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@
363363
<tr>
364364
<td>{{ $database->database }}</td>
365365
<td>{{ $database->username }} ({{ $database->remote }})</td>
366-
<td><code>{{ Crypt::decrypt($database->password) }}</code></td>
366+
<td><code>{{ Crypt::decrypt($database->password) }}</code> <a href="#" data-action="reset-database-password" data-id="{{ $database->id }}"><i class="fa fa-refresh pull-right"></i></a></td>
367367
<td><code>{{ $database->a_host }}:{{ $database->a_port }}</code></td>
368368
<td class="text-center"><a href="#delete" data-action="delete_database" data-database="{{ $database->id }}" class="text-danger"><i class="fa fa-trash-o"></i></a></td>
369369
</tr>
@@ -530,6 +530,36 @@
530530
});
531531
});
532532
});
533+
$('[data-action="reset-database-password"]').click(function (e) {
534+
e.preventDefault();
535+
var block = $(this);
536+
$(this).find('i').addClass('fa-spin');
537+
$.ajax({
538+
type: 'POST',
539+
url: '{{ route('server.ajax.reset-database-password', $server->uuidShort) }}',
540+
headers: {
541+
'X-CSRF-TOKEN': '{{ csrf_token() }}'
542+
},
543+
data: {
544+
'database': $(this).data('id')
545+
}
546+
}).done(function (data) {
547+
block.parent().find('code').html(data);
548+
}).fail(function(jqXHR, textStatus, errorThrown) {
549+
console.error(jqXHR);
550+
var error = 'An error occured while trying to process this request.';
551+
if (typeof jqXHR.responseJSON !== 'undefined' && typeof jqXHR.responseJSON.error !== 'undefined') {
552+
error = jqXHR.responseJSON.error;
553+
}
554+
swal({
555+
type: 'error',
556+
title: 'Whoops!',
557+
text: error
558+
});
559+
}).always(function () {
560+
block.find('i').removeClass('fa-spin');
561+
});
562+
});
533563
});
534564
</script>
535565
@endsection

0 commit comments

Comments
 (0)