ASGI via Daphne for websockets, WSGI via Gunicorn. Implemented xterm.js for shell proxy to target servers.
This commit is contained in:
@@ -8,8 +8,10 @@ from django.utils import timezone
|
||||
from guardian.shortcuts import get_objects_for_user, get_perms
|
||||
|
||||
from apps.access.models import AccessRequest
|
||||
from apps.keys.utils import render_system_username
|
||||
from apps.keys.models import SSHKey
|
||||
from apps.servers.models import Server, ServerAccount
|
||||
from apps.servers.permissions import user_can_shell
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
@@ -60,12 +62,8 @@ def dashboard(request):
|
||||
@login_required(login_url="/accounts/login/")
|
||||
def detail(request, server_id: int):
|
||||
now = timezone.now()
|
||||
try:
|
||||
server = Server.objects.get(id=server_id)
|
||||
except Server.DoesNotExist:
|
||||
raise Http404("Server not found")
|
||||
if "view_server" not in get_perms(request.user, server):
|
||||
raise Http404("Server not found")
|
||||
server = _get_server_or_404(request, server_id)
|
||||
can_shell = user_can_shell(request.user, server, now)
|
||||
|
||||
access = (
|
||||
AccessRequest.objects.filter(
|
||||
@@ -78,17 +76,90 @@ def detail(request, server_id: int):
|
||||
.first()
|
||||
)
|
||||
|
||||
account = ServerAccount.objects.filter(server=server, user=request.user).first()
|
||||
active_key = (
|
||||
SSHKey.objects.filter(user=request.user, is_active=True).order_by("-created_at").first()
|
||||
)
|
||||
account, system_username, certificate_key_id = _load_account_context(request, server)
|
||||
context = {
|
||||
"server": server,
|
||||
"expires_at": access.expires_at if access else None,
|
||||
"last_accessed": None,
|
||||
"account_present": account.is_present if account else None,
|
||||
"account_synced_at": account.last_synced_at if account else None,
|
||||
"system_username": account.system_username if account else None,
|
||||
"certificate_key_id": active_key.id if active_key else None,
|
||||
"system_username": system_username,
|
||||
"certificate_key_id": certificate_key_id,
|
||||
"active_tab": "details",
|
||||
"can_shell": can_shell,
|
||||
}
|
||||
return render(request, "servers/detail.html", context)
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
def shell(request, server_id: int):
|
||||
server = _get_server_or_404(request, server_id)
|
||||
if not user_can_shell(request.user, server):
|
||||
raise Http404("Shell access not available")
|
||||
_, system_username, certificate_key_id = _load_account_context(request, server)
|
||||
shell_target = server.hostname or server.ipv4 or server.ipv6 or ""
|
||||
cert_filename = ""
|
||||
if certificate_key_id:
|
||||
cert_filename = f"keywarden-{request.user.id}-{certificate_key_id}-cert.pub"
|
||||
command = ""
|
||||
if shell_target and system_username and certificate_key_id:
|
||||
command = (
|
||||
"ssh -i /path/to/private_key "
|
||||
f"-o CertificateFile=~/Downloads/{cert_filename} "
|
||||
f"{system_username}@{shell_target} -t /bin/bash"
|
||||
)
|
||||
context = {
|
||||
"server": server,
|
||||
"system_username": system_username,
|
||||
"certificate_key_id": certificate_key_id,
|
||||
"shell_target": shell_target,
|
||||
"shell_command": command,
|
||||
"cert_filename": cert_filename,
|
||||
"active_tab": "shell",
|
||||
"is_popout": request.GET.get("popout") == "1",
|
||||
"can_shell": True,
|
||||
}
|
||||
return render(request, "servers/shell.html", context)
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
def audit(request, server_id: int):
|
||||
server = _get_server_or_404(request, server_id)
|
||||
context = {
|
||||
"server": server,
|
||||
"active_tab": "audit",
|
||||
"can_shell": user_can_shell(request.user, server),
|
||||
}
|
||||
return render(request, "servers/audit.html", context)
|
||||
|
||||
|
||||
@login_required(login_url="/accounts/login/")
|
||||
def settings(request, server_id: int):
|
||||
server = _get_server_or_404(request, server_id)
|
||||
context = {
|
||||
"server": server,
|
||||
"active_tab": "settings",
|
||||
"can_shell": user_can_shell(request.user, server),
|
||||
}
|
||||
return render(request, "servers/settings.html", context)
|
||||
|
||||
|
||||
def _get_server_or_404(request, server_id: int) -> Server:
|
||||
try:
|
||||
server = Server.objects.get(id=server_id)
|
||||
except Server.DoesNotExist:
|
||||
raise Http404("Server not found")
|
||||
if "view_server" not in get_perms(request.user, server):
|
||||
raise Http404("Server not found")
|
||||
return server
|
||||
|
||||
|
||||
def _load_account_context(request, server: Server):
|
||||
account = ServerAccount.objects.filter(server=server, user=request.user).first()
|
||||
system_username = account.system_username if account else render_system_username(
|
||||
request.user.username, request.user.id
|
||||
)
|
||||
active_key = SSHKey.objects.filter(user=request.user, is_active=True).order_by("-created_at").first()
|
||||
certificate_key_id = active_key.id if active_key else None
|
||||
return account, system_username, certificate_key_id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user