From fb0b1a796b353afa90fcda4f656194ad4aaab510 Mon Sep 17 00:00:00 2001 From: Tanishq Goyal Date: Mon, 20 Jul 2026 13:25:46 +0530 Subject: [PATCH 1/2] feat: add search functionality to pending and published blogs by author name --- backend/app/routers/admin.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/app/routers/admin.py b/backend/app/routers/admin.py index 12a9b74..979ceb3 100644 --- a/backend/app/routers/admin.py +++ b/backend/app/routers/admin.py @@ -48,11 +48,12 @@ async def list_pending_blogs( admin: dict = Depends(require_admin), page: int = Query(1, ge=1), limit: int = Query(10, ge=1, le=50), + search: str = Query("", description="Filter by author name"), db: Session = Depends(get_db) ): skip = (page - 1) * limit tenant_id = admin.get("tenant_id") - + query = db.query(BlogPost).filter( BlogPost.tenant_id == tenant_id, or_( @@ -60,7 +61,9 @@ async def list_pending_blogs( ~BlogPost.status.in_(["approved", "published", "rejected", "Approved", "Published"]) ) ) - + if search.strip(): + query = query.filter(BlogPost.author_name.ilike(f"%{search.strip()}%")) + total = query.count() blogs = query.order_by(desc(BlogPost.created_at)).offset(skip).limit(limit).all() @@ -88,16 +91,19 @@ async def list_published_blogs( admin: dict = Depends(require_admin), page: int = Query(1, ge=1), limit: int = Query(10, ge=1, le=50), + search: str = Query("", description="Filter by author name"), db: Session = Depends(get_db) ): skip = (page - 1) * limit tenant_id = admin.get("tenant_id") - + query = db.query(BlogPost).filter( BlogPost.tenant_id == tenant_id, BlogPost.status.in_(["approved", "published"]) ) - + if search.strip(): + query = query.filter(BlogPost.author_name.ilike(f"%{search.strip()}%")) + total = query.count() blogs = query.order_by(desc(BlogPost.created_at)).offset(skip).limit(limit).all() From cfe8929e8d686a12af1a190f081f4c2417083cdf Mon Sep 17 00:00:00 2001 From: Tanishq Goyal Date: Wed, 22 Jul 2026 13:20:27 +0530 Subject: [PATCH 2/2] feat: update user role from 'admin' to 'cms_admin' across schemas and authorization checks --- backend/app/models/schemas.py | 6 +++--- backend/app/routers/blogs.py | 8 ++++---- backend/core/deps.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/app/models/schemas.py b/backend/app/models/schemas.py index 97a752b..9c16309 100644 --- a/backend/app/models/schemas.py +++ b/backend/app/models/schemas.py @@ -7,7 +7,7 @@ class SignupIn(BaseModel): name: str email: EmailStr password: str - role: Literal["user", "admin"] = "user" # keep role + role: Literal["user", "cms_admin"] = "user" # keep role class LoginIn(BaseModel): @@ -19,7 +19,7 @@ class UserOut(BaseModel): id: str name: str email: EmailStr - role: Literal["user", "admin"] + role: Literal["user", "cms_admin"] class AdminBlogMiniOut(BaseModel): @@ -41,7 +41,7 @@ class AdminUserWithBlogsOut(BaseModel): id: str name: str email: EmailStr - role: Literal["user", "admin"] + role: Literal["user", "cms_admin"] created_at: Optional[datetime] = None last_login_at: Optional[datetime] = None blog_counts: AdminBlogCountsOut = AdminBlogCountsOut() diff --git a/backend/app/routers/blogs.py b/backend/app/routers/blogs.py index b909b7a..66d62ec 100644 --- a/backend/app/routers/blogs.py +++ b/backend/app/routers/blogs.py @@ -205,7 +205,7 @@ async def get_blog(blog_id: str, user: dict = Depends(get_current_user), db: Ses raise HTTPException(status_code=404, detail="Blog not found") if b.author_id != user["id"]: - if user.get("role") != "admin" or b.tenant_id != user.get("tenant_id"): + if user.get("role") != "cms_admin" or b.tenant_id != user.get("tenant_id"): raise HTTPException(status_code=403, detail="Not allowed") return _map_blog_detail(b) @@ -219,7 +219,7 @@ async def delete_blog_route(blog_id: str, user: dict = Depends(get_current_user) raise HTTPException(status_code=404, detail="Blog not found") if b.author_id != user["id"]: - if user.get("role") != "admin" or b.tenant_id != user.get("tenant_id"): + if user.get("role") != "cms_admin" or b.tenant_id != user.get("tenant_id"): raise HTTPException(status_code=403, detail="Not allowed") db.delete(b) @@ -235,7 +235,7 @@ async def update_blog_route(blog_id: str, payload: BlogCreateIn, user: dict = De raise HTTPException(status_code=404, detail="Blog not found") if b.author_id != user["id"]: - if user.get("role") != "admin" or b.tenant_id != user.get("tenant_id"): + if user.get("role") != "cms_admin" or b.tenant_id != user.get("tenant_id"): raise HTTPException(status_code=403, detail="Not allowed") content = b.content_blocks or {} @@ -292,7 +292,7 @@ async def change_to_draft(blog_id: str, user: dict = Depends(get_current_user), raise HTTPException(status_code=404, detail="Blog not found") if b.author_id != user["id"]: - if user.get("role") != "admin" or b.tenant_id != user.get("tenant_id"): + if user.get("role") != "cms_admin" or b.tenant_id != user.get("tenant_id"): raise HTTPException(status_code=403, detail="Not allowed") if b.status != "published": diff --git a/backend/core/deps.py b/backend/core/deps.py index dbc2dbe..768d03f 100644 --- a/backend/core/deps.py +++ b/backend/core/deps.py @@ -103,10 +103,10 @@ async def require_admin(user: dict = Depends(get_current_user)): """ Middleware dependency to ensure the authenticated user has administrative privileges. """ - if user.get("role") != "admin": + if user.get("role") != "cms_admin": logger.warning(f"Access denied: User {user.get('email')} attempted to access an admin-only route.") raise HTTPException( - status_code=403, + status_code=403, detail="Admin privileges required to perform this action." ) return user \ No newline at end of file