diff --git a/AT_frontend/.gitignore b/AT_frontend/.gitignore new file mode 100644 index 0000000..860b323 --- /dev/null +++ b/AT_frontend/.gitignore @@ -0,0 +1,2 @@ +.venv/ +__pychache__/ \ No newline at end of file diff --git a/AT_frontend/app.py b/AT_frontend/app.py new file mode 100644 index 0000000..b1af769 --- /dev/null +++ b/AT_frontend/app.py @@ -0,0 +1,152 @@ +from flask import Flask, render_template, request, redirect, url_for, flash, session +from flask_wtf import FlaskForm +from wtforms import StringField, PasswordField, BooleanField, SubmitField +from wtforms.validators import DataRequired +from functools import wraps +import os +from flask_sqlalchemy import SQLAlchemy +from datetime import datetime + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'your-secret-key' # Change this to a random string + +# Database configuration - update with your friend's database info +app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///logs.db' # Change this to match your friend's DB +app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False +db = SQLAlchemy(app) + +# Simple log model - adjust to match your friend's database structure +class Log(db.Model): + id = db.Column(db.Integer, primary_key=True) + action = db.Column(db.String(100), nullable=False) + timestamp = db.Column(db.DateTime, default=datetime.utcnow) + + def __repr__(self): + return f"Log('{self.action}', '{self.timestamp}')" + +# Keep your existing user dictionary for authentication +users = { + "admin": {"password": "admin123", "role": "admin"}, + "user": {"password": "user123", "role": "user"} +} + +# Add a function to create a new log entry +def add_log(action): + log = Log(action=action) + db.session.add(log) + db.session.commit() + +class LoginForm(FlaskForm): + username = StringField('Username', validators=[DataRequired()]) + password = PasswordField('Password', validators=[DataRequired()]) + remember = BooleanField('Remember Me') + +class GateControlForm(FlaskForm): + open_gate = SubmitField('Open Gate') + close_gate = SubmitField('Close Gate') + check_camera = SubmitField('Check Camera') + debug_mode = BooleanField('Debug Mode') + +def login_required(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if 'logged_in' not in session: + return redirect(url_for('login')) + return f(*args, **kwargs) + return decorated_function + +def admin_required(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if 'role' not in session or session['role'] != 'admin': + flash('You need to be an admin to access this page.') + return redirect(url_for('login')) + return f(*args, **kwargs) + return decorated_function + +@app.route('/') +def index(): + if 'logged_in' in session: + if session['role'] == 'admin': + return redirect(url_for('dashboard')) + return redirect(url_for('user_page')) + return redirect(url_for('login')) + +@app.route('/login', methods=['GET', 'POST']) +def login(): + form = LoginForm() + error = None + + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + + if username in users and users[username]['password'] == password: + session['logged_in'] = True + session['username'] = username + session['role'] = users[username]['role'] + + # Log the login action + add_log(f"User {username} logged in") + + if users[username]['role'] == 'admin': + return redirect(url_for('dashboard')) + else: + return redirect(url_for('user_page')) + else: + # Log the failed login attempt + add_log(f"Failed login attempt for user {username}") + error = 'Invalid credentials. Please try again.' + + return render_template('inlog.html', form=form, error=error) + +@app.route('/dashboard', methods=['GET', 'POST']) +@login_required +@admin_required +def dashboard(): + form = GateControlForm() + gate_status = "Closed" + camera_status = "Inactive" + debug_mode = False + + # Get the most recent logs to display + recent_logs = Log.query.order_by(Log.timestamp.desc()).limit(10).all() + + if form.validate_on_submit(): + if form.open_gate.data: + gate_status = "Open" + add_log("Gate opened by " + session['username']) + elif form.close_gate.data: + gate_status = "Closed" + add_log("Gate closed by " + session['username']) + elif form.check_camera.data: + camera_status = "Active" + add_log("Camera checked by " + session['username']) + + debug_mode = form.debug_mode.data + if debug_mode: + add_log("Debug mode enabled by " + session['username']) + + return render_template('dashboard.html', form=form, gate_status=gate_status, + camera_status=camera_status, debug_mode=debug_mode, + recent_logs=recent_logs) + +@app.route('/user') +@login_required +def user_page(): + add_log(f"User {session['username']} accessed user page") + return "Regular user page - Access restricted" + +@app.route('/logout') +def logout(): + if 'username' in session: + add_log(f"User {session['username']} logged out") + session.clear() + return redirect(url_for('login')) + +# Initialize database +with app.app_context(): + db.create_all() + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/AT_frontend/forms.py b/AT_frontend/forms.py new file mode 100644 index 0000000..1e45ef9 --- /dev/null +++ b/AT_frontend/forms.py @@ -0,0 +1,33 @@ +from flask import Flask, render_template, redirect, url_for +from flask_wtf import FlaskForm +from wtforms import StringField, SubmitField, BooleanField +from wtforms.validators import DataRequired + +app = Flask(__name__) +app.config['SECRET_KEY'] = 'mijngeheimesleutel' + +class GateControlForm(FlaskForm): + open_gate = SubmitField('Open Gate') + close_gate = SubmitField('Close Gate') + debug_mode = BooleanField('Enable Debug Mode') + check_camera = SubmitField('Check Camera') # New button to check camera status + +class InputForm(FlaskForm): + name = StringField('Name', validators=[DataRequired()]) + submit = SubmitField('Submit') + +@app.route('/', methods=['GET', 'POST']) +def dashboard(): + gate_status = "Closed" + debug_mode = False + form = GateControlForm() + if form.validate_on_submit(): + if form.open_gate.data: + gate_status = "Open" + elif form.close_gate.data: + debug_mode = form.debug_mode.data + return render_template('dashboard.html', form=form, gate_status=gate_status, debug_mode=debug_mode) + return render_template('dashboard.html', form=form, gate_status=gate_status, debug_mode=debug_mode) + +if __name__ == '__main__': + app.run(debug=True) \ No newline at end of file diff --git a/AT_frontend/instance/logs.db b/AT_frontend/instance/logs.db new file mode 100644 index 0000000..8efe1ea Binary files /dev/null and b/AT_frontend/instance/logs.db differ diff --git a/AT_frontend/instance/site.db b/AT_frontend/instance/site.db new file mode 100644 index 0000000..416bb25 Binary files /dev/null and b/AT_frontend/instance/site.db differ diff --git a/AT_frontend/templates/base.html b/AT_frontend/templates/base.html new file mode 100644 index 0000000..8e26039 --- /dev/null +++ b/AT_frontend/templates/base.html @@ -0,0 +1,50 @@ + + + + + + + Admin Dashboard + + + +
+
+ + +
+
+

Admin Dashboard

+
+
+ + +
+ Logout +
+
+ + {%block content%} + + {% endblock %} + \ No newline at end of file diff --git a/AT_frontend/templates/dashboard.html b/AT_frontend/templates/dashboard.html new file mode 100644 index 0000000..db79af8 --- /dev/null +++ b/AT_frontend/templates/dashboard.html @@ -0,0 +1,68 @@ +{%extends 'base.html' %} +{% block content %} +
+
+
+
+
Gate Control Dashboard
+
+ {{ form.hidden_tag() }} +
+ {{ form.open_gate(class="btn btn-dark") }} +
+
+ {{ form.close_gate(class="btn btn-dark") }} +
+
+ {{ form.check_camera(class="btn btn-dark") }} +
+
+ {{ form.debug_mode() }} + +
+
+ +
+
+
Gate Status: {{ gate_status }}
+
Camera Status: {{ camera_status }}
+ {% if debug_mode %} + Debug Mode is Enabled + {% endif %} +
+
+
+
+
+
+
System Logs
+
+ + + + + + + + + + {% for log in recent_logs %} + + + + + + {% endfor %} + +
TimeActionStatus
{{ log.timestamp.strftime('%H:%M:%S') }}{{ log.action }} + + {{ log.status }} + +
+
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/AT_frontend/templates/inlog.html b/AT_frontend/templates/inlog.html new file mode 100644 index 0000000..739c54f --- /dev/null +++ b/AT_frontend/templates/inlog.html @@ -0,0 +1,44 @@ + + + + + + + + Inlog + + + +
+
+

Admin Login

+
+ {{ form.csrf_token }} +
+ + +
+
+ + +
+ Must be 8-20 characters long. +
+
+
+ + +
+ {% if error %} +
+ {{ error }} +
+ {% endif %} +
+ +
+
+
+
+ + \ No newline at end of file