add all files

This commit is contained in:
2024-05-22 12:32:30 +02:00
parent 3b7e9acd32
commit 646033244f
23 changed files with 1747 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
# Use an official Python runtime as a parent image
FROM python:3.9
# Set the working directory in the container
WORKDIR /Program
# Install the required system packages
RUN apt-get update && \
apt-get install -y \
gcc \
libldap2-dev \
libsasl2-dev \
libssl-dev \
build-essential \
python3-flask \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
# Copy the current directory contents into the container at /Program
COPY ./Program/ /Program
# Copy the entrypoint script into the container
COPY ./Program/entrypoint.sh /entrypoint.sh
# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Make the entrypoint script executable
RUN chmod +x /entrypoint.sh
# Make port 5000 available to the world outside this container
EXPOSE 5000
# Set the entrypoint to the entrypoint script
ENTRYPOINT ["/entrypoint.sh"]
+12
View File
@@ -0,0 +1,12 @@
__pycache__
*.pyc
*.pyo
*.pyd
env
venv
.idea
.vscode
.git
.gitignore
.DS_Store
*.db
+65
View File
@@ -0,0 +1,65 @@
from threading import Thread
from flask import Flask, request, jsonify
from env import *
import sqlite3
app = Flask(__name__)
# Function to verify if the user is allowed to open the door
def check_access(rfid_uid, door_id):
try:
conn = sqlite3.connect(DBFILE) # Update with your database file path
cursor = conn.cursor()
# Get the user's UPN and group memberships based on the RFID UID
cursor.execute("SELECT upn, MemberOf FROM Users WHERE rFIDUID = ?", (rfid_uid,))
user_data = cursor.fetchone()
if user_data is None:
return False, None # User not found
upn, user_groups = user_data
# Get the group associated with the door
cursor.execute("SELECT GroupCn FROM Doors WHERE id = ?", (door_id,))
door_group = cursor.fetchone()
if door_group is None:
return False, None # Door not found
door_group = door_group[0]
# Check if the user's group is allowed to open the door
if door_group in user_groups.split(','):
return True, upn # Access granted
else:
return False, None # Access denied
except sqlite3.Error as e:
print(f"SQLite Error: {e}")
return False, None
# Route to handle door access requests
@app.route('/access', methods=['POST'])
def door_access():
data = request.get_json()
rfid_uid = data.get('rfid_uid')
door_id = data.get('door_id')
if rfid_uid is None or door_id is None:
return jsonify({'error': 'RFID UID and door ID are required'}), 400
access_granted, upn = check_access(rfid_uid, door_id)
if access_granted:
return jsonify({'access_granted': True, 'upn': upn}), 200
else:
return jsonify({'access_granted': False}), 200
def run_flask_app():
app.run(debug=True, use_reloader=False, port=WebAPIPORT)
def run_webAPI_thread():
print(f"STARTING API on port {WebAPIPORT}")
flask_thread = Thread(target=run_flask_app)
flask_thread.start()
flask_thread.join()
if __name__ == '__main__':
app.run(debug=True)
+103
View File
@@ -0,0 +1,103 @@
from threading import Thread
from flask import Flask, render_template, send_file, Response, request, redirect, jsonify
import io
from ldapSync import sync_ldap_to_database
from database import *
from env import *
app = Flask(__name__)
# Route to the home
@app.route('/')
def add_door_form():
existing_groups = get_existing_groups(DBFILE) # Update with your database file path
logs = get_latest_logs(DBFILE,5)
#print(logs[0])
return render_template('./index.html', existing_groups=existing_groups, logs=logs)
# Route to display the fuser db
@app.route('/UserDB')
def index():
users = get_users()
return render_template('userdb.html', users=users)
# Route to display the fuser db
@app.route('/LogsDB')
def logsdb():
logs = get_logs()
return render_template('logsdb.html', logs=logs)
@app.route('/export_logs')
def export_logs():
logs = get_logs()
# Create a file-like string to write logs
log_output = io.StringIO()
for log in logs:
log_line = f"{log[0]},{log[1]},{log[2]},{log[3]},{'Yes' if log[4] else 'No'},\n"
log_output.write(log_line)
# Set the position to the beginning of the stream
log_output.seek(0)
# Create a response with the file data
return Response(
log_output,
mimetype="text/plain",
headers={"Content-disposition": "attachment; filename=logs.csv"}
)
# Route to handle form submission and add the door to the database
@app.route('/add_door', methods=['POST'])
def add_door():
Door_id = request.form["Door_id"]
group_cn = request.form["group_cn"]
# Update with your database file path
exec = add_door_to_database(DBFILE, group_cn, Door_id)
if add_door_to_database(DBFILE, group_cn, Door_id):
return redirect('/')
else:
return f"Failed to add door to the database."
# Route to handle sync button click
@app.route('/sync')
def sync():
sync_ldap_to_database(DBFILE)
return render_template('./LDAP.html')
redirect('/')
# Route to handle door access requests
@app.route('/access', methods=['POST'])
def door_access():
data = request.get_json()
rfid_uid = data.get('rfid_uid')
door_id = data.get('door_id')
if rfid_uid is None or door_id is None:
return jsonify({'error': 'RFID UID and door ID are required'}), 400
access_granted, upn = check_access(rfid_uid, door_id)
if access_granted:
print('')
log_access_attempt(DBFILE,upn,rfid_uid,True,door_id)
return jsonify({'access_granted': True, 'upn': upn}), 200
else:
log_access_attempt(DBFILE,upn,rfid_uid,False,door_id)
return jsonify({'access_granted': False}), 403
def run_flask_app():
app.run(debug=True, use_reloader=False, port=5000, host="0.0.0.0")
def run_webServer_thread():
print(f'STARTING WEB SERVER ON PORT {WebServerPORT}')
flask_thread = Thread(target=run_flask_app, daemon=True)
flask_thread.start()
# flask_thread.join()
if __name__ == '__main__':
app.run(debug=True)
Binary file not shown.
+269
View File
@@ -0,0 +1,269 @@
from datetime import datetime
import sqlite3
from env import *
# Function to check if a table exists in the database
def table_exists(cursor, table_name):
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name=?", (table_name,))
return cursor.fetchone() is not None
# Function to create the Users table
def create_users_table(cursor):
cursor.execute('''CREATE TABLE Users (
upn TEXT PRIMARY KEY,
rFIDUID TEXT,
MemberOf TEXT,
FOREIGN KEY (MemberOf) REFERENCES Groups(cn)
)''')
# Function to create the Groups table
def create_groups_table(cursor):
cursor.execute('''CREATE TABLE Groups (
cn TEXT PRIMARY KEY
)''')
# Function to create the Doors table
def create_doors_table(cursor):
cursor.execute('''CREATE TABLE Doors (
id INTEGER PRIMARY KEY,
GroupCn TEXT,
FOREIGN KEY (GroupCn) REFERENCES Groups(cn)
)''')
# Function to create the logs table
def create_logs_table(cursor):
"""
Create a log table with columns id, timestamp, user, and granted.
:param db_file: The database file path.
"""
cursor.execute('''
CREATE TABLE IF NOT EXISTS log (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT ,
user TEXT ,
rFIDUID TEXT,
door_id INTEGER ,
granted BOOLEAN ,
FOREIGN KEY (door_id) REFERENCES Doors (id)
FOREIGN KEY (user) REFERENCES Users (upn)
FOREIGN KEY (rFIDUID) REFERENCES Users (rFIDUID)
)
''')
# Function to setup the database
def setup_database(db_file):
# Connect to the SQLite database
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
# Check and create Users table
if not table_exists(cursor, "Users"):
create_users_table(cursor)
print(f"[{datetime.now()}] Users table created successfully.")
else:
print(f"[{datetime.now()}] Users table already exists.")
# Check and create Groups table
if not table_exists(cursor, "Groups"):
create_groups_table(cursor)
print(f"[{datetime.now()}] Groups table created successfully.")
else:
print(f"[{datetime.now()}] Groups table already exists.")
# Check and create Doors table
if not table_exists(cursor, "Doors"):
create_doors_table(cursor)
print(f"[{datetime.now()}] Doors table created successfully.")
else:
print(f"[{datetime.now()}] Doors table already exists.")
# Check and create Doors table
if not table_exists(cursor, "Log"):
create_logs_table(cursor)
print(f"[{datetime.now()}] Log table created successfully.")
else:
print(f"[{datetime.now()}] Log table already exists.")
# Commit changes and close connection
conn.commit()
conn.close()
def log_access_attempt(db_file, user, rFIDUID, granted, doorID):
"""
Log an access attempt to the log table.
:param db_file: The database file path.
:param user: The user attempting access.
:param rFIDUID: The user's tag uid
:param granted: Whether access was granted (True/False).
:param doorID: The door id
"""
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
print(f'[{datetime.now()}] User {user} get granted : {granted} on door : {doorID}')
cursor.execute('''
INSERT INTO log (timestamp, user, rFIDUID, granted, door_id) VALUES (?, ?, ?, ?, ?)
''', (datetime.now(), user, rFIDUID, granted, doorID))
conn.commit()
conn.close()
def print_users_table(cursor):
cursor.execute("SELECT * FROM Users")
rows = cursor.fetchall()
print("Users:")
for row in rows:
print(row)
# Function to print the content of the Groups table
def print_groups_table(cursor):
cursor.execute("SELECT * FROM Groups")
rows = cursor.fetchall()
print("Groups:")
for row in rows:
print(row)
# Function to print the content of the Doors table
def print_doors_table(cursor):
cursor.execute("SELECT * FROM Doors")
rows = cursor.fetchall()
print("Doors:")
for row in rows:
print(row)
# Function to print the content of the Log table
def print_log_table(cursor):
cursor.execute("SELECT * FROM log")
rows = cursor.fetchall()
print("Logs:")
for row in rows:
print(row)
# Function to print the content of the entire database
def print_database_content(db_file):
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
print_users_table(cursor)
print_groups_table(cursor)
print_doors_table(cursor)
print_log_table(cursor)
conn.close()
def get_logs():
"""
Fetch all logs from the log table in the database.
:return: List of log records.
"""
conn = sqlite3.connect(DBFILE)
cursor = conn.cursor()
cursor.execute('''
SELECT timestamp, user, rFIDUID, granted, door_id
FROM log
ORDER BY id DESC
''')
logs = cursor.fetchall()
conn.close()
return logs
def get_latest_logs(db_file,limit=10):
"""
Fetch the latest logs from the database.
:param limit: The number of latest logs to fetch.
:return: List of log entries.
"""
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute('''
SELECT timestamp, user, rFIDUID, granted, door_id
FROM log
ORDER BY id DESC
LIMIT ?
''', (limit,))
logs = cursor.fetchall()
conn.close()
return logs
# Function to fetch list of existing groups from the database
def get_existing_groups(db_file):
try:
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute("SELECT cn FROM Groups")
groups = cursor.fetchall()
conn.close()
return [group[0] for group in groups]
except sqlite3.Error as e:
print(f"SQLite Error: {e}")
return []
def get_users():
"""
Fetch all users from the Users table in the database.
:return: List of user records.
"""
conn = sqlite3.connect(DBFILE)
cursor = conn.cursor()
cursor.execute('SELECT upn, rFIDUID, MemberOf FROM Users')
users = cursor.fetchall()
conn.close()
return users
# Function to add a door to the database
def add_door_to_database(db_file, group_cn, Door_id):
try:
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
cursor.execute("INSERT INTO Doors (id, GroupCn) VALUES (?,?)", (Door_id,group_cn,))
conn.commit()
conn.close()
#print_database_content(DBFILE)
return True
except sqlite3.Error as e:
#print_database_content(DBFILE)
print(f"SQLite Error: {e}")
return (False, e)
# Function to verify if the user is allowed to open the door
def check_access(rfid_uid_str, door_id):
try:
conn = sqlite3.connect(DBFILE) # Update with your database file path
cursor = conn.cursor()
# Convert the received RFID UID string to bytes
rfid_uid_bytes = rfid_uid_str.encode('utf-8')
# Get the user's UPN and group memberships based on the RFID UID
cursor.execute("SELECT upn, MemberOf FROM Users WHERE rFIDUID = ?", (rfid_uid_bytes,))
user_data = cursor.fetchone()
if user_data is None:
return False, None # User not found
upn_bytes, user_groups = user_data
# Decode the UPN bytes to string
upn = upn_bytes.decode('utf-8')
# Get the group associated with the door
cursor.execute("SELECT GroupCn FROM Doors WHERE id = ?", (door_id,))
door_group = cursor.fetchone()
if door_group is None:
return False, None # Door not found
door_group = door_group[0]
# Check if the user's group is allowed to open the door
if door_group in user_groups.split(','):
return True, upn # Access granted
else:
return False, None # Access denied
except sqlite3.Error as e:
print(f"SQLite Error: {e}")
return False, None
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
ls /app/Program
echo patate
# Create env.py with environment variables
cat <<EOT > /app/env.py
LDAPUSER = "${LDAPUSER}"
LDAPPASS = "${LDAPPASS}"
LDAP_SERVER = "${LDAP_SERVER}"
DOOR_ACCESS_GROUPS_DN = "${DOOR_ACCESS_GROUPS_DN}"
USERS_DN = "${USERS_DN}"
DBFILE = "${DBFILE}"
WebServerPORT = ${WebServerPORT}
EOT
# Run the main server script
exec python3 /Program/server.py
+10
View File
@@ -0,0 +1,10 @@
LDAPUSER = "RO.doorAccess"
LDAPPASS = "@dmin.01I"
LDAP_SERVER = 'ldap://10.100.100.10'
DOOR_ACCESS_GROUPS_DN = 'ou=DoorAccess,ou=Groups,ou=BTS,dc=ad,dc=bts,dc=com'
USERS_DN = 'ou=Users,ou=BTS,dc=ad,dc=bts,dc=com'
DBFILE = "/db/data.db"
WebServerPORT = 5000
+164
View File
@@ -0,0 +1,164 @@
from datetime import datetime
import ldap
import sqlite3
import threading
import schedule
from env import *
# Function to initialize LDAP connection
def initialize_ldap_connection():
"""
## Settings :
None
## Behavior
Init the connection to the LDAP server.
Return LDAPobjet instance when connected
if it fail, return None and print error code
"""
try:
connect = ldap.initialize(LDAP_SERVER)
connect.set_option(ldap.OPT_REFERRALS, 0)
connect.simple_bind_s(LDAPUSER, LDAPPASS)
print(f"[{datetime.now()}] LDAP connection successful.")
return connect
except ldap.LDAPError as e:
print(f'[{datetime.now()}] LDAP Error: {e}')
return None
# Function to retrieve users from LDAP
def retrieve_users_from_ldap(ldap_connection):
"""
## Settings :
- ldap_connection : LDAPobjet instance
## Behavior
retrieve the users in the specified OU
Return result when it success
if it fail, return empty list and print error code
"""
try:
result = ldap_connection.search_s(USERS_DN, ldap.SCOPE_SUBTREE, '(objectClass=user)')
return result
except ldap.LDAPError as e:
print(f'[{datetime.now()}] LDAP Error: {e}')
return []
# Function to retrieve groups from LDAP
def retrieve_groups_from_ldap(ldap_connection):
"""
## Settings :
- ldap_connection : LDAPobjet instance
## Behavior
retrieve the groups in the specified OU
Return result when it success
if it fail, return empty list and print error code
"""
try:
result = ldap_connection.search_s(DOOR_ACCESS_GROUPS_DN, ldap.SCOPE_SUBTREE, '(objectClass=group)')
return result
except ldap.LDAPError as e:
print(f'[{datetime.now()}]LDAP Error: {e}')
return []
# Function to add user to the database or update if already exists
def add_user_to_database(conn, cursor, upn, rfid_uid, member_of):
try:
cursor.execute("SELECT * FROM Users WHERE upn=?", (upn,))
existing_user = cursor.fetchone()
if existing_user:
# User already exists, check if data needs to be updated
if existing_user[1] != rfid_uid or existing_user[2] != member_of:
cursor.execute("UPDATE Users SET rFIDUID=?, MemberOf=? WHERE upn=?", (rfid_uid, member_of, upn))
conn.commit()
print(f"[{datetime.now()}] User '{upn}' updated in the database.")
else:
print(f"[{datetime.now()}] User '{upn}' already exists in the database with the same data.")
else:
# User doesn't exist, insert new user
cursor.execute("INSERT INTO Users (upn, rFIDUID, MemberOf) VALUES (?, ?, ?)", (upn, rfid_uid, member_of))
conn.commit()
print(f"[{datetime.now()}] User '{upn}' added to the database.")
except sqlite3.Error as e:
print(f'SQLite Error: {e}')
# Function to add group to the database or update if already exists
def add_group_to_database(conn, cursor, cn):
try:
cursor.execute("SELECT * FROM Groups WHERE cn=?", (cn,))
existing_group = cursor.fetchone()
if existing_group:
# Group already exists, no need to update
print(f"[{datetime.now()}] Group '{cn}' already exists in the database.")
else:
# Group doesn't exist, insert new group
cursor.execute("INSERT INTO Groups (cn) VALUES (?)", (cn,))
conn.commit()
print(f"[{datetime.now()}] Group '{cn}' added to the database.")
except sqlite3.Error as e:
print(f'SQLite Error: {e}')
# Function to sync LDAP users and groups to the database
def sync_ldap_to_database(db_file):
"""
Syncs LDAP users and groups to the SQLite database.
Args:
db_file (str): The path to the SQLite database file.
Returns:
None
This function connects to the LDAP server, retrieves user and group information,
and synchronizes it with the SQLite database. It checks if users are disabled in
LDAP and removes them from the database if necessary. It also ensures that users
and groups are added or updated in the database according to the LDAP information.
Note:
The LDAP connection must be properly configured and the LDAP server accessible
from the machine running this script.
"""
ldap_conn = initialize_ldap_connection()
if ldap_conn:
conn = sqlite3.connect(db_file)
cursor = conn.cursor()
# Retrieve users from LDAP and add them to the database
users = retrieve_users_from_ldap(ldap_conn)
for dn, user_info in users:
upn = user_info.get('userPrincipalName', [''])[0]
rfid_uid = user_info.get('rFIDUID', [''])[0]
member_of = [group.decode('utf-8').split(',')[0].split('=')[1] for group in user_info.get('memberOf', [])]
# Check if the user is disabled in LDAP
user_account_control = user_info.get('userAccountControl', [0])[0]
if user_account_control == b'514' or user_account_control == b'66050': # Check if the 9th bit is set (ADS_UF_ACCOUNTDISABLE flag)
# User is disabled, check if user exists in the database and remove if present
cursor.execute("SELECT * FROM Users WHERE upn=?", (upn,))
existing_user = cursor.fetchone()
if existing_user:
cursor.execute("DELETE FROM Users WHERE upn=?", (upn,))
conn.commit()
print(f"[{datetime.now()}] User '{upn}' disabled in LDAP and removed from the database.")
else:
print(f"[{datetime.now()}] User '{upn}' disabled in LDAP but not present in the database.")
continue # Skip adding the disabled user to the database
# User is not disabled, add or update user in the database
add_user_to_database(conn, cursor, upn, rfid_uid, ', '.join(member_of))
# Retrieve groups from LDAP and add them to the database
groups = retrieve_groups_from_ldap(ldap_conn)
for dn, group_info in groups:
cn = group_info.get('cn', [''])[0].decode('utf-8')
add_group_to_database(conn, cursor, cn)
# Close connections
conn.close()
ldap_conn.unbind()
def run_sync_ldap_to_database_thread(db_file):
print(f"[{datetime.now()}] Running LDAP sync")
threading.Thread(target=sync_ldap_to_database, args=(db_file,), daemon=True).start()
def schedule_sync_ldap_to_database(db_file):
run_sync_ldap_to_database_thread(db_file) # Run immediately
schedule.every(5).minutes.do(run_sync_ldap_to_database_thread, db_file)
+4
View File
@@ -0,0 +1,4 @@
Flask==2.0.2
Werkzeug==2.0.3
python-ldap==3.3.1
schedule==1.2.1
+15
View File
@@ -0,0 +1,15 @@
from ldapSync import *
from database import *
from Webserver import run_webServer_thread
from env import *
import schedule
setup_database(DBFILE)
print_database_content(DBFILE)
run_webServer_thread()
schedule_sync_ldap_to_database(DBFILE)
while True :
schedule.run_pending()
+102
View File
@@ -0,0 +1,102 @@
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
}
.container {
width: 80%;
margin: 0 auto;
padding: 20px;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
color: #333;
}
table {
width: 100%;
border-collapse: collapse;
margin-bottom: 20px;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 12px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
tr:nth-child(even) {
background-color: #f9f9f9;
}
tr:hover {
background-color: #f1f1f1;
}
form {
width: 100%;
max-width: 600px;
margin: 0 auto 20px;
padding: 20px;
background-color: #fff;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
form label {
display: block;
margin-bottom: 8px;
color: #333;
}
form input[type="number"],
form input[type="text"],
form select {
width: 100%;
padding: 10px;
margin-bottom: 12px;
border: 1px solid #ddd;
border-radius: 4px;
}
form input[type="submit"] {
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
form input[type="submit"]:hover {
background-color: #45a049;
}
.navbar {
background-color: #45a049;
overflow: hidden;
}
.navbar a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
}
.navbar a:hover {
background-color: #ddd;
color: black;
}
+16
View File
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LDAP Success</title>
</head>
<body>
<script>
// Display popup message
alert("LDAP sync ended succesfully");
window.location.href = "/";
</script>
</body>
</html>
+65
View File
@@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Access Logs</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="navbar">
<a href="/">Home</a>
<a href="/UserDB">Users</a>
<a href="/LogsDB">Logs</a>
</div>
<div class="container">
<h1>Latest Access Logs</h1>
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>Tag UID</th>
<th>Door ID</th>
<th>Access Granted</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log[0] }}</td>
<td>{{ log[1] }}</td>
<td>{{ log[2] }}</td>
<td>{{ log[4] }}</td>
<td>{{ 'Yes' if log[3] == 1 else 'No' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<h1>Add Door</h1>
<form action="/add_door" method="post">
<label for="Door_id">Door ID:</label>
<input type="number" id="Door_id" name="Door_id" required><br><br>
<label for="group_cn">Group CN:</label>
<select id="group_cn" name="group_cn" required>
{% for group in existing_groups %}
<option value="{{ group }}">{{ group }}</option>
{% endfor %}
</select><br><br>
<input type="submit" value="Submit">
</form>
<h1>Force LDAP Synchronization</h1>
<form action="/sync">
<input type="submit" value="Sync LDAP">
</form>
</div>
<script>
// Refresh the page every 5 seconds
setTimeout(function(){
location.reload();
}, 5000);
</script>
</body>
</html>
+83
View File
@@ -0,0 +1,83 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Access Logs</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<script>
function filterTable() {
var timestampInput = document.getElementById("timestampFilter").value.toLowerCase();
var userInput = document.getElementById("userFilter").value.toLowerCase();
var rfidUidInput = document.getElementById("rfidUidFilter").value.toLowerCase();
var doorIdInput = document.getElementById("doorIdFilter").value.toLowerCase();
var table = document.getElementById("logsTable");
var tr = table.getElementsByTagName("tr");
for (var i = 1; i < tr.length; i++) {
var tdTimestamp = tr[i].getElementsByTagName("td")[0];
var tdUser = tr[i].getElementsByTagName("td")[1];
var tdRfidUid = tr[i].getElementsByTagName("td")[2];
var tdDoorId = tr[i].getElementsByTagName("td")[3];
if (tdTimestamp && tdUser && tdRfidUid && tdDoorId) {
var timestampValue = tdTimestamp.textContent || tdTimestamp.innerText;
var userValue = tdUser.textContent || tdUser.innerText;
var rfidUidValue = tdRfidUid.textContent || tdRfidUid.innerText;
var doorIdValue = tdDoorId.textContent || tdDoorId.innerText;
if (timestampValue.toLowerCase().indexOf(timestampInput) > -1 &&
userValue.toLowerCase().indexOf(userInput) > -1 &&
rfidUidValue.toLowerCase().indexOf(rfidUidInput) > -1 &&
doorIdValue.toLowerCase().indexOf(doorIdInput) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
</head>
<body>
<div class="navbar">
<a href="/">Home</a>
<a href="/UserDB">Users</a>
<a href="/LogsDB">Logs</a>
</div>
<div class="container">
<h1>Access Logs</h1>
<div class="filter-container">
<input type="text" id="timestampFilter" onkeyup="filterTable()" placeholder="Filter by timestamp">
<input type="text" id="userFilter" onkeyup="filterTable()" placeholder="Filter by user">
<input type="text" id="rfidUidFilter" onkeyup="filterTable()" placeholder="Filter by RFID UID">
<input type="text" id="doorIdFilter" onkeyup="filterTable()" placeholder="Filter by door ID">
</div>
<button onclick="window.location.href='/export_logs'">Export Logs as csv</button>
<table id="logsTable">
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>RFID UID</th>
<th>Door ID</th>
<th>Access Granted</th>
</tr>
</thead>
<tbody>
{% for log in logs %}
<tr>
<td>{{ log[0] }}</td>
<td>{{ log[1] }}</td>
<td>{{ log[2] }}</td>
<td>{{ log[4] }}</td>
<td>{{ 'Yes' if log[3] else 'No' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
+39
View File
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Users </title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="navbar">
<a href="/">Home</a>
<a href="/UserDB">Users</a>
<a href="/LogsDB">Logs</a>
</div>
<div class="container">
<h1>Users Database</h1>
<table>
<thead>
<tr>
<th>UPN</th>
<th>RFID UID</th>
<th>Member Of</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user[0] }}</td>
<td>{{ user[1] }}</td>
<td>{{ user[2] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
+27
View File
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add Door</title>
</head>
<body>
<h1>Add Door</h1>
<form action="/add_door" method="post">
<label for="Door_id" name="Door_id">Door ID:</label>
<input type="integer" id="Door_id" name="Door_id" required><br><br>
<label for="group_cn">Group CN:</label>
<select id="group_cn" name="group_cn" required>
{% for group in existing_groups %}
<option value="{{ group }}">{{ group }}</option>
{% endfor %}
</select><br><br>
<input type="submit" value="Submit">
</form>
<br>
<h1>Force LDAP Synchronization</h1>
<form action="/sync">
<input type="submit" value="Sync LDAP">
</form>
</body>
</html>
+17
View File
@@ -0,0 +1,17 @@
services:
rf-ad:
build: ./
ports:
- "5000:5000"
environment:
- LDAPUSER
- LDAPPASS
- LDAP_SERVER
- DOOR_ACCESS_GROUPS_DN
- USERS_DN
- DBFILE
- WebServerPORT
volumes:
- /opt/rf-ad/app:/app
- /opt/rf-ad/db:/db