api.auth: User with password hash

This commit is contained in:
Helmut Merz 2026-11-05 12:53:26 +01:00
parent e0a53dce68
commit 12c099b06b
3 changed files with 19 additions and 3 deletions

View file

@ -29,7 +29,7 @@ zope = [
"zope.traversing", "zope.traversing",
] ]
api = ["fastapi[standard]"] api = ["fastapi[standard]"]
auth = ["authlib", "pyjwt[crypto]", "cryptography", "requests"] auth = ["authlib", "pyjwt[crypto]", "cryptography", "pwdlib[argon2]", "requests"]
zopetest = ["zope.testrunner"] zopetest = ["zope.testrunner"]
apitest = ["pytest", "httpx2"] apitest = ["pytest", "httpx2"]

View file

@ -1,6 +1,7 @@
# scopes.api.auth user # scopes.api.auth user
from fastapi import APIRouter from fastapi import APIRouter
from pwdlib import PasswordHash
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from typing import List from typing import List
@ -13,9 +14,19 @@ class User(BaseModel):
login: str login: str
display_name: str display_name: str
email: str | None = None email: str | None = None
pw_hash: str | None = None pw_hash: str | None = Field(exclude=True, default=None)
groups: List[str] = Field(default_factory=list) groups: List[str] = Field(default_factory=list)
# password handling
pw_hash = PasswordHash.recommended()
def hashPassword(pw):
return pw_hash.hash(pw)
def verifyPassword(plain, hashed):
return pw_hash.verify(plain, hashed)
# routes # routes
router = APIRouter() router = APIRouter()

View file

@ -61,10 +61,15 @@ def test_tracking(storage, caplog):
def test_user(storage, caplog): def test_user(storage, caplog):
users = storage.create(st_user.Users) users = storage.create(st_user.Users)
u01 = st_user.User('jim', 'jim', data=dict(display_name='Jim')) pw = 'secret'
pw_hash = api_user.hashPassword(pw)
u01 = st_user.User('jim', 'jim', data=dict(display_name='Jim', pw_hash=pw_hash))
u01id = users.save(u01) u01id = users.save(u01)
storage.commit() storage.commit()
with TestClient(app) as clt: with TestClient(app) as clt:
caplog.set_level(config.settings.log_level) caplog.set_level(config.settings.log_level)
users = clt.get('/users').json() users = clt.get('/users').json()
assert len(users) == 1 assert len(users) == 1
u01i = users[0]
assert u01i.get(pw_hash) is None