def _verify_token(user_id=None, email=None, lifetime=LIFETIME): data = {"aud": VERIFY_USER_TOKEN_AUDIENCE} if user_id is not None: data["user_id"] = str(user_id) if email is not None: data["email"] = email return generate_jwt(data, SECRET, lifetime, JWT_ALGORITHM)
def verify_user(loop, client, id): user = loop.run_until_complete(get_fapiuser_user(id)) a = user.is_verified b = user.is_active assert not a assert b if not a and b: token_data = { "user_id": str(user.id), "email": user.email, "aud": VERIFY_USER_TOKEN_AUDIENCE, } token = generate_jwt( data=token_data, secret=s.SECRET_KEY_EMAIL, lifetime_seconds=s.VERIFY_EMAIL_TTL, ) res = client.get(f'/auth/verify?t={token}&debug=true') decoded_token = jwt.decode(token, s.SECRET_KEY_EMAIL, audience=VERIFY_USER_TOKEN_AUDIENCE, algorithms=[JWT_ALGORITHM]) data = res.json() usermod = loop.run_until_complete( get_usermod(decoded_token.get('user_id'))) a = str(usermod.id) == data.get('id') b = usermod.email == data.get('email') c = usermod.is_verified assert a assert b assert c return a, b, c
async def request_verify_token( request: Request, email: EmailStr = Body(..., embed=True) ): try: user = await get_user(email) if user.is_verified: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ErrorCode.VERIFY_USER_ALREADY_VERIFIED, ) elif user.is_active: token_data = { "user_id": str(user.id), "email": email, "aud": VERIFY_USER_TOKEN_AUDIENCE, } token = generate_jwt( token_data, verification_token_secret, verification_token_lifetime_seconds, ) if after_verification_request: await run_handler(after_verification_request, user, token, request) except UserNotExists: pass return None
async def send_registration_email(user: UserMod, text_path: str, html_path: Optional[str] = None, debug=False): debug = debug if s.DEBUG else False try: user = await fapiuser.get_user(user.email) except UserNotExists: return if not user.is_verified and user.is_active: token_data = { "user_id": str(user.id), "email": user.email, "aud": VERIFY_USER_TOKEN_AUDIENCE, } token = generate_jwt( data=token_data, secret=s.SECRET_KEY_EMAIL, lifetime_seconds=s.VERIFY_EMAIL_TTL, ) context = { 'verify_code': token, 'fake_code': secrets.token_hex(32), 'url': f'{s.SITE_URL}/authentication/verify?t={token}', 'site_name': s.SITE_NAME, 'title': 'Email Verification' } # Prepare the email mailman = Mailman(recipient=user.email) mailman.setup_email(subject=context['title']) mailman.send(text=text_path, html=html_path, context=context)
async def _generate_token(self, user): data = { "user_id": str(user.id), "sub": str(user.id), "aud": self.token_audience, "external_user_id": str(user.id), } return generate_jwt(data, self.lifetime_seconds, self.secret, JWT_ALGORITHM)
async def forgot_password(email: EmailStr = Body(..., embed=True)): user = await user_db.get_by_email(email) if user is not None and user.is_active: token_data = {"user_id": user.id, "aud": reset_password_token_audience} token = generate_jwt( token_data, reset_password_token_lifetime_seconds, reset_password_token_secret, ) await router.run_handlers(Event.ON_AFTER_FORGOT_PASSWORD, user, token) return None
async def forgot_password( request: Request, email: EmailStr = Body(..., embed=True) ): user = await user_db.get_by_email(email) if user is not None and user.is_active: token_data = {"user_id": str(user.id), "aud": RESET_PASSWORD_TOKEN_AUDIENCE} token = generate_jwt( token_data, reset_password_token_secret, reset_password_token_lifetime_seconds, ) if after_forgot_password: await run_handler(after_forgot_password, user, token, request) return None
def auth_headers_tempdb(tempdb, loop): """Headers for the VERIFIED_USER_EMAIL user. Same user all the time just diff id.""" async def ab(): return await tempdb() user = loop.run_until_complete(ab()) token_data = { "user_id": str(user.id), "email": user.email, "aud": jwtauth.token_audience, } access_token = generate_jwt( data=token_data, secret=s.SECRET_KEY, lifetime_seconds=s.ACCESS_TOKEN_EXPIRE, ) headers = {'Authorization': f'Bearer {access_token}'} yield headers, user, access_token
async def test_valid_token_missing_user_id( self, test_app_client: httpx.AsyncClient, inactive_user: UserDB, after_register, activation_callback, ): created_user = inactive_user token_data = {"user_id": str(""), "aud": ACTIVATE_USER_TOKEN_AUDIENCE} token = generate_jwt( token_data, activation_token_lifetime_seconds, activation_token_secret, ) response = await test_app_client.post("/activate", json=token) assert response.status_code == status.HTTP_400_BAD_REQUEST data = cast(Dict[str, Any], response.json()) assert data["detail"] == ErrorCode.ACTIVATE_USER_BAD_TOKEN assert after_register.called is False assert activation_callback.called is False
async def send_password_email(user: UserMod, text_path: str, html_path: Optional[str] = None, reset_form_url=None, debug=False): debug = debug if s.DEBUG else False reset_form_url = reset_form_url or s.FORM_RESET_PASSWORD try: user = await fapiuser.get_user(user.email) except UserNotExists: return if user.is_active and user.is_verified: token_data = { "user_id": str(user.id), "aud": RESET_PASSWORD_TOKEN_AUDIENCE } token = generate_jwt( data=token_data, secret=s.SECRET_KEY_EMAIL, lifetime_seconds=s.VERIFY_EMAIL_TTL, ) context = { 'verify_code': token, 'fake_code': secrets.token_hex(32), # 'url': f'{s.SITE_URL}/authentication/reset-password?t={token}', 'url': f'{s.SITE_URL}{reset_form_url}?t={token}', 'site_name': s.SITE_NAME, 'title': 'Change Password' } # Prepare the email mailman = Mailman(recipient=user.email) mailman.setup_email(subject=context['title']) mailman.send(text=text_path, html=html_path, context=context) if debug: return context.get('verify_code', None)
def test_registration_verification(tempdb, loop, client, random_email, passwd): async def ab(): await tempdb() loop.run_until_complete(ab()) # Register data = json.dumps(dict(email=random_email, password=passwd)) res = client.post('/auth/register', data=data) data = res.json() assert res.status_code == 201 assert data.get('is_active') assert not data.get('is_verified') user = loop.run_until_complete(get_fapiuser_user(data.get('id'))) if user.is_active and not user.is_verified: token_data = { "user_id": str(user.id), "email": user.email, "aud": VERIFY_USER_TOKEN_AUDIENCE, } token = generate_jwt( data=token_data, secret=s.SECRET_KEY_EMAIL, lifetime_seconds=s.VERIFY_EMAIL_TTL, ) res = client.get(f'/auth/verify?t={token}&debug=true') data = res.json() decoded_token = jwt.decode(token, s.SECRET_KEY_EMAIL, audience=VERIFY_USER_TOKEN_AUDIENCE, algorithms=[JWT_ALGORITHM]) usermod = loop.run_until_complete( get_usermod(decoded_token.get('user_id'))) assert str(usermod.id) == data.get('id') assert usermod.email == data.get('email') assert usermod.is_verified
async def request_verify_token(request: Request, email: EmailStr = Body(..., embed=True)): try: user = await get_user(email) if not user.is_verified and user.is_active: token_data = { "user_id": str(user.id), "email": email, "aud": VERIFY_USER_TOKEN_AUDIENCE, } token = generate_jwt( token_data, verification_token_secret, verification_token_lifetime_seconds, ) if after_verification_request: await run_handler(after_verification_request, user, token, request) except UserNotExists: pass return None
async def test_inactive_user( self, test_app_client: httpx.AsyncClient, inactive_user: UserDB, after_register, activation_callback, ): created_user = inactive_user token_data = { "user_id": str(created_user.id), "aud": ACTIVATE_USER_TOKEN_AUDIENCE, } token = generate_jwt( token_data, activation_token_lifetime_seconds, activation_token_secret, ) response = await test_app_client.post("/activate", json=token) assert response.status_code == status.HTTP_202_ACCEPTED assert after_register.called is True assert activation_callback.called is False data = cast(Dict[str, Any], response.json()) assert data["is_active"] is True
async def register(request: Request, user: user_create_model): # type: ignore user = cast(models.BaseUserCreate, user) # Prevent mypy complain existing_user = await user_db.get_by_email(user.email) if existing_user is not None and existing_user.is_active: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail=ErrorCode.REGISTER_USER_ALREADY_EXISTS, ) hashed_password = get_password_hash(user.password) if existing_user is None: db_user = user_db_model(**user.create_update_dict(), hashed_password=hashed_password, is_active=not activation_callback) created_user = await user_db.create(db_user) else: created_user = existing_user if activation_callback: token_data = { "user_id": str(created_user.id), "aud": ACTIVATE_USER_TOKEN_AUDIENCE, } token = generate_jwt( token_data, activation_token_lifetime_seconds, activation_token_secret, ) await run_handler(activation_callback, created_user, token, request) elif after_register: await run_handler(after_register, created_user, request) return created_user
def _forgot_password_token(user_id=None, lifetime=LIFETIME): data = {"aud": "fastapi-users:reset"} if user_id is not None: data["user_id"] = user_id return generate_jwt(data, lifetime, SECRET, JWT_ALGORITHM)
def generate_state_token(data: Dict[str, str], secret: str, lifetime_seconds: int = 3600) -> str: data["aud"] = STATE_TOKEN_AUDIENCE return generate_jwt(data, secret, lifetime_seconds, JWT_ALGORITHM)
async def _generate_token(self, user: BaseUserDB) -> str: data = {"user_id": str(user.id), "aud": self.token_audience} return generate_jwt(data, self.secret, self.lifetime_seconds, JWT_ALGORITHM)
def _token(user=None, lifetime=LIFETIME): data = {"aud": "fastapi-users:auth"} if user is not None: data["user_id"] = user.id return generate_jwt(data, lifetime, SECRET, JWT_ALGORITHM)
async def get_login_response(self, user: BaseUserDB, response: Response): data = {"user_id": user.id, "aud": self.token_audience} token = generate_jwt(data, self.lifetime_seconds, self.secret, JWT_ALGORITHM) return {"token": token}