Skip to content

Commit

Permalink
Partial PR repairs.
Browse files Browse the repository at this point in the history
  • Loading branch information
roisol144 committed Oct 31, 2024
1 parent 95a067a commit 8562dbd
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 50 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,3 @@
__pycache__/
.pytest_cache/

# SQL initialization script
init.sql
43 changes: 15 additions & 28 deletions bank_accounts.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ def get_bank_accounts():
user_id = request.args.get('user_id')
try:
cursor, conn = get_db_connection()
if cursor is None or conn is None:
logging.debug("Couldn't connect to db.")
return jsonify({'error' : 'Internal Error' }), 500

cursor.execute('SELECT * FROM bank_accounts WHERE user_id = %s', (user_id,))
bank_accounts = cursor.fetchall()
Expand All @@ -70,6 +67,9 @@ def get_bank_accounts():
logging.debug("General Error occured.")
return jsonify({'error': 'Internal Error'}), 500

except DatabaseConnectionError as e:
return jsonify({'error': 'Internal Error'}), 500

@bank_accounts_bp.route('/bank_accounts', methods=['POST'])
def create_bank_account():
data = request.get_json()
Expand All @@ -84,20 +84,16 @@ def create_bank_account():
account_id = str(uuid4())
account_number = str(int(uuid4()))[:6]
logging.debug(f"Account number: {account_number}")
hashed_account_number = hashlib.sha256(account_number.encode()).hexdigest()
salt = os.urandom(16).hex()
hashed_account_number = hashlib.sha256((account_number + salt).encode()).hexdigest()
encrypted_account_number = encrypt_account_number(account_number).decode('utf-8')
currency = Currency.USD.value
balance = 2000
currency = Currency.USD.value
balance = 0 # change it to other default value that will be config
account_type = AccountType.CHECKINGS.value
created_at = datetime.datetime.now()
status = Status.ACTIVE.value

cursor, conn = get_db_connection()
if cursor is None or conn is None:
raise DatabaseConnectionError

# Enabling Auto Commit feature
conn.autocommit = True

cursor.execute("""
INSERT INTO bank_accounts (id, user_id, account_number, balance, type, currency, created_at, status, hashed_account_number)
Expand All @@ -111,18 +107,13 @@ def create_bank_account():
except UserNotFoundError as e:
return jsonify({'error' : 'User not found'}), 404
except Exception as e:
return jsonify({'error', 'Internal Erorr'}), 500
return jsonify({'error': 'Internal Error'}), 500

return jsonify({'account_id': account_id, 'account_number': encrypted_account_number, 'created_at':created_at}), 201
return jsonify({'account_id': account_id, 'account_number': encrypted_account_number, 'created_at': created_at}), 201


@bank_accounts_bp.route('/bank_accounts/transfer', methods=['POST'])
def transfer():
logging.debug("Transfer function called")
logging.debug(f"Request method: {request.method}")
logging.debug(f"Request path: {request.path}")
logging.debug(f"Request JSON: {request.get_json()}")

def transfer():
data = request.get_json()
transfer_id = str(uuid4())
to_account_number = data.get('to_account_number')
Expand All @@ -138,21 +129,17 @@ def transfer():
return jsonify({'error': 'Invalid transaction type'}), 400

try:
if amount <= 0:
return jsonify({'error': 'Amount must be positive'}), 400

from_account_id = get_account_id_by_user_id(g.current_user_id)
logging.debug(f"From account ID: {from_account_id}")

if not from_account_id:
raise AccountNotFoundError("Account not found for the current user")

if amount <= 0:
return jsonify({'error': 'Amount must be positive'}), 400

cursor, conn = get_db_connection()
if cursor is None or conn is None:
raise DatabaseConnectionError("Failed to connect to db.")

conn.autocommit = True

cursor, conn = get_db_connection()

# Check if the sender's account exists
cursor.execute("SELECT balance FROM bank_accounts WHERE id = %s", (from_account_id,))
sender_account = cursor.fetchone()
Expand Down
16 changes: 4 additions & 12 deletions db.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,15 @@ def get_db_connection():

try:
conn = psycopg2.connect(db_url)
conn.autocommit = True
cursor = conn.cursor(cursor_factory=RealDictCursor)
return cursor, conn
except Exception as e:
logging.error("Failed to connect to DB.", exc_info=True)
return None, None

raise DatabaseConnectionError("Could not connect to DB.")
def get_user_by_email(email):
try:
cursor, conn = get_db_connection()
if cursor is None or conn is None:
raise DatabaseConnectionError("No connection to DB.")
logging.debug("No connection to the database.")
return None

cursor.execute("SELECT * FROM users WHERE email = %s", (email,))
user = cursor.fetchone()
Expand All @@ -44,14 +40,10 @@ def get_user_by_email(email):
conn.close()
return user

except OperationalError as e:
logging.error(f"An error occured when trying to fetch user.", exc_info=True)

except DatabaseConnectionError as e:
raise DatabaseConnectionError("Failed to connect to the db")

except DatabaseError as e:
logging.error("Database error:", exc_info=True)
raise DatabaseConnectionError("An error occurred while fetching user.")

except Exception as e:
logging.debug(f"Error fetching user by email: {email}", exc_info=True)
return None
Expand Down
1 change: 1 addition & 0 deletions init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE DATABASE test_db;
4 changes: 2 additions & 2 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ def log_reponse_info(response):
# protected/non-protected routes
open_routes = {
('/users/login', 'POST'): 'login',
('/users/register', 'POST'): 'register',
('/bank_accounts', 'POST'): 'create_bank_account'
('/users/register', 'POST'): 'register'
}

closed_routes = {
('/users', 'GET'): 'get_user',
('/bank_accounts', 'POST'): 'create_bank_account',
('/bank_accounts', 'GET') : 'get_bank_account',
('/bank_accounts/transfer', 'POST') : 'transfer'
}
Expand Down
23 changes: 17 additions & 6 deletions users.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,11 @@ def register():
try:
# psycopg2 sql injection
cursor, conn = get_db_connection()
if cursor is None or conn is None:
return jsonify({'error' : 'Internal Error' }), 500

cursor.execute("""
INSERT INTO users (id, first_name, last_name, email, password_hash, created_at, updated_at)
VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING id;
""", (user_id, data['first_name'], data['last_name'], email, hashed_password, str(created_at), str(updated_at)))

conn.commit()
cursor.close()
conn.close()

Expand Down Expand Up @@ -103,17 +99,32 @@ def get_user():
@users_bp.route('/users/login', methods=['POST'])
def login():
data = request.get_json()

# Input validation
if not data or 'email' not in data or 'password' not in data:
return jsonify({'error': 'Email and password are required.'}), 400

email = data.get('email')
password = data.get('password')
user = get_user_by_email(email) # Get USER

try:
user = get_user_by_email(email) # Get USER
except UserNotFoundError:
return jsonify({'error': 'User Not Found'}), 404
except DatabaseConnectionError:
logging.error("Couldn't connect to server", exc_info=True)
return jsonify({'error': 'Internal Error'}), 500
except Exception as e:
logging.error("An unexpected error occurred", exc_info=True)
return jsonify({'error': 'An unexpected error occurred.'}), 500

if user and bcrypt.check_password_hash(user['password_hash'], password):
login_time = datetime.datetime.now()
token = generate_token(user['id'])
logging.debug(f"user with email {email} logged in at {login_time}...")
return jsonify({
'message': 'Logged In Successfully',
'toekn': token
'token': token
}), 200
else:
return jsonify({'error': 'Invalid email or password.'}), 401

0 comments on commit 8562dbd

Please sign in to comment.