Skip to content

Commit

Permalink
Added audit logs to user database and to audit.txt (#113)
Browse files Browse the repository at this point in the history
* Added audit logs to user database and to audit.txt

Added a schema for audit logs with current timestamp, and the same is transferred to audit.txt for line based record keeping.

* Added comments

Added some comments to explain fucntion logic

---------

Signed-off-by: wongaid <[email protected]>
Co-authored-by: wongaid <[email protected]>
  • Loading branch information
alkatra and wongaid authored Nov 29, 2023
1 parent 3d49a8a commit 8e03cd4
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 8 deletions.
89 changes: 86 additions & 3 deletions neo_dolfin/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,52 @@ class UserTestMap(db.Model):
userid = db.Column(db.String(80), unique=True, nullable=False)
testid = db.Column(db.Integer, nullable=False)

with app.app_context():
db.create_all()
class UserAuditLog(db.Model):
timestamp = db.Column(db.DateTime, primary_key=True, default=datetime.datetime.now)
username = db.Column(db.String(80), nullable=False)
action = db.Column(db.String(80), nullable=False)
message = db.Column(db.String(255), nullable=False)

try:
with app.app_context():
db.create_all()
except Exception as e:
print("Error creating database:", str(e))

# SQLite User Data Database Setup
#df4.drop(['enrich', 'links'], axis=1, inplace=True) # Drop unnecessary columns
#df4['transactionDate'] = pd.to_datetime(df4['transactionDate'], format='%d/%m/%Y') # Convert 'transactionDate' to datetime format for easy manipulation
#df4['day'] = df4['transactionDate'].dt.day # Create new columns for day, month, and year
#df4['month'] = df4['transactionDate'].dt.month # Create new columns for day, month, and year
#df4['year'] = df4['transactionDate'].dt.year # Create new columns for day, month, and year

# Function to clean the 'subClass' column
#def clean_subClass(row):
# if pd.isnull(row['subClass']) and row['class'] == 'cash-withdrawal':
# return 'cash-withdrawal'
# if row['subClass'] == '{\\title\\":\\"\\"':
# return 'bank-fee'
# match = re.search(r'\\title\\":\\"(.*?)\\"', str(row['subClass']))
# if match:
# extracted_subClass = match.group(1)
# if extracted_subClass == 'Unknown':
# return row['description']
# return extracted_subClass
# return row['subClass']

# df4['subClass'] = df4.apply(clean_subClass, axis=1) # Clean the 'subClass' column
# df4['subClass'] = df4['subClass'].apply(lambda x: 'Professional and Other Interest Group Services' if x == '{\\title\\":\\"Civic' else x) # Update specific 'subClass' values
# Check if the SQLite database file already exists
# db_file = "db/transactions_ut.db"
# if not os.path.exists(db_file):
# If the database file doesn't exist, create a new one
# conn = sqlite3.connect(db_file)
# Import the cleaned DataFrame to the SQLite database
# df4.to_sql("transactions", conn, if_exists="replace", index=False)
# conn.close()
# else:
# If the database file already exists, connect to it
# conn = sqlite3.connect(db_file)

## Basiq API
basiq_service = BasiqService()
Expand Down Expand Up @@ -114,6 +158,16 @@ def is_australia_or_localhost(self, ip_addr):
return 0
#app.wsgi_app = GeoLockChecker(app.wsgi_app)

# Handles the logging of an authentication or registration event to a txt output and a log database
def add_user_audit_log(username, action, message):
new_log = UserAuditLog(username=username, action=action, message=message)
print(new_log)
db.session.add(new_log)
db.session.commit()
with open("audit.txt", 'a') as file:
file.write(f"[{new_log.timestamp}] [user-{action}] username: {username}: {message}\n")


# ROUTING
## LANDING PAGE
@app.route("/",methods = ['GET']) #Initial landing page for application
Expand Down Expand Up @@ -174,14 +228,43 @@ def login():

# Load transactional data
loadDatabase(testId)

# log successful authentication challenge
add_user_audit_log(username, 'login-success', 'User logged in successfully.')
# redirect to the dashboard.
return redirect('/dash')

## Otherwise:
# log un-successful authentication challenge
add_user_audit_log(username, 'login-fail', 'User login failed.')
return 'Login failed. Please check your credentials.'

return render_template('login.html') # Create a login form in the HTML template

## REGISTER
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
email = request.form['email']
password = request.form['password']

# Check if the username or email already exists in the database
existing_user = User.query.filter_by(username=username).first()
existing_email = User.query.filter_by(email=email).first()

if existing_user or existing_email:
add_user_audit_log(username, 'register-fail', 'User registration failed.')
return 'Username or email already exists. Please choose a different one.'

# Create a new user and add it to the database
new_user = User(username=username, email=email, password=password)
db.session.add(new_user)
db.session.commit()
add_user_audit_log(username, 'register-success', 'User registered successfully.')
return redirect('/login')

return render_template('register.html') # Create a registration form in the HTML template

@app.route('/dash',methods=['GET','POST'])
def auth_dash2():

Expand Down
5 changes: 0 additions & 5 deletions neo_dolfin/audit.txt
Original file line number Diff line number Diff line change
@@ -1,5 +0,0 @@
[2023-11-24 17:09:33] login-fail: Failed login attempt for user admin
[2023-11-24 17:09:38] login-fail: Failed login attempt for user admin
[2023-11-24 17:09:41] login-fail: Failed login attempt for user admin
[2023-11-24 17:10:00] register: User admin registered
[2023-11-24 17:10:03] login: User admin logged in

0 comments on commit 8e03cd4

Please sign in to comment.