api.auth: HTTP Basic Auth working
This commit is contained in:
parent
8963c2ac87
commit
342f48042c
4 changed files with 31 additions and 14 deletions
|
|
@ -1,14 +1,15 @@
|
|||
# scopes.api.auth user
|
||||
|
||||
from datetime import datetime
|
||||
from fastapi import APIRouter, Body
|
||||
from fastapi import APIRouter, Body, Depends, HTTPException
|
||||
from fastapi.security import HTTPBasic, HTTPBasicCredentials
|
||||
import jwt
|
||||
from pwdlib import PasswordHash
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Annotated, List
|
||||
|
||||
from scopes.api import deps
|
||||
from scopes.config import settings
|
||||
from scopes.api.auth import config
|
||||
from scopes.storage import user as st_user
|
||||
from scopes.storage.common import Storage
|
||||
|
||||
|
|
@ -33,6 +34,10 @@ class UserEdit(UserBase):
|
|||
|
||||
# password handling, authentication
|
||||
|
||||
def dummy_auth() -> User:
|
||||
return User(name='tester', login='tester', display_name='Tester')
|
||||
config.auth_methods['testing'] = dummy_auth
|
||||
|
||||
pw_hash = PasswordHash.recommended()
|
||||
|
||||
def hashPassword(pw):
|
||||
|
|
@ -41,11 +46,27 @@ def hashPassword(pw):
|
|||
def verifyPassword(plain, hashed):
|
||||
return pw_hash.verify(plain, hashed)
|
||||
|
||||
def userFromToken(users: deps.Users, token: deps.AuthToken):
|
||||
payload = jwt.decode(token, settings.jwt_key, algorithms=[settings.jwt_algorithm])
|
||||
userName = payload.get('sub')
|
||||
user = users.queryLast(name=userName)
|
||||
security = HTTPBasic()
|
||||
|
||||
type Credentials = Annotated[HTTPBasicCredentials, Depends(security)]
|
||||
|
||||
def basicAuth(users: deps.Users, cred: Credentials) -> User:
|
||||
tr = users.queryLast(login=cred.username)
|
||||
users.storage.commit()
|
||||
user = tr.toObject(User)
|
||||
if verifyPassword(cred.password, user.pw_hash):
|
||||
return user
|
||||
raise HTTPException(status_code=401, detail='credentials',
|
||||
headers={"WWW-Authenticate": "Basic"})
|
||||
config.auth_methods['basic'] = basicAuth
|
||||
|
||||
def userFromToken(users: deps.Users, token: deps.AuthToken) -> User:
|
||||
payload = jwt.decode(token, config.settings.jwt_key,
|
||||
algorithms=[config.settings.jwt_algorithm])
|
||||
userName = payload.get('sub')
|
||||
tr = users.queryLast(name=userName)
|
||||
users.storage.commit()
|
||||
return tr.toObject(User)
|
||||
|
||||
# routes
|
||||
|
||||
|
|
@ -59,8 +80,8 @@ async def get_users(users: deps.Users):
|
|||
@router.post('/users', response_model=User)
|
||||
async def post_user(user: Annotated[UserEdit, Body()], users: deps.Users,
|
||||
auth_user: deps.AuthUser):
|
||||
print('*** post_user', auth_user)
|
||||
tr = st_user.User.fromObject(user)
|
||||
users.save(tr)
|
||||
#print('*** post_user', auth_user, tr)
|
||||
return tr.toObject(User)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from scopes.storage import user as st_user
|
|||
type Storage = Annotated[common.Storage, Depends(storage)]
|
||||
type Users = Annotated[st_user.Users, Depends(users)]
|
||||
|
||||
type AuthUser = Annotated[str, Depends(auth_user)]
|
||||
type AuthUser = Annotated[str, Depends(auth_user())]
|
||||
type AuthToken = Annotated[str, Depends(auth_token)]
|
||||
|
||||
# storage
|
||||
|
|
@ -30,7 +30,7 @@ def users(storage: Storage):
|
|||
def auth_user():
|
||||
auth = auth_config.auth_methods.get(auth_config.settings.auth_method)
|
||||
if auth is not None:
|
||||
return auth()
|
||||
return auth
|
||||
|
||||
def auth_token():
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ DBUSER=testuser
|
|||
DBPASSWORD=secret
|
||||
DBSCHEMA=testing
|
||||
|
||||
AUTH_METHOD=testing
|
||||
AUTH_METHOD=basic
|
||||
|
||||
# openssl rand -hex 32:
|
||||
JWT_KEY=391a521ee5ba2b6ce67b8fdbb9f0ca88f40a87d3bc1e82974381b647bb0fc776
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@ def storage():
|
|||
storage.commit()
|
||||
return storage
|
||||
|
||||
def dummy_auth():
|
||||
return api_user.User(name='tester', login='tester', display_name='Tester')
|
||||
auth_config.auth_methods['testing'] = dummy_auth
|
||||
|
||||
def async_client():
|
||||
return AsyncClient(transport=ASGITransport(app=app), base_url='http://test')
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue