More localization (#358)

* Translate missing items on About page

* Localize import summary dialog

* Make site menu translation reactive

* Localize import options

* Include semi colon in string

* Move API texts to frontend + better status codes

* Provide feedback to user when no meal is planned

* Fix API tests after latest rework

* Add warning for API changes in changelog

* Refactor API texts handling

* Refactor API texts handling #2

* Better API feedback

* Rearrange strings hierarchy

* Add messages upon recipe updated

* Fix 'recipe effected' typo

* Remove snackbar usage in backend

* Translate toolbox

* Provide feedback for tags CRUD

* Fix messed up merge

* Translate sign-up form

* Better feedback for sign-up CRUD

* Refactor log-in API texts handling

* No error message when user is not authenticated

* Remove unimportant console log
This commit is contained in:
sephrat
2021-04-29 18:22:45 +02:00
committed by GitHub
parent 861020ffe0
commit 1e5edc7434
72 changed files with 890 additions and 606 deletions

View File

@@ -7,7 +7,6 @@ from mealie.core import security
from mealie.core.security import authenticate_user
from mealie.db.db_setup import generate_session
from mealie.routes.deps import get_current_user
from mealie.schema.snackbar import SnackResponse
from mealie.schema.user import UserInDB
from sqlalchemy.orm.session import Session
@@ -28,15 +27,11 @@ def get_token(
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
access_token = security.create_access_token(dict(sub=email))
return SnackResponse.success(
"User Successfully Logged In",
{"access_token": access_token, "token_type": "bearer"},
)
return {"access_token": access_token, "token_type": "bearer"}
@router.get("/refresh")

View File

@@ -1,7 +1,7 @@
import shutil
from datetime import timedelta
from fastapi import APIRouter, Depends, File, UploadFile
from fastapi import APIRouter, Depends, File, UploadFile, status, HTTPException
from fastapi.responses import FileResponse
from mealie.core import security
from mealie.core.config import app_dirs, settings
@@ -9,7 +9,6 @@ from mealie.core.security import get_password_hash, verify_password
from mealie.db.database import db
from mealie.db.db_setup import generate_session
from mealie.routes.deps import get_current_user
from mealie.schema.snackbar import SnackResponse
from mealie.schema.user import ChangePassword, UserBase, UserIn, UserInDB, UserOut
from sqlalchemy.orm.session import Session
@@ -25,8 +24,7 @@ async def create_user(
new_user.password = get_password_hash(new_user.password)
data = db.users.create(session, new_user.dict())
return SnackResponse.success(f"User Created: {new_user.full_name}", data)
return db.users.create(session, new_user.dict())
@router.get("", response_model=list[UserOut])
@@ -35,10 +33,10 @@ async def get_all_users(
session: Session = Depends(generate_session),
):
if current_user.admin:
return db.users.get_all(session)
else:
return {"details": "user not authorized"}
if not current_user.admin:
raise HTTPException( status.HTTP_403_FORBIDDEN )
return db.users.get_all(session)
@router.get("/self", response_model=UserOut)
@@ -68,7 +66,6 @@ async def reset_user_password(
new_password = get_password_hash(settings.DEFAULT_PASSWORD)
db.users.update_password(session, id, new_password)
return SnackResponse.success("Users Password Reset")
@router.put("/{id}")
@@ -85,8 +82,7 @@ async def update_user(
if current_user.id == id:
access_token = security.create_access_token(data=dict(sub=new_data.email))
token = {"access_token": access_token, "token_type": "bearer"}
return SnackResponse.success("User Updated", token)
return token
@router.get("/{id}/image")
@@ -121,10 +117,8 @@ async def update_user_image(
with dest.open("wb") as buffer:
shutil.copyfileobj(profile_image.file, buffer)
if dest.is_file:
return SnackResponse.success("File uploaded")
else:
return SnackResponse.error("Failure uploading file")
if not dest.is_file:
raise HTTPException( status.HTTP_500_INTERNAL_SERVER_ERROR )
@router.put("/{id}/password")
@@ -139,12 +133,12 @@ async def update_password(
match_passwords = verify_password(password_change.current_password, current_user.password)
match_id = current_user.id == id
if match_passwords and match_id:
new_password = get_password_hash(password_change.new_password)
db.users.update_password(session, id, new_password)
return SnackResponse.success("Password Updated")
else:
return SnackResponse.error("Existing password does not match")
if not ( match_passwords and match_id ):
raise HTTPException( status.HTTP_401_UNAUTHORIZED )
new_password = get_password_hash(password_change.new_password)
db.users.update_password(session, id, new_password)
@router.delete("/{id}")
@@ -156,8 +150,13 @@ async def delete_user(
""" Removes a user from the database. Must be the current user or a super user"""
if id == 1:
return SnackResponse.error("Error! Cannot Delete Super User")
raise HTTPException(
status_code=status.HTTP_403_FORBIDDEN,
detail='SUPER_USER'
)
if current_user.id == id or current_user.admin:
db.users.delete(session, id)
return SnackResponse.error("User Deleted")
try:
db.users.delete(session, id)
except:
raise HTTPException( status.HTTP_400_BAD_REQUEST )

View File

@@ -6,7 +6,6 @@ from mealie.db.db_setup import generate_session
from fastapi import APIRouter, Depends
from mealie.routes.deps import get_current_user
from mealie.schema.sign_up import SignUpIn, SignUpOut, SignUpToken
from mealie.schema.snackbar import SnackResponse
from mealie.schema.user import UserIn, UserInDB
from sqlalchemy.orm.session import Session
@@ -33,18 +32,16 @@ async def create_user_sign_up_key(
):
""" Generates a Random Token that a new user can sign up with """
if current_user.admin:
sign_up = {
"token": str(uuid.uuid1().hex),
"name": key_data.name,
"admin": key_data.admin,
}
db_entry = db.sign_ups.create(session, sign_up)
if not current_user.admin:
raise HTTPException( status.HTTP_403_FORBIDDEN )
return db_entry
sign_up = {
"token": str(uuid.uuid1().hex),
"name": key_data.name,
"admin": key_data.admin,
}
return db.sign_ups.create(session, sign_up)
else:
return {"details": "not authorized"}
@router.post("/{token}")
@@ -58,7 +55,7 @@ async def create_user_with_token(
# Validate Token
db_entry: SignUpOut = db.sign_ups.get(session, token, limit=1)
if not db_entry:
return SnackResponse.error("Invalid Token")
raise HTTPException( status.HTTP_401_UNAUTHORIZED )
# Create User
new_user.admin = db_entry.admin
@@ -68,9 +65,6 @@ async def create_user_with_token(
# DeleteToken
db.sign_ups.delete(session, token)
# Respond
return SnackResponse.success(f"User Created: {new_user.full_name}", data)
@router.delete("/{token}")
async def delete_token(
@@ -79,8 +73,7 @@ async def delete_token(
session: Session = Depends(generate_session),
):
""" Removed a token from the database """
if current_user.admin:
db.sign_ups.delete(session, token)
return SnackResponse.error("Sign Up Token Deleted")
else:
return {"details", "not authorized"}
if not current_user.admin:
raise HTTPException( status.HTTP_403_FORBIDDEN )
db.sign_ups.delete(session, token)