Reworked setup.py, now you can run cmd_chat directly. Reworked sanic http webserver to make it work. Update readme, etc...

This commit is contained in:
mirai 2023-11-27 14:30:01 +03:00
parent c5fa982f65
commit 316a0e3e1e
7 changed files with 76 additions and 67 deletions

View File

@ -27,35 +27,20 @@ if __name__ == '__main__':
```
### Or (Windows)
### Or
Start server:
```
.\cmd_chat.bat serve localhost 5000
cmd_chat serve localhost 5000
```
Connect to server:
```
.\cmd_chat.bat connect localhost 5000 tyler
cmd_chat connect localhost 5000 tyler
```
### Or (Linux)
Start server:
```
python3 cmd_chat.py serve localhost 5000
```
Connect to server:
```
python3 cmd_chat.py connect localhost 5000 tyler
```
How does encryption work?
* The client generates a private key.

View File

@ -1,2 +0,0 @@
@echo off
python cmd_chat.py %*

View File

@ -1,7 +1,8 @@
import asyncio
import cmd_chat
async def main():
await cmd_chat.run()
if __name__ == '__main__':
asyncio.run(
cmd_chat.run()
)
asyncio.run(main())

View File

@ -1,19 +1,15 @@
import asyncio
import argparse
from cmd_chat.server.server import app
from cmd_chat.server.server import run_server
from cmd_chat.client.client import Client
async def run_server(
def run_http_server(
ip: str,
port: int
) -> None:
app.run(
host=ip,
port=port,
dev=False
)
run_server(ip, port, False)
async def run_client(
@ -53,12 +49,16 @@ async def run() -> None:
)
args = parser.parse_args()
if args.command == 'serve':
await run_server(args.ip_address, int(args.port))
run_http_server(args.ip_address, int(args.port))
elif args.command == 'connect':
if not args.username:
parser.error("Username is required for 'connect' command")
await run_client(args.username, args.ip_address, int(args.port))
if __name__ == '__main__':
def main():
asyncio.run(run())
if __name__ == '__main__':
main()

View File

@ -3,6 +3,10 @@ import asyncio
import rsa
from cryptography.fernet import Fernet
from functools import partial
from sanic.worker.loader import AppLoader
from sanic.response import HTTPResponse
from sanic import Sanic, Request, response, Websocket
@ -30,39 +34,54 @@ USERS: dict[str, str] = {}
PUBLIC_KEY = Fernet.generate_key()
@app.websocket("/talk")
async def talk_ws_view(request: Request, ws: Websocket) -> HTTPResponse:
while True:
serialized_message: dict = await _get_bytes_and_serialize(ws)
await _check_ws_for_close_status(
serialized_message,
ws
)
new_message = await _generate_new_message(
serialized_message.get("text")
)
MESSAGES_MEMORY_DB.append(new_message)
await ws.send(
str({"status": "ok"})
)
await asyncio.sleep(0.2)
def attach_endpoints(app: Sanic):
@app.websocket("/talk")
async def talk_ws_view(request: Request, ws: Websocket) -> HTTPResponse:
while True:
serialized_message: dict = await _get_bytes_and_serialize(ws)
await _check_ws_for_close_status(
serialized_message,
ws
)
new_message = await _generate_new_message(
serialized_message.get("text")
)
MESSAGES_MEMORY_DB.append(new_message)
await ws.send(
str({"status": "ok"})
)
await asyncio.sleep(0.2)
@app.websocket("/update")
async def update_ws_view(request: Request, ws: Websocket) -> HTTPResponse:
while True:
payload = await _generate_update_payload(
MESSAGES_MEMORY_DB,
USERS
)
await ws.send(payload.encode())
await asyncio.sleep(0.2)
@app.websocket("/update")
async def update_ws_view(request: Request, ws: Websocket) -> HTTPResponse:
while True:
payload = await _generate_update_payload(
MESSAGES_MEMORY_DB,
USERS
)
await ws.send(payload.encode())
await asyncio.sleep(0.2)
@app.route('/get_key', methods=['GET', 'POST'])
async def get_key_view(request: Request) -> HTTPResponse:
public_key = rsa.PublicKey.load_pkcs1(request.form.get('pubkey'))
encrypted_data = rsa.encrypt(PUBLIC_KEY, public_key)
if request.ip not in USERS:
USERS[f"{request.ip}, {request.form.get('username')}"] = PUBLIC_KEY
return response.raw(encrypted_data)
@app.route('/get_key', methods=['GET', 'POST'])
async def get_key_view(request: Request) -> HTTPResponse:
public_key = rsa.PublicKey.load_pkcs1(request.form.get('pubkey'))
encrypted_data = rsa.encrypt(PUBLIC_KEY, public_key)
if request.ip not in USERS:
USERS[f"{request.ip}, {request.form.get('username')}"] = PUBLIC_KEY
return response.raw(encrypted_data)
def create_app(app_name: str) -> Sanic:
app = Sanic(app_name)
attach_endpoints(app)
return app
def run_server(host: str, port: int, dev: bool=False) -> None:
loader = AppLoader(factory=partial(create_app, "CMD_SERVER"))
app = loader.load()
app.prepare(host=host, port=port, dev=dev)
Sanic.serve(primary=app, app_loader=loader)

View File

@ -5,3 +5,4 @@ cryptography
colorama
pydantic
websocket-client
flask

View File

@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
setuptools.setup(
name="secured_console_chat",
version="1.1.1",
version="1.1.21",
author="dinosaurtirex",
author_email="sneakybeaky18@gmail.com",
packages=[
@ -13,7 +13,7 @@ setuptools.setup(
"cmd_chat/client",
"cmd_chat/client/core",
"cmd_chat/client/core/abs",
"cmd_chat/server",
"cmd_chat/server"
],
description="Secured console chat with RSA & Fernet",
long_description=description,
@ -21,6 +21,11 @@ setuptools.setup(
url="https://github.com/dinosaurtirex/cmd-chat",
license='MIT',
python_requires='>=3.10',
entry_points={
'console_scripts': [
'cmd_chat = cmd_chat:main'
]
},
install_requires=[
"sanic",
"requests",