Skip to content

Commit

Permalink
Add support for user deletion (#2486)
Browse files Browse the repository at this point in the history
The aim here is to retain the database "User" entry but wholly
anonymised (getting rid of their display name and their provider
username)
  • Loading branch information
olliestanley committed Apr 14, 2023
1 parent 1813bcc commit a37157c
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 0 deletions.
1 change: 1 addition & 0 deletions backend/oasst_backend/api/v1/users.py
Expand Up @@ -210,6 +210,7 @@ def delete_user(
):
"""
Delete a user by global user ID. Only trusted clients can delete users.
User deletion anonymises the data of the user.
"""
ur = UserRepository(db, api_client)
ur.mark_user_deleted(user_id)
Expand Down
8 changes: 8 additions & 0 deletions backend/oasst_backend/user_repository.py
Expand Up @@ -4,6 +4,7 @@
from oasst_backend.config import settings
from oasst_backend.models import ApiClient, User
from oasst_backend.utils.database_utils import CommitMode, managed_tx_method
from oasst_shared import utils as shared_utils
from oasst_shared.exceptions import OasstError, OasstErrorCode
from oasst_shared.schemas import protocol as protocol_schema
from oasst_shared.utils import utcnow
Expand Down Expand Up @@ -105,6 +106,7 @@ def update_user(
def mark_user_deleted(self, id: UUID) -> None:
"""
Update a user by global user ID to set deleted flag. Only trusted clients may delete users.
User deletion anonymises the data of the user.
Raises:
OasstError: 403 if untrusted client attempts to delete a user. 404 if user with ID not found.
Expand All @@ -119,6 +121,12 @@ def mark_user_deleted(self, id: UUID) -> None:

user.deleted = True

# Anonymise user data
user.display_name = shared_utils.DELETED_USER_DISPLAY_NAME
# Ensure uniqueness of (username, auth_method, api_client_id) Index
user.username = f"{shared_utils.DELETED_USER_ID_PREFIX}{user.id}"
user.show_on_leaderboard = False

self.db.add(user)

@managed_tx_method(CommitMode.COMMIT)
Expand Down
@@ -0,0 +1,27 @@
"""Add deleted field to user
Revision ID: f0e18084aae4
Revises: 78f16015b904
Create Date: 2023-04-12 20:33:28.239793
"""
import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "f0e18084aae4"
down_revision = "78f16015b904"
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("user", sa.Column("deleted", sa.Boolean(), nullable=False))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("user", "deleted")
# ### end Alembic commands ###
2 changes: 2 additions & 0 deletions inference/server/oasst_inference_server/models/user.py
Expand Up @@ -14,6 +14,8 @@ class DbUser(SQLModel, table=True):

display_name: str = Field(nullable=False, max_length=256)

deleted: bool = Field(default=False)


class DbRefreshToken(SQLModel, table=True):
__tablename__ = "refresh_token"
Expand Down
21 changes: 21 additions & 0 deletions inference/server/oasst_inference_server/routes/admin.py
Expand Up @@ -5,6 +5,7 @@
from oasst_inference_server import auth, database, deps, models
from oasst_inference_server.schemas import worker as worker_schema
from oasst_inference_server.settings import settings
from oasst_shared import utils as shared_utils

router = fastapi.APIRouter(
prefix="/admin",
Expand Down Expand Up @@ -87,3 +88,23 @@ async def revoke_refresh_tokens(
refresh_token.enabled = False
await session.commit()
return fastapi.Response(status_code=200)


@router.delete("/users/{user_id}")
async def delete_user(
user_id: str,
root_token: str = Depends(get_root_token),
session: database.AsyncSession = Depends(deps.create_session),
):
"""Deletes a user."""
logger.info(f"Deleting user {user_id}")
user = await session.get(models.DbUser, user_id)
user.deleted = True

# Anonymise user data
user.display_name = shared_utils.DELETED_USER_DISPLAY_NAME
# Ensure uniqueness
user.provider_account_id = f"{shared_utils.DELETED_USER_ID_PREFIX}{user.id}"

await session.commit()
return fastapi.Response(status_code=200)
3 changes: 3 additions & 0 deletions oasst-shared/oasst_shared/utils.py
Expand Up @@ -4,6 +4,9 @@

from loguru import logger

DELETED_USER_DISPLAY_NAME = "Deleted User"
DELETED_USER_ID_PREFIX = "deleted_"


def utcnow() -> datetime:
"""Return the current utc date and time with tzinfo set to UTC."""
Expand Down

0 comments on commit a37157c

Please sign in to comment.