A simple web application that allows invitation based registration to a matrix instance
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.7 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. import logging
  2. import os
  3. import uuid
  4. from urllib.parse import urlparse, urljoin
  5. import flask
  6. from flask import Flask, redirect, render_template, request, g
  7. from flask_login import LoginManager, login_required, login_user, logout_user, UserMixin, \
  8. current_user
  9. from flask_wtf import CSRFProtect
  10. from db import get_db, get_registration_codes, add_registration_code, \
  11. expire_registration_code, delete_registration_code, get_registered_users
  12. from forms import RegistrationForm, LoginForm, RegistrationCodeForm, \
  13. ExpireRegistrationCodeForm
  14. csrf = CSRFProtect()
  15. login_manager = LoginManager()
  16. log = logging.getLogger(__name__)
  17. def init_db(flask_app):
  18. with flask_app.app_context():
  19. db = get_db()
  20. with flask_app.open_resource('schema.sql', mode='r') as f:
  21. db.cursor().executescript(f.read())
  22. log.info("Initialized DB")
  23. db.commit()
  24. def create_app():
  25. flask_app = Flask(__name__)
  26. flask_app.config.update(dict(
  27. ADMIN_TOKEN=os.getenv("ADMIN_TOKEN", uuid.uuid4().__str__()),
  28. SECRET_KEY=os.getenv("SECRET_KEY", "changeme"),
  29. WTF_CSRF_SECRET_KEY=os.getenv("CSRF_SECRET_KEY", "csrf_changeme")
  30. ))
  31. print("Admin Token: %s" % flask_app.config.get("ADMIN_TOKEN"))
  32. csrf.init_app(flask_app)
  33. login_manager.init_app(flask_app)
  34. login_manager.login_view = "admin_login"
  35. init_db(flask_app)
  36. return flask_app
  37. app = create_app()
  38. class User(UserMixin):
  39. username: str
  40. token: str
  41. authenticated: bool = False
  42. def __init__(self, username: str, token: str):
  43. self.username = username
  44. self.token = token
  45. def is_authenticated(self):
  46. return self.authenticated
  47. def get_id(self):
  48. return self.username
  49. def is_safe_url(target):
  50. ref_url = urlparse(request.host_url)
  51. test_url = urlparse(urljoin(request.host_url, target))
  52. return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc
  53. @login_manager.user_loader
  54. def load_user(user_id):
  55. if user_id == "admin":
  56. return User("admin", app.config.get("ADMIN_TOKEN"))
  57. else:
  58. return None
  59. @app.route('/')
  60. def index():
  61. return 'Hello World!'
  62. @app.route('/register', methods=('GET', 'POST'))
  63. def registration():
  64. form = RegistrationForm()
  65. if form.validate_on_submit():
  66. return redirect('/success')
  67. if 'registrationCode' in request.values:
  68. form.registration_code.data = request.values['registrationCode']
  69. return render_template('register.html', form=form)
  70. @app.route('/admin')
  71. @login_required
  72. def admin_index():
  73. context = {
  74. 'add_registration_code_form': RegistrationCodeForm(),
  75. 'registration_codes': get_registration_codes(),
  76. 'registered_users': get_registered_users()
  77. }
  78. return render_template('admin.html', **context)
  79. @app.route('/admin/add_registration_code', methods=['POST'])
  80. @login_required
  81. def admin_add_registration_code():
  82. form = RegistrationCodeForm()
  83. if form.validate_on_submit():
  84. expiration_time = form.expiration_time.data
  85. max_usages = form.max_usages.data
  86. add_registration_code(expiration_time, max_usages)
  87. redirect('/admin')
  88. return redirect('/admin')
  89. @app.route('/admin/expire_registration_code', methods=['POST'])
  90. @login_required
  91. def admin_expire_registration_code():
  92. form = ExpireRegistrationCodeForm()
  93. if form.validate_on_submit():
  94. if form.expire.data:
  95. expire_registration_code(form.registration_code.data)
  96. elif form.delete.data:
  97. delete_registration_code(form.registration_code.data)
  98. redirect('/admin')
  99. return redirect('/admin')
  100. @app.route('/admin/login', methods=('GET', 'POST'))
  101. def admin_login():
  102. form = LoginForm()
  103. tmp = current_user
  104. if form.validate_on_submit():
  105. user = load_user(form.username.data)
  106. if user is not None:
  107. if form.token.data == user.token:
  108. user.authenticated = True
  109. login_user(user)
  110. flask.flash('Logged in successfully.')
  111. next_loc = flask.request.args.get('next')
  112. if not is_safe_url(next_loc):
  113. return flask.abort(400)
  114. else:
  115. if next_loc is not None:
  116. return redirect(next_loc)
  117. else:
  118. return redirect('/admin')
  119. return render_template('login.html', form=form)
  120. @app.route("/admin/logout")
  121. @login_required
  122. def admin_logout():
  123. logout_user()
  124. flask.flash('Logged out successfully.')
  125. return redirect('/')
  126. @app.teardown_appcontext
  127. def close_connection(exception):
  128. db = getattr(g, '_database', None)
  129. if db is not None:
  130. db.close()
  131. if __name__ == '__main__':
  132. app.run()