Merge pull request #3 from biondizzle/codex/add-login-to-console-management-page
Add console login with env credentials
This commit is contained in:
4
.env
4
.env
@@ -29,3 +29,7 @@ APP_SECRET=6aa2ea989e29de27bc42a77db9849b87
|
||||
# DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
|
||||
DATABASE_URL="mysql://vultradmin:AVNS_jn444_0nHCHAvnZkTFN@vultr-prod-a6de266e-e9c6-477c-abf3-7ec2e7a7bfc8-vultr-prod-3195.vultrdb.com:18140/defaultdb?serverVersion=8.0.32&charset=utf8mb4"
|
||||
###< doctrine/doctrine-bundle ###
|
||||
|
||||
# Console login credentials
|
||||
CONSOLE_USER=admin
|
||||
CONSOLE_PASS=changeMe
|
||||
|
||||
@@ -55,6 +55,17 @@ console_api_stats:
|
||||
controller: App\Controller\ConsoleApiController::stats
|
||||
methods: [GET]
|
||||
|
||||
# Console Authentication Routes
|
||||
console_login:
|
||||
path: /console/login
|
||||
controller: App\Controller\ConsoleController::login
|
||||
methods: [GET, POST]
|
||||
|
||||
console_logout:
|
||||
path: /console/logout
|
||||
controller: App\Controller\ConsoleController::logout
|
||||
methods: [GET]
|
||||
|
||||
# Console Frontend Route
|
||||
console_frontend:
|
||||
path: /console/{route}
|
||||
|
||||
@@ -19,9 +19,20 @@ class ConsoleApiController extends AbstractController
|
||||
private EntityManagerInterface $entityManager
|
||||
) {}
|
||||
|
||||
private function checkAuth(Request $request): ?JsonResponse
|
||||
{
|
||||
if (!$request->getSession()->get('console_logged_in')) {
|
||||
return new JsonResponse(['error' => 'Unauthorized'], Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Credentials Management
|
||||
public function credentials(Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
if ($request->getMethod() === 'GET') {
|
||||
$credentials = $this->entityManager->getRepository(S3Credential::class)->findAll();
|
||||
|
||||
@@ -63,6 +74,9 @@ class ConsoleApiController extends AbstractController
|
||||
|
||||
public function credentialDetail(int $id, Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
$credential = $this->entityManager->getRepository(S3Credential::class)->find($id);
|
||||
|
||||
if (!$credential) {
|
||||
@@ -115,6 +129,9 @@ class ConsoleApiController extends AbstractController
|
||||
// Buckets Management
|
||||
public function buckets(Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
if ($request->getMethod() === 'GET') {
|
||||
$buckets = $this->entityManager->getRepository(S3Bucket::class)->findAll();
|
||||
|
||||
@@ -177,6 +194,9 @@ class ConsoleApiController extends AbstractController
|
||||
|
||||
public function bucketDetail(string $name, Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
$bucket = $this->s3Service->findBucketByName($name);
|
||||
|
||||
if (!$bucket) {
|
||||
@@ -224,6 +244,9 @@ class ConsoleApiController extends AbstractController
|
||||
// Objects Management
|
||||
public function objects(string $bucketName, Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
$bucket = $this->s3Service->findBucketByName($bucketName);
|
||||
|
||||
if (!$bucket) {
|
||||
@@ -270,6 +293,9 @@ class ConsoleApiController extends AbstractController
|
||||
|
||||
public function objectDetail(string $bucketName, string $objectKey, Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
$bucket = $this->s3Service->findBucketByName($bucketName);
|
||||
|
||||
if (!$bucket) {
|
||||
@@ -309,6 +335,9 @@ class ConsoleApiController extends AbstractController
|
||||
// Multipart Uploads
|
||||
public function multipartUploads(string $bucketName, Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
$bucket = $this->s3Service->findBucketByName($bucketName);
|
||||
|
||||
if (!$bucket) {
|
||||
@@ -339,6 +368,9 @@ class ConsoleApiController extends AbstractController
|
||||
// Presigned URLs
|
||||
public function presignedUrls(Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
if ($request->getMethod() === 'GET') {
|
||||
$urls = $this->entityManager->getRepository(\App\Entity\S3PresignedUrl::class)
|
||||
->createQueryBuilder('p')
|
||||
@@ -392,6 +424,9 @@ class ConsoleApiController extends AbstractController
|
||||
// Statistics
|
||||
public function stats(Request $request): JsonResponse
|
||||
{
|
||||
if ($resp = $this->checkAuth($request)) {
|
||||
return $resp;
|
||||
}
|
||||
$credentialCount = $this->entityManager->getRepository(S3Credential::class)->count([]);
|
||||
$bucketCount = $this->entityManager->getRepository(S3Bucket::class)->count([]);
|
||||
$objectCount = $this->entityManager->getRepository(S3Object::class)->count([]);
|
||||
|
||||
@@ -4,11 +4,47 @@ namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
|
||||
class ConsoleController extends AbstractController
|
||||
{
|
||||
public function index(string $route = ''): Response
|
||||
public function index(Request $request, string $route = ''): Response
|
||||
{
|
||||
if (!$request->getSession()->get('console_logged_in')) {
|
||||
return new RedirectResponse('/console/login');
|
||||
}
|
||||
|
||||
return $this->render('console/index.html.twig');
|
||||
}
|
||||
|
||||
public function login(Request $request): Response
|
||||
{
|
||||
if ($request->getSession()->get('console_logged_in')) {
|
||||
return new RedirectResponse('/console');
|
||||
}
|
||||
|
||||
$error = null;
|
||||
if ($request->isMethod('POST')) {
|
||||
$user = $request->request->get('username');
|
||||
$pass = $request->request->get('password');
|
||||
$envUser = $_ENV['CONSOLE_USER'] ?? 'admin';
|
||||
$envPass = $_ENV['CONSOLE_PASS'] ?? 'password';
|
||||
|
||||
if ($user === $envUser && $pass === $envPass) {
|
||||
$request->getSession()->set('console_logged_in', true);
|
||||
return new RedirectResponse('/console');
|
||||
}
|
||||
|
||||
$error = 'Invalid credentials';
|
||||
}
|
||||
|
||||
return $this->render('console/login.html.twig', ['error' => $error]);
|
||||
}
|
||||
|
||||
public function logout(Request $request): Response
|
||||
{
|
||||
$request->getSession()->remove('console_logged_in');
|
||||
return new RedirectResponse('/console/login');
|
||||
}
|
||||
}
|
||||
34
templates/console/login.html.twig
Normal file
34
templates/console/login.html.twig
Normal file
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>vStash Console Login</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; background: #f7fafc; display:flex; align-items:center; justify-content:center; height:100vh; }
|
||||
.login-box { background:white; padding:2rem; border-radius:0.5rem; box-shadow:0 1px 3px rgba(0,0,0,0.1); width:300px; }
|
||||
.form-group { margin-bottom:1rem; }
|
||||
label { display:block; margin-bottom:0.5rem; }
|
||||
input { width:100%; padding:0.5rem; border:1px solid #d2d6dc; border-radius:0.375rem; }
|
||||
button { width:100%; padding:0.5rem; background:#3182ce; color:white; border:none; border-radius:0.375rem; cursor:pointer; }
|
||||
.error { color:#c53030; margin-bottom:1rem; text-align:center; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="login-box">
|
||||
<h2 style="text-align:center;margin-bottom:1rem;">Console Login</h2>
|
||||
{% if error %}<div class="error">{{ error }}</div>{% endif %}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label>Username</label>
|
||||
<input type="text" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Password</label>
|
||||
<input type="password" name="password" required>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user