auths.py 5.2 KB
Newer Older
1
from fastapi import Response, Request
2
3
4
5
6
7
8
9
10
11
12
13
from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta
from typing import List, Union

from fastapi import APIRouter
from pydantic import BaseModel
import time
import uuid

from apps.web.models.auths import (
    SigninForm,
    SignupForm,
14
    UpdateProfileForm,
15
    UpdatePasswordForm,
16
17
18
19
20
21
    UserResponse,
    SigninResponse,
    Auths,
)
from apps.web.models.users import Users

22
from utils.utils import get_password_hash, get_current_user, create_token
23
from utils.misc import get_gravatar_url, validate_email_format
Timothy J. Baek's avatar
Timothy J. Baek committed
24
from constants import ERROR_MESSAGES
25

Timothy J. Baek's avatar
Timothy J. Baek committed
26
27
router = APIRouter()

28
29
30
31
32
############################
# GetSessionUser
############################


33
@router.get("/", response_model=UserResponse)
34
35
36
37
38
39
40
41
async def get_session_user(user=Depends(get_current_user)):
    return {
        "id": user.id,
        "email": user.email,
        "name": user.name,
        "role": user.role,
        "profile_image_url": user.profile_image_url,
    }
42
43


44
############################
45
# Update Profile
46
47
48
49
############################


@router.post("/update/profile", response_model=UserResponse)
50
51
async def update_profile(
    form_data: UpdateProfileForm, session_user=Depends(get_current_user)
52
53
):
    if session_user:
54
55
56
        user = Users.update_user_by_id(
            session_user.id,
            {"profile_image_url": form_data.profile_image_url, "name": form_data.name},
57
58
59
60
61
62
63
64
65
        )
        if user:
            return user
        else:
            raise HTTPException(400, detail=ERROR_MESSAGES.DEFAULT())
    else:
        raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)


66
67
68
69
70
############################
# Update Password
############################


71
@router.post("/update/password", response_model=bool)
72
73
74
async def update_password(
    form_data: UpdatePasswordForm, session_user=Depends(get_current_user)
):
75
76
    if session_user:
        user = Auths.authenticate_user(session_user.email, form_data.password)
77

78
79
        if user:
            hashed = get_password_hash(form_data.new_password)
Timothy J. Baek's avatar
Timothy J. Baek committed
80
            return Auths.update_user_password_by_id(user.id, hashed)
81
82
        else:
            raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_PASSWORD)
83
84
85
86
    else:
        raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
############################
# SignIn
############################


@router.post("/signin", response_model=SigninResponse)
async def signin(form_data: SigninForm):
    user = Auths.authenticate_user(form_data.email.lower(), form_data.password)
    if user:
        token = create_token(data={"email": user.email})

        return {
            "token": token,
            "token_type": "Bearer",
            "id": user.id,
            "email": user.email,
            "name": user.name,
            "role": user.role,
Timothy J. Baek's avatar
Timothy J. Baek committed
105
            "profile_image_url": user.profile_image_url,
106
107
        }
    else:
Timothy J. Baek's avatar
Timothy J. Baek committed
108
        raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
109
110
111
112
113
114
115
116


############################
# SignUp
############################


@router.post("/signup", response_model=SigninResponse)
117
async def signup(request: Request, form_data: SignupForm):
118
    if not request.app.state.ENABLE_SIGNUP:
119
        raise HTTPException(400, detail=ERROR_MESSAGES.ACCESS_PROHIBITED)
120

121
122
    if not validate_email_format(form_data.email.lower()):
        raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_EMAIL_FORMAT)
123

124
125
    if Users.get_user_by_email(form_data.email.lower()):
        raise HTTPException(400, detail=ERROR_MESSAGES.EMAIL_TAKEN)
126

127
128
129
    try:
        role = "admin" if Users.get_num_users() == 0 else "pending"
        hashed = get_password_hash(form_data.password)
130
131
132
        user = Auths.insert_new_auth(
            form_data.email.lower(), hashed, form_data.name, role
        )
133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
        if user:
            token = create_token(data={"email": user.email})
            # response.set_cookie(key='token', value=token, httponly=True)

            return {
                "token": token,
                "token_type": "Bearer",
                "id": user.id,
                "email": user.email,
                "name": user.name,
                "role": user.role,
                "profile_image_url": user.profile_image_url,
            }
        else:
148
            raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
149
    except Exception as err:
150
151
        raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err))

152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

############################
# ToggleSignUp
############################


@router.get("/signup/enabled", response_model=bool)
async def get_sign_up_status(request: Request, user=Depends(get_current_user)):
    if user.role == "admin":
        return request.app.state.ENABLE_SIGNUP
    else:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
        )


@router.get("/signup/enabled/toggle", response_model=bool)
async def toggle_sign_up(request: Request, user=Depends(get_current_user)):
    if user.role == "admin":
        request.app.state.ENABLE_SIGNUP = not request.app.state.ENABLE_SIGNUP
        return request.app.state.ENABLE_SIGNUP
174
    else:
175
176
177
178
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
        )