Skip to content

Features/firewall #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ A Docker image has not been created for this project because it requires access
- Check the current firewall status to ensure security.
- A dedicated website monitoring page for tracking uptime and performance.
- Track and save total network data sent/received in the database for data usage monitoring.
- Improve website monitor, save data in database with timestamp to show the history of the website.

## Learnings 📖

Expand Down
25 changes: 2 additions & 23 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,12 @@
import os
import time
import datetime
import threading
from src.config import app, db
from src.config import app
from src import routes
from src.utils import get_system_info_for_db
from src.models import SystemInformation, ApplicationGeneralSettings
from sqlalchemy.exc import SQLAlchemyError
from src.logger import logger
from src.thread_process import monitor_settings, start_website_monitoring

def register_routes():
app.register_blueprint(routes.dashboard_bp)
app.register_blueprint(routes.settings_bp)
app.register_blueprint(routes.system_health_bp)
app.register_blueprint(routes.cpu_info_bp)
app.register_blueprint(routes.disk_info_bp)
app.register_blueprint(routes.memory_info_bp)
app.register_blueprint(routes.network_info_bp)
app.register_blueprint(routes.speedtest_bp)
app.register_blueprint(routes.process_bp)


if __name__ == "__main__":
register_routes()

# background thread to monitor system settings changes
# monitor_settings() # Starts monitoring for system logging changes
start_website_monitoring() # Starts pinging active websites
# start_website_monitoring() # Starts pinging active websites

# Run the Flask application
app.run(host="0.0.0.0", port=5000, debug=True)
2 changes: 1 addition & 1 deletion setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fi

# function to check for required dependencies
check_dependencies() {
local dependencies=(git curl wget unzip figlet locust)
local dependencies=(git curl wget unzip figlet locust iptables)
for cmd in "${dependencies[@]}"; do
if ! command -v $cmd &> /dev/null; then
log "CRITICAL" "$cmd is required but not installed. Please install it and try again.\nsudo apt install $cmd"
Expand Down
5 changes: 3 additions & 2 deletions src/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
def server_start():
logger.info("Server started")



# 403 forbidden
@app.errorhandler(403)
def forbidden(e):
"""
This function is called when a user tries to access a resource that they are not allowed to access.
"""
return render_template("error/403.html"), 403

# not found page
Expand Down
30 changes: 30 additions & 0 deletions src/docs/future_plans.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
For a deep analysis of the **SystemGuard** project with the Firewall feature, here are some suggestions to improve:

1. **Code Structure**:
- **Modularize the code**: Split large files into smaller, reusable modules (e.g., separate routes, services, and database logic).
- **Error Handling**: Improve exception handling, especially for critical functions like firewall rule changes and system monitoring.
- **Logging**: Implement structured logging for better debugging and system monitoring.

2. **Security**:
- **Sanitize Inputs**: Ensure the inputs (such as firewall rules, ports) are validated and sanitized.
- **Sudo Password Management**: Implement a time-based reset for `sudo` sessions.
- **Rate Limiting**: Implement rate-limiting for operations that can modify system states, such as enabling/disabling ports.

3. **User Interface**:
- **User Feedback**: Provide better feedback when operations succeed/fail, such as modal windows or alerts.
- **Responsive Design**: Ensure all pages are fully responsive, especially for smaller devices.
- **Modern CSS Framework**: Consider leveraging a CSS framework like Bootstrap or Tailwind for faster styling and grid layouts.

4. **Documentation**:
- **Detailed Setup Instructions**: Improve the README with more detailed setup instructions, especially for the firewall feature.
- **Code Comments**: Add comments explaining complex sections, such as how firewall rules are applied.

5. **Database Optimization**:
- **Indexed Fields**: Add indexing to frequently queried fields to improve database performance.
- **Optimize Queries**: Review database queries and optimize those that may impact performance during heavy usage.

6. **Testing**:
- **Unit Tests**: Add unit and integration tests for each core feature, particularly the firewall management and monitoring features.
- **CI/CD Pipeline**: Set up continuous integration to run tests automatically when new changes are made.

These improvements will enhance maintainability, security, performance, and user experience.
3 changes: 1 addition & 2 deletions src/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@


# Create a logs directory if it doesn't exist
if not os.path.exists('logs'):
os.makedirs('logs')
os.makedirs('logs', exist_ok=True)

# Log Formatter with datetime, log level, and message
formatter = logging.Formatter(
Expand Down
8 changes: 4 additions & 4 deletions src/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from src.models.dashboard_netowrk import DashboardNetworkSettings
from src.models.user_dashboard_settings import UserDashboardSettings
from src.models.page_toggle_settings import PageToggleSettings
from src.models.application_general_settings import ApplicationGeneralSettings
from src.models.application_general_settings import GeneralSettings
from src.models.smtp_configuration import SMTPSettings
from src.models.network_speed_test_result import NetworkSpeedTestResult
from src.models.system_information import SystemInformation
Expand Down Expand Up @@ -52,9 +52,9 @@
db.session.commit()

# Initialize default user_dashboard_settings
general_settings = ApplicationGeneralSettings.query.first()
general_settings = GeneralSettings.query.first()
if not general_settings:
db.session.add(ApplicationGeneralSettings())
db.session.add(GeneralSettings())
db.session.commit()


Expand All @@ -63,7 +63,7 @@
def inject_settings():
if current_user.is_anonymous:
return dict(user_dashboard_settings=None, card_settings=None, page_toggles_settings=None, general_settings=None)
general_settings = ApplicationGeneralSettings.query.first()
general_settings = GeneralSettings.query.first()
card_settings = UserCardSettings.query.filter_by(user_id=current_user.id).first()
user_dashboard_settings = UserDashboardSettings.query.filter_by(
user_id=current_user.id
Expand Down
12 changes: 11 additions & 1 deletion src/models/application_general_settings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
from src.config import db

class ApplicationGeneralSettings(db.Model):
class GeneralSettings(db.Model):
"""
General settings model for the application
---
Properties:
- id: int
- enable_alerts: if email alerts are enabled
- timezone: the timezone of the system
- enable_cache: if caching is enabled
- is_logging_system_info: if system info is logged
"""
__tablename__ = 'general_settings'

id = db.Column(db.Integer, primary_key=True)
Expand Down
11 changes: 11 additions & 0 deletions src/models/dashboard_netowrk.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@


class DashboardNetworkSettings(db.Model):
"""
Dashboard network settings model for the application
---
Properties:
- id: int
- name: the name of the dashboard
- description: the description of the dashboard
- ip_address: the IP address of the dashboard
- port: the port of the dashboard
- link: the link to the dashboard
"""
__tablename__ = "DashboardGroup"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), unique=True, nullable=False)
Expand Down
19 changes: 18 additions & 1 deletion src/models/monitored_website.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,32 @@


class MonitoredWebsite(db.Model):
"""
Monitored website model for the application
---
Properties:
- id: int
- name: the name of the website
- ping_interval: the interval in seconds to ping the website
- is_ping_active: if the website should be pinged
- email_address: the email address to send alerts to
- ping_status: the status of the website
- ping_status_code: the status code of the website
- last_ping_time: the last time the website was pinged
- email_alerts_enabled: if email alerts are enabled
"""
__tablename__ = 'monitored_websites'

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255), nullable=False)
ping_interval = db.Column(db.Integer, nullable=False) # in seconds
is_ping_active = db.Column(db.Boolean, default=True) # True: ping the site, False: do not ping
email_alerts_enabled = db.Column(db.Boolean, default=False)
email_address = db.Column(db.String(255), nullable=True)
ping_status = db.Column(db.String(50), nullable=True) # Stores 'UP' or 'DOWN'
ping_status_code = db.Column(db.Integer, nullable=True)
last_ping_time = db.Column(db.DateTime, nullable=True)
email_alerts_enabled = db.Column(db.Boolean, default=False)


def __repr__(self):
return f'<Website {self.name} - Ping Every {self.ping_interval}s>'
10 changes: 10 additions & 0 deletions src/models/network_speed_test_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
from src.config import db

class NetworkSpeedTestResult(db.Model):
"""
Network speed test result model for the application
---
Properties:
- id: int
- download_speed: the download speed
- upload_speed: the upload speed
- ping: the ping
- timestamp: the timestamp of the speed test
"""
__tablename__ = "network_speed_test_result"
id = db.Column(db.Integer, primary_key=True)
download_speed = db.Column(db.String(50))
Expand Down
13 changes: 13 additions & 0 deletions src/models/page_toggle_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,19 @@
from src.config import db

class PageToggleSettings(db.Model):
"""
Page toggle settings model for the application
---
Properties:
- id: int
- user_id: the user id
- is_cpu_info_enabled: if CPU info is enabled
- is_memory_info_enabled: if memory info is enabled
- is_disk_info_enabled: if disk info is enabled
- is_network_info_enabled: if network info is enabled
- is_process_info_enabled: if process info is enabled
- is_dashboard_network_enabled: if the dashboard network is enabled
"""
__tablename__ = 'feature_toggle_settings'

id = db.Column(db.Integer, primary_key=True)
Expand Down
11 changes: 11 additions & 0 deletions src/models/smtp_configuration.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
from src.config import db

class SMTPSettings(db.Model):
"""
SMTP settings model for the application
---
Properties:
- id: int
- username: the username for the SMTP server
- password: the password for the SMTP server
- smtp_server: the SMTP server
- smtp_port: the SMTP port
- email_from: the email address to send from
"""
__tablename__ = "smtp_settings"
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(150), unique=True, nullable=False)
Expand Down
12 changes: 12 additions & 0 deletions src/models/system_information.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@


class SystemInformation(db.Model):
"""
System information model for the application
---
Properties:
- id: int
- cpu_percent: the CPU percentage
- memory_percent: the memory percentage
- battery_percent: the battery percentage
- network_sent: the network sent
- network_received: the network received
- timestamp: the timestamp of the system information
"""
__tablename__ = "system_information"
id = db.Column(db.Integer, primary_key=True)
cpu_percent = db.Column(db.Float, nullable=False)
Expand Down
19 changes: 19 additions & 0 deletions src/models/user_card_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@


class UserCardSettings(db.Model):
"""
User card settings model for the application
---
Properties:
- id: int
- user_id: the user id
- is_user_card_enabled: if the user card is enabled
- is_server_card_enabled: if the server card is enabled
- is_battery_card_enabled: if the battery card is enabled
- is_cpu_core_card_enabled: if the CPU core card is enabled
- is_cpu_usage_card_enabled: if the CPU usage card is enabled
- is_cpu_temp_card_enabled: if the CPU temp card is enabled
- is_dashboard_memory_card_enabled: if the dashboard memory card is enabled
- is_memory_usage_card_enabled: if the memory usage card is enabled
- is_disk_usage_card_enabled: if the disk usage card is enabled
- is_system_uptime_card_enabled: if the system uptime card is enabled
- is_network_statistic_card_enabled: if the network statistic card is enabled
- is_speedtest_enabled: if speedtests are enabled
"""
__tablename__ = "user_card_settings"

id = db.Column(db.Integer, primary_key=True)
Expand Down
13 changes: 12 additions & 1 deletion src/models/user_dashboard_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@
from src.config import db

class UserDashboardSettings(db.Model):
"""
User dashboard settings model for the application
---
Properties:
- id: int
- user_id: the user id
- speedtest_cooldown: the cooldown for speedtests
- number_of_speedtests: the number of speedtests
- refresh_interval: the refresh interval for the dashboard
"""
__tablename__ = 'user_dashboard_settings'

id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
speedtest_cooldown = db.Column(db.Integer, default=60)
number_of_speedtests = db.Column(db.Integer, default=1)
refresh_interval = db.Column(db.Integer, default=0)

bytes_to_megabytes = db.Column(db.Integer, default=1000)

12 changes: 12 additions & 0 deletions src/models/user_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
from src.config import db

class UserProfile(db.Model, UserMixin):
"""
User profile model for the application
---
Properties:
- id: int
- username: the username
- email: the email
- password: the password
- user_level: the user level
- receive_email_alerts: if the user receives email alerts
- profession: the profession of the user
"""
__tablename__ = 'users'

id = db.Column(db.Integer, primary_key=True)
Expand Down
3 changes: 2 additions & 1 deletion src/routes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
from src.routes.smtp_email_config import smtp_email_config_bp
from src.routes.user import user_bp
from src.routes.graphs import graphs_bp
from src.routes.ping import ping_bp
from src.routes.ping import ping_bp
from src.routes.firewall import firewall_bp
Loading