1
0

app.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. import datetime as datetime
  2. import configparser as configparser
  3. import os
  4. from urllib.parse import urlparse
  5. import webbrowser
  6. from emailtool.emailer import Emailer
  7. from flask import Flask, render_template, request, redirect, url_for, jsonify, session
  8. from flask_httpauth import HTTPBasicAuth
  9. import configparser
  10. from gevent.pywsgi import WSGIServer
  11. import socket
  12. import logging
  13. from peewee import Model, CharField, TextField, DateTimeField, SqliteDatabase, BooleanField
  14. import hashlib
  15. db_name = 'users.db'
  16. db = SqliteDatabase(db_name)
  17. class User(Model):
  18. username = CharField()
  19. password = CharField()
  20. logged_in = BooleanField(default=False)
  21. class Meta:
  22. database = db
  23. class IlsUser(Model):
  24. username = CharField()
  25. email = CharField()
  26. reset_datetime = DateTimeField(default=datetime.datetime.now)
  27. class Meta:
  28. database = db
  29. config = configparser.ConfigParser()
  30. config.read('settings.ini')
  31. application_settings = config['application']
  32. smtp_settings = config['smtp']
  33. http_settings = config['http']
  34. domain_settings = config['domain']
  35. log = logging.getLogger('werkzeug')
  36. log.setLevel(logging.INFO)
  37. if application_settings['debug'].lower() == 'true':
  38. debug = True
  39. else:
  40. debug = False
  41. def send_email(to, subject, body):
  42. # Get settings from smtp_settings
  43. host = smtp_settings['host']
  44. port = smtp_settings['port']
  45. username = smtp_settings['username']
  46. password = smtp_settings['password']
  47. # Create an instance of the Emailer class
  48. emailer = Emailer(host, port, username, password)
  49. # Call the send_email method
  50. emailer.send_email(to, subject, body)
  51. # Encrypt the password with SHA256
  52. def encrypt_password(password):
  53. hash = hashlib.sha256(password.encode('utf-8')).hexdigest()
  54. return hash
  55. def shutdown_session(exception=None):
  56. print('Stopping HTTP Service...')
  57. http_server.stop()
  58. # Get the systems hostname
  59. def get_hostname():
  60. return socket.gethostname()
  61. # Get systems IP address
  62. def get_ip_address():
  63. return socket.gethostbyname(socket.gethostname())
  64. # Method to check if a URL is valid
  65. def is_valid_url(url):
  66. try:
  67. result = urlparse(url)
  68. return all([result.scheme, result.netloc])
  69. except:
  70. return False
  71. def requires_auth():
  72. print('Checking for session...')
  73. if 'username' in session:
  74. print('Username in session')
  75. username = session['username']
  76. user = User.get(User.username == username)
  77. if user.logged_in is True:
  78. return True
  79. else:
  80. print('1')
  81. return False
  82. else:
  83. print('2')
  84. return False
  85. # Check for DB tables and create if they don't exist
  86. if db.table_exists('user') is False:
  87. db.create_tables([User, IlsUser])
  88. User.create(username='admin', password=encrypt_password('admin'))
  89. if db.table_exists('ilsuser') is False:
  90. db.create_tables([IlsUser])
  91. db.close()
  92. app = Flask(__name__)
  93. app.secret_key = 'super secret key'
  94. @app.before_request
  95. def before_request():
  96. db.connect()
  97. @app.after_request
  98. def after_request(response):
  99. db.close()
  100. return response
  101. # Create a route for the home page
  102. @app.route('/', methods=['GET', 'POST'])
  103. def index():
  104. # send_email('aday@twinfallspubliclibrary.org', 'TEST', 'This is a test email')
  105. error = None
  106. reset = False
  107. reset_url = is_valid_url(domain_settings['reset_url'])
  108. if reset_url is False:
  109. error = 'Invalid Reset URL. Please contact your system administrator.'
  110. if request.method == 'POST':
  111. print('POST')
  112. username = request.form.get('username')
  113. # Check for the username in the DB
  114. try:
  115. user = IlsUser.filter(IlsUser.username == username).first()
  116. except Exception as e:
  117. print(e)
  118. user = None
  119. if user:
  120. # Reset login datetime
  121. user.reset_datetime = datetime.datetime.now()
  122. user.save()
  123. print(reset_url)
  124. # Open the reset URL in a new tab if the URL is valid
  125. if reset_url is not False:
  126. webbrowser.open_new_tab(reset_url)
  127. # Set reset to True to pass back to the view to display the correct content back to the user.
  128. reset = True
  129. print(reset_url)
  130. context = {
  131. 'domain': domain_settings['name'],
  132. 'error': error,
  133. 'reset': reset,
  134. 'reset_url:': reset_url,
  135. }
  136. return render_template('index.html', context=context)
  137. # Create a route for admin page
  138. @app.route('/admin')
  139. def admin():
  140. # Check to see if user is logged in
  141. if not requires_auth():
  142. return redirect(url_for('login'))
  143. return render_template('admin.html')
  144. @app.route('/logout')
  145. def logout():
  146. if 'username' in session:
  147. username = session['username']
  148. user = User.get(User.username == username)
  149. user.logged_in = False
  150. user.save()
  151. session.pop('username', None)
  152. return redirect(url_for('login'))
  153. @app.route('/login', methods=['GET', 'POST'])
  154. def login():
  155. if request.method == 'POST':
  156. username = request.form.get('username')
  157. password = encrypt_password(request.form.get('password'))
  158. try:
  159. user = User.filter(User.username == username and User.password == password).first()
  160. except Exception as e:
  161. print(e)
  162. user = None
  163. session.pop('username', None)
  164. if user:
  165. # Login user
  166. session['username'] = request.form.get('username')
  167. user.logged_in = True
  168. user.save()
  169. return redirect(url_for('admin'))
  170. else:
  171. error = 'Invalid Credentials. Please try again.'
  172. context = {
  173. 'error': error
  174. }
  175. return render_template('login.html', context=context)
  176. context = {
  177. }
  178. return render_template('login.html', context=context)
  179. # on exit of the program make sure the http server is stopped
  180. #@app.teardown_appcontext
  181. if __name__ == "__main__":
  182. print("------------------------- Start up -----------------------------")
  183. print("Starting HTTP Service on port %s..." % http_settings['port'])
  184. if debug is True:
  185. print("Debug mode is enabled.")
  186. http_server = WSGIServer(('0.0.0.0', int(http_settings['port'])), app)
  187. else:
  188. http_server = WSGIServer(('0.0.0.0', int(http_settings['port'])), app, log=log, error_log=log)
  189. print("HTTP Service Started.")
  190. print("--------------------- Application Details ---------------------")
  191. print("Application started at %s" % datetime.datetime.now())
  192. print("System IP Address: %s" % get_ip_address())
  193. print("System Hostname: %s" % get_hostname())
  194. print("Access the Dashboard using a web browser using any of the following:")
  195. print("http://%s:%s or http://%s:%s" % (get_hostname(), http_settings['port'], get_ip_address(), http_settings['port']))
  196. print("---------------------------------------------------------------")
  197. print("To stop the application close this window.")
  198. print("---------------------------------------------------------------")
  199. http_server.serve_forever()