|
@@ -1,16 +1,46 @@
|
|
|
import datetime as datetime
|
|
|
+import configparser as configparser
|
|
|
+import os
|
|
|
+from urllib.parse import urlparse
|
|
|
+import webbrowser
|
|
|
from emailtool.emailer import Emailer
|
|
|
-from flask import Flask, render_template, request, redirect, url_for
|
|
|
+from flask import Flask, render_template, request, redirect, url_for, jsonify, session
|
|
|
+from flask_httpauth import HTTPBasicAuth
|
|
|
import configparser
|
|
|
from gevent.pywsgi import WSGIServer
|
|
|
import socket
|
|
|
import logging
|
|
|
+from peewee import Model, CharField, TextField, DateTimeField, SqliteDatabase, BooleanField
|
|
|
+import hashlib
|
|
|
+
|
|
|
+db_name = 'users.db'
|
|
|
+db = SqliteDatabase(db_name)
|
|
|
+
|
|
|
+
|
|
|
+class User(Model):
|
|
|
+ username = CharField()
|
|
|
+ password = CharField()
|
|
|
+ logged_in = BooleanField(default=False)
|
|
|
+
|
|
|
+ class Meta:
|
|
|
+ database = db
|
|
|
+
|
|
|
+
|
|
|
+class IlsUser(Model):
|
|
|
+ username = CharField()
|
|
|
+ email = CharField()
|
|
|
+ reset_datetime = DateTimeField(default=datetime.datetime.now)
|
|
|
+
|
|
|
+ class Meta:
|
|
|
+ database = db
|
|
|
+
|
|
|
|
|
|
config = configparser.ConfigParser()
|
|
|
config.read('settings.ini')
|
|
|
application_settings = config['application']
|
|
|
smtp_settings = config['smtp']
|
|
|
http_settings = config['http']
|
|
|
+domain_settings = config['domain']
|
|
|
|
|
|
log = logging.getLogger('werkzeug')
|
|
|
log.setLevel(logging.INFO)
|
|
@@ -34,19 +64,12 @@ def send_email(to, subject, body):
|
|
|
emailer.send_email(to, subject, body)
|
|
|
|
|
|
|
|
|
-app = Flask(__name__)
|
|
|
-
|
|
|
-
|
|
|
-# Create a route for the home page
|
|
|
-@app.route('/')
|
|
|
-def index():
|
|
|
- # send_email('aday@twinfallspubliclibrary.org', 'TEST', 'This is a test email')
|
|
|
-
|
|
|
- return render_template('index.html')
|
|
|
+# Encrypt the password with SHA256
|
|
|
+def encrypt_password(password):
|
|
|
+ hash = hashlib.sha256(password.encode('utf-8')).hexdigest()
|
|
|
+ return hash
|
|
|
|
|
|
|
|
|
-# on exit of the program make sure the http server is stopped
|
|
|
-#@app.teardown_appcontext
|
|
|
def shutdown_session(exception=None):
|
|
|
print('Stopping HTTP Service...')
|
|
|
http_server.stop()
|
|
@@ -62,6 +85,156 @@ def get_ip_address():
|
|
|
return socket.gethostbyname(socket.gethostname())
|
|
|
|
|
|
|
|
|
+# Method to check if a URL is valid
|
|
|
+def is_valid_url(url):
|
|
|
+ try:
|
|
|
+ result = urlparse(url)
|
|
|
+ return all([result.scheme, result.netloc])
|
|
|
+ except:
|
|
|
+ return False
|
|
|
+
|
|
|
+def requires_auth():
|
|
|
+ print('Checking for session...')
|
|
|
+ if 'username' in session:
|
|
|
+ print('Username in session')
|
|
|
+ username = session['username']
|
|
|
+ user = User.get(User.username == username)
|
|
|
+ if user.logged_in is True:
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ print('1')
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ print('2')
|
|
|
+ return False
|
|
|
+
|
|
|
+
|
|
|
+# Check for DB tables and create if they don't exist
|
|
|
+if db.table_exists('user') is False:
|
|
|
+ db.create_tables([User, IlsUser])
|
|
|
+ User.create(username='admin', password=encrypt_password('admin'))
|
|
|
+
|
|
|
+if db.table_exists('ilsuser') is False:
|
|
|
+ db.create_tables([IlsUser])
|
|
|
+
|
|
|
+db.close()
|
|
|
+
|
|
|
+app = Flask(__name__)
|
|
|
+app.secret_key = 'super secret key'
|
|
|
+
|
|
|
+@app.before_request
|
|
|
+def before_request():
|
|
|
+ db.connect()
|
|
|
+
|
|
|
+
|
|
|
+@app.after_request
|
|
|
+def after_request(response):
|
|
|
+ db.close()
|
|
|
+ return response
|
|
|
+
|
|
|
+
|
|
|
+# Create a route for the home page
|
|
|
+@app.route('/', methods=['GET', 'POST'])
|
|
|
+def index():
|
|
|
+ # send_email('aday@twinfallspubliclibrary.org', 'TEST', 'This is a test email')
|
|
|
+ error = None
|
|
|
+ reset = False
|
|
|
+ reset_url = is_valid_url(domain_settings['reset_url'])
|
|
|
+ if reset_url is False:
|
|
|
+ error = 'Invalid Reset URL. Please contact your system administrator.'
|
|
|
+
|
|
|
+ if request.method == 'POST':
|
|
|
+ print('POST')
|
|
|
+ username = request.form.get('username')
|
|
|
+
|
|
|
+ # Check for the username in the DB
|
|
|
+ try:
|
|
|
+ user = IlsUser.filter(IlsUser.username == username).first()
|
|
|
+ except Exception as e:
|
|
|
+ print(e)
|
|
|
+ user = None
|
|
|
+
|
|
|
+ if user:
|
|
|
+ # Reset login datetime
|
|
|
+ user.reset_datetime = datetime.datetime.now()
|
|
|
+ user.save()
|
|
|
+ print(reset_url)
|
|
|
+ # Open the reset URL in a new tab if the URL is valid
|
|
|
+ if reset_url is not False:
|
|
|
+ webbrowser.open_new_tab(reset_url)
|
|
|
+ # Set reset to True to pass back to the view to display the correct content back to the user.
|
|
|
+ reset = True
|
|
|
+
|
|
|
+ print(reset_url)
|
|
|
+ context = {
|
|
|
+ 'domain': domain_settings['name'],
|
|
|
+ 'error': error,
|
|
|
+ 'reset': reset,
|
|
|
+ 'reset_url:': reset_url,
|
|
|
+ }
|
|
|
+ return render_template('index.html', context=context)
|
|
|
+
|
|
|
+
|
|
|
+# Create a route for admin page
|
|
|
+@app.route('/admin')
|
|
|
+def admin():
|
|
|
+ # Check to see if user is logged in
|
|
|
+ if not requires_auth():
|
|
|
+ return redirect(url_for('login'))
|
|
|
+
|
|
|
+ return render_template('admin.html')
|
|
|
+
|
|
|
+
|
|
|
+@app.route('/logout')
|
|
|
+def logout():
|
|
|
+ if 'username' in session:
|
|
|
+ username = session['username']
|
|
|
+ user = User.get(User.username == username)
|
|
|
+ user.logged_in = False
|
|
|
+ user.save()
|
|
|
+ session.pop('username', None)
|
|
|
+ return redirect(url_for('login'))
|
|
|
+
|
|
|
+
|
|
|
+@app.route('/login', methods=['GET', 'POST'])
|
|
|
+def login():
|
|
|
+ if request.method == 'POST':
|
|
|
+ username = request.form.get('username')
|
|
|
+ password = encrypt_password(request.form.get('password'))
|
|
|
+
|
|
|
+ try:
|
|
|
+ user = User.filter(User.username == username and User.password == password).first()
|
|
|
+ except Exception as e:
|
|
|
+ print(e)
|
|
|
+ user = None
|
|
|
+ session.pop('username', None)
|
|
|
+
|
|
|
+ if user:
|
|
|
+ # Login user
|
|
|
+ session['username'] = request.form.get('username')
|
|
|
+ user.logged_in = True
|
|
|
+ user.save()
|
|
|
+
|
|
|
+ return redirect(url_for('admin'))
|
|
|
+ else:
|
|
|
+ error = 'Invalid Credentials. Please try again.'
|
|
|
+
|
|
|
+ context = {
|
|
|
+ 'error': error
|
|
|
+ }
|
|
|
+ return render_template('login.html', context=context)
|
|
|
+
|
|
|
+ context = {
|
|
|
+
|
|
|
+ }
|
|
|
+ return render_template('login.html', context=context)
|
|
|
+
|
|
|
+
|
|
|
+# on exit of the program make sure the http server is stopped
|
|
|
+#@app.teardown_appcontext
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
if __name__ == "__main__":
|
|
|
print("------------------------- Start up -----------------------------")
|
|
|
print("Starting HTTP Service on port %s..." % http_settings['port'])
|