auths.py 4.89 KB
Newer Older
1
from fastapi import Response, Request
2
3
4
5
from fastapi import Depends, FastAPI, HTTPException, status
from datetime import datetime, timedelta
from typing import List, Union

6
from fastapi import APIRouter, status
7
8
9
10
11
12
13
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, get_admin_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
############################
# 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:
96
        token = create_token(data={"id": user.id})
97
98
99
100
101
102
103
104

        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(status.HTTP_403_FORBIDDEN, detail=ERROR_MESSAGES.ACCESS_PROHIBITED)
120

121
    if not validate_email_format(form_data.email.lower()):
122
        raise HTTPException(status.HTTP_400_BAD_REQUEST, 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
        if user:
135
            token = create_token(data={"id": user.id})
136
137
138
139
140
141
142
143
144
145
146
147
            # 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

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


@router.get("/signup/enabled", response_model=bool)
159
160
async def get_sign_up_status(request: Request, user=Depends(get_admin_user)):
    return request.app.state.ENABLE_SIGNUP
161
162
163


@router.get("/signup/enabled/toggle", response_model=bool)
164
165
166
async def toggle_sign_up(request: Request, user=Depends(get_admin_user)):
    request.app.state.ENABLE_SIGNUP = not request.app.state.ENABLE_SIGNUP
    return request.app.state.ENABLE_SIGNUP