users.py 4.86 KB
Newer Older
Timothy J. Baek's avatar
Timothy J. Baek committed
1
from fastapi import Response, Request
Timothy J. Baek's avatar
Timothy J. Baek committed
2
3
4
5
6
7
8
9
from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta
from typing import List, Union, Optional

from fastapi import APIRouter
from pydantic import BaseModel
import time
import uuid
10
import logging
Timothy J. Baek's avatar
Timothy J. Baek committed
11

Timothy J. Baek's avatar
Timothy J. Baek committed
12
from apps.web.models.users import UserModel, UserUpdateForm, UserRoleUpdateForm, Users
Timothy J. Baek's avatar
Timothy J. Baek committed
13
from apps.web.models.auths import Auths
Timothy J. Baek's avatar
Timothy J. Baek committed
14
from apps.web.models.chats import Chats
Timothy J. Baek's avatar
Timothy J. Baek committed
15

16
from utils.utils import get_verified_user, get_password_hash, get_admin_user
Timothy J. Baek's avatar
Timothy J. Baek committed
17
18
from constants import ERROR_MESSAGES

19
from config import SRC_LOG_LEVELS
Timothy J. Baek's avatar
Timothy J. Baek committed
20

21
22
23
log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["MODELS"])

Timothy J. Baek's avatar
Timothy J. Baek committed
24
25
26
27
28
29
30
31
router = APIRouter()

############################
# GetUsers
############################


@router.get("/", response_model=List[UserModel])
32
async def get_users(skip: int = 0, limit: int = 50, user=Depends(get_admin_user)):
33
    return Users.get_users(skip, limit)
Timothy J. Baek's avatar
Timothy J. Baek committed
34
35


Timothy J. Baek's avatar
Timothy J. Baek committed
36
37
38
39
40
41
42
############################
# User Permissions
############################


@router.get("/permissions/user")
async def get_user_permissions(request: Request, user=Depends(get_admin_user)):
43
    return request.app.state.config.USER_PERMISSIONS
Timothy J. Baek's avatar
Timothy J. Baek committed
44
45
46
47
48
49


@router.post("/permissions/user")
async def update_user_permissions(
    request: Request, form_data: dict, user=Depends(get_admin_user)
):
50
51
    request.app.state.config.USER_PERMISSIONS = form_data
    return request.app.state.config.USER_PERMISSIONS
Timothy J. Baek's avatar
Timothy J. Baek committed
52
53


Timothy J. Baek's avatar
Timothy J. Baek committed
54
55
56
57
58
59
############################
# UpdateUserRole
############################


@router.post("/update/role", response_model=Optional[UserModel])
Timothy J. Baek's avatar
Timothy J. Baek committed
60
61
async def update_user_role(form_data: UserRoleUpdateForm, user=Depends(get_admin_user)):

62
    if user.id != form_data.id and form_data.id != Users.get_first_user().id:
Timothy J. Baek's avatar
Timothy J. Baek committed
63
        return Users.update_user_role_by_id(form_data.id, form_data.role)
64
65
66
67
68

    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail=ERROR_MESSAGES.ACTION_PROHIBITED,
    )
Timothy J. Baek's avatar
Timothy J. Baek committed
69
70


71
72
73
74
75
76
77
78
79
80
81
82
83
############################
# GetUserById
############################


class UserResponse(BaseModel):
    name: str
    profile_image_url: str


@router.get("/{user_id}", response_model=UserResponse)
async def get_user_by_id(user_id: str, user=Depends(get_verified_user)):

Timothy J. Baek's avatar
Timothy J. Baek committed
84
85
86
87
88
89
90
91
92
93
94
    if user_id.startswith("shared-"):
        chat_id = user_id.replace("shared-", "")
        chat = Chats.get_chat_by_id(chat_id)
        if chat:
            user_id = chat.user_id
        else:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=ERROR_MESSAGES.USER_NOT_FOUND,
            )

95
96
97
98
99
100
101
102
103
104
105
    user = Users.get_user_by_id(user_id)

    if user:
        return UserResponse(name=user.name, profile_image_url=user.profile_image_url)
    else:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=ERROR_MESSAGES.USER_NOT_FOUND,
        )


Timothy J. Baek's avatar
Timothy J. Baek committed
106
############################
Timothy J. Baek's avatar
Timothy J. Baek committed
107
# UpdateUserById
Timothy J. Baek's avatar
Timothy J. Baek committed
108
109
110
############################


Timothy J. Baek's avatar
Timothy J. Baek committed
111
112
@router.post("/{user_id}/update", response_model=Optional[UserModel])
async def update_user_by_id(
113
    user_id: str, form_data: UserUpdateForm, session_user=Depends(get_admin_user)
Timothy J. Baek's avatar
Timothy J. Baek committed
114
115
116
117
):
    user = Users.get_user_by_id(user_id)

    if user:
Timothy J. Baek's avatar
Timothy J. Baek committed
118
119
        if form_data.email.lower() != user.email:
            email_user = Users.get_user_by_email(form_data.email.lower())
Timothy J. Baek's avatar
Timothy J. Baek committed
120
121
122
123
124
125
126
127
            if email_user:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=ERROR_MESSAGES.EMAIL_TAKEN,
                )

        if form_data.password:
            hashed = get_password_hash(form_data.password)
128
            log.debug(f"hashed: {hashed}")
Timothy J. Baek's avatar
Timothy J. Baek committed
129
130
            Auths.update_user_password_by_id(user_id, hashed)

Timothy J. Baek's avatar
Timothy J. Baek committed
131
        Auths.update_email_by_id(user_id, form_data.email.lower())
Timothy J. Baek's avatar
Timothy J. Baek committed
132
133
134
135
        updated_user = Users.update_user_by_id(
            user_id,
            {
                "name": form_data.name,
Timothy J. Baek's avatar
Timothy J. Baek committed
136
                "email": form_data.email.lower(),
Timothy J. Baek's avatar
Timothy J. Baek committed
137
138
139
140
141
142
143
                "profile_image_url": form_data.profile_image_url,
            },
        )

        if updated_user:
            return updated_user

Timothy J. Baek's avatar
Timothy J. Baek committed
144
        raise HTTPException(
Timothy J. Baek's avatar
Timothy J. Baek committed
145
            status_code=status.HTTP_400_BAD_REQUEST,
146
            detail=ERROR_MESSAGES.DEFAULT(),
Timothy J. Baek's avatar
Timothy J. Baek committed
147
        )
148

149
150
151
152
153
    raise HTTPException(
        status_code=status.HTTP_400_BAD_REQUEST,
        detail=ERROR_MESSAGES.USER_NOT_FOUND,
    )

154
155

############################
Timothy J. Baek's avatar
Timothy J. Baek committed
156
# DeleteUserById
157
158
159
160
############################


@router.delete("/{user_id}", response_model=bool)
161
162
163
164
165
166
167
async def delete_user_by_id(user_id: str, user=Depends(get_admin_user)):
    if user.id != user_id:
        result = Auths.delete_auth_by_id(user_id)

        if result:
            return True

168
        raise HTTPException(
169
170
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ERROR_MESSAGES.DELETE_USER_ERROR,
171
        )
172
173
174
175
176

    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail=ERROR_MESSAGES.ACTION_PROHIBITED,
    )