auths.py 5.18 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
    ProfileImageUrlForm,
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
############################
# Update Profile Image Url
############################


@router.post("/update/profile", response_model=UserResponse)
async def update_profile_image_url(
    form_data: ProfileImageUrlForm, session_user=Depends(get_current_user)
):
    if session_user:
        user = Users.update_user_profile_image_url_by_id(
            session_user.id, form_data.profile_image_url
        )
        if user:
            return user
        else:
            raise HTTPException(400, detail=ERROR_MESSAGES.DEFAULT())
    else:
        raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)


65
66
67
68
69
############################
# Update Password
############################


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

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


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
############################
# 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
104
            "profile_image_url": user.profile_image_url,
105
106
        }
    else:
Timothy J. Baek's avatar
Timothy J. Baek committed
107
        raise HTTPException(400, detail=ERROR_MESSAGES.INVALID_CRED)
108
109
110
111
112
113
114
115


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


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

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

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

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

133
134
135
136
137
138
139
140
141
142
143
144
145
146
        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:
147
            raise HTTPException(500, detail=ERROR_MESSAGES.CREATE_USER_ERROR)
148
    except Exception as err:
149
150
        raise HTTPException(500, detail=ERROR_MESSAGES.DEFAULT(err))

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

############################
# 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
173
    else:
174
175
176
177
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
        )