File size: 4,908 Bytes
90e28c8
 
420f2a2
16a87c0
846543a
 
a8317c2
3219cc1
87168f1
73ab5b2
 
87cc64e
f06079d
87cc64e
0e4af71
73ab5b2
 
 
2a13a09
73ab5b2
 
a40b741
6b91541
 
 
de7729d
6b91541
de7729d
0e4af71
597f2fc
420f2a2
7c9ef15
 
597f2fc
7c9ef15
01b603f
 
597f2fc
7c9ef15
 
 
 
 
828d76a
50e8588
 
0bbc3b6
50e8588
828d76a
3ce2714
aa6aa93
 
3ce2714
 
 
3f1d12a
3ce2714
aa6aa93
 
3f1d12a
3ce2714
aa6aa93
 
 
73ab5b2
1fcc6f4
4f9d6d3
92a1e0e
 
b81db0f
92a1e0e
 
 
 
b81db0f
92a1e0e
4f9d6d3
b81db0f
 
 
 
 
92a1e0e
b81db0f
 
7e59b23
92a1e0e
 
7e59b23
73ab5b2
9034fa5
420f2a2
 
73ab5b2
 
aa6aa93
73ab5b2
4f9d6d3
420f2a2
826bfef
4f9d6d3
f6cb392
73ab5b2
b81db0f
f03d991
b81db0f
73ab5b2
92a1e0e
f73c46a
 
 
 
 
 
 
92a1e0e
420f2a2
 
 
 
73ab5b2
 
f27830c
 
 
 
f6cb392
 
 
f27830c
 
 
 
73ab5b2
87168f1
 
 
 
 
6b91541
87168f1
c96aa7a
 
 
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
#auth.py

from fastapi import Depends, HTTPException, Form, status
from fastapi.security import OAuth2PasswordBearer
from pydantic import BaseModel
from sqlalchemy.orm import Session
from database import get_db, get_user_by_email  # Import database functions
from models import User, VerificationToken
import jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta
import os

yoursecretkey = os.environ['my_secret_key']

class AuthViews:
    def __init__(self):
        self.pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
        self.SECRET_KEY = yoursecretkey  # Replace with your actual secret key
        self.ALGORITHM = "HS256"
        self.ACCESS_TOKEN_EXPIRE_MINUTES = 30
    def create_access_token(self, data: dict, expires_delta: timedelta):
        to_encode = data.copy()
        expire = datetime.utcnow() + expires_delta
        to_encode.update({"exp": expire})
        encoded_jwt = jwt.encode(to_encode, self.SECRET_KEY, algorithm=self.ALGORITHM)
        return encoded_jwt
         
auth_views = AuthViews()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

def verify_token(token: str = Depends(oauth2_scheme)):
    try:
        payload = jwt.decode(token, auth_views.SECRET_KEY, algorithms=[auth_views.ALGORITHM])
        return payload.get("sub")
    except jwt.ExpiredSignatureError:
        raise HTTPException(status_code=401, detail="Token has expired")
    except jwt.PyJWTError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )

class UserCreate(BaseModel):
    username: str
    email: str
    password: str
    confirm_password: str


# Use auth_views.pwd_context to access the password context from the AuthViews instance
def authenticate_user(db: Session, email: str, password: str):
    user = get_user_by_email(db, email)
    if user is None:
        raise HTTPException(status_code=400, detail="User not found")

    # Use the pwd_context from the auth_views instance
    if not auth_views.pwd_context.verify(password, user.hashed_password):
        raise HTTPException(status_code=400, detail="Incorrect password")

    return user



from emailx import send_verification_email, generate_verification_token

def get_user_by_verification_token(db: Session, verification_token: str):
    return db.query(User).filter(User.email_verification_token == verification_token).first()

def verify_email(verification_token: str, db: Session = Depends(get_db)):
    # Verify the email using the token
    user = get_user_by_verification_token(db, verification_token)
    
    if not user:
        raise HTTPException(status_code=400, detail="Invalid verification token")

    if user.is_verified:
        raise HTTPException(status_code=400, detail="Email already verified")

    # Mark the email as verified
    user.is_verified = True
    user.email_verification_token = None  # Optionally clear the verification token
    db.commit()
    return {"message": "Email verification successful"}



def register(user: UserCreate, db: Session):
    # Validate email format and check for existing users
    db_user = get_user_by_email(db, user.email)
    if db_user:
        raise HTTPException(status_code=400, detail="Email already registered")

    # Hash the password
    hashed_password = auth_views.pwd_context.hash(user.password)

    # Generate a verification token
    verification_token = generate_verification_token(user.email)
    reset_link = f"https://gregniuki-loginauth.hf.space/verify?token={verification_token}"
    # Send a verification email
    send_verification_email(user.email, reset_link)

    # Verify the email
   # verify_email(verification_token, db)

    # Create the user in the database
    # Set the email_verification_token field in the User model
    user_in_db = User(
        email=user.email,
        username=user.username,  # Set the username here
        hashed_password=hashed_password,
        email_verification_token=verification_token
    )


    db.add(user_in_db)
    db.commit()
    db.refresh(user_in_db)
    return user_in_db


def resetpassword(user: User, db: Session):
    # Generate a verification token
    verification_token = generate_verification_token(user.email)

    # Send a verification email with reset linkhttps://gregniuki-loginauth.hf.space/verify/{verification_token}
    reset_link = f"https://gregniuki-loginauth.hf.space/reset-password?token={verification_token}"
    send_verification_email(user.email, reset_link)

    # Update the user's email verification token
    user.email_verification_token = verification_token
    db.commit()

def get_current_user(token: str = Depends(verify_token)):
    if not token:
        raise HTTPException(status_code=401, detail="Token not valid")
    return token