mominah commited on
Commit
506e8fb
·
verified ·
1 Parent(s): d3be5c2

Update auth.py

Browse files
Files changed (1) hide show
  1. auth.py +1 -121
auth.py CHANGED
@@ -6,7 +6,7 @@ from urllib.parse import quote_plus
6
  from typing import List, Optional, Any
7
 
8
  from dotenv import load_dotenv
9
- from fastapi import APIRouter, HTTPException, Depends, Request, UploadFile, File, Form, Body
10
  from fastapi.responses import JSONResponse
11
  from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
12
  from jose import JWTError, jwt
@@ -15,17 +15,6 @@ from pydantic import BaseModel, EmailStr, Field, validator
15
  from pymongo import MongoClient
16
  import os.path
17
 
18
- # ----- OTP and Email Imports -----
19
- import smtplib
20
- from email.mime.multipart import MIMEMultipart
21
- from email.mime.text import MIMEText
22
- try:
23
- import markdown
24
- except ImportError:
25
- markdown = None
26
- import secrets
27
- # ----------------------------------
28
-
29
  load_dotenv()
30
 
31
  # Setup logging
@@ -38,8 +27,6 @@ MONGO_URL = os.getenv("CONNECTION_STRING").replace("${PASSWORD}", password)
38
  client = MongoClient(MONGO_URL)
39
  db = client.users_database
40
  users_collection = db.users
41
- # New collection to store OTP records
42
- otp_collection = db.otp_verifications
43
 
44
  # OAuth2 setup
45
  oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
@@ -173,123 +160,16 @@ def save_avatar_file(file: UploadFile) -> str:
173
  file.file.close()
174
  return file_path
175
 
176
- # ----- OTP and Email Functions -----
177
- def generate_otp(length=6):
178
- """Generate a numeric OTP of specified length."""
179
- digits = "0123456789"
180
- otp = ''.join(secrets.choice(digits) for _ in range(length))
181
- return otp
182
-
183
- def send_email_func(sender_email, sender_password, receiver_email, subject, body):
184
- smtp_server = "smtp.gmail.com"
185
- port = 587
186
- message = MIMEMultipart("alternative")
187
- message["Subject"] = subject
188
- message["From"] = sender_email
189
- message["To"] = receiver_email
190
-
191
- part1 = MIMEText(body, "plain")
192
- if markdown:
193
- html_content = markdown.markdown(body)
194
- else:
195
- html_content = f"<pre>{body}</pre>"
196
-
197
- html_template = f"""\
198
- <html>
199
- <head>
200
- <style>
201
- body {{
202
- font-family: Arial, sans-serif;
203
- line-height: 1.6;
204
- margin: 20px;
205
- }}
206
- h1, h2, h3 {{
207
- color: #333;
208
- }}
209
- pre {{
210
- background: #f4f4f4;
211
- padding: 10px;
212
- border: 1px solid #ddd;
213
- }}
214
- </style>
215
- </head>
216
- <body>
217
- {html_content}
218
- </body>
219
- </html>
220
- """
221
- part2 = MIMEText(html_template, "html")
222
- message.attach(part1)
223
- message.attach(part2)
224
-
225
- try:
226
- with smtplib.SMTP(smtp_server, port, timeout=10) as server:
227
- server.starttls()
228
- server.login(sender_email, sender_password)
229
- server.sendmail(sender_email, receiver_email, message.as_string())
230
- logger.info("Successfully sent email")
231
- except Exception as e:
232
- logger.error(f"Error sending email: {e}")
233
- raise e
234
- # ------------------------------------
235
-
236
  # ----- Auth Endpoints -----
237
 
238
- @router.post("/send_otp")
239
- async def send_otp(receiver_email: EmailStr = Body(..., embed=True)):
240
- """
241
- Generates an OTP and sends it via email to the provided receiver_email.
242
- (For demonstration purposes, the OTP is returned. Remove it in production.)
243
- """
244
- sender_email = os.getenv("SENDER_EMAIL")
245
- sender_password = os.getenv("SENDER_PASSWORD")
246
- if not sender_email or not sender_password:
247
- raise HTTPException(status_code=500, detail="Email sender credentials are not configured.")
248
-
249
- otp = generate_otp(6)
250
- subject = "Your One-Time Password (OTP)"
251
- body = f"""\
252
- # Your OTP
253
-
254
- Here is your one-time password (OTP):
255
-
256
- `{otp}`
257
-
258
- Please use the code above to verify your email and proceed with account creation.
259
- """
260
- try:
261
- send_email_func(sender_email, sender_password, receiver_email, subject, body)
262
- # Store OTP record with a 10-minute expiration
263
- otp_record = {
264
- "email": receiver_email,
265
- "otp": otp,
266
- "expires_at": datetime.utcnow() + timedelta(minutes=1)
267
- }
268
- otp_collection.update_one({"email": receiver_email}, {"$set": otp_record}, upsert=True)
269
- except Exception as e:
270
- raise HTTPException(status_code=500, detail=f"Error sending OTP email: {str(e)}")
271
- return {"message": "OTP sent successfully", "otp": otp} # Remove OTP from response in production
272
-
273
  @router.post("/signup", response_model=Token)
274
  async def signup(
275
  request: Request,
276
  name: str = Form(...),
277
  email: EmailStr = Form(...),
278
  password: str = Form(...),
279
- otp: str = Form(...),
280
  avatar: Optional[UploadFile] = File(None)
281
  ):
282
- # Verify OTP for this email
283
- otp_record = otp_collection.find_one({"email": email})
284
- if not otp_record:
285
- raise HTTPException(status_code=400, detail="No OTP sent to this email. Please request an OTP first.")
286
- if otp_record["otp"] != otp:
287
- raise HTTPException(status_code=400, detail="Invalid OTP provided.")
288
- if datetime.utcnow() > otp_record["expires_at"]:
289
- raise HTTPException(status_code=400, detail="OTP has expired. Please request a new one.")
290
- # Remove the OTP record after successful verification
291
- otp_collection.delete_one({"email": email})
292
-
293
  try:
294
  _ = User(name=name, email=email, password=password)
295
  except Exception as e:
 
6
  from typing import List, Optional, Any
7
 
8
  from dotenv import load_dotenv
9
+ from fastapi import APIRouter, HTTPException, Depends, Request, UploadFile, File, Form
10
  from fastapi.responses import JSONResponse
11
  from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
12
  from jose import JWTError, jwt
 
15
  from pymongo import MongoClient
16
  import os.path
17
 
 
 
 
 
 
 
 
 
 
 
 
18
  load_dotenv()
19
 
20
  # Setup logging
 
27
  client = MongoClient(MONGO_URL)
28
  db = client.users_database
29
  users_collection = db.users
 
 
30
 
31
  # OAuth2 setup
32
  oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
 
160
  file.file.close()
161
  return file_path
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  # ----- Auth Endpoints -----
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  @router.post("/signup", response_model=Token)
166
  async def signup(
167
  request: Request,
168
  name: str = Form(...),
169
  email: EmailStr = Form(...),
170
  password: str = Form(...),
 
171
  avatar: Optional[UploadFile] = File(None)
172
  ):
 
 
 
 
 
 
 
 
 
 
 
173
  try:
174
  _ = User(name=name, email=email, password=password)
175
  except Exception as e: