richtext's picture
Upload folder using huggingface_hub
3674b4b verified
from fastapi import APIRouter, HTTPException, status, Request
from backend.core.dependencies import DbSession, AdminUser
from backend.schemas.group import (
GroupCreate, GroupUpdate, GroupResponse, GroupDetailResponse,
GroupMemberResponse, GroupSiteResponse,
AssignUserToGroupRequest, AssignSiteToGroupRequest
)
from backend.models import Group, User, Site, UserGroup, GroupSite, AuditLog
router = APIRouter()
@router.get("", response_model=list[GroupResponse])
def list_groups(db: DbSession, admin: AdminUser):
groups = db.query(Group).all()
return [
GroupResponse(
id=g.id,
name=g.name,
description=g.description,
created_at=g.created_at,
updated_at=g.updated_at,
member_count=len(g.members),
site_count=len(g.sites)
)
for g in groups
]
@router.post("", response_model=GroupResponse, status_code=status.HTTP_201_CREATED)
def create_group(group_data: GroupCreate, db: DbSession, admin: AdminUser, request: Request):
existing = db.query(Group).filter(Group.name == group_data.name).first()
if existing:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Group with this name already exists"
)
group = Group(name=group_data.name, description=group_data.description)
db.add(group)
db.commit()
db.refresh(group)
# Audit log
audit = AuditLog(
user_id=admin.id,
action="group_created",
resource_type="group",
resource_id=group.id,
details={"name": group.name, "description": group.description},
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.commit()
return GroupResponse(
id=group.id,
name=group.name,
description=group.description,
created_at=group.created_at,
updated_at=group.updated_at,
member_count=0,
site_count=0
)
@router.get("/{group_id}", response_model=GroupDetailResponse)
def get_group(group_id: str, db: DbSession, admin: AdminUser):
group = db.query(Group).filter(Group.id == group_id).first()
if not group:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Group not found"
)
members = [
GroupMemberResponse(
user_id=ug.user.id,
email=ug.user.email,
full_name=ug.user.full_name,
role=ug.role
)
for ug in group.members
]
sites = [
GroupSiteResponse(
site_id=gs.site.id,
site_code=gs.site.site_code,
site_name=gs.site.name
)
for gs in group.sites
]
return GroupDetailResponse(
id=group.id,
name=group.name,
description=group.description,
created_at=group.created_at,
updated_at=group.updated_at,
member_count=len(members),
site_count=len(sites),
members=members,
sites=sites
)
@router.put("/{group_id}", response_model=GroupResponse)
def update_group(group_id: str, group_data: GroupUpdate, db: DbSession, admin: AdminUser, request: Request):
group = db.query(Group).filter(Group.id == group_id).first()
if not group:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Group not found"
)
changes = {}
old_name = group.name
if group_data.name is not None:
# Check for duplicate name
existing = db.query(Group).filter(Group.name == group_data.name, Group.id != group_id).first()
if existing:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Group with this name already exists"
)
if group_data.name != group.name:
changes["name"] = {"old": group.name, "new": group_data.name}
group.name = group_data.name
if group_data.description is not None:
if group_data.description != group.description:
changes["description"] = {"old": group.description, "new": group_data.description}
group.description = group_data.description
db.commit()
db.refresh(group)
# Audit log
if changes:
audit = AuditLog(
user_id=admin.id,
action="group_updated",
resource_type="group",
resource_id=group.id,
details={"group_name": old_name, "changes": changes},
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.commit()
return GroupResponse(
id=group.id,
name=group.name,
description=group.description,
created_at=group.created_at,
updated_at=group.updated_at,
member_count=len(group.members),
site_count=len(group.sites)
)
@router.delete("/{group_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_group(group_id: str, db: DbSession, admin: AdminUser, request: Request):
group = db.query(Group).filter(Group.id == group_id).first()
if not group:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="Group not found"
)
# Audit log before deletion
audit = AuditLog(
user_id=admin.id,
action="group_deleted",
resource_type="group",
resource_id=group.id,
details={"name": group.name, "member_count": len(group.members), "site_count": len(group.sites)},
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.delete(group)
db.commit()
@router.post("/{group_id}/users", status_code=status.HTTP_201_CREATED)
def assign_user_to_group(group_id: str, data: AssignUserToGroupRequest, db: DbSession, admin: AdminUser, request: Request):
group = db.query(Group).filter(Group.id == group_id).first()
if not group:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Group not found")
user = db.query(User).filter(User.id == data.user_id).first()
if not user:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
existing = db.query(UserGroup).filter(
UserGroup.user_id == data.user_id,
UserGroup.group_id == group_id
).first()
action = "user_role_updated" if existing else "user_assigned_to_group"
old_role = existing.role if existing else None
if existing:
existing.role = data.role
else:
ug = UserGroup(user_id=data.user_id, group_id=group_id, role=data.role)
db.add(ug)
db.commit()
# Audit log
details = {
"user_email": user.email,
"group_name": group.name,
"role": data.role
}
if old_role:
details["old_role"] = old_role
audit = AuditLog(
user_id=admin.id,
action=action,
resource_type="user_group",
resource_id=f"{user.id}:{group.id}",
details=details,
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.commit()
return {"message": "User assigned to group"}
@router.delete("/{group_id}/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
def remove_user_from_group(group_id: str, user_id: str, db: DbSession, admin: AdminUser, request: Request):
ug = db.query(UserGroup).filter(
UserGroup.user_id == user_id,
UserGroup.group_id == group_id
).first()
if not ug:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not in group")
# Get names for audit log
user = db.query(User).filter(User.id == user_id).first()
group = db.query(Group).filter(Group.id == group_id).first()
# Audit log before deletion
audit = AuditLog(
user_id=admin.id,
action="user_removed_from_group",
resource_type="user_group",
resource_id=f"{user_id}:{group_id}",
details={
"user_email": user.email if user else user_id,
"group_name": group.name if group else group_id,
"role": ug.role
},
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.delete(ug)
db.commit()
@router.post("/{group_id}/sites", status_code=status.HTTP_201_CREATED)
def assign_site_to_group(group_id: str, data: AssignSiteToGroupRequest, db: DbSession, admin: AdminUser, request: Request):
group = db.query(Group).filter(Group.id == group_id).first()
if not group:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Group not found")
site = db.query(Site).filter(Site.id == data.site_id).first()
if not site:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Site not found")
existing = db.query(GroupSite).filter(
GroupSite.site_id == data.site_id,
GroupSite.group_id == group_id
).first()
if existing:
return {"message": "Site already in group"}
gs = GroupSite(site_id=data.site_id, group_id=group_id)
db.add(gs)
db.commit()
# Audit log
audit = AuditLog(
user_id=admin.id,
action="site_assigned_to_group",
resource_type="group_site",
resource_id=f"{group.id}:{site.id}",
details={
"site_code": site.site_code,
"site_name": site.name,
"group_name": group.name
},
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.commit()
return {"message": "Site assigned to group"}
@router.delete("/{group_id}/sites/{site_id}", status_code=status.HTTP_204_NO_CONTENT)
def remove_site_from_group(group_id: str, site_id: str, db: DbSession, admin: AdminUser, request: Request):
gs = db.query(GroupSite).filter(
GroupSite.site_id == site_id,
GroupSite.group_id == group_id
).first()
if not gs:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Site not in group")
# Get names for audit log
site = db.query(Site).filter(Site.id == site_id).first()
group = db.query(Group).filter(Group.id == group_id).first()
# Audit log before deletion
audit = AuditLog(
user_id=admin.id,
action="site_removed_from_group",
resource_type="group_site",
resource_id=f"{group_id}:{site_id}",
details={
"site_code": site.site_code if site else site_id,
"site_name": site.name if site else None,
"group_name": group.name if group else group_id
},
ip_address=request.client.host if request.client else None
)
db.add(audit)
db.delete(gs)
db.commit()