File size: 5,192 Bytes
b856986
9e798a1
 
 
 
 
 
 
 
f30e75c
b856986
8450c71
b856986
f30e75c
9e798a1
f30e75c
8450c71
9e798a1
b856986
 
 
8450c71
 
9e798a1
b856986
 
9e798a1
 
 
b856986
 
 
9e798a1
 
 
 
 
 
b856986
9e798a1
 
 
f30e75c
 
 
 
 
9e798a1
 
 
 
 
b856986
9e798a1
 
 
 
 
 
 
b856986
 
 
9e798a1
b856986
 
9e798a1
 
 
 
b856986
 
 
9e798a1
 
 
 
 
b856986
 
9e798a1
 
 
 
 
b856986
9e798a1
 
 
 
 
 
 
 
 
 
 
 
 
b856986
 
 
9e798a1
 
 
 
 
 
 
b856986
f30e75c
 
 
 
 
 
 
 
57ab719
 
 
 
 
3ebd012
57ab719
 
 
 
 
 
 
6c582f0
 
 
427d907
6c582f0
 
 
427d907
6c582f0
 
 
 
 
427d907
6c582f0
fbeb0b0
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from fastapi import APIRouter, HTTPException, status
from .Schema import (
    RegisterUserRequest,
    LoginUserRequest,
    AccessTokenResponse,
    ForgotPasswordRequest,
    VerifyResetTokenRequest,
    ResetPasswordRequest,
    BaseResponse,
    UserResponse,
)
from .Model import User
from jose import jwt
from typing import List
from datetime import datetime, timedelta
from App.Android.Android import AndroidClient

# JWT Configurations
SECRET_KEY = "your_secret_key_here"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
user_router = APIRouter(tags=["User"])


def create_access_token(data: dict, expires_delta: timedelta = None):
    to_encode = data.copy()
    expire = datetime.utcnow() + (
        expires_delta or timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    )
    to_encode.update({"exp": expire})
    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)


@user_router.post(
    "/user/register", response_model=BaseResponse, status_code=status.HTTP_201_CREATED
)
async def register_user(request: RegisterUserRequest):
    existing_user = await User.filter(phoneNumber=request.phoneNumber).first()
    if existing_user:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="User already exists."
        )
    # client part
    client = AndroidClient()
    print(request.json())
    response = await client.register_user(request=request)
    print(response)
    request.hash_password()
    new_user = await User.create(**request.dict())
    return BaseResponse(
        code=200, message="User created successfully", payload={"user_id": new_user.id}
    )


@user_router.post(
    "/user/login", response_model=AccessTokenResponse, status_code=status.HTTP_200_OK
)
async def login_user(request: LoginUserRequest):
    db_user = await User.filter(phoneNumber=request.phoneNumber).first()
    if db_user and db_user.verify_password(request.password):
        access_token = create_access_token(data={"sub": db_user.phoneNumber})
        return AccessTokenResponse(access_token=access_token, token_type="bearer")
    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid credentials"
    )


@user_router.post(
    "/user/forgot-password", response_model=BaseResponse, status_code=status.HTTP_200_OK
)
async def forgot_password(request: ForgotPasswordRequest):
    user = await User.filter(phoneNumber=request.phoneNumber).first()
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
        )
    await user.initiate_password_reset()
    return BaseResponse(code=200, message="Password reset token sent to your phone.")


@user_router.post(
    "/user/verify-reset-token",
    response_model=BaseResponse,
    status_code=status.HTTP_200_OK,
)
async def verify_reset_token(request: VerifyResetTokenRequest):
    user = await User.filter(
        phoneNumber=request.phoneNumber, reset_token=request.reset_token
    ).first()
    if not user or datetime.utcnow() > user.reset_token_expiration:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid or expired token."
        )
    return BaseResponse(code=200, message="Token verified. Proceed to reset password.")


@user_router.post(
    "/user/reset-password", response_model=BaseResponse, status_code=status.HTTP_200_OK
)
async def reset_password(request: ResetPasswordRequest):
    user = await User.filter(phoneNumber=request.phoneNumber).first()
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
        )
    if not await user.reset_password(request.reset_token, request.new_password):
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid or expired token."
        )
    return BaseResponse(code=200, message="Password has been reset successfully.")


@user_router.get(
    "/user/all", response_model=List[UserResponse], status_code=status.HTTP_200_OK
)
async def get_all_users():
    users = await User.all()
    return [UserResponse.from_orm(user) for user in users]


@user_router.delete(
    "/user/{user_id}", response_model=BaseResponse, status_code=status.HTTP_200_OK
)
async def delete_user(user_id: str):
    user = await User.filter(id=user_id).first()
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
        )
    await user.delete()
    return BaseResponse(code=200, message="User deleted successfully.")


@user_router.put(
    "/user/toggle_status/{user_id}",
    response_model=BaseResponse,
    status_code=status.HTTP_200_OK,
)
async def toggle_user_status(user_id: str):
    user = await User.filter(id=user_id).first()
    if not user:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND, detail="User not found."
        )
    user.account_locked = not user.account_locked
    await user.save()
    message = (
        "User disabled successfully."
        if user.account_locked
        else "User enabled successfully."
    )
    return BaseResponse(code=200, message=message)