Development
This commit is contained in:
parent
f5722f3c7b
commit
d60bf15ce4
15 changed files with 367 additions and 285 deletions
|
|
@ -1,84 +1,86 @@
|
|||
from pathlib import Path
|
||||
from flask import Blueprint, request, session, redirect, flash
|
||||
import json, os, secrets
|
||||
from datetime import datetime, timezone, timedelta
|
||||
import time, secrets
|
||||
import auth
|
||||
import config_utils
|
||||
import settings
|
||||
|
||||
_PAGE = Path(__file__).parent.name
|
||||
|
||||
bp = Blueprint(_PAGE, __name__)
|
||||
|
||||
|
||||
|
||||
def _load_accounts():
|
||||
try:
|
||||
with open(config_utils.ACCOUNTS_FILE) as f:
|
||||
return json.load(f)
|
||||
except Exception:
|
||||
return {'accounts': []}
|
||||
|
||||
def _save_accounts(data):
|
||||
with open(config_utils.ACCOUNTS_FILE, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
|
||||
@bp.route('/action/accountverifyemail/email_verify', methods=['POST'])
|
||||
@auth.require_level('nothing')
|
||||
def email_verify():
|
||||
# Abort if already logged in
|
||||
if session.get('access_level', 'nothing') != 'nothing':
|
||||
return redirect('/overview')
|
||||
|
||||
pending = session.get('pending_create_account')
|
||||
|
||||
if not pending:
|
||||
pending_email = session.get('pending_verify_email', '').lower()
|
||||
if not pending_email:
|
||||
flash('No pending account creation found. Please start over.', 'error')
|
||||
return redirect('/accountcreate')
|
||||
|
||||
expires = datetime.fromisoformat(pending['expires'])
|
||||
if datetime.now(tz=timezone.utc) > expires:
|
||||
session.pop('pending_create_account', None)
|
||||
try:
|
||||
con = config_utils.open_accounts_db()
|
||||
row = con.execute(
|
||||
'SELECT * FROM pending_verifications WHERE email=?', (pending_email,)
|
||||
).fetchone()
|
||||
con.close()
|
||||
except Exception:
|
||||
row = None
|
||||
|
||||
if not row:
|
||||
flash('No pending account creation found. Please start over.', 'error')
|
||||
return redirect('/accountcreate')
|
||||
|
||||
if int(time.time()) > row['expires_ts']:
|
||||
try:
|
||||
con = config_utils.open_accounts_db()
|
||||
con.execute('DELETE FROM pending_verifications WHERE email=?', (pending_email,))
|
||||
con.commit()
|
||||
con.close()
|
||||
except Exception:
|
||||
pass
|
||||
session.pop('pending_verify_email', None)
|
||||
flash('Verification code has expired. Please start over.', 'error')
|
||||
return redirect('/accountcreate')
|
||||
|
||||
submitted = request.form.get('code', '').strip()
|
||||
if submitted != pending['code']:
|
||||
if submitted != row['code']:
|
||||
flash('Incorrect verification code.', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
||||
data = _load_accounts()
|
||||
accounts = data.get('accounts', [])
|
||||
account = next(
|
||||
(a for a in accounts if a.get('email_address', '').lower() == pending['email'].lower()),
|
||||
None
|
||||
)
|
||||
|
||||
account = config_utils.get_account_by_email(pending_email)
|
||||
if account is None:
|
||||
session.pop('pending_create_account', None)
|
||||
session.pop('pending_verify_email', None)
|
||||
flash('Account no longer exists. Contact your manager.', 'error')
|
||||
return redirect('/accountcreate')
|
||||
|
||||
if account.get('hashed_password'):
|
||||
session.pop('pending_create_account', None)
|
||||
session.pop('pending_verify_email', None)
|
||||
flash('This account is already set up. Please log in.', 'error')
|
||||
return redirect('/accountlogin')
|
||||
|
||||
now = datetime.now(tz=timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||
account['hashed_password'] = pending['hashed_password']
|
||||
account['timezone'] = pending['timezone']
|
||||
if not account.get('account_created_utc'):
|
||||
account['account_created_utc'] = now
|
||||
if not account.get('account_created_by'):
|
||||
account['account_created_by'] = 'self'
|
||||
now = int(time.time())
|
||||
try:
|
||||
con = config_utils.open_accounts_db()
|
||||
con.execute(
|
||||
'UPDATE accounts SET hashed_password=?, created_ts=?, created_by=? WHERE account_id=?',
|
||||
(row['hashed_password'], now, 'self', account['account_id'])
|
||||
)
|
||||
con.execute('DELETE FROM pending_verifications WHERE email=?', (pending_email,))
|
||||
con.commit()
|
||||
con.close()
|
||||
except Exception as exc:
|
||||
flash(f'Could not complete account setup: {exc}', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
||||
_save_accounts(data)
|
||||
session.pop('pending_create_account', None)
|
||||
|
||||
session['email_address'] = account['email_address']
|
||||
session['access_level'] = account.get('access_level', 'viewer')
|
||||
session['timezone'] = pending['timezone']
|
||||
session.permanent = True
|
||||
session.pop('pending_verify_email', None)
|
||||
session['account_id'] = account['account_id']
|
||||
session['tz_offset_seconds'] = int(row['tz_offset_seconds'])
|
||||
session['apply_changes_immediately'] = False
|
||||
session.permanent = True
|
||||
|
||||
return redirect('/overview')
|
||||
|
||||
|
|
@ -86,30 +88,35 @@ def email_verify():
|
|||
@bp.route('/action/accountverifyemail/email_resend')
|
||||
@auth.require_level('nothing')
|
||||
def email_resend():
|
||||
# Abort if already logged in
|
||||
if session.get('access_level', 'nothing') != 'nothing':
|
||||
return redirect('/overview')
|
||||
|
||||
from pages.accountcreate.action import _send_verification_email, CODE_TTL_MIN
|
||||
from pages.accountcreate.action import _send_verification_email, CODE_TTL_SECS
|
||||
|
||||
pending = session.get('pending_create_account')
|
||||
|
||||
if not pending:
|
||||
pending_email = session.get('pending_verify_email', '').lower()
|
||||
if not pending_email:
|
||||
flash('No pending account creation found. Please start over.', 'error')
|
||||
return redirect('/accountcreate')
|
||||
|
||||
code = f'{secrets.randbelow(1000000):06d}'
|
||||
expires = (datetime.now(tz=timezone.utc) + timedelta(minutes=CODE_TTL_MIN)).isoformat()
|
||||
code = f'{secrets.randbelow(1000000):06d}'
|
||||
expires_ts = int(time.time()) + CODE_TTL_SECS
|
||||
|
||||
try:
|
||||
_send_verification_email(pending['email'], code)
|
||||
_send_verification_email(pending_email, code)
|
||||
except Exception as exc:
|
||||
flash(f'Could not resend verification email: {exc}', 'error')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
||||
pending['code'] = code
|
||||
pending['expires'] = expires
|
||||
session['pending_create_account'] = pending
|
||||
try:
|
||||
con = config_utils.open_accounts_db()
|
||||
con.execute(
|
||||
'UPDATE pending_verifications SET code=?, expires_ts=? WHERE email=?',
|
||||
(code, expires_ts, pending_email)
|
||||
)
|
||||
con.commit()
|
||||
con.close()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
flash('A new verification code has been sent.', 'success')
|
||||
return redirect(f'/{_PAGE}')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue