from flask import Blueprint, request, session, redirect, flash import json, bcrypt from auth import require_level import sanitize bp = Blueprint('action_log_in', __name__) DATA_DIR = '/data' def _load_accounts(): try: with open(f'{DATA_DIR}/authorized_accounts.json') as f: return json.load(f) except Exception: return {'accounts': []} @bp.route('/action/log_in', methods=['POST']) @require_level('nothing') def log_in(): # Abort if already logged in if session.get('access_level', 'nothing') != 'nothing': return redirect('/view/view_overview') email = sanitize.email(request.form.get('email', '')) password = request.form.get('password', '') if not email or not password: flash('Email address and password are required.', 'error') return redirect('/view/view_log_in') accounts = _load_accounts().get('accounts', []) account = next((a for a in accounts if a.get('email_address', '').lower() == email), None) if account is None: flash('Email address not recognised.', 'error') return redirect('/view/view_log_in') if not account.get('hashed_password'): flash('Account setup is not complete. Please use Create Account to set your password first.', 'error') return redirect('/view/view_log_in') stored_hash = account['hashed_password'].encode('utf-8') if not bcrypt.checkpw(password.encode('utf-8'), stored_hash): flash('Invalid email address or password.', 'error') return redirect('/view/view_log_in') session.clear() session['email_address'] = account['email_address'] session['access_level'] = account.get('access_level', 'viewer') session['timezone'] = account.get('timezone', '') session.permanent = True return redirect('/view/view_overview')