Skip to content

Commit 217762a

Browse files
committed
More complete implementation of database management in panel.
Still missing ability to change passwords for databases, but that will come soon.
1 parent e14d1d3 commit 217762a

File tree

10 files changed

+384
-42
lines changed

10 files changed

+384
-42
lines changed

app/Http/Controllers/Admin/DatabaseController.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@
2323
*/
2424
namespace Pterodactyl\Http\Controllers\Admin;
2525

26+
use Alert;
2627
use DB;
28+
use Log;
2729

2830
use Pterodactyl\Models;
31+
use Pterodactyl\Repositories\DatabaseRepository;
32+
use Pterodactyl\Exceptions\DisplayException;
33+
use Pterodactyl\Exceptions\DisplayValidationException;
2934

3035
use Pterodactyl\Http\Controllers\Controller;
3136
use Illuminate\Http\Request;
@@ -62,4 +67,64 @@ public function getIndex(Request $request)
6267
]);
6368
}
6469

70+
public function getNew(Request $request)
71+
{
72+
return view('admin.databases.new', [
73+
'nodes' => Models\Node::select('nodes.id', 'nodes.name', 'locations.long as a_location')
74+
->join('locations', 'locations.id', '=', 'nodes.location')
75+
->get()
76+
]);
77+
}
78+
79+
public function postNew(Request $request)
80+
{
81+
try {
82+
$repo = new DatabaseRepository;
83+
$repo->add($request->except([
84+
'_token'
85+
]));
86+
87+
Alert::success('Successfully added a new database server to the system.')->flash();
88+
return redirect()->route('admin.databases', [
89+
'tab' => 'tab_dbservers'
90+
]);
91+
} catch (DisplayValidationException $ex) {
92+
return redirect()->route('admin.databases.new')->withErrors(json_decode($ex->getMessage()))->withInput();
93+
} catch (\Exception $ex) {
94+
if ($ex instanceof DisplayException || $ex instanceof \PDOException) {
95+
Alert::danger($ex->getMessage())->flash();
96+
} else {
97+
Log::error($ex);
98+
Alert::danger('An error occurred while attempting to delete this database server from the system.')->flash();
99+
}
100+
return redirect()->route('admin.databases.new')->withInput();
101+
}
102+
}
103+
104+
public function deleteDatabase(Request $request, $id)
105+
{
106+
try {
107+
$repo = new DatabaseRepository;
108+
$repo->drop($id);
109+
} catch (\Exception $ex) {
110+
Log::error($ex);
111+
return response()->json([
112+
'error' => ($ex instanceof DisplayException) ? $ex->getMessage() : 'An error occurred while attempting to delete this database from the system.'
113+
], 500);
114+
}
115+
}
116+
117+
public function deleteServer(Request $request, $id)
118+
{
119+
try {
120+
$repo = new DatabaseRepository;
121+
$repo->delete($id);
122+
} catch (\Exception $ex) {
123+
Log::error($ex);
124+
return response()->json([
125+
'error' => ($ex instanceof DisplayException) ? $ex->getMessage() : 'An error occurred while attempting to delete this database server from the system.'
126+
], 500);
127+
}
128+
}
129+
65130
}

app/Http/Controllers/Admin/ServersController.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -413,18 +413,4 @@ public function postDatabase(Request $request, $id)
413413
])->withInput();
414414
}
415415

416-
public function deleteDatabase(Request $request, $id, $database)
417-
{
418-
try {
419-
$repo = new DatabaseRepository;
420-
$repo->drop($database);
421-
return response('', 204);
422-
} catch (\Exception $ex) {
423-
Log::error($ex);
424-
return response()->json([
425-
'error' => 'An exception occured while attempting to delete this database.'
426-
], 500);
427-
}
428-
}
429-
430416
}

app/Http/Controllers/Server/ServerController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ public function getSettings(Request $request, $uuid)
228228

229229
return view('server.settings', [
230230
'server' => $server,
231+
'databases' => Models\Database::select('databases.*', 'database_servers.host as a_host', 'database_servers.port as a_port')
232+
->where('server', $server->id)
233+
->join('database_servers', 'database_servers.id', '=', 'databases.db_server')
234+
->get(),
231235
'node' => Models\Node::find($server->node),
232236
'variables' => $variables->where('user_viewable', 1),
233237
'service' => $service,

app/Http/Routes/AdminRoutes.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,10 +158,6 @@ public function map(Router $router) {
158158
'uses' => 'Admin\ServersController@postDatabase'
159159
]);
160160

161-
$router->delete('/view/{id}/database/{database}', [
162-
'uses' => 'Admin\ServersController@deleteDatabase'
163-
]);
164-
165161
// Change Server Details
166162
$router->post('/view/{id}/details', [
167163
'uses' => 'Admin\ServersController@postUpdateServerDetails'
@@ -328,6 +324,14 @@ public function map(Router $router) {
328324
$router->post('/new', [
329325
'uses' => 'Admin\DatabaseController@postNew'
330326
]);
327+
$router->delete('/delete/{id}', [
328+
'as' => 'admin.databases.delete',
329+
'uses' => 'Admin\DatabaseController@deleteDatabase'
330+
]);
331+
$router->delete('/delete-server/{id}', [
332+
'as' => 'admin.databases.delete-server',
333+
'uses' => 'Admin\DatabaseController@deleteServer'
334+
]);
331335
});
332336

333337
}

app/Policies/ServerPolicy.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,4 +434,20 @@ public function resetSftp(User $user, Server $server)
434434
return $user->permissions()->server($server)->permission('reset-sftp')->exists();
435435
}
436436

437+
/**
438+
* Check if user has permission to view databases for a server.
439+
*
440+
* @param Pterodactyl\Models\User $user
441+
* @param Pterodactyl\Models\Server $server
442+
* @return boolean
443+
*/
444+
public function viewDatabases(User $user, Server $server)
445+
{
446+
if ($this->isOwner($user, $server)) {
447+
return true;
448+
}
449+
450+
return $user->permissions()->server($server)->permission('view-databases')->exists();
451+
}
452+
437453
}

app/Repositories/DatabaseRepository.php

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
namespace Pterodactyl\Repositories;
2525

2626
use Crypt;
27+
use Log;
2728
use DB;
2829
use Validator;
2930

@@ -56,21 +57,20 @@ public function create($server, $options)
5657

5758
DB::beginTransaction();
5859

59-
$db = new Models\Database;
60-
$db->fill([
61-
'server' => $server->id,
62-
'db_server' => $options['db_server'],
63-
'database' => $server->uuidShort . '_' . $options['database'],
64-
'username' => $server->uuidShort . '_' . str_random(7),
65-
'remote' => $options['remote'],
66-
'password' => Crypt::encrypt(str_random(20))
67-
]);
68-
$db->save();
69-
70-
// Contact Remote
71-
$dbr = Models\DatabaseServer::findOrFail($options['db_server']);
72-
7360
try {
61+
$db = new Models\Database;
62+
$db->fill([
63+
'server' => $server->id,
64+
'db_server' => $options['db_server'],
65+
'database' => $server->uuidShort . '_' . $options['database'],
66+
'username' => $server->uuidShort . '_' . str_random(7),
67+
'remote' => $options['remote'],
68+
'password' => Crypt::encrypt(str_random(20))
69+
]);
70+
$db->save();
71+
72+
// Contact Remote
73+
$dbr = Models\DatabaseServer::findOrFail($options['db_server']);
7474

7575
$capsule = new Capsule;
7676
$capsule->addConnection([
@@ -82,7 +82,10 @@ public function create($server, $options)
8282
'password' => Crypt::decrypt($dbr->password),
8383
'charset' => 'utf8',
8484
'collation' => 'utf8_unicode_ci',
85-
'prefix' => ''
85+
'prefix' => '',
86+
'options' => [
87+
\PDO::ATTR_TIMEOUT => 3,
88+
]
8689
]);
8790

8891
$capsule->setAsGlobal();
@@ -110,10 +113,9 @@ public function drop($database)
110113
$db = Models\Database::findOrFail($database);
111114
$dbr = Models\DatabaseServer::findOrFail($db->db_server);
112115

113-
try {
114-
115-
DB::beginTransaction();
116+
DB::beginTransaction();
116117

118+
try {
117119
$capsule = new Capsule;
118120
$capsule->addConnection([
119121
'driver' => 'mysql',
@@ -124,7 +126,10 @@ public function drop($database)
124126
'password' => Crypt::decrypt($dbr->password),
125127
'charset' => 'utf8',
126128
'collation' => 'utf8_unicode_ci',
127-
'prefix' => ''
129+
'prefix' => '',
130+
'options' => [
131+
\PDO::ATTR_TIMEOUT => 3,
132+
]
128133
]);
129134

130135
$capsule->setAsGlobal();
@@ -143,4 +148,83 @@ public function drop($database)
143148

144149
}
145150

151+
/**
152+
* Deletes a database server from the system if it is empty.
153+
* @param int $server The ID of the Database Server.
154+
* @return
155+
*/
156+
public function delete($server)
157+
{
158+
$dbh = Models\DatabaseServer::findOrFail($server);
159+
$databases = Models\Database::where('db_server', $dbh->id)->count();
160+
161+
if ($databases > 0) {
162+
throw new DisplayException('You cannot delete a database server that has active databases attached to it.');
163+
}
164+
165+
return $dbh->delete();
166+
}
167+
168+
/**
169+
* Adds a new Database Server to the system.
170+
* @param array $data
171+
*/
172+
public function add(array $data)
173+
{
174+
$validator = Validator::make($data, [
175+
'name' => 'required|string|max:255',
176+
'host' => 'required|ip|unique:database_servers,host',
177+
'port' => 'required|numeric|between:1,65535',
178+
'username' => 'required|string|max:32',
179+
'password' => 'required|string',
180+
'linked_node' => 'sometimes',
181+
]);
182+
183+
if ($validator->fails()) {
184+
throw new DisplayValidationException($validator->errors());
185+
}
186+
187+
DB::beginTransaction();
188+
189+
try {
190+
$capsule = new Capsule;
191+
$capsule->addConnection([
192+
'driver' => 'mysql',
193+
'host' => $data['host'],
194+
'port' => $data['port'],
195+
'database' => 'mysql',
196+
'username' => $data['username'],
197+
'password' => $data['password'],
198+
'charset' => 'utf8',
199+
'collation' => 'utf8_unicode_ci',
200+
'prefix' => '',
201+
'options' => [
202+
\PDO::ATTR_TIMEOUT => 3,
203+
]
204+
]);
205+
206+
$capsule->setAsGlobal();
207+
208+
// Allows us to check that we can connect to things.
209+
Capsule::select('SELECT 1 FROM dual');
210+
211+
$dbh = new Models\DatabaseServer;
212+
$dbh->fill([
213+
'name' => $data['name'],
214+
'host' => $data['host'],
215+
'port' => $data['port'],
216+
'username' => $data['username'],
217+
'password' => Crypt::encrypt($data['password']),
218+
'max_databases' => NULL,
219+
'linked_node' => (!empty($data['linked_node']) && $data['linked_node'] > 0) ? $data['linked_node'] : NULL
220+
]);
221+
$dbh->save();
222+
223+
DB::commit();
224+
} catch (\Exception $ex) {
225+
DB::rollBack();
226+
throw $ex;
227+
}
228+
}
229+
146230
}

0 commit comments

Comments
 (0)