[#4] Passwords in AgencyConf model
This commit is contained in:
parent
319be9f803
commit
c03d5b1232
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -144,6 +144,7 @@ data/trash/
|
||||||
data/gtfs/
|
data/gtfs/
|
||||||
data/grfs
|
data/grfs
|
||||||
data/tmp
|
data/tmp
|
||||||
|
data/agencyconf/**
|
||||||
|
|
||||||
#these files are under app/static but they get copied to the outside directory on startup
|
#these files are under app/static but they get copied to the outside directory on startup
|
||||||
logging.conf
|
logging.conf
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,18 @@ class AgencyConf(BaseModel):
|
||||||
max_length=256,
|
max_length=256,
|
||||||
pattern=r'^[a-zA-Z0-9]+$',
|
pattern=r'^[a-zA-Z0-9]+$',
|
||||||
examples=["d8yLuY4DqMEUCLcfJASi"])
|
examples=["d8yLuY4DqMEUCLcfJASi"])
|
||||||
|
password: str = Field(
|
||||||
|
description="The agency's password for generating JWT tokens",
|
||||||
|
min_length=8,
|
||||||
|
max_length=256,
|
||||||
|
examples=["$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"])
|
||||||
model_config = ConfigDict(json_schema_extra={
|
model_config = ConfigDict(json_schema_extra={
|
||||||
"title": "Agency Configuration",
|
"title": "Agency Configuration",
|
||||||
"description": "Configuration for an agency.",
|
"description": "Configuration for an agency.",
|
||||||
"example":
|
"example":
|
||||||
{
|
{
|
||||||
"agency_id": "mfdz",
|
"agency_id": "mfdz",
|
||||||
"api_key": "d8yLuY4DqMEUCLcfJASi"
|
"api_key": "d8yLuY4DqMEUCLcfJASi",
|
||||||
|
"password": "$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ from fastapi import HTTPException, status
|
||||||
|
|
||||||
from amarillo.models.AgencyConf import AgencyConf
|
from amarillo.models.AgencyConf import AgencyConf
|
||||||
from amarillo.services.config import config
|
from amarillo.services.config import config
|
||||||
|
from amarillo.services.passwords import get_password_hash
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -85,6 +86,8 @@ class AgencyConfService:
|
||||||
logger.error(message)
|
logger.error(message)
|
||||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)
|
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=message)
|
||||||
|
|
||||||
|
agency_conf.password = get_password_hash(agency_conf.password)
|
||||||
|
|
||||||
with open(f'{agency_conf_directory}/{agency_id}.json', 'w', encoding='utf-8') as f:
|
with open(f'{agency_conf_directory}/{agency_id}.json', 'w', encoding='utf-8') as f:
|
||||||
f.write(agency_conf.json())
|
f.write(agency_conf.json())
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@ import logging
|
||||||
from fastapi import Depends, HTTPException, Header, status, APIRouter
|
from fastapi import Depends, HTTPException, Header, status, APIRouter
|
||||||
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
|
||||||
from jose import JWTError, jwt
|
from jose import JWTError, jwt
|
||||||
from passlib.context import CryptContext
|
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from amarillo.routers.agencyconf import verify_api_key
|
from amarillo.routers.agencyconf import verify_api_key
|
||||||
|
from amarillo.services.passwords import verify_password
|
||||||
|
|
||||||
from amarillo.services.config import config
|
from amarillo.services.config import config
|
||||||
|
|
||||||
|
|
@ -60,21 +60,11 @@ class User(BaseModel):
|
||||||
class UserInDB(User):
|
class UserInDB(User):
|
||||||
hashed_password: str
|
hashed_password: str
|
||||||
|
|
||||||
|
|
||||||
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
|
||||||
|
|
||||||
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token", auto_error=False)
|
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token", auto_error=False)
|
||||||
async def verify_optional_api_key(X_API_Key: Optional[str] = Header(None)):
|
async def verify_optional_api_key(X_API_Key: Optional[str] = Header(None)):
|
||||||
if X_API_Key == None: return None
|
if X_API_Key == None: return None
|
||||||
return await verify_api_key(X_API_Key)
|
return await verify_api_key(X_API_Key)
|
||||||
|
|
||||||
def verify_password(plain_password, hashed_password):
|
|
||||||
return pwd_context.verify(plain_password, hashed_password)
|
|
||||||
|
|
||||||
|
|
||||||
def get_password_hash(password):
|
|
||||||
return pwd_context.hash(password)
|
|
||||||
|
|
||||||
def get_agency(db, agency_id: str):
|
def get_agency(db, agency_id: str):
|
||||||
if agency_id in db:
|
if agency_id in db:
|
||||||
user_dict = db[agency_id]
|
user_dict = db[agency_id]
|
||||||
|
|
|
||||||
10
amarillo/services/passwords.py
Normal file
10
amarillo/services/passwords.py
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
from passlib.context import CryptContext
|
||||||
|
|
||||||
|
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
||||||
|
|
||||||
|
def verify_password(plain_password, hashed_password):
|
||||||
|
return pwd_context.verify(plain_password, hashed_password)
|
||||||
|
|
||||||
|
|
||||||
|
def get_password_hash(password):
|
||||||
|
return pwd_context.hash(password)
|
||||||
Loading…
Reference in a new issue