mirror of
https://github.com/hay-kot/mealie.git
synced 2025-07-05 20:42:23 -07:00
feat: Consolidate Admin User APIs (#5050)
Co-authored-by: Kuchenpirat <24235032+Kuchenpirat@users.noreply.github.com>
This commit is contained in:
parent
31f90c79c0
commit
47eb1ebbb1
7 changed files with 24 additions and 53 deletions
|
@ -1,4 +1,4 @@
|
|||
import { useUserApi } from "~/composables/api";
|
||||
import { useAdminApi } from "~/composables/api";
|
||||
import type { UserIn, UserOut } from "~/lib/api/types/user";
|
||||
|
||||
/*
|
||||
|
@ -8,7 +8,7 @@ to control whether the object is substantiated... but some of the others rely on
|
|||
*/
|
||||
|
||||
export const useAllUsers = function () {
|
||||
const api = useUserApi();
|
||||
const api = useAdminApi();
|
||||
const asyncKey = String(Date.now());
|
||||
const { data: users, refresh: refreshAllUsers } = useLazyAsyncData(asyncKey, async () => {
|
||||
const { data } = await api.users.getAll();
|
||||
|
@ -24,7 +24,7 @@ export const useAllUsers = function () {
|
|||
};
|
||||
|
||||
export const useUser = function (refreshFunc: CallableFunction | null = null) {
|
||||
const api = useUserApi();
|
||||
const api = useAdminApi();
|
||||
const loading = ref(false);
|
||||
|
||||
function getUser(id: string) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from functools import cached_property
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.core import security
|
||||
|
@ -42,6 +42,11 @@ class AdminUserManagementRoutes(BaseAdminController):
|
|||
|
||||
@router.post("", response_model=UserOut, status_code=201)
|
||||
def create_one(self, data: UserIn):
|
||||
if self.repos.users.get_by_username(data.username):
|
||||
raise HTTPException(status.HTTP_409_CONFLICT, {"message": self.t("exceptions.username-conflict-error")})
|
||||
elif self.repos.users.get_one(data.email, "email"):
|
||||
raise HTTPException(status.HTTP_409_CONFLICT, {"message": self.t("exceptions.email-conflict-error")})
|
||||
|
||||
data.password = security.hash_password(data.password)
|
||||
return self.mixins.create_one(data)
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ router = APIRouter()
|
|||
|
||||
router.include_router(registration.router, prefix=user_prefix, tags=["Users: Registration"])
|
||||
router.include_router(crud.user_router)
|
||||
router.include_router(crud.admin_router)
|
||||
router.include_router(forgot_password.router, prefix=user_prefix, tags=["Users: Passwords"])
|
||||
router.include_router(images.router, prefix=user_prefix, tags=["Users: Images"])
|
||||
router.include_router(api_tokens.router)
|
||||
|
|
|
@ -1,52 +1,17 @@
|
|||
from fastapi import Depends, HTTPException, status
|
||||
from fastapi import HTTPException, status
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.core.security import hash_password
|
||||
from mealie.core.security.providers.credentials_provider import CredentialsProvider
|
||||
from mealie.db.models.users.users import AuthMethod
|
||||
from mealie.routes._base import BaseAdminController, BaseUserController, controller
|
||||
from mealie.routes._base.mixins import HttpRepo
|
||||
from mealie.routes._base.routers import AdminAPIRouter, UserAPIRouter
|
||||
from mealie.routes._base import BaseUserController, controller
|
||||
from mealie.routes._base.routers import UserAPIRouter
|
||||
from mealie.routes.users._helpers import assert_user_change_allowed
|
||||
from mealie.schema.response import ErrorResponse, SuccessResponse
|
||||
from mealie.schema.response.pagination import PaginationQuery
|
||||
from mealie.schema.user import ChangePassword, UserBase, UserIn, UserOut
|
||||
from mealie.schema.user.user import UserPagination, UserRatings, UserRatingSummary
|
||||
from mealie.schema.user import ChangePassword, UserBase, UserOut
|
||||
from mealie.schema.user.user import UserRatings, UserRatingSummary
|
||||
|
||||
user_router = UserAPIRouter(prefix="/users", tags=["Users: CRUD"])
|
||||
admin_router = AdminAPIRouter(prefix="/users", tags=["Users: Admin CRUD"])
|
||||
|
||||
|
||||
@controller(admin_router)
|
||||
class AdminUserController(BaseAdminController):
|
||||
@property
|
||||
def mixins(self) -> HttpRepo:
|
||||
return HttpRepo[UserIn, UserOut, UserBase](self.repos.users, self.logger)
|
||||
|
||||
@admin_router.get("", response_model=UserPagination)
|
||||
def get_all(self, q: PaginationQuery = Depends(PaginationQuery)):
|
||||
"""Returns all users from all groups"""
|
||||
|
||||
response = self.repos.users.page_all(
|
||||
pagination=q,
|
||||
override=UserOut,
|
||||
)
|
||||
|
||||
response.set_pagination_guides(admin_router.url_path_for("get_all"), q.model_dump())
|
||||
return response
|
||||
|
||||
@admin_router.post("", response_model=UserOut, status_code=201)
|
||||
def create_user(self, new_user: UserIn):
|
||||
new_user.password = hash_password(new_user.password)
|
||||
return self.mixins.create_one(new_user)
|
||||
|
||||
@admin_router.get("/{item_id}", response_model=UserOut)
|
||||
def get_user(self, item_id: UUID4):
|
||||
return self.mixins.get_one(item_id)
|
||||
|
||||
@admin_router.delete("/{item_id}")
|
||||
def delete_user(self, item_id: UUID4):
|
||||
self.mixins.delete_one(item_id)
|
||||
|
||||
|
||||
@controller(user_router)
|
||||
|
|
8
tests/fixtures/fixture_users.py
vendored
8
tests/fixtures/fixture_users.py
vendored
|
@ -76,7 +76,7 @@ def h2_user(session: Session, admin_token, api_client: TestClient, unique_user:
|
|||
"admin": False,
|
||||
"tokens": [],
|
||||
}
|
||||
response = api_client.post(api_routes.users, json=user_data, headers=admin_token)
|
||||
response = api_client.post(api_routes.admin_users, json=user_data, headers=admin_token)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Log in as this user
|
||||
|
@ -135,7 +135,7 @@ def g2_user(session: Session, admin_token, api_client: TestClient):
|
|||
}
|
||||
|
||||
api_client.post(api_routes.admin_groups, json={"name": group}, headers=admin_token)
|
||||
response = api_client.post(api_routes.users, json=create_data, headers=admin_token)
|
||||
response = api_client.post(api_routes.admin_users, json=create_data, headers=admin_token)
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
|
@ -258,7 +258,7 @@ def user_tuple(session: Session, admin_token, api_client: TestClient) -> Generat
|
|||
users_out = []
|
||||
|
||||
for usr in [create_data_1, create_data_2]:
|
||||
response = api_client.post(api_routes.users, json=usr, headers=admin_token)
|
||||
response = api_client.post(api_routes.admin_users, json=usr, headers=admin_token)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Log in as this user
|
||||
|
@ -312,7 +312,7 @@ def user_token(admin_token, api_client: TestClient):
|
|||
"tokens": [],
|
||||
}
|
||||
|
||||
response = api_client.post(api_routes.users, json=create_data, headers=admin_token)
|
||||
response = api_client.post(api_routes.admin_users, json=create_data, headers=admin_token)
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ def test_api_token_private(api_client: TestClient, admin_token):
|
|||
response = api_client.post(api_routes.users_api_tokens, json={"name": "Test API Token"}, headers=admin_token)
|
||||
assert response.status_code == 201
|
||||
|
||||
response = api_client.get(api_routes.users, headers=admin_token, params={"perPage": -1})
|
||||
response = api_client.get(api_routes.admin_users, headers=admin_token, params={"perPage": -1})
|
||||
assert response.status_code == 200
|
||||
for user in response.json()["items"]:
|
||||
for user_token in user["tokens"] or []:
|
||||
|
@ -39,7 +39,7 @@ def test_api_token_private(api_client: TestClient, admin_token):
|
|||
|
||||
|
||||
def test_use_token(api_client: TestClient, long_live_token):
|
||||
response = api_client.get(api_routes.users, headers=long_live_token)
|
||||
response = api_client.get(api_routes.admin_users, headers=long_live_token)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
|
|
|
@ -88,9 +88,11 @@ def test_user_update(api_client: TestClient, unique_user: TestUser, admin_user:
|
|||
|
||||
|
||||
def test_admin_updates(api_client: TestClient, admin_user: TestUser, unique_user: TestUser):
|
||||
response = api_client.get(api_routes.users_item_id(unique_user.user_id), headers=admin_user.token)
|
||||
response = api_client.get(api_routes.admin_users_item_id(unique_user.user_id), headers=admin_user.token)
|
||||
assert response.status_code == 200
|
||||
user = response.json()
|
||||
response = api_client.get(api_routes.users_item_id(admin_user.user_id), headers=admin_user.token)
|
||||
|
||||
response = api_client.get(api_routes.admin_users_item_id(admin_user.user_id), headers=admin_user.token)
|
||||
admin = response.json()
|
||||
|
||||
# admin updating themselves
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue