Compare commits
3 Commits
1f548eb0c5
...
eb8f512aec
| Author | SHA1 | Date | |
|---|---|---|---|
| eb8f512aec | |||
| bdeb28fbf5 | |||
| 3889fe1561 |
@@ -62,19 +62,34 @@ def guac_encode(*args: str) -> str:
|
|||||||
return f"{','.join(f'{len(arg)}.{arg}' for arg in args)};"
|
return f"{','.join(f'{len(arg)}.{arg}' for arg in args)};"
|
||||||
|
|
||||||
class CollabVMState(IntEnum):
|
class CollabVMState(IntEnum):
|
||||||
DISCONNECTED = -1
|
"""Represents client connection states."""
|
||||||
|
WS_DISCONNECTED = -1
|
||||||
|
"""WebSocket is disconnected."""
|
||||||
WS_CONNECTED = 0
|
WS_CONNECTED = 0
|
||||||
|
"""WebSocket is connected."""
|
||||||
VM_CONNECTED = 1
|
VM_CONNECTED = 1
|
||||||
|
"""Connected to the VM but not logged in."""
|
||||||
LOGGED_IN = 2
|
LOGGED_IN = 2
|
||||||
|
"""Authenticated with announced auth server."""
|
||||||
|
|
||||||
class CollabVMRank(IntEnum):
|
class CollabVMRank(IntEnum):
|
||||||
UNREGISTERED = 0
|
"""Represents user ranks."""
|
||||||
REGISTERED = 1
|
Unregistered = 0
|
||||||
ADMIN = 2
|
"""Represents an unregistered user."""
|
||||||
MOD = 3
|
Registered = 1
|
||||||
|
"""Represents a registered user."""
|
||||||
|
Admin = 2
|
||||||
|
"""Represents an admin user."""
|
||||||
|
Mod = 3
|
||||||
|
"""Represents a moderator user."""
|
||||||
|
|
||||||
class CollabVMClientRenameStatus(IntEnum):
|
class CollabVMClientRenameStatus(IntEnum):
|
||||||
|
"""Represents the status of a client rename attempt."""
|
||||||
SUCCEEDED = 0
|
SUCCEEDED = 0
|
||||||
|
"""The rename attempt was successful."""
|
||||||
FAILED_TAKEN = 1
|
FAILED_TAKEN = 1
|
||||||
|
"""The desired name is already taken."""
|
||||||
FAILED_INVALID = 2
|
FAILED_INVALID = 2
|
||||||
|
"""The desired name is invalid."""
|
||||||
FAILED_REJECTED = 3
|
FAILED_REJECTED = 3
|
||||||
|
"""The rename attempt was authoritatively rejected."""
|
||||||
35
cvmsentry.py
35
cvmsentry.py
@@ -22,11 +22,9 @@ log = logging.getLogger("cvmsentry")
|
|||||||
log.setLevel(LOG_LEVEL)
|
log.setLevel(LOG_LEVEL)
|
||||||
log.addHandler(stdout_handler)
|
log.addHandler(stdout_handler)
|
||||||
|
|
||||||
log.info(f"CVM-Sentry started")
|
|
||||||
|
|
||||||
users = {}
|
users = {}
|
||||||
vm_botuser = {}
|
vm_botuser = {}
|
||||||
STATE = CollabVMState.DISCONNECTED
|
STATE = CollabVMState.WS_DISCONNECTED
|
||||||
|
|
||||||
def get_origin_from_ws_url(ws_url: str) -> str:
|
def get_origin_from_ws_url(ws_url: str) -> str:
|
||||||
domain = (
|
domain = (
|
||||||
@@ -64,8 +62,8 @@ async def connect(vm_name: str):
|
|||||||
origin=Origin(get_origin_from_ws_url(uri)),
|
origin=Origin(get_origin_from_ws_url(uri)),
|
||||||
user_agent_header="cvmsentry/1 (https://git.nixlabs.dev/clair/cvmsentry)"
|
user_agent_header="cvmsentry/1 (https://git.nixlabs.dev/clair/cvmsentry)"
|
||||||
) as websocket:
|
) as websocket:
|
||||||
log.info(f"Connected to VM '{vm_name}' at {uri}")
|
|
||||||
STATE = CollabVMState.WS_CONNECTED
|
STATE = CollabVMState.WS_CONNECTED
|
||||||
|
log.info(f"Connected to VM '{vm_name}' at {uri}")
|
||||||
await send_guac(websocket, "rename", "")
|
await send_guac(websocket, "rename", "")
|
||||||
await send_guac(websocket, "connect", vm_name)
|
await send_guac(websocket, "connect", vm_name)
|
||||||
if vm_name not in users:
|
if vm_name not in users:
|
||||||
@@ -103,11 +101,13 @@ async def connect(vm_name: str):
|
|||||||
case ["login", "1"]:
|
case ["login", "1"]:
|
||||||
STATE = CollabVMState.LOGGED_IN
|
STATE = CollabVMState.LOGGED_IN
|
||||||
#await send_chat_message(websocket, random.choice(config.autostart_messages))
|
#await send_chat_message(websocket, random.choice(config.autostart_messages))
|
||||||
case ["chat", user, message]:
|
case ["chat", user, message, *backlog]:
|
||||||
system_message = (user == "")
|
system_message = (user == "")
|
||||||
if system_message:
|
if system_message:
|
||||||
continue
|
continue
|
||||||
|
if not backlog:
|
||||||
log.info(f"[{vm_name} - {user}]: {message}")
|
log.info(f"[{vm_name} - {user}]: {message}")
|
||||||
|
|
||||||
utc_now = datetime.now(timezone.utc)
|
utc_now = datetime.now(timezone.utc)
|
||||||
utc_day = utc_now.strftime("%Y-%m-%d")
|
utc_day = utc_now.strftime("%Y-%m-%d")
|
||||||
timestamp = utc_now.isoformat()
|
timestamp = utc_now.isoformat()
|
||||||
@@ -121,6 +121,18 @@ async def connect(vm_name: str):
|
|||||||
if utc_day not in log_data:
|
if utc_day not in log_data:
|
||||||
log_data[utc_day] = []
|
log_data[utc_day] = []
|
||||||
|
|
||||||
|
if backlog:
|
||||||
|
for i in range(0, len(backlog), 2):
|
||||||
|
backlog_user = backlog[i]
|
||||||
|
backlog_message = backlog[i + 1]
|
||||||
|
if not any(entry["message"] == backlog_message and entry["username"] == backlog_user for entry in log_data[utc_day]):
|
||||||
|
log.info(f"[{vm_name} - {backlog_user} (backlog)]: {backlog_message}")
|
||||||
|
log_data[utc_day].append({
|
||||||
|
"timestamp": timestamp,
|
||||||
|
"username": backlog_user,
|
||||||
|
"message": backlog_message
|
||||||
|
})
|
||||||
|
|
||||||
log_data[utc_day].append({
|
log_data[utc_day].append({
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
"username": user,
|
"username": user,
|
||||||
@@ -138,7 +150,11 @@ async def connect(vm_name: str):
|
|||||||
case "about":
|
case "about":
|
||||||
await send_chat_message(websocket, config.responses.get("about", "CVM-Sentry (NO RESPONSE CONFIGURED)"))
|
await send_chat_message(websocket, config.responses.get("about", "CVM-Sentry (NO RESPONSE CONFIGURED)"))
|
||||||
case "dump":
|
case "dump":
|
||||||
log.debug(f"{json.dumps(users)}")
|
if user != "dfu":
|
||||||
|
await send_chat_message(websocket, "You do not have permission to use this command.")
|
||||||
|
continue
|
||||||
|
log.debug(f"({STATE.name} - {vm_name}) Dumping user list for VM {vm_name}: {users[vm_name]}")
|
||||||
|
await send_chat_message(websocket, f"Dumped user list to console.")
|
||||||
case ["adduser", count, *list]:
|
case ["adduser", count, *list]:
|
||||||
for i in range(int(count)):
|
for i in range(int(count)):
|
||||||
user = list[i * 2]
|
user = list[i * 2]
|
||||||
@@ -163,11 +179,14 @@ async def connect(vm_name: str):
|
|||||||
if username in users[vm_name]:
|
if username in users[vm_name]:
|
||||||
del users[vm_name][username]
|
del users[vm_name][username]
|
||||||
log.info(f"[{vm_name}] User '{username}' left.")
|
log.info(f"[{vm_name}] User '{username}' left.")
|
||||||
|
case ["sync", *args] | ["png", *args] | ["flag", *args] | ["size", *args]:
|
||||||
|
continue
|
||||||
case _:
|
case _:
|
||||||
if decoded is not None:
|
if decoded is not None:
|
||||||
if decoded[0] in ("sync", "png", "flag", "size"):
|
|
||||||
continue
|
|
||||||
log.debug(f"({STATE.name} - {vm_name}) Unhandled message: {decoded}")
|
log.debug(f"({STATE.name} - {vm_name}) Unhandled message: {decoded}")
|
||||||
|
|
||||||
|
log.info(f"({STATE.name}) CVM-Sentry started")
|
||||||
|
|
||||||
for vm in config.vms.keys():
|
for vm in config.vms.keys():
|
||||||
|
|
||||||
def start_vm_thread(vm_name: str):
|
def start_vm_thread(vm_name: str):
|
||||||
|
|||||||
Reference in New Issue
Block a user