mirror of
https://github.com/danswer-ai/danswer.git
synced 2025-03-26 17:51:54 +01:00
DAN-58 Email validation (#39)
This commit is contained in:
parent
6ed86ed369
commit
fb9c3e530b
@ -1,10 +0,0 @@
|
||||
import os
|
||||
|
||||
DISABLE_AUTH = os.environ.get("DISABLE_AUTH", "").lower() == "true"
|
||||
|
||||
SECRET = os.environ.get("SECRET", "")
|
||||
SESSION_EXPIRE_TIME_SECONDS = int(os.environ.get("SESSION_EXPIRE_TIME_SECONDS", 3600))
|
||||
|
||||
ENABLE_OAUTH = os.environ.get("ENABLE_OAUTH", "False").lower() != "false"
|
||||
GOOGLE_OAUTH_CLIENT_ID = os.environ.get("GOOGLE_OAUTH_CLIENT_ID", "")
|
||||
GOOGLE_OAUTH_CLIENT_SECRET = os.environ.get("GOOGLE_OAUTH_CLIENT_SECRET", "")
|
@ -1,19 +1,30 @@
|
||||
import smtplib
|
||||
import uuid
|
||||
from collections.abc import AsyncGenerator
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from typing import Optional
|
||||
|
||||
from danswer.auth.configs import DISABLE_AUTH
|
||||
from danswer.auth.configs import GOOGLE_OAUTH_CLIENT_ID
|
||||
from danswer.auth.configs import GOOGLE_OAUTH_CLIENT_SECRET
|
||||
from danswer.auth.configs import SECRET
|
||||
from danswer.auth.configs import SESSION_EXPIRE_TIME_SECONDS
|
||||
from danswer.auth.schemas import UserCreate
|
||||
from danswer.auth.schemas import UserRole
|
||||
from danswer.configs.app_configs import DISABLE_AUTH
|
||||
from danswer.configs.app_configs import GOOGLE_OAUTH_CLIENT_ID
|
||||
from danswer.configs.app_configs import GOOGLE_OAUTH_CLIENT_SECRET
|
||||
from danswer.configs.app_configs import REQUIRE_EMAIL_VERIFICATION
|
||||
from danswer.configs.app_configs import SECRET
|
||||
from danswer.configs.app_configs import SESSION_EXPIRE_TIME_SECONDS
|
||||
from danswer.configs.app_configs import SMTP_PASS
|
||||
from danswer.configs.app_configs import SMTP_PORT
|
||||
from danswer.configs.app_configs import SMTP_SERVER
|
||||
from danswer.configs.app_configs import SMTP_USER
|
||||
from danswer.configs.app_configs import VALID_EMAIL_DOMAIN
|
||||
from danswer.configs.app_configs import WEB_DOMAIN
|
||||
from danswer.db.auth import get_access_token_db
|
||||
from danswer.db.auth import get_user_count
|
||||
from danswer.db.auth import get_user_db
|
||||
from danswer.db.models import AccessToken
|
||||
from danswer.db.models import User
|
||||
from danswer.utils.logging import setup_logger
|
||||
from fastapi import Depends
|
||||
from fastapi import HTTPException
|
||||
from fastapi import Request
|
||||
@ -30,6 +41,27 @@ from fastapi_users.authentication.strategy.db import DatabaseStrategy
|
||||
from fastapi_users.db import SQLAlchemyUserDatabase
|
||||
from httpx_oauth.clients.google import GoogleOAuth2
|
||||
|
||||
logger = setup_logger()
|
||||
|
||||
|
||||
def send_user_verification_email(user_email: str, token: str) -> None:
|
||||
msg = MIMEMultipart()
|
||||
msg["Subject"] = "Danswer Email Verification"
|
||||
msg["From"] = "no-reply@danswer.dev"
|
||||
msg["To"] = user_email
|
||||
|
||||
link = f"{WEB_DOMAIN}/verify-email?token={token}"
|
||||
|
||||
body = MIMEText(f"Click the following link to verify your email address: {link}")
|
||||
msg.attach(body)
|
||||
|
||||
with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as s:
|
||||
s.starttls()
|
||||
# If credentials fails with gmail, check (You need an app password, not just the basic email password)
|
||||
# https://support.google.com/accounts/answer/185833?sjid=8512343437447396151-NA
|
||||
s.login(SMTP_USER, SMTP_PASS)
|
||||
s.send_message(msg)
|
||||
|
||||
|
||||
class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):
|
||||
reset_password_token_secret = SECRET
|
||||
@ -52,17 +84,34 @@ class UserManager(UUIDIDMixin, BaseUserManager[User, uuid.UUID]):
|
||||
async def on_after_register(
|
||||
self, user: User, request: Optional[Request] = None
|
||||
) -> None:
|
||||
print(f"User {user.id} has registered.")
|
||||
logger.info(f"User {user.id} has registered.")
|
||||
|
||||
async def on_after_forgot_password(
|
||||
self, user: User, token: str, request: Optional[Request] = None
|
||||
) -> None:
|
||||
print(f"User {user.id} has forgot their password. Reset token: {token}")
|
||||
logger.info(f"User {user.id} has forgot their password. Reset token: {token}")
|
||||
|
||||
async def on_after_request_verify(
|
||||
self, user: User, token: str, request: Optional[Request] = None
|
||||
) -> None:
|
||||
print(f"Verification requested for user {user.id}. Verification token: {token}")
|
||||
if VALID_EMAIL_DOMAIN:
|
||||
if user.email.count("@") != 1:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Email is not valid",
|
||||
)
|
||||
domain = user.email.split("@")[-1]
|
||||
if domain != VALID_EMAIL_DOMAIN:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Email domain is not valid",
|
||||
)
|
||||
|
||||
logger.info(
|
||||
f"Verification requested for user {user.id}. Verification token: {token}"
|
||||
)
|
||||
|
||||
send_user_verification_email(user.email, token)
|
||||
|
||||
|
||||
async def get_user_manager(
|
||||
@ -92,7 +141,9 @@ google_oauth_client = GoogleOAuth2(GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_S
|
||||
|
||||
fastapi_users = FastAPIUsers[User, uuid.UUID](get_user_manager, [auth_backend])
|
||||
|
||||
current_active_user = fastapi_users.current_user(active=True, optional=DISABLE_AUTH)
|
||||
current_active_user = fastapi_users.current_user(
|
||||
active=True, verified=REQUIRE_EMAIL_VERIFICATION, optional=DISABLE_AUTH
|
||||
)
|
||||
|
||||
|
||||
def current_admin_user(user: User = Depends(current_active_user)) -> User | None:
|
||||
|
@ -23,6 +23,27 @@ BLURB_LENGTH = 200 # Characters. Blurbs will be truncated at the first punctuat
|
||||
WEB_DOMAIN = os.environ.get("WEB_DOMAIN", "http://localhost:3000")
|
||||
|
||||
|
||||
#####
|
||||
# Auth Configs
|
||||
#####
|
||||
DISABLE_AUTH = os.environ.get("DISABLE_AUTH", "").lower() == "true"
|
||||
REQUIRE_EMAIL_VERIFICATION = (
|
||||
os.environ.get("REQUIRE_EMAIL_VERIFICATION", "").lower() == "true"
|
||||
)
|
||||
SMTP_SERVER = os.environ.get("SMTP_SERVER", "smtp.gmail.com")
|
||||
SMTP_PORT = int(os.environ.get("SMTP_PORT", "587"))
|
||||
SMTP_USER = os.environ.get("SMTP_USER", "your-email@gmail.com")
|
||||
SMTP_PASS = os.environ.get("SMTP_PASS", "your-gmail-password")
|
||||
|
||||
SECRET = os.environ.get("SECRET", "")
|
||||
SESSION_EXPIRE_TIME_SECONDS = int(os.environ.get("SESSION_EXPIRE_TIME_SECONDS", 3600))
|
||||
VALID_EMAIL_DOMAIN = os.environ.get("VALID_EMAIL_DOMAIN", "")
|
||||
# OAuth Login Flow
|
||||
ENABLE_OAUTH = os.environ.get("ENABLE_OAUTH", "").lower() != "false"
|
||||
GOOGLE_OAUTH_CLIENT_ID = os.environ.get("GOOGLE_OAUTH_CLIENT_ID", "")
|
||||
GOOGLE_OAUTH_CLIENT_SECRET = os.environ.get("GOOGLE_OAUTH_CLIENT_SECRET", "")
|
||||
|
||||
|
||||
#####
|
||||
# Vector DB Configs
|
||||
#####
|
||||
@ -47,6 +68,7 @@ GOOGLE_DRIVE_INCLUDE_SHARED = False
|
||||
|
||||
GITHUB_ACCESS_TOKEN = os.environ.get("GITHUB_ACCESS_TOKEN", "")
|
||||
|
||||
|
||||
#####
|
||||
# Query Configs
|
||||
#####
|
||||
|
@ -1,6 +1,4 @@
|
||||
import uvicorn
|
||||
from danswer.auth.configs import ENABLE_OAUTH
|
||||
from danswer.auth.configs import SECRET
|
||||
from danswer.auth.schemas import UserCreate
|
||||
from danswer.auth.schemas import UserRead
|
||||
from danswer.auth.schemas import UserUpdate
|
||||
@ -9,6 +7,8 @@ from danswer.auth.users import fastapi_users
|
||||
from danswer.auth.users import google_oauth_client
|
||||
from danswer.configs.app_configs import APP_HOST
|
||||
from danswer.configs.app_configs import APP_PORT
|
||||
from danswer.configs.app_configs import ENABLE_OAUTH
|
||||
from danswer.configs.app_configs import SECRET
|
||||
from danswer.configs.app_configs import WEB_DOMAIN
|
||||
from danswer.server.admin import router as admin_router
|
||||
from danswer.server.event_loading import router as event_processing_router
|
||||
|
@ -116,7 +116,7 @@ if __name__ == "__main__":
|
||||
)
|
||||
parser.add_argument(
|
||||
"--slack-export-dir",
|
||||
default="/Users/chrisweaver/Downloads/test-slack-export",
|
||||
default="~/Downloads/test-slack-export",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--qdrant-collection",
|
||||
@ -133,6 +133,6 @@ if __name__ == "__main__":
|
||||
recreate_collection(args.qdrant_collection)
|
||||
|
||||
# load_slack_batch(args.slack_export_dir, args.qdrant_collection)
|
||||
# load_web_batch(args.website_url, args.qdrant_collection)
|
||||
load_web_batch(args.website_url, args.qdrant_collection)
|
||||
# load_google_drive_batch(args.qdrant_collection)
|
||||
load_github_batch(args.github_owner, args.github_repo, args.qdrant_collection)
|
||||
# load_github_batch(args.github_owner, args.github_repo, args.qdrant_collection)
|
||||
|
Loading…
x
Reference in New Issue
Block a user