Skip to content

Commit

Permalink
fix: User Management (#1394)
Browse files Browse the repository at this point in the history
* Fix a few major issues with users

* Fix issue where production won't load chats

* Change to scrypt

* production works now

* Move debug opts into dev

* code review suggestions
  • Loading branch information
Jonpro03 authored Aug 3, 2024
1 parent 887d533 commit b94dd89
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 143 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ RUN npm run build
FROM python:3.11-slim-bookworm as release

# Set ENV
ENV NODE_ENV='development'
ENV NODE_ENV='production'
ENV TZ=Etc/UTC
WORKDIR /usr/src/app

Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,29 @@ git clone https://github.com/serge-chat/serge.git
cd serge/
docker compose -f docker-compose.dev.yml up --build
```

The solution will accept a python debugger session on port 5678. Example launch.json for VSCode:

```json
{
"version": "0.2.0",
"configurations": [
{
"name": "Remote Debug",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}/api",
"remoteRoot": "/usr/src/app/api/"
}
],
"justMyCode": false
}
]
}
```
62 changes: 1 addition & 61 deletions api/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ pytest = "^8.3.2"
hypercorn = {extras = ["trio"], version = "^0.17.3"}

pyjwt = "^2.8.0"
passlib = {extras = ["bcrypt"], version = "^1.7.4"}
python-jose = {extras = ["cryptography"], version = "^3.3.0"}
aiofiles = "^23.2.1"
python-multipart = "^0.0.9"
Expand Down
22 changes: 15 additions & 7 deletions api/src/serge/utils/security.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import base64
import hashlib
import os

from datetime import datetime, timedelta
from typing import Optional

from fastapi import HTTPException, status
from jose import JWTError, jwt
from passlib.context import CryptContext
from serge.models.settings import Settings

ALGORITHM = "HS256"
Expand All @@ -15,15 +18,20 @@
headers={"WWW-Authenticate": "Bearer"},
)

pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
def verify_password(plain_password: str, hashed_password: str) -> bool:
salt_and_hash = base64.b64decode(hashed_password.encode("utf-8"))
salt = salt_and_hash[:16]
stored_password = salt_and_hash[16:]
new_hashed_password = hashlib.scrypt(plain_password.encode("utf-8"), salt=salt, n=8192, r=8, p=1, dklen=64)
return new_hashed_password == stored_password


def get_password_hash(password):
return pwd_context.hash(password)
def get_password_hash(password: str) -> str:
salt = os.urandom(16)
hashed_password = hashlib.scrypt(password.encode("utf-8"), salt=salt, n=8192, r=8, p=1, dklen=64)
salt_and_hash = salt + hashed_password
return base64.b64encode(salt_and_hash).decode("utf-8")


def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ services:
ports:
- 8008:8008
- 9124:9124

- 5678:5678
volumes:
datadb:
weights:
8 changes: 5 additions & 3 deletions scripts/dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,15 @@ redis-server /etc/redis/redis.conf &
cd /usr/src/app/web || exit 1
npm run dev -- --host 0.0.0.0 --port 8008 &

python -m pip install debugpy -t /tmp

# Start the API
cd /usr/src/app/api || exit 1
hypercorn_cmd="hypercorn src.serge.main:api_app --reload --bind 0.0.0.0:9124"
hypercorn_cmd="python /tmp/debugpy --listen 0.0.0.0:5678 -m hypercorn src.serge.main:api_app --reload --bind 0.0.0.0:9124"
if [ "$SERGE_ENABLE_IPV6" = true ] && [ "$SERGE_ENABLE_IPV4" != true ]; then
hypercorn_cmd="hypercorn src.serge.main:api_app --reload --bind [::]:9124"
hypercorn_cmd="python /tmp/debugpy --listen 0.0.0.0:5678 -m hypercorn src.serge.main:api_app --reload --bind [::]:9124"
elif [ "$SERGE_ENABLE_IPV4" = true ] && [ "$SERGE_ENABLE_IPV6" = true ]; then
hypercorn_cmd="hypercorn src.serge.main:api_app --reload --bind 0.0.0.0:9124 --bind [::]:9124"
hypercorn_cmd="python /tmp/debugpy --listen 0.0.0.0:5678 -m hypercorn src.serge.main:api_app --reload --bind 0.0.0.0:9124 --bind [::]:9124"
fi

$hypercorn_cmd || {
Expand Down
2 changes: 1 addition & 1 deletion web/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@
method: "POST",
});
data.userData = null;
window.location.reload();
window.location.href = "/";
}}
>
<svg
Expand Down
23 changes: 14 additions & 9 deletions web/src/routes/account/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ interface User {
}

export const load: Load = async () => {
try {
const user = await fetch("/api/user/", {
method: "GET",
}).then((response) => response.json());
return { user };
} catch (error) {
console.error(error);
return { user: null };
}
const user = await fetch("/api/user/", {
method: "GET",
})
.then((response) => {
if (response.status == 401) {
window.location.href = "/";
}
return response.json();
})
.catch((error) => {
console.log(error);
window.location.href = "/";
});
return { user };
};
56 changes: 0 additions & 56 deletions web/src/routes/chat/[id]/+page.server.ts

This file was deleted.

16 changes: 15 additions & 1 deletion web/src/routes/chat/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,19 @@
accept: "application/json",
},
},
).then((response) => response.json());
)
.then((response) => {
if (response.status == 401) {
console.log("Not authorized");
window.location.href = "/";
} else {
return response.json();
}
})
.catch((error) => {
console.log(error);
window.location.href = "/";
});
await invalidate("/api/chat/");
await goto("/chat/" + newData);
}
Expand All @@ -142,6 +154,8 @@
await invalidate("/api/chat/" + $page.params.id);
} else if (response.status === 202) {
showToast("Chat in progress!");
} else if (response.status === 401) {
window.location.href = "/";
} else {
showToast("An error occurred: " + response.statusText);
}
Expand Down
13 changes: 11 additions & 2 deletions web/src/routes/chat/[id]/+page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,17 @@ interface Response {
}

export const load: PageLoad = async ({ fetch, params }) => {
const r = await fetch("/api/chat/" + params.id);
const data = (await r.json()) as Response;
const data = await fetch("/api/chat/" + params.id)
.then((response) => {
if (response.status == 401) {
window.location.href = "/";
}
return response.json();
})
.catch((error) => {
console.log(error);
window.location.href = "/";
});

return {
chat: data,
Expand Down

0 comments on commit b94dd89

Please sign in to comment.