diff --git a/app/api/routes/routes.py b/app/api/routes/routes.py index e5b2e1a..8298052 100644 --- a/app/api/routes/routes.py +++ b/app/api/routes/routes.py @@ -1,7 +1,9 @@ from flask import Blueprint, request, jsonify, send_from_directory from app.api.services import ( AuthorizationService, - TransactionService, LoanService, + TransactionService, + LoanService, + AuthService ) from app.utils.logger import logger from app.api.middlewares import enforce_json, require_auth @@ -36,9 +38,17 @@ def serve_paths(filename): return send_from_directory(swagger_dir, filename) +# Login endpoint +@api.route("/login", methods=["POST"]) +def login(): + data = request.get_json() + response = AuthService.login(data) + return response + + # Get All Transactions Endpoint @api.route("/transactions", methods=["GET"]) -# @jwt_required() +@jwt_required() def get_transactions(): # Extract query parameters for filtering filters = { @@ -56,7 +66,7 @@ def get_transactions(): # Get All Loans Endpoint @api.route("/loans", methods=["GET"]) -# @jwt_required() +@jwt_required() def get_loans(): # Extract query parameters for filtering filters = { diff --git a/app/api/services/__init__.py b/app/api/services/__init__.py index 35aa334..70d8957 100644 --- a/app/api/services/__init__.py +++ b/app/api/services/__init__.py @@ -3,3 +3,4 @@ from app.api.services.customer_consent import CustomerConsentService from app.api.services.authorization import AuthorizationService from app.api.services.transaction import TransactionService from app.api.services.loan import LoanService +from app.api.services.auth_service import AuthService diff --git a/app/api/services/auth_service.py b/app/api/services/auth_service.py new file mode 100644 index 0000000..33faf54 --- /dev/null +++ b/app/api/services/auth_service.py @@ -0,0 +1,58 @@ +from flask import jsonify +from app.utils.logger import logger +from app.api.services.base_service import BaseService +from app.models.user import User +from flask_jwt_extended import create_access_token +from datetime import timedelta + + +class AuthService(BaseService): + @staticmethod + def login(data): + """ + Process the login request. + + Args: + data (dict): Login credentials including username and password. + + Returns: + dict: A standardized response with JWT token and user information. + """ + try: + # Extract credentials + username = data.get('username') + password = data.get('password') + + # Validate input + if not username or not password: + return jsonify({ + "message": "Username and password are required" + }), 400 + + # Get user by username + user = User.get_user_by_username(username) + + # Check if user exists and password is correct + if not user or not user.check_password(password): + return jsonify({ + "message": "Invalid username or password" + }), 401 + + # Create JWT token with 15 minute expiration + access_token = create_access_token( + identity=user.username, + expires_delta=timedelta(minutes=15), + additional_claims={"name": user.name} + ) + + # Return token and user information + return { + "jwt_token": access_token, + "name": user.name + } + + except Exception as e: + logger.error(f"An error occurred during login: {str(e)}", exc_info=True) + return jsonify({ + "message": "Internal Server Error" + }), 500 \ No newline at end of file diff --git a/app/models/__init__.py b/app/models/__init__.py index 8fd1277..9fbb27f 100644 --- a/app/models/__init__.py +++ b/app/models/__init__.py @@ -2,5 +2,6 @@ from .customer import Customer from .account import Account from .loan import Loan from .transaction import Transaction +from .user import User -__all__ = ['Customer', 'Account', 'Loan', 'Transaction'] \ No newline at end of file +__all__ = ['Customer', 'Account', 'Loan', 'Transaction', User] \ No newline at end of file