forked from Alex/Pterodactyl-Panel
Merge pull request #1963 from Sir3lit/maxconn
Add Max Concurrent Connections for database users
This commit is contained in:
commit
72ecac5236
@ -68,9 +68,10 @@ interface DatabaseRepositoryInterface extends RepositoryInterface
|
|||||||
* @param string $username
|
* @param string $username
|
||||||
* @param string $remote
|
* @param string $remote
|
||||||
* @param string $password
|
* @param string $password
|
||||||
|
* @param $max_connections
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createUser(string $username, string $remote, string $password): bool;
|
public function createUser(string $username, string $remote, string $password, string $max_connections): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give a specific user access to a given database.
|
* Give a specific user access to a given database.
|
||||||
|
@ -25,6 +25,7 @@ class StoreServerDatabaseRequest extends AdminFormRequest
|
|||||||
$query->where('database_host_id', $this->input('database_host_id') ?? 0);
|
$query->where('database_host_id', $this->input('database_host_id') ?? 0);
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
'max_connections' => 'nullable',
|
||||||
'remote' => 'required|string|regex:/^[0-9%.]{1,15}$/',
|
'remote' => 'required|string|regex:/^[0-9%.]{1,15}$/',
|
||||||
'database_host_id' => 'required|integer|exists:database_hosts,id',
|
'database_host_id' => 'required|integer|exists:database_hosts,id',
|
||||||
];
|
];
|
||||||
|
@ -30,7 +30,7 @@ class Database extends Model
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'server_id', 'database_host_id', 'database', 'username', 'password', 'remote',
|
'server_id', 'database_host_id', 'database', 'username', 'password', 'remote', 'max_connections',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,6 +41,7 @@ class Database extends Model
|
|||||||
protected $casts = [
|
protected $casts = [
|
||||||
'server_id' => 'integer',
|
'server_id' => 'integer',
|
||||||
'database_host_id' => 'integer',
|
'database_host_id' => 'integer',
|
||||||
|
'max_connections' => 'integer',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,6 +52,7 @@ class Database extends Model
|
|||||||
'database_host_id' => 'required|exists:database_hosts,id',
|
'database_host_id' => 'required|exists:database_hosts,id',
|
||||||
'database' => 'required|string|alpha_dash|between:3,100',
|
'database' => 'required|string|alpha_dash|between:3,100',
|
||||||
'username' => 'string|alpha_dash|between:3,100',
|
'username' => 'string|alpha_dash|between:3,100',
|
||||||
|
'max_connections' => 'nullable|integer',
|
||||||
'remote' => 'required|string|regex:/^[0-9%.]{1,15}$/',
|
'remote' => 'required|string|regex:/^[0-9%.]{1,15}$/',
|
||||||
'password' => 'string',
|
'password' => 'string',
|
||||||
];
|
];
|
||||||
|
@ -135,11 +135,16 @@ class DatabaseRepository extends EloquentRepository implements DatabaseRepositor
|
|||||||
* @param string $username
|
* @param string $username
|
||||||
* @param string $remote
|
* @param string $remote
|
||||||
* @param string $password
|
* @param string $password
|
||||||
|
* @param $max_connections
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createUser(string $username, string $remote, string $password): bool
|
public function createUser(string $username, string $remote, string $password, $max_connections): bool
|
||||||
{
|
{
|
||||||
return $this->run(sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', $username, $remote, $password));
|
if (!$max_connections) {
|
||||||
|
return $this->run(sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\'', $username, $remote, $password));
|
||||||
|
} else {
|
||||||
|
return $this->run(sprintf('CREATE USER `%s`@`%s` IDENTIFIED BY \'%s\' WITH MAX_USER_CONNECTIONS %s', $username, $remote, $password, $max_connections));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,7 +84,8 @@ class DatabaseManagementService
|
|||||||
$this->repository->createUser(
|
$this->repository->createUser(
|
||||||
$database->username,
|
$database->username,
|
||||||
$database->remote,
|
$database->remote,
|
||||||
$this->encrypter->decrypt($database->password)
|
$this->encrypter->decrypt($database->password),
|
||||||
|
$database->max_connections
|
||||||
);
|
);
|
||||||
$this->repository->assignUserToDatabase(
|
$this->repository->assignUserToDatabase(
|
||||||
$database->database,
|
$database->database,
|
||||||
|
@ -71,7 +71,7 @@ class DatabasePasswordService
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->repository->dropUser($database->username, $database->remote);
|
$this->repository->dropUser($database->username, $database->remote);
|
||||||
$this->repository->createUser($database->username, $database->remote, $password);
|
$this->repository->createUser($database->username, $database->remote, $password, $database->max_connections);
|
||||||
$this->repository->assignUserToDatabase($database->database, $database->username, $database->remote);
|
$this->repository->assignUserToDatabase($database->database, $database->username, $database->remote);
|
||||||
$this->repository->flush();
|
$this->repository->flush();
|
||||||
});
|
});
|
||||||
|
@ -56,6 +56,7 @@ class ServerDatabaseTransformer extends BaseTransformer
|
|||||||
'database' => $model->database,
|
'database' => $model->database,
|
||||||
'username' => $model->username,
|
'username' => $model->username,
|
||||||
'remote' => $model->remote,
|
'remote' => $model->remote,
|
||||||
|
'max_connections' => $model->max_connections,
|
||||||
'created_at' => Chronos::createFromFormat(Chronos::DEFAULT_TO_STRING_FORMAT, $model->created_at)
|
'created_at' => Chronos::createFromFormat(Chronos::DEFAULT_TO_STRING_FORMAT, $model->created_at)
|
||||||
->setTimezone(config('app.timezone'))
|
->setTimezone(config('app.timezone'))
|
||||||
->toIso8601String(),
|
->toIso8601String(),
|
||||||
|
@ -58,6 +58,7 @@ class DatabaseTransformer extends BaseClientTransformer
|
|||||||
'name' => $model->database,
|
'name' => $model->database,
|
||||||
'username' => $model->username,
|
'username' => $model->username,
|
||||||
'connections_from' => $model->remote,
|
'connections_from' => $model->remote,
|
||||||
|
'max_connections' => $model->max_connections,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class AddMaxConnectionsColumnToDatabasesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('databases', function (Blueprint $table) {
|
||||||
|
$table->integer('max_connections')->nullable()->default(0)->after('password');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::table('databases', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('max_connections');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -51,7 +51,7 @@ export default ({ database, className }: Props) => {
|
|||||||
addError({ key: 'database:delete', message: httpErrorToHuman(error) });
|
addError({ key: 'database:delete', message: httpErrorToHuman(error) });
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Formik
|
<Formik
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
<th>Database Name</th>
|
<th>Database Name</th>
|
||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>Connections From</th>
|
<th>Connections From</th>
|
||||||
|
<th>Max Connections</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($databases as $database)
|
@foreach($databases as $database)
|
||||||
@ -107,6 +108,11 @@
|
|||||||
<td class="middle">{{ $database->database }}</td>
|
<td class="middle">{{ $database->database }}</td>
|
||||||
<td class="middle">{{ $database->username }}</td>
|
<td class="middle">{{ $database->username }}</td>
|
||||||
<td class="middle">{{ $database->remote }}</td>
|
<td class="middle">{{ $database->remote }}</td>
|
||||||
|
@if($database->max_connections != null)
|
||||||
|
<td class="middle">{{ $database->max_connections }}</td>
|
||||||
|
@else
|
||||||
|
<td class="middle">Unlimited</td>
|
||||||
|
@endif
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a href="{{ route('admin.servers.view.database', $database->getRelation('server')->id) }}">
|
<a href="{{ route('admin.servers.view.database', $database->getRelation('server')->id) }}">
|
||||||
<button class="btn btn-xs btn-primary">Manage</button>
|
<button class="btn btn-xs btn-primary">Manage</button>
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
<th>Username</th>
|
<th>Username</th>
|
||||||
<th>Connections From</th>
|
<th>Connections From</th>
|
||||||
<th>Host</th>
|
<th>Host</th>
|
||||||
|
<th>Max Conenctions</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
@foreach($server->databases as $database)
|
@foreach($server->databases as $database)
|
||||||
@ -45,6 +46,11 @@
|
|||||||
<td>{{ $database->username }}</td>
|
<td>{{ $database->username }}</td>
|
||||||
<td>{{ $database->remote }}</td>
|
<td>{{ $database->remote }}</td>
|
||||||
<td><code>{{ $database->host->host }}:{{ $database->host->port }}</code></td>
|
<td><code>{{ $database->host->host }}:{{ $database->host->port }}</code></td>
|
||||||
|
@if($database->max_connections != null)
|
||||||
|
<td>{{ $database->max_connections }}</td>
|
||||||
|
@else
|
||||||
|
<td>Unlimited</td>
|
||||||
|
@endif
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<button data-action="reset-password" data-id="{{ $database->id }}" class="btn btn-xs btn-primary"><i class="fa fa-refresh"></i></button>
|
<button data-action="reset-password" data-id="{{ $database->id }}" class="btn btn-xs btn-primary"><i class="fa fa-refresh"></i></button>
|
||||||
<button data-action="remove" data-id="{{ $database->id }}" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i></button>
|
<button data-action="remove" data-id="{{ $database->id }}" class="btn btn-xs btn-danger"><i class="fa fa-trash"></i></button>
|
||||||
@ -83,6 +89,11 @@
|
|||||||
<input id="pRemote" type="text" name="remote" class="form-control" value="%" />
|
<input id="pRemote" type="text" name="remote" class="form-control" value="%" />
|
||||||
<p class="text-muted small">This should reflect the IP address that connections are allowed from. Uses standard MySQL notation. If unsure leave as <code>%</code>.</p>
|
<p class="text-muted small">This should reflect the IP address that connections are allowed from. Uses standard MySQL notation. If unsure leave as <code>%</code>.</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="pmax_connections" class="control-label">Concurrent Connections</label>
|
||||||
|
<input id="pmax_connections" type="text" name="max_connections" class="form-control"/>
|
||||||
|
<p class="text-muted small">This should reflect the max number of concurrent connections from this user to the database. Leave empty for unlimited.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
|
Loading…
Reference in New Issue
Block a user