Skip to content
Snippets Groups Projects
Commit af89bc02 authored by Martinz, David's avatar Martinz, David
Browse files

added basic web based messaging server

parent d0811802
No related branches found
No related tags found
No related merge requests found
# Use a minimal Python image
FROM python:3.9-slim
# Create a non-root user (optional)
#RUN useradd -m appuser
# Set the working directory
WORKDIR /app
# Copy the necessary files
COPY ./app /app
COPY requirements.txt /app
# Install dependencies
RUN pip install -r requirements.txt
# Switch to non-root user (optional)
#USER appuser
# Expose the port the app runs on
EXPOSE 5000
# Start the Flask app
CMD ["python", "app.py"]
from flask import Flask, request, redirect, url_for, render_template, flash, send_from_directory
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
import os
# Flask app setup
app = Flask(__name__, template_folder='templates', static_folder='static')
app.config['UPLOAD_FOLDER'] = './uploads'
app.secret_key = 'supersecretkey'
# Ensure the uploads directory exists
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
# In-memory user data (for demonstration purposes)
users = {}
messages = {}
# Flask-Login setup
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
# User class
class User(UserMixin):
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password = password
# Load user function for Flask-Login
@login_manager.user_loader
def load_user(user_id):
for username, user in users.items():
if user['id'] == int(user_id):
return User(user['id'], username, user['password'])
return None
# Home page
@app.route('/')
def index():
return render_template('index.html')
# Register page
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if username in users:
flash('Username already exists', 'register-danger')
else:
user_id = len(users) + 1
users[username] = {'id': user_id, 'password': password}
flash('Registration successful!', 'login-success')
return redirect(url_for('login'))
return render_template('register.html')
# Login page
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if username in users and users[username]['password'] == password:
user = User(users[username]['id'], username, password)
login_user(user)
flash('Login successful!', 'login-success')
return redirect(url_for('index'))
else:
flash('Invalid username or password', 'login-danger')
return render_template('login.html')
# Logout
@app.route('/logout')
@login_required
def logout():
logout_user()
flash('You have been logged out.', 'login-info')
return redirect(url_for('login'))
# Send message
@app.route('/message', methods=['POST', 'GET'])
@login_required
def send_message():
if request.method == 'POST':
sender = current_user.username
recipient = request.form.get('recipient')
message = request.form.get('message')
if recipient in users:
messages[recipient].append({'from': sender, 'message': message})
flash('Message sent!', 'message-success')
else:
flash('Recipient not found', 'message-danger')
return redirect(url_for('index'))
return render_template('send_message.html')
@app.route('/send_file', methods=['GET', 'POST'])
@login_required
def send_file():
if request.method == 'POST':
recipient = request.form.get('recipient')
if recipient not in users:
flash('Recipient not found', 'file-danger')
return redirect(url_for('send_file'))
if 'file' not in request.files:
flash('No file part', 'file-danger')
return redirect(url_for('send_file'))
file = request.files['file']
if file.filename == '':
flash('No selected file', 'file-danger')
return redirect(url_for('send_file'))
file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
file.save(file_path)
messages[recipient].append({'from': 'send_file', 'message': f'File uploaded: {file.filename}'})
flash(f'File {file.filename} uploaded and sent to {recipient}', 'file-success')
return redirect(url_for('index'))
return render_template('send_file.html')
@app.route('/uploads/<filename>')
@login_required
def download_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{% block title %}Messaging App{% endblock %}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{{ url_for('index') }}">Messaging App</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="{{ url_for('index') }}">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('send_file') }}">Send Files</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('send_message') }}">Send Message</a>
</li>
</ul>
<ul class="navbar-nav ms-auto">
{% if current_user.is_authenticated %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ current_user.username }}
</a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="{{ url_for('logout') }}">Log Out</a></li>
</ul>
</li>
{% else %}
<li class="nav-item">
<a class="nav-link" href="{{ url_for('login') }}">Log In</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('register') }}">Register</a>
</li>
{% endif %}
</ul>
</div>
</nav>
<div class="container mt-4">
{% block content %}{% endblock %}
</div>
<!-- Bootstrap JS Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</body>
</html>
{% extends 'base.html' %}
{% from "macros.html" import render_flash_messages %}
{% block title %}Home - Messaging App{% endblock %}
{% block content %}
<div class="container">
<h1>Welcome to the Messaging App</h1>
<p class="lead">A simple app to send messages and share files.</p>
{{ render_flash_messages('login-') }}
</div>
{% endblock %}
{% extends 'base.html' %}
{% from "macros.html" import render_flash_messages %}
{% block title %}Login - Messaging App{% endblock %}
{% block content %}
<div class="container mt-5">
{{ render_flash_messages('login-') }}
<div class="row justify-content-center">
<div class="col-md-6">
<h2 class="text-center mb-4">Login</h2>
<form action="{{ url_for('login') }}" method="post" class="p-4 border rounded shadow-sm">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" name="username" class="form-control" id="username" placeholder="Enter your username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" name="password" class="form-control" id="password" placeholder="Enter your password" required>
</div>
<button type="submit" class="btn btn-primary w-100">Login</button>
</form>
<div class="text-center mt-3">
<a href="{{ url_for('register') }}">Don't have an account? Register</a>
</div>
</div>
</div>
</div>
{% endblock %}
{# macros.html #}
{% macro render_flash_messages(category_prefix) %}
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
{% if category.startswith(category_prefix) %}
<div class="alert alert-{{ category.split('-')[1] }}">{{ message }}</div>
{% endif %}
{% endfor %}
{% endif %}
{% endwith %}
{% endmacro %}
{% extends 'base.html' %}
{% from "macros.html" import render_flash_messages %}
{% block title %}Register - Messaging App{% endblock %}
{% block content %}
<div class="container mt-5">
{{ render_flash_messages('register-') }}
<div class="row justify-content-center">
<div class="col-md-6">
<h2 class="text-center mb-4">Register</h2>
<form action="{{ url_for('register') }}" method="post" class="p-4 border rounded shadow-sm">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" name="username" class="form-control" id="username" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" name="password" class="form-control" id="password" required>
</div>
<button type="submit" class="btn btn-primary w-100">Register</button>
</form>
<div class="text-center mt-3">
<a href="{{ url_for('login') }}">Already have an account? Login</a>
</div>
</div>
</div>
</div>
{% endblock %}
{% extends 'base.html' %}
{% from "macros.html" import render_flash_messages %}
{% block title %}Home - Messaging App{% endblock %}
{% block content %}
<div class="container">
{{ render_flash_messages('file-') }}
<h2>Send a File</h2>
<form action="{{ url_for('send_file') }}" method="post" enctype="multipart/form-data" class="mb-4">
<div class="mb-3">
<label for="recipient" class="form-label">Recipient</label>
<input type="text" name="recipient" class="form-control" id="recipient" required>
</div>
<div class="mb-3">
<label for="file" class="form-label">Choose file</label>
<input type="file" name="file" class="form-control" id="file" required>
</div>
<button type="submit" class="btn btn-primary">Send File</button>
</form>
</div>
{% endblock %}
{% extends 'base.html' %}
{% from "macros.html" import render_flash_messages %}
{% block title %}Home - Messaging App{% endblock %}
{% block content %}
<div class="container">
{{ render_flash_messages('message-') }}
<h2>Send a Message</h2>
<form action="{{ url_for('send_message') }}" method="post" class="mb-4">
<div class="mb-3">
<label for="recipient" class="form-label">Recipient</label>
<input type="text" name="recipient" class="form-control" id="recipient" required>
</div>
<div class="mb-3">
<label for="message" class="form-label">Message</label>
<textarea name="message" class="form-control" id="message" rows="3" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Send Message</button>
</form>
</div>
{% endblock %}
#!/bin/bash
echo "You've been hacked!\n"
whoami
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- ./app/uploads:/app/uploads
#!/bin/bash
echo "You've been hacked!\n"
whoami
Flask==2.2.5
Werkzeug==2.2.3
flask-login
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment