Skip to content
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

Monitor Certificate Checker #77

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
Binary file removed .DS_Store
Binary file not shown.
31 changes: 30 additions & 1 deletion app/main/utils.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import socket
import ssl
import subprocess
import os
import traceback
import requests
from flask import current_app, render_template
from flask import app, current_app, render_template
from app.models import Posts, MeetingNotes, Monitor, News, EventPosts, Events, Users, Documents
from app import db, mail
from datetime import datetime
from sqlalchemy.exc import SQLAlchemyError
from app.constants import file_types
from flask_mail import Message
import datetime



class VirusDetectedException(Exception):
Expand Down Expand Up @@ -462,6 +466,31 @@ def send_website_down_email(id,
msg.html = email
mail.send(msg)

def get_certificate_expiry_date_time(url):
# Use requests to get the certificate
with requests.get(url, stream=True) as response:
cert = response.raw.connection.sock.getpeercert()
exp_date_text = cert['notAfter']
# Parse the date with timezone information
expiry_date = datetime.datetime.strptime(exp_date_text, '%b %d %H:%M:%S %Y %Z')
# Assuming the certificate's time zone is UTC
expiry_date = expiry_date.replace(tzinfo=datetime.timezone.utc)
return expiry_date

def is_certificate_expired(url):
try:
expiry_date = get_certificate_expiry_date_time(url)
# Get the current time in UTC
current_date = datetime.datetime.now(datetime.timezone.utc)
time_remaining = expiry_date - current_date
if time_remaining.days < 0:
return True, "Certificate has expired."
elif time_remaining.days < 7:
return False, f"Certificate is expiring soon: {time_remaining.days} days remaining."
else:
return False, f"Certificate is valid: {time_remaining.days} days remaining."
except Exception as e:
return True, f"Error checking certificate: {e}"

def ping_website(monitor_info):
"""
Expand Down
9 changes: 6 additions & 3 deletions app/main/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from flask import render_template, redirect, url_for, session, request as flask_request, jsonify, current_app, flash, send_file, send_from_directory
import socket
import ssl
from flask import app, render_template, redirect, url_for, session, request as flask_request, jsonify, current_app, flash, send_file, send_from_directory
from flask_login import login_required, current_user
from app.models import Users, Posts, EventPosts, Documents, Monitor
from . import main
Expand All @@ -10,7 +12,7 @@
get_rooms_by_division,
create_document,
allowed_file,
VirusDetectedException,
VirusDetectedException, is_certificate_expired,
scan_file,
process_documents_search,
process_posts_search,
Expand All @@ -37,6 +39,7 @@ def index():
Queries for the next 4 events from today forward to display in the Calendar section
:return: HTML template for home page
"""

posts = Posts.query.filter_by(deleted=False).order_by(Posts.date_created.desc()).limit(20).all()
events = EventPosts.query.filter(Posts.deleted == False, EventPosts.event_date >= datetime.utcnow()).order_by(
EventPosts.event_date.asc()).limit(4).all()
Expand Down Expand Up @@ -856,4 +859,4 @@ def monitor():
websites = Monitor.query.order_by(Monitor.id.asc()).all()

return render_template('monitor.html', websites=websites,
site_refresh_rate=current_app.config['FRONTEND_REFRESH_RATE'])
site_refresh_rate=current_app.config['FRONTEND_REFRESH_RATE'])
1 change: 1 addition & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,3 +667,4 @@ class Monitor(db.Model):
last_success_timestamp = db.Column(db.DateTime)
response_header = db.Column(db.String)
use_ssl = db.Column(db.Boolean)
expiration_date = db.Column(db.Date)
9 changes: 9 additions & 0 deletions app/static/js/monitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ function WebsiteMonitorFunction () {
$('#website-' + websiteID + '-check').show();
$('#website-' + websiteID + '-warning').hide();
$('#website-' + websiteID + '-x').hide();


} else {
tableRow.removeClass('warning');
tableRow.removeClass('success');
Expand All @@ -35,7 +37,14 @@ function WebsiteMonitorFunction () {
$('#website-' + websiteID + '-time-2').html(data['most_recent_success']);
$('#website-' + websiteID + '-status-code').html(data['status_code']);
$('#modalBody-' + websiteID).html(data['reason']);

if (data['is_expired']) {
$('#website-' + websiteID + '-expiration-status').html('Expired');
} else {
$('#website-' + websiteID + '-expiration-status').html('Valid');
}
},

error: function (data) {
tableRow.removeClass('danger');
tableRow.removeClass('success');
Expand Down
8 changes: 8 additions & 0 deletions app/templates/email/monitor_email_alert.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,13 @@
<td class="monitor-email-data"><strong>Use SSL?</strong></td>
<td>{{ use_ssl }}</td>
</tr>
<tr>
<td class="monitor-email-data"><strong>Expiration Date</strong></td>
<td>{{ expiration_date }}</td>
</tr>
<tr>
<td class="monitor-email-data"><strong>Certificate Expired?</strong></td>
<td>{{ 'Yes' if is_expired else 'No' }}</td>

</table>
{% endblock %}
5 changes: 5 additions & 0 deletions app/templates/monitor.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ <h1 class="breadcrumb-header">Website Monitor</h1>
<th>Current Timestamp</th>
<th>Most Recent Success</th>
<th>Status Code</th>
<th>Certificate Expired</th>
</tr>
</thead>
<tbody>
Expand Down Expand Up @@ -66,6 +67,10 @@ <h3 class="website-name">
<td>
<p id="website-{{ website.id }}-status-code" class="status"></p>
</td>

<td>
<p id="website-{{ website.id }}-expiration-status"></p>
</td>
</tr>

{% endfor %}
Expand Down
60 changes: 51 additions & 9 deletions intranet.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#!/usr/bin/env python
from datetime import datetime
import os
from flask_migrate import Migrate
from flask.cli import main
import requests

from app import create_app, db
from app.models import Documents, EventPosts, Events, MeetingNotes, Monitor, News, Posts, Roles, Users
Expand Down Expand Up @@ -81,13 +83,53 @@ def ping():
ping_website(monitor)


@app.cli.command()
def test():
"""Run the unit tests."""
import unittest
tests = unittest.TestLoader().discover('tests')
unittest.TextTestRunner(verbosity=2).run(tests)


if __name__ == '__main__':
main()
@app.cli.command('check_certificate')
def check_certificate():
monitors = Monitor.query.all()

for monitor in monitors:
print(f"Checking URL: {monitor.url}")
print()

try:
with requests.get(monitor.url, stream=True) as response:
# Check if the response was successful
if response.status_code == 200:
cert = response.raw.connection.sock.getpeercert()

if cert: # Ensure cert is not None
expiration_date_str = cert['notAfter']
print(f"Certificate found. Expiration Date: {expiration_date_str}")
print()

# Convert expiration date string into a datetime object
expiration_date = datetime.strptime(expiration_date_str, "%b %d %H:%M:%S %Y %Z")
monitor.expiration_date = expiration_date.date()
print(f"Parsed expiration date: {expiration_date}")
print()

# Determine if the certificate is expired
today = datetime.now()
is_expired = expiration_date <= today
monitor.is_expired = is_expired
print(f"Set is_expired to: {is_expired} for {monitor.url}")
else:
print("No certificate found.")
monitor.expiration_date = None
print()
else:
print(f"Failed to retrieve {monitor.url}. Status code: {response.status_code}")
monitor.expiration_date = None
print()
except Exception as e:
print(f"Error while checking {monitor.url}: {e}")
monitor.is_expired = False
monitor.expiration_date = None
print("Set is_expired to False and expiration_date to None due to exception.")
print()

# Commit changes to the database
db.session.commit()
print(f"Committed: is_expired={monitor.is_expired}, expiration_date={monitor.expiration_date} for {monitor.url}")
print()
1 change: 1 addition & 0 deletions migrations/versions/044e18572cbe_added_monitor_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def upgrade():
sa.Column('last_success_timestamp', sa.DateTime(), nullable=True),
sa.Column('response_header', sa.String(), nullable=True),
sa.Column('use_ssl', sa.Boolean(), nullable=False),
sa.Column('expiration_date', sa.Date(), nullable=True),
sa.PrimaryKeyConstraint('id')
)
# ### end Alembic commands ###
Expand Down