Files
MermsCoreFlask/app/api/services/login.py
T
2025-08-04 19:23:56 -04:00

326 lines
13 KiB
Python

from flask import session, jsonify
#from app.models.loan import Loan
from app.utils.logger import logger
from app.api.services.base_service import BaseService
# from app.api.schemas.eligibility_check import EligibilityCheckSchema
from marshmallow import ValidationError
# from app.api.enums import TransactionType
# from app.api.integrations import SimbrellaIntegration
from app.extensions import db
from app.models import PasswordReset, Members
#from app.api.services.offer_analysis import OfferAnalysis
from app.api.helpers.response_helper import ResponseHelper
from werkzeug.security import generate_password_hash, check_password_hash
from app.api.schemas.login import LoginSchema
from app.api.schemas.reset_pass_start import ResetPassStart
from app.api.schemas.reset_pass_verify import ResetPassVerify
from app.api.schemas.reset_pass_complete import ResetPassComplete
import json
import datetime
import jwt
import random
from app.config import Config
class LoginService(BaseService):
@staticmethod
def process_reset(data):
try:
with db.session.begin():
validated_data = LoginService.validate_data(data, ResetPassStart())
username = validated_data.get('username')
member = Members.get_member_by_username(username)
if not member:
invalid_data = {
"error_message": "You will get email to continue the process if the account is valid",
"reset_message": "",
"message_key": "invalid_username_or_password",
}
return ResponseHelper.success(data=invalid_data)
reset_data = PasswordReset.create_reset(username=username)
BaseService.send_resetpass_mail(member.email, str(member.uid), member.id, "FF","LL") #pending_uid, pending_id, firstname, lastname
response_data = {
"error_message": "",
"reset_message": "Check your email to continue password reset.",
"message_key": "check_your_email_message",
}
return ResponseHelper.success(data=response_data)
except ValidationError as err:
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.error(result_description=str(err))
except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback()
return ResponseHelper.internal_server_error()
@staticmethod
def verify_reset(data):
try:
with db.session.begin():
validated_data = LoginService.validate_data(data, ResetPassVerify())
reset_token = validated_data.get('reset_token')
logger.error("GOT HERE 000001 ")
data ={}
if not reset_token:
return jsonify({'message': 'Error - missing reset_token '}), 403
try:
data = jwt.decode(reset_token, LoginService.JWT_SECRET_KEY, algorithms=["HS256"])
except:
return jsonify({'status': 'INVALID2', 'message': 'Link is invalid'}), 403
logger.error("GOT HERE 000002 ")
if not data:
invalid_data = {
"error_message": "The link is invalid please try again later",
"reset_message": "",
"message_key": "invalid_pass_reset_link",
}
return ResponseHelper.success(data=invalid_data)
user_data = data["user"]
logger.error(f"GOT HERE 000003 {user_data}")
response_data = {
"error_message": "",
"pending_uid": user_data["pending_uid"],
"pending_id": user_data["pending_id"],
"reset_message": "Check your email to continue password reset.",
"message_key": "continue_reset",
}
return ResponseHelper.success(data=response_data)
except ValidationError as err:
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.error(result_description=str(err))
except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback()
return ResponseHelper.internal_server_error()
@staticmethod
def complete_reset(data):
try:
with db.session.begin():
validated_data = LoginService.validate_data(data, ResetPassComplete())
reset_token = validated_data.get('reset_token')
reset_uid = validated_data.get('reset_uid')
new_password = validated_data.get('new_password')
member = Members.get_member_by_username(new_password)
if not member:
invalid_data = {
"error_message": "You will get email to continue the process if the account is valid",
"reset_message": "",
"message_key": "invalid_username_or_password",
}
return ResponseHelper.success(data=invalid_data)
reset_data = PasswordReset.create_reset(username=username)
BaseService.send_resetpass_mail(member.email, str(member.uid), member.id, "FF",
"LL") # pending_uid, pending_id, firstname, lastname
response_data = {
"error_message": "",
"reset_message": "Check your email to continue password reset.",
"message_key": "check_your_email_message",
}
return ResponseHelper.success(data=response_data)
except ValidationError as err:
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.error(result_description=str(err))
except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback()
return ResponseHelper.internal_server_error()
@staticmethod
def process_request(data):
try:
with db.session.begin():
validated_data = LoginService.validate_data(data, LoginSchema())
username = validated_data.get('username')
password = validated_data.get('password')
member = Members.get_member_by_username(username)
# pass22 = generate_password_hash(password)
# logger.info("Password generated = > {}".format(pass22) )
if not member:
invalid_data = {
"error_message": "invalid username or password",
"message_key": "invalid_username_or_password",
}
return ResponseHelper.success(data=invalid_data)
pass_check = check_password_hash(member.password, password)
logger.info("Password check: {}".format(pass_check))
if not member or not pass_check:
invalid_data = {
"error_message": "invalid username or password",
"message_key": "invalid_username_or_password",
}
return ResponseHelper.success(data=invalid_data)
user_data = {}
user_data["id"] = member.id,
user_data["member_id"]= member.id,
user_data["uid"] = str(member.uid),
user_token = jwt.encode(
{"user": user_data, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=3330)},
Config.JWT_SECRET_KEY,
algorithm="HS256"
)
# Simulate processing
response_data = {
"member_id": member.id,
"uid": str(member.uid),
"username": member.username,
"account_name": member.account_name,
"firstname":member.firstname,
"lastname": member.lastname,
"room": member.uid,
"token": user_token
}
return ResponseHelper.success(data=response_data)
except ValidationError as err:
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.error(result_description=str(err))
except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback()
return ResponseHelper.internal_server_error()
@staticmethod
def login_user(username, password):
try:
member = Members.get_member_by_username(username)
if not member:
invalid_data = {
"error_message": "invalid username or password",
"message_key": "invalid_username_or_password",
}
return ResponseHelper.success(data=invalid_data)
pass_check = check_password_hash(member.password, password)
logger.info("Password check: {}".format(pass_check))
if not member or not pass_check:
invalid_data = {
"error_message": "invalid username or password",
"message_key": "invalid_username_or_password",
}
return ResponseHelper.success(data=invalid_data)
user_data = {}
user_data["id"] = member.id,
user_data["member_id"]= member.id,
user_data["uid"] = str(member.uid),
user_token = jwt.encode(
{"user": user_data, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=3330)},
Config.JWT_SECRET_KEY,
algorithm="HS256"
)
# Simulate processing
response_data = {
"member_id": member.id,
"uid": str(member.uid),
"username": member.username,
"account_name": member.account_name,
"firstname":member.firstname,
"lastname": member.lastname,
"room": member.uid,
"token": user_token
}
return ResponseHelper.success(data=response_data)
except ValidationError as err:
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
db.session.rollback()
return ResponseHelper.error(result_description=str(err))
except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback()
return ResponseHelper.internal_server_error()
# @staticmethod
# def check_loan_limits(customer_id):
# """
# Checks if a customer has exceeded the loan limits for given offer.
# """
# loan = Loan.get_customer_last_loan(customer_id)
#
# if not loan:
# return True
#
# offer_id = loan.offer_id[:5]
#
# offer = Offer.get_offer_by_id(offer_id)
# if not offer:
# logger.error(f"Offer not found for offer_id: {offer_id} (customer_id: {customer_id})")
# return False
#
# daily_count = Loan.get_daily_loan_count(customer_id, offer.product_id)
#
# logger.info(f"daily_count: {daily_count}, Max: {offer.max_daily_loans}")
#
# if offer.max_daily_loans is not None and daily_count >= offer.max_daily_loans:
# return False
#
# return True