feat: add option to log out users automatically after completing a purchase
This commit is contained in:
parent
1e561fd9cd
commit
d54aa2bc57
12 changed files with 158 additions and 21 deletions
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -1,5 +1,18 @@
|
||||||
# Matemat Changelog
|
# Matemat Changelog
|
||||||
|
|
||||||
|
<!-- BEGIN RELEASE v0.3.10 -->
|
||||||
|
## Version 0.3.10
|
||||||
|
|
||||||
|
Add option to log out users automatically after completing a purchase
|
||||||
|
|
||||||
|
### Changes
|
||||||
|
|
||||||
|
<!-- BEGIN CHANGES 0.3.10 -->
|
||||||
|
- Add option to log out users automatically after completing a purchase
|
||||||
|
<!-- END CHANGES 0.3.10 -->
|
||||||
|
|
||||||
|
<!-- END RELEASE v0.3.10 -->
|
||||||
|
|
||||||
<!-- BEGIN RELEASE v0.3.9 -->
|
<!-- BEGIN RELEASE v0.3.9 -->
|
||||||
## Version 0.3.9
|
## Version 0.3.9
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ class MatematDatabase(object):
|
||||||
users: List[User] = []
|
users: List[User] = []
|
||||||
with self.db.transaction(exclusive=False) as c:
|
with self.db.transaction(exclusive=False) as c:
|
||||||
for row in c.execute('''
|
for row in c.execute('''
|
||||||
SELECT user_id, username, email, is_admin, is_member, balance, receipt_pref
|
SELECT user_id, username, email, is_admin, is_member, balance, receipt_pref, logout_after_purchase
|
||||||
FROM users
|
FROM users
|
||||||
WHERE touchkey IS NOT NULL OR NOT :must_have_touchkey
|
WHERE touchkey IS NOT NULL OR NOT :must_have_touchkey
|
||||||
ORDER BY username COLLATE NOCASE ASC
|
ORDER BY username COLLATE NOCASE ASC
|
||||||
|
@ -92,12 +92,13 @@ class MatematDatabase(object):
|
||||||
'must_have_touchkey': with_touchkey
|
'must_have_touchkey': with_touchkey
|
||||||
}):
|
}):
|
||||||
# Decompose each row and put the values into a User object
|
# Decompose each row and put the values into a User object
|
||||||
user_id, username, email, is_admin, is_member, balance, receipt_p = row
|
user_id, username, email, is_admin, is_member, balance, receipt_p, logout_after_purchase = row
|
||||||
try:
|
try:
|
||||||
receipt_pref: ReceiptPreference = ReceiptPreference(receipt_p)
|
receipt_pref: ReceiptPreference = ReceiptPreference(receipt_p)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise DatabaseConsistencyError(f'{receipt_p} is not a valid ReceiptPreference')
|
raise DatabaseConsistencyError(f'{receipt_p} is not a valid ReceiptPreference')
|
||||||
users.append(User(user_id, username, balance, email, is_admin, is_member, receipt_pref))
|
users.append(User(user_id, username, balance, email, is_admin, is_member, receipt_pref,
|
||||||
|
logout_after_purchase))
|
||||||
return users
|
return users
|
||||||
|
|
||||||
def get_user(self, uid: int) -> User:
|
def get_user(self, uid: int) -> User:
|
||||||
|
@ -108,7 +109,7 @@ class MatematDatabase(object):
|
||||||
with self.db.transaction(exclusive=False) as c:
|
with self.db.transaction(exclusive=False) as c:
|
||||||
# Fetch all values to construct the user
|
# Fetch all values to construct the user
|
||||||
c.execute('''
|
c.execute('''
|
||||||
SELECT user_id, username, email, is_admin, is_member, balance, receipt_pref
|
SELECT user_id, username, email, is_admin, is_member, balance, receipt_pref, logout_after_purchase
|
||||||
FROM users
|
FROM users
|
||||||
WHERE user_id = ?
|
WHERE user_id = ?
|
||||||
''',
|
''',
|
||||||
|
@ -117,19 +118,20 @@ class MatematDatabase(object):
|
||||||
if row is None:
|
if row is None:
|
||||||
raise ValueError(f'No user with user ID {uid} exists.')
|
raise ValueError(f'No user with user ID {uid} exists.')
|
||||||
# Unpack the row and construct the user
|
# Unpack the row and construct the user
|
||||||
user_id, username, email, is_admin, is_member, balance, receipt_p = row
|
user_id, username, email, is_admin, is_member, balance, receipt_p, logout_after_purchase = row
|
||||||
try:
|
try:
|
||||||
receipt_pref: ReceiptPreference = ReceiptPreference(receipt_p)
|
receipt_pref: ReceiptPreference = ReceiptPreference(receipt_p)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise DatabaseConsistencyError(f'{receipt_p} is not a valid ReceiptPreference')
|
raise DatabaseConsistencyError(f'{receipt_p} is not a valid ReceiptPreference')
|
||||||
return User(user_id, username, balance, email, is_admin, is_member, receipt_pref)
|
return User(user_id, username, balance, email, is_admin, is_member, receipt_pref, logout_after_purchase)
|
||||||
|
|
||||||
def create_user(self,
|
def create_user(self,
|
||||||
username: str,
|
username: str,
|
||||||
password: str,
|
password: str,
|
||||||
email: Optional[str] = None,
|
email: Optional[str] = None,
|
||||||
admin: bool = False,
|
admin: bool = False,
|
||||||
member: bool = True) -> User:
|
member: bool = True,
|
||||||
|
logout_after_purchase: bool = False) -> User:
|
||||||
"""
|
"""
|
||||||
Create a new user.
|
Create a new user.
|
||||||
:param username: The name of the new user.
|
:param username: The name of the new user.
|
||||||
|
@ -137,6 +139,7 @@ class MatematDatabase(object):
|
||||||
:param email: The user's email address, defaults to None.
|
:param email: The user's email address, defaults to None.
|
||||||
:param admin: Whether the user is an administrator, defaults to False.
|
:param admin: Whether the user is an administrator, defaults to False.
|
||||||
:param member: Whether the user is a member, defaults to True.
|
:param member: Whether the user is a member, defaults to True.
|
||||||
|
:param logout_after_purchase: Whether the user should be logged out after completing a purchase.
|
||||||
:return: A User object representing the created user.
|
:return: A User object representing the created user.
|
||||||
:raises ValueError: If a user with the same name already exists.
|
:raises ValueError: If a user with the same name already exists.
|
||||||
"""
|
"""
|
||||||
|
@ -150,8 +153,10 @@ class MatematDatabase(object):
|
||||||
raise ValueError(f'A user with the name \'{username}\' already exists.')
|
raise ValueError(f'A user with the name \'{username}\' already exists.')
|
||||||
# Insert the user into the database.
|
# Insert the user into the database.
|
||||||
c.execute('''
|
c.execute('''
|
||||||
INSERT INTO users (username, email, password, balance, is_admin, is_member, lastchange, created)
|
INSERT INTO users (username, email, password, balance, is_admin, is_member, lastchange, created,
|
||||||
VALUES (:username, :email, :pwhash, 0, :admin, :member, STRFTIME('%s', 'now'), STRFTIME('%s', 'now'))
|
logout_after_purchase)
|
||||||
|
VALUES (:username, :email, :pwhash, 0, :admin, :member, STRFTIME('%s', 'now'), STRFTIME('%s', 'now'),
|
||||||
|
logout_after_purchase)
|
||||||
''', {
|
''', {
|
||||||
'username': username,
|
'username': username,
|
||||||
'email': email,
|
'email': email,
|
||||||
|
@ -179,14 +184,15 @@ class MatematDatabase(object):
|
||||||
raise ValueError('Exactly one of password and touchkey must be provided')
|
raise ValueError('Exactly one of password and touchkey must be provided')
|
||||||
with self.db.transaction(exclusive=False) as c:
|
with self.db.transaction(exclusive=False) as c:
|
||||||
c.execute('''
|
c.execute('''
|
||||||
SELECT user_id, username, email, password, touchkey, is_admin, is_member, balance, receipt_pref
|
SELECT user_id, username, email, password, touchkey, is_admin, is_member, balance, receipt_pref,
|
||||||
|
logout_after_purchase
|
||||||
FROM users
|
FROM users
|
||||||
WHERE username = ?
|
WHERE username = ?
|
||||||
''', [username])
|
''', [username])
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
if row is None:
|
if row is None:
|
||||||
raise AuthenticationError('User does not exist')
|
raise AuthenticationError('User does not exist')
|
||||||
user_id, username, email, pwhash, tkhash, admin, member, balance, receipt_p = row
|
user_id, username, email, pwhash, tkhash, admin, member, balance, receipt_p, logout_after_purchase = row
|
||||||
if password is not None and not compare_digest(crypt.crypt(password, pwhash), pwhash):
|
if password is not None and not compare_digest(crypt.crypt(password, pwhash), pwhash):
|
||||||
raise AuthenticationError('Password mismatch')
|
raise AuthenticationError('Password mismatch')
|
||||||
elif touchkey is not None \
|
elif touchkey is not None \
|
||||||
|
@ -199,7 +205,7 @@ class MatematDatabase(object):
|
||||||
receipt_pref: ReceiptPreference = ReceiptPreference(receipt_p)
|
receipt_pref: ReceiptPreference = ReceiptPreference(receipt_p)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise DatabaseConsistencyError(f'{receipt_p} is not a valid ReceiptPreference')
|
raise DatabaseConsistencyError(f'{receipt_p} is not a valid ReceiptPreference')
|
||||||
return User(user_id, username, balance, email, admin, member, receipt_pref)
|
return User(user_id, username, balance, email, admin, member, receipt_pref, logout_after_purchase)
|
||||||
|
|
||||||
def change_password(self, user: User, oldpass: str, newpass: str, verify_password: bool = True) -> None:
|
def change_password(self, user: User, oldpass: str, newpass: str, verify_password: bool = True) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -280,6 +286,7 @@ class MatematDatabase(object):
|
||||||
balance: int = kwargs['balance'] if 'balance' in kwargs else user.balance
|
balance: int = kwargs['balance'] if 'balance' in kwargs else user.balance
|
||||||
balance_reason: Optional[str] = kwargs['balance_reason'] if 'balance_reason' in kwargs else None
|
balance_reason: Optional[str] = kwargs['balance_reason'] if 'balance_reason' in kwargs else None
|
||||||
receipt_pref: ReceiptPreference = kwargs['receipt_pref'] if 'receipt_pref' in kwargs else user.receipt_pref
|
receipt_pref: ReceiptPreference = kwargs['receipt_pref'] if 'receipt_pref' in kwargs else user.receipt_pref
|
||||||
|
logout_after_purchase: bool = kwargs['logout_after_purchase'] if 'logout_after_purchase' in kwargs else user.logout_after_purchase
|
||||||
with self.db.transaction() as c:
|
with self.db.transaction() as c:
|
||||||
c.execute('SELECT balance FROM users WHERE user_id = :user_id', {'user_id': user.id})
|
c.execute('SELECT balance FROM users WHERE user_id = :user_id', {'user_id': user.id})
|
||||||
row = c.fetchone()
|
row = c.fetchone()
|
||||||
|
@ -312,7 +319,8 @@ class MatematDatabase(object):
|
||||||
is_admin = :is_admin,
|
is_admin = :is_admin,
|
||||||
is_member = :is_member,
|
is_member = :is_member,
|
||||||
receipt_pref = :receipt_pref,
|
receipt_pref = :receipt_pref,
|
||||||
lastchange = STRFTIME('%s', 'now')
|
lastchange = STRFTIME('%s', 'now'),
|
||||||
|
logout_after_purchase = :logout_after_purchase
|
||||||
WHERE user_id = :user_id
|
WHERE user_id = :user_id
|
||||||
''', {
|
''', {
|
||||||
'user_id': user.id,
|
'user_id': user.id,
|
||||||
|
@ -321,7 +329,8 @@ class MatematDatabase(object):
|
||||||
'balance': balance,
|
'balance': balance,
|
||||||
'is_admin': is_admin,
|
'is_admin': is_admin,
|
||||||
'is_member': is_member,
|
'is_member': is_member,
|
||||||
'receipt_pref': receipt_pref.value
|
'receipt_pref': receipt_pref.value,
|
||||||
|
'logout_after_purchase': logout_after_purchase
|
||||||
})
|
})
|
||||||
# Only update the actual user object after the changes in the database succeeded
|
# Only update the actual user object after the changes in the database succeeded
|
||||||
user.name = name
|
user.name = name
|
||||||
|
@ -329,6 +338,7 @@ class MatematDatabase(object):
|
||||||
user.balance = balance
|
user.balance = balance
|
||||||
user.is_admin = is_admin
|
user.is_admin = is_admin
|
||||||
user.is_member = is_member
|
user.is_member = is_member
|
||||||
|
user.logout_after_purchase = user.logout_after_purchase
|
||||||
user.receipt_pref = receipt_pref
|
user.receipt_pref = receipt_pref
|
||||||
|
|
||||||
def delete_user(self, user: User) -> None:
|
def delete_user(self, user: User) -> None:
|
||||||
|
|
|
@ -276,3 +276,11 @@ def migrate_schema_5_to_6(c: sqlite3.Cursor):
|
||||||
ALTER TABLE products ADD COLUMN
|
ALTER TABLE products ADD COLUMN
|
||||||
custom_price INTEGER(1) DEFAULT 0;
|
custom_price INTEGER(1) DEFAULT 0;
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
|
def migrate_schema_6_to_7(c: sqlite3.Cursor):
|
||||||
|
# Add custom_price column
|
||||||
|
c.execute('''
|
||||||
|
ALTER TABLE users ADD COLUMN
|
||||||
|
logout_after_purchase INTEGER(1) DEFAULT 0;
|
||||||
|
''')
|
||||||
|
|
|
@ -26,7 +26,8 @@ class User:
|
||||||
email: Optional[str] = None,
|
email: Optional[str] = None,
|
||||||
is_admin: bool = False,
|
is_admin: bool = False,
|
||||||
is_member: bool = False,
|
is_member: bool = False,
|
||||||
receipt_pref: ReceiptPreference = ReceiptPreference.NONE) -> None:
|
receipt_pref: ReceiptPreference = ReceiptPreference.NONE,
|
||||||
|
logout_after_purchase: bool = False) -> None:
|
||||||
self.id: int = _id
|
self.id: int = _id
|
||||||
self.name: str = name
|
self.name: str = name
|
||||||
self.balance: int = balance
|
self.balance: int = balance
|
||||||
|
@ -34,6 +35,7 @@ class User:
|
||||||
self.is_admin: bool = is_admin
|
self.is_admin: bool = is_admin
|
||||||
self.is_member: bool = is_member
|
self.is_member: bool = is_member
|
||||||
self.receipt_pref: ReceiptPreference = receipt_pref
|
self.receipt_pref: ReceiptPreference = receipt_pref
|
||||||
|
self.logout_after_purchase: bool = logout_after_purchase
|
||||||
|
|
||||||
def __eq__(self, other) -> bool:
|
def __eq__(self, other) -> bool:
|
||||||
if not isinstance(other, User):
|
if not isinstance(other, User):
|
||||||
|
@ -44,7 +46,9 @@ class User:
|
||||||
self.email == other.email and \
|
self.email == other.email and \
|
||||||
self.is_admin == other.is_admin and \
|
self.is_admin == other.is_admin and \
|
||||||
self.is_member == other.is_member and \
|
self.is_member == other.is_member and \
|
||||||
self.receipt_pref == other.receipt_pref
|
self.receipt_pref == other.receipt_pref and \
|
||||||
|
self.logout_after_purchase == other.logout_after_purchase
|
||||||
|
|
||||||
def __hash__(self) -> int:
|
def __hash__(self) -> int:
|
||||||
return hash((self.id, self.name, self.balance, self.email, self.is_admin, self.is_member, self.receipt_pref))
|
return hash((self.id, self.name, self.balance, self.email, self.is_admin, self.is_member, self.receipt_pref,
|
||||||
|
self.logout_after_purchase))
|
||||||
|
|
|
@ -413,3 +413,84 @@ SCHEMAS[6] = [
|
||||||
ON DELETE SET NULL ON UPDATE CASCADE
|
ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
);
|
);
|
||||||
''']
|
''']
|
||||||
|
|
||||||
|
|
||||||
|
SCHEMAS[7] = [
|
||||||
|
'''
|
||||||
|
CREATE TABLE users (
|
||||||
|
user_id INTEGER PRIMARY KEY,
|
||||||
|
username TEXT UNIQUE NOT NULL,
|
||||||
|
email TEXT DEFAULT NULL,
|
||||||
|
password TEXT NOT NULL,
|
||||||
|
touchkey TEXT DEFAULT NULL,
|
||||||
|
is_admin INTEGER(1) NOT NULL DEFAULT 0,
|
||||||
|
is_member INTEGER(1) NOT NULL DEFAULT 1,
|
||||||
|
balance INTEGER(8) NOT NULL DEFAULT 0,
|
||||||
|
lastchange INTEGER(8) NOT NULL DEFAULT 0,
|
||||||
|
receipt_pref INTEGER(1) NOT NULL DEFAULT 0,
|
||||||
|
created INTEGER(8) NOT NULL DEFAULT 0,
|
||||||
|
logout_after_purchase INTEGER(1) DEFAULT 0
|
||||||
|
);
|
||||||
|
''',
|
||||||
|
'''
|
||||||
|
CREATE TABLE products (
|
||||||
|
product_id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT UNIQUE NOT NULL,
|
||||||
|
stock INTEGER(8) DEFAULT 0,
|
||||||
|
stockable INTEGER(1) DEFAULT 1,
|
||||||
|
price_member INTEGER(8) NOT NULL,
|
||||||
|
price_non_member INTEGER(8) NOT NULL,
|
||||||
|
custom_price INTEGER(1) DEFAULT 0
|
||||||
|
);
|
||||||
|
''',
|
||||||
|
'''
|
||||||
|
CREATE TABLE transactions ( -- "superclass" of the following 3 tables
|
||||||
|
ta_id INTEGER PRIMARY KEY,
|
||||||
|
user_id INTEGER DEFAULT NULL,
|
||||||
|
value INTEGER(8) NOT NULL,
|
||||||
|
old_balance INTEGER(8) NOT NULL,
|
||||||
|
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
||||||
|
ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
''',
|
||||||
|
'''
|
||||||
|
CREATE TABLE consumptions ( -- transactions involving buying a product
|
||||||
|
ta_id INTEGER PRIMARY KEY,
|
||||||
|
product TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
||||||
|
ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
''',
|
||||||
|
'''
|
||||||
|
CREATE TABLE deposits ( -- transactions involving depositing cash
|
||||||
|
ta_id INTEGER PRIMARY KEY,
|
||||||
|
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
||||||
|
ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
''',
|
||||||
|
'''
|
||||||
|
CREATE TABLE modifications ( -- transactions involving balance modification by an admin
|
||||||
|
ta_id INTEGER NOT NULL,
|
||||||
|
agent TEXT NOT NULL,
|
||||||
|
reason TEXT DEFAULT NULL,
|
||||||
|
PRIMARY KEY (ta_id),
|
||||||
|
FOREIGN KEY (ta_id) REFERENCES transactions(ta_id)
|
||||||
|
ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
''',
|
||||||
|
'''
|
||||||
|
CREATE TABLE receipts ( -- receipts sent to the users
|
||||||
|
receipt_id INTEGER PRIMARY KEY,
|
||||||
|
user_id INTEGER NOT NULL,
|
||||||
|
first_ta_id INTEGER DEFAULT NULL,
|
||||||
|
last_ta_id INTEGER DEFAULT NULL,
|
||||||
|
date INTEGER(8) DEFAULT (STRFTIME('%s', 'now')),
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(user_id)
|
||||||
|
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||||
|
FOREIGN KEY (first_ta_id) REFERENCES transactions(ta_id)
|
||||||
|
ON DELETE SET NULL ON UPDATE CASCADE,
|
||||||
|
FOREIGN KEY (last_ta_id) REFERENCES transactions(ta_id)
|
||||||
|
ON DELETE SET NULL ON UPDATE CASCADE
|
||||||
|
);
|
||||||
|
''']
|
||||||
|
|
|
@ -40,7 +40,7 @@ class DatabaseTransaction(object):
|
||||||
|
|
||||||
class DatabaseWrapper(object):
|
class DatabaseWrapper(object):
|
||||||
|
|
||||||
SCHEMA_VERSION = 6
|
SCHEMA_VERSION = 7
|
||||||
|
|
||||||
def __init__(self, filename: str) -> None:
|
def __init__(self, filename: str) -> None:
|
||||||
self._filename: str = filename
|
self._filename: str = filename
|
||||||
|
@ -89,6 +89,8 @@ class DatabaseWrapper(object):
|
||||||
migrate_schema_4_to_5(c)
|
migrate_schema_4_to_5(c)
|
||||||
if from_version <= 5 and to_version >= 6:
|
if from_version <= 5 and to_version >= 6:
|
||||||
migrate_schema_5_to_6(c)
|
migrate_schema_5_to_6(c)
|
||||||
|
if from_version <= 6 and to_version >= 7:
|
||||||
|
migrate_schema_6_to_7(c)
|
||||||
|
|
||||||
def connect(self) -> None:
|
def connect(self) -> None:
|
||||||
if self.is_connected():
|
if self.is_connected():
|
||||||
|
|
|
@ -75,6 +75,7 @@ def handle_change(args: FormsDict, files: FormsDict, user: User, db: MatematData
|
||||||
return
|
return
|
||||||
username = str(args.username)
|
username = str(args.username)
|
||||||
email = str(args.email)
|
email = str(args.email)
|
||||||
|
logout_after_purchase = 'logout_after_purchase' in args
|
||||||
# An empty e-mail field should be interpreted as NULL
|
# An empty e-mail field should be interpreted as NULL
|
||||||
if len(email) == 0:
|
if len(email) == 0:
|
||||||
email = None
|
email = None
|
||||||
|
@ -84,7 +85,8 @@ def handle_change(args: FormsDict, files: FormsDict, user: User, db: MatematData
|
||||||
return
|
return
|
||||||
# Attempt to update username, e-mail and receipt preference
|
# Attempt to update username, e-mail and receipt preference
|
||||||
try:
|
try:
|
||||||
db.change_user(user, agent=None, name=username, email=email, receipt_pref=receipt_pref)
|
db.change_user(user, agent=None, name=username, email=email, receipt_pref=receipt_pref,
|
||||||
|
logout_after_purchase=logout_after_purchase)
|
||||||
except DatabaseConsistencyError:
|
except DatabaseConsistencyError:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -176,8 +178,10 @@ def handle_admin_change(args: FormsDict, files: FormsDict, db: MatematDatabase):
|
||||||
password = str(args.password)
|
password = str(args.password)
|
||||||
is_member = 'ismember' in args
|
is_member = 'ismember' in args
|
||||||
is_admin = 'isadmin' in args
|
is_admin = 'isadmin' in args
|
||||||
|
logout_after_purchase = 'logout_after_purchase' in args
|
||||||
# Create the user in the database
|
# Create the user in the database
|
||||||
newuser: User = db.create_user(username, password, email, member=is_member, admin=is_admin)
|
newuser: User = db.create_user(username, password, email, member=is_member, admin=is_admin,
|
||||||
|
logout_after_purchase=logout_after_purchase)
|
||||||
|
|
||||||
# If a default avatar is set, copy it to the user's avatar path
|
# If a default avatar is set, copy it to the user's avatar path
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ def buy():
|
||||||
# If no user is logged in, redirect to the main page, as a purchase must always be bound to a user
|
# If no user is logged in, redirect to the main page, as a purchase must always be bound to a user
|
||||||
if not session.has(session_id, 'authenticated_user'):
|
if not session.has(session_id, 'authenticated_user'):
|
||||||
redirect('/')
|
redirect('/')
|
||||||
|
authlevel: int = session.get(session_id, 'authentication_level')
|
||||||
# Connect to the database
|
# Connect to the database
|
||||||
with MatematDatabase(config['DatabaseFile']) as db:
|
with MatematDatabase(config['DatabaseFile']) as db:
|
||||||
# Fetch the authenticated user from the database
|
# Fetch the authenticated user from the database
|
||||||
|
@ -34,6 +35,9 @@ def buy():
|
||||||
stock_provider = c.get_stock_provider()
|
stock_provider = c.get_stock_provider()
|
||||||
if stock_provider.needs_update():
|
if stock_provider.needs_update():
|
||||||
stock_provider.update_stock(product, -1)
|
stock_provider.update_stock(product, -1)
|
||||||
|
# Logout user if configured, logged in via touchkey and no price entry input was shown
|
||||||
|
if user.logout_after_purchase and authlevel < 2 and not product.custom_price:
|
||||||
|
redirect('/logout')
|
||||||
# Redirect to the main page (where this request should have come from)
|
# Redirect to the main page (where this request should have come from)
|
||||||
redirect(f'/?lastaction=buy&lastproduct={pid}&lastprice={price}')
|
redirect(f'/?lastaction=buy&lastproduct={pid}&lastprice={price}')
|
||||||
redirect('/')
|
redirect('/')
|
||||||
|
|
|
@ -111,6 +111,7 @@ def handle_change(args: FormsDict, files: FormsDict, user: User, authuser: User,
|
||||||
balance_reason = None
|
balance_reason = None
|
||||||
is_member = 'ismember' in args
|
is_member = 'ismember' in args
|
||||||
is_admin = 'isadmin' in args
|
is_admin = 'isadmin' in args
|
||||||
|
logout_after_purchase = 'logout_after_purchase' in args
|
||||||
# An empty e-mail field should be interpreted as NULL
|
# An empty e-mail field should be interpreted as NULL
|
||||||
if len(email) == 0:
|
if len(email) == 0:
|
||||||
email = None
|
email = None
|
||||||
|
@ -121,7 +122,8 @@ def handle_change(args: FormsDict, files: FormsDict, user: User, authuser: User,
|
||||||
db.change_password(user, '', password, verify_password=False)
|
db.change_password(user, '', password, verify_password=False)
|
||||||
# Write the user detail changes
|
# Write the user detail changes
|
||||||
db.change_user(user, agent=authuser, name=username, email=email, is_member=is_member, is_admin=is_admin,
|
db.change_user(user, agent=authuser, name=username, email=email, is_member=is_member, is_admin=is_admin,
|
||||||
balance=balance, balance_reason=balance_reason, receipt_pref=receipt_pref)
|
balance=balance, balance_reason=balance_reason, receipt_pref=receipt_pref,
|
||||||
|
logout_after_purchase=logout_after_purchase)
|
||||||
except DatabaseConsistencyError:
|
except DatabaseConsistencyError:
|
||||||
return
|
return
|
||||||
# If a new avatar was uploaded, process it
|
# If a new avatar was uploaded, process it
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
<label for="admin-myaccount-isadmin">Admin: </label>
|
<label for="admin-myaccount-isadmin">Admin: </label>
|
||||||
<input id="admin-myaccount-isadmin" type="checkbox" disabled="disabled" {% if authuser.is_admin %} checked="checked" {% endif %}/><br/>
|
<input id="admin-myaccount-isadmin" type="checkbox" disabled="disabled" {% if authuser.is_admin %} checked="checked" {% endif %}/><br/>
|
||||||
|
|
||||||
|
<label for="admin-myaccount-logout-after-purchase">Logout after purchase: </label>
|
||||||
|
<input id="admin-myaccount-logout-after-purchase" type="checkbox" name="logout_after_purchase" {% if authuser.logout_after_purchase %} checked="checked" {% endif %}/><br/>
|
||||||
|
|
||||||
<input type="submit" value="Save changes" />
|
<input type="submit" value="Save changes" />
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
<label for="admin-newuser-isadmin">Admin: </label>
|
<label for="admin-newuser-isadmin">Admin: </label>
|
||||||
<input id="admin-newuser-isadmin" type="checkbox" name="isadmin" /><br/>
|
<input id="admin-newuser-isadmin" type="checkbox" name="isadmin" /><br/>
|
||||||
|
|
||||||
|
<label for="admin-myaccount-logout-after-purchase">Logout after purchase: </label>
|
||||||
|
<input id="admin-myaccount-logout-after-purchase" type="checkbox" name="logout_after_purchase" /><br/>
|
||||||
|
|
||||||
<input type="submit" value="Create User" />
|
<input type="submit" value="Create User" />
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
<label for="moduser-account-isadmin">Admin: </label>
|
<label for="moduser-account-isadmin">Admin: </label>
|
||||||
<input id="moduser-account-isadmin" name="isadmin" type="checkbox" {% if user.is_admin %} checked="checked" {% endif %}/><br/>
|
<input id="moduser-account-isadmin" name="isadmin" type="checkbox" {% if user.is_admin %} checked="checked" {% endif %}/><br/>
|
||||||
|
|
||||||
|
<label for="admin-myaccount-logout-after-purchase">Logout after purchase: </label>
|
||||||
|
<input id="admin-myaccount-logout-after-purchase" type="checkbox" name="logout_after_purchase" {% if user.logout_after_purchase %} checked="checked" {% endif %}/><br/>
|
||||||
|
|
||||||
<label for="moduser-account-balance">Balance: </label>
|
<label for="moduser-account-balance">Balance: </label>
|
||||||
CHF <input id="moduser-account-balance" name="balance" type="number" step="0.01" value="{{ user.balance|chf(False) }}" /><br/>
|
CHF <input id="moduser-account-balance" name="balance" type="number" step="0.01" value="{{ user.balance|chf(False) }}" /><br/>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue