mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-05-31 20:25:14 -04:00
refactor(backend): ♻️ move router dependencies to mealie.core.dependencies module
This commit is contained in:
parent
e1fb306a92
commit
985ad8017d
2
mealie/core/dependencies/__init__.py
Normal file
2
mealie/core/dependencies/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .dependencies import *
|
||||||
|
from .grouped import *
|
48
mealie/core/dependencies/grouped.py
Normal file
48
mealie/core/dependencies/grouped.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
from fastapi import BackgroundTasks, Depends
|
||||||
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
|
from .dependencies import generate_session, get_current_user, is_logged_in
|
||||||
|
|
||||||
|
|
||||||
|
class ReadDeps:
|
||||||
|
"""
|
||||||
|
ReadDeps contains the common dependencies for all read operations through the API.
|
||||||
|
Note: The user object is used to definer what assets the user has access to.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
background_tasks: BackgroundTasks
|
||||||
|
session: Session
|
||||||
|
user: bool
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
|
session: Session = Depends(generate_session),
|
||||||
|
user=Depends(is_logged_in),
|
||||||
|
):
|
||||||
|
self.session = session
|
||||||
|
self.background_tasks = background_tasks
|
||||||
|
self.user = user
|
||||||
|
|
||||||
|
|
||||||
|
class WriteDeps:
|
||||||
|
"""
|
||||||
|
WriteDeps contains the common dependencies for all read operations through the API.
|
||||||
|
Note: The user must be logged in or the route will return a 401 error.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
background_tasks: BackgroundTasks
|
||||||
|
session: Session
|
||||||
|
user: bool
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
background_tasks: BackgroundTasks,
|
||||||
|
session: Session = Depends(generate_session),
|
||||||
|
user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
self.session = session
|
||||||
|
self.background_tasks = background_tasks
|
||||||
|
self.user = user
|
@ -4,9 +4,9 @@ from fastapi.security import OAuth2PasswordRequestForm
|
|||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.core import security
|
from mealie.core import security
|
||||||
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.core.security import authenticate_user
|
from mealie.core.security import authenticate_user
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.user import UserInDB
|
from mealie.schema.user import UserInDB
|
||||||
from mealie.services.events import create_user_event
|
from mealie.services.events import create_user_event
|
||||||
|
@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import is_logged_in
|
from mealie.core.dependencies import is_logged_in
|
||||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||||
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
|
from mealie.schema.recipe import CategoryIn, RecipeCategoryResponse
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||||
from mealie.schema.user import GroupBase, GroupInDB, UpdateGroup, UserInDB
|
from mealie.schema.user import GroupBase, GroupInDB, UpdateGroup, UserInDB
|
||||||
from mealie.services.events import create_group_event
|
from mealie.services.events import create_group_event
|
||||||
|
@ -4,7 +4,7 @@ from starlette.responses import FileResponse
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.meal_plan import MealPlanIn, MealPlanOut
|
from mealie.schema.meal_plan import MealPlanIn, MealPlanOut
|
||||||
from mealie.schema.user import GroupInDB, UserInDB
|
from mealie.schema.user import GroupInDB, UserInDB
|
||||||
|
@ -4,7 +4,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.meal_plan import ListItem, MealPlanOut, ShoppingListIn, ShoppingListOut
|
from mealie.schema.meal_plan import ListItem, MealPlanOut, ShoppingListIn, ShoppingListOut
|
||||||
from mealie.schema.recipe import Recipe
|
from mealie.schema.recipe import Recipe
|
||||||
|
@ -5,7 +5,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe import CommentOut, CreateComment, SaveComment
|
from mealie.schema.recipe import CommentOut, CreateComment, SaveComment
|
||||||
from mealie.schema.user import UserInDB
|
from mealie.schema.user import UserInDB
|
||||||
|
@ -12,7 +12,7 @@ from mealie.core.config import settings
|
|||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user, temporary_zip_path
|
from mealie.core.dependencies import get_current_user, temporary_zip_path
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.recipe import CreateRecipeByURL, Recipe, RecipeImageTypes
|
from mealie.schema.recipe import CreateRecipeByURL, Recipe, RecipeImageTypes
|
||||||
from mealie.schema.recipe.recipe import CreateRecipe
|
from mealie.schema.recipe.recipe import CreateRecipe
|
||||||
|
@ -2,7 +2,7 @@ from typing import List, Optional
|
|||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from mealie.routes.deps import get_admin_user, get_current_user
|
from mealie.core.dependencies import get_admin_user, get_current_user
|
||||||
|
|
||||||
|
|
||||||
class AdminAPIRouter(APIRouter):
|
class AdminAPIRouter(APIRouter):
|
||||||
|
@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.meal_plan import ShoppingListIn, ShoppingListOut
|
from mealie.schema.meal_plan import ShoppingListIn, ShoppingListOut
|
||||||
from mealie.schema.user import UserInDB
|
from mealie.schema.user import UserInDB
|
||||||
|
@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import AdminAPIRouter
|
from mealie.routes.routers import AdminAPIRouter
|
||||||
from mealie.schema.admin import SiteSettings
|
from mealie.schema.admin import SiteSettings
|
||||||
from mealie.schema.user import GroupInDB, UserInDB
|
from mealie.schema.user import GroupInDB, UserInDB
|
||||||
|
@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import is_logged_in
|
from mealie.core.dependencies import is_logged_in
|
||||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||||
from mealie.schema.recipe import RecipeTagResponse, TagIn
|
from mealie.schema.recipe import RecipeTagResponse, TagIn
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
from mealie.core.security import create_access_token
|
from mealie.core.security import create_access_token
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, UserInDB
|
from mealie.schema.user import CreateToken, LoingLiveTokenIn, LongLiveTokenInDB, UserInDB
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ from mealie.core import security
|
|||||||
from mealie.core.security import get_password_hash
|
from mealie.core.security import get_password_hash
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
from mealie.routes.routers import AdminAPIRouter, UserAPIRouter
|
||||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||||
from mealie.schema.user import UserBase, UserIn, UserInDB, UserOut
|
from mealie.schema.user import UserBase, UserIn, UserInDB, UserOut
|
||||||
|
@ -3,7 +3,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
|
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||||
from mealie.schema.user import UserFavorites, UserInDB
|
from mealie.schema.user import UserFavorites, UserInDB
|
||||||
|
@ -5,7 +5,7 @@ from fastapi.responses import FileResponse
|
|||||||
from fastapi.routing import APIRouter
|
from fastapi.routing import APIRouter
|
||||||
|
|
||||||
from mealie.core.config import app_dirs
|
from mealie.core.config import app_dirs
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||||
from mealie.schema.user import UserInDB
|
from mealie.schema.user import UserInDB
|
||||||
|
@ -5,7 +5,7 @@ from mealie.core.config import settings
|
|||||||
from mealie.core.security import get_password_hash, verify_password
|
from mealie.core.security import get_password_hash, verify_password
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user
|
from mealie.core.dependencies import get_current_user
|
||||||
from mealie.routes.routers import UserAPIRouter
|
from mealie.routes.routers import UserAPIRouter
|
||||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||||
from mealie.schema.user import ChangePassword, UserInDB
|
from mealie.schema.user import ChangePassword, UserInDB
|
||||||
|
@ -6,7 +6,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
from mealie.core.security import get_password_hash
|
from mealie.core.security import get_password_hash
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_admin_user
|
from mealie.core.dependencies import get_admin_user
|
||||||
from mealie.routes.routers import AdminAPIRouter
|
from mealie.routes.routers import AdminAPIRouter
|
||||||
from mealie.schema.user import SignUpIn, SignUpOut, SignUpToken, UserIn, UserInDB
|
from mealie.schema.user import SignUpIn, SignUpOut, SignUpToken, UserIn, UserInDB
|
||||||
from mealie.services.events import create_user_event
|
from mealie.services.events import create_user_event
|
||||||
|
@ -4,7 +4,7 @@ from typing import Optional
|
|||||||
from fastapi import APIRouter, Depends, HTTPException, status
|
from fastapi import APIRouter, Depends, HTTPException, status
|
||||||
from starlette.responses import FileResponse
|
from starlette.responses import FileResponse
|
||||||
|
|
||||||
from mealie.routes.deps import validate_file_token
|
from mealie.core.dependencies import validate_file_token
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/utils", tags=["Utils"], include_in_schema=True)
|
router = APIRouter(prefix="/api/utils", tags=["Utils"], include_in_schema=True)
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from sqlalchemy.orm.session import Session
|
|||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.db.database import db
|
from mealie.db.database import db
|
||||||
from mealie.db.db_setup import SessionLocal, generate_session
|
from mealie.db.db_setup import SessionLocal, generate_session
|
||||||
from mealie.routes.deps import is_logged_in
|
from mealie.core.dependencies import is_logged_in
|
||||||
from mealie.schema.recipe import RecipeSummary
|
from mealie.schema.recipe import RecipeSummary
|
||||||
|
|
||||||
logger = get_logger()
|
logger = get_logger()
|
||||||
|
@ -5,7 +5,7 @@ from pydantic import BaseModel
|
|||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.db.db_setup import generate_session
|
from mealie.db.db_setup import generate_session
|
||||||
from mealie.routes.deps import get_current_user, is_logged_in
|
from mealie.core.dependencies import get_current_user, is_logged_in
|
||||||
|
|
||||||
|
|
||||||
class CommonDeps(BaseModel):
|
class CommonDeps(BaseModel):
|
||||||
@ -17,7 +17,7 @@ class CommonDeps(BaseModel):
|
|||||||
arbitrary_types_allowed = True
|
arbitrary_types_allowed = True
|
||||||
|
|
||||||
|
|
||||||
def _read_deps(
|
def read_deps(
|
||||||
background_tasks: BackgroundTasks,
|
background_tasks: BackgroundTasks,
|
||||||
session: Session = Depends(generate_session),
|
session: Session = Depends(generate_session),
|
||||||
current_user=Depends(is_logged_in),
|
current_user=Depends(is_logged_in),
|
||||||
@ -29,7 +29,7 @@ def _read_deps(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def _write_deps(
|
def write_deps(
|
||||||
background_tasks: BackgroundTasks,
|
background_tasks: BackgroundTasks,
|
||||||
session: Session = Depends(generate_session),
|
session: Session = Depends(generate_session),
|
||||||
current_user=Depends(get_current_user),
|
current_user=Depends(get_current_user),
|
||||||
|
@ -3,6 +3,8 @@ from sqlalchemy.exc import IntegrityError
|
|||||||
from sqlalchemy.orm.session import Session
|
from sqlalchemy.orm.session import Session
|
||||||
|
|
||||||
from mealie.core.config import get_settings
|
from mealie.core.config import get_settings
|
||||||
|
from mealie.core.dependencies import ReadDeps
|
||||||
|
from mealie.core.dependencies.grouped import WriteDeps
|
||||||
from mealie.db.database import get_database
|
from mealie.db.database import get_database
|
||||||
from mealie.db.db_setup import SessionLocal
|
from mealie.db.db_setup import SessionLocal
|
||||||
from mealie.schema.recipe.recipe import CreateRecipe, Recipe
|
from mealie.schema.recipe.recipe import CreateRecipe, Recipe
|
||||||
@ -10,8 +12,6 @@ from mealie.schema.user.user import UserInDB
|
|||||||
from mealie.services.events import create_recipe_event
|
from mealie.services.events import create_recipe_event
|
||||||
from mealie.services.recipe.media import delete_assets
|
from mealie.services.recipe.media import delete_assets
|
||||||
|
|
||||||
from .common_deps import CommonDeps, _read_deps, _write_deps
|
|
||||||
|
|
||||||
|
|
||||||
class RecipeService:
|
class RecipeService:
|
||||||
recipe: Recipe
|
recipe: Recipe
|
||||||
@ -27,7 +27,7 @@ class RecipeService:
|
|||||||
self.settings = get_settings()
|
self.settings = get_settings()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def read_existing(cls, slug: str, local_deps: CommonDeps = Depends(_read_deps)):
|
def read_existing(cls, slug: str, deps: ReadDeps = Depends()):
|
||||||
"""
|
"""
|
||||||
Used for dependency injection for routes that require an existing recipe. If the recipe doesn't exist
|
Used for dependency injection for routes that require an existing recipe. If the recipe doesn't exist
|
||||||
or the user doens't not have the required permissions, the proper HTTP Status code will be raised.
|
or the user doens't not have the required permissions, the proper HTTP Status code will be raised.
|
||||||
@ -44,12 +44,12 @@ class RecipeService:
|
|||||||
Returns:
|
Returns:
|
||||||
RecipeService: The Recipe Service class with a populated recipe attribute
|
RecipeService: The Recipe Service class with a populated recipe attribute
|
||||||
"""
|
"""
|
||||||
new_class = cls(local_deps.session, local_deps.user, local_deps.background_tasks)
|
new_class = cls(deps.session, deps.user, deps.background_tasks)
|
||||||
new_class.assert_existing(slug)
|
new_class.assert_existing(slug)
|
||||||
return new_class
|
return new_class
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def write_existing(cls, slug: str, local_deps: CommonDeps = Depends(_write_deps)):
|
def write_existing(cls, slug: str, deps: WriteDeps = Depends()):
|
||||||
"""
|
"""
|
||||||
Used for dependency injection for routes that require an existing recipe. The only difference between
|
Used for dependency injection for routes that require an existing recipe. The only difference between
|
||||||
read_existing and write_existing is that the user is required to be logged in on write_existing method.
|
read_existing and write_existing is that the user is required to be logged in on write_existing method.
|
||||||
@ -66,19 +66,19 @@ class RecipeService:
|
|||||||
Returns:
|
Returns:
|
||||||
RecipeService: The Recipe Service class with a populated recipe attribute
|
RecipeService: The Recipe Service class with a populated recipe attribute
|
||||||
"""
|
"""
|
||||||
new_class = cls(local_deps.session, local_deps.user, local_deps.background_tasks)
|
new_class = cls(deps.session, deps.user, deps.background_tasks)
|
||||||
new_class.assert_existing(slug)
|
new_class.assert_existing(slug)
|
||||||
return new_class
|
return new_class
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def base(cls, local_deps: CommonDeps = Depends(_write_deps)) -> Recipe:
|
def base(cls, deps: WriteDeps = Depends()) -> Recipe:
|
||||||
"""A Base instance to be used as a router dependency
|
"""A Base instance to be used as a router dependency
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
HTTPException: 400 Bad Request
|
HTTPException: 400 Bad Request
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return cls(local_deps.session, local_deps.user, local_deps.background_tasks)
|
return cls(deps.session, deps.user, deps.background_tasks)
|
||||||
|
|
||||||
def pupulate_recipe(self, slug: str) -> Recipe:
|
def pupulate_recipe(self, slug: str) -> Recipe:
|
||||||
"""Populates the recipe attribute with the recipe from the database.
|
"""Populates the recipe attribute with the recipe from the database.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from mealie.core import security
|
from mealie.core import security
|
||||||
from mealie.routes.deps import validate_file_token
|
from mealie.core.dependencies import validate_file_token
|
||||||
|
|
||||||
|
|
||||||
def test_create_file_token():
|
def test_create_file_token():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user