1
0
Files
coconut-leaf/src/database.py

161 lines
5.0 KiB
Python
Raw Normal View History

2021-01-16 22:15:10 +08:00
import config
import sqlite3
import json
2021-01-19 22:20:11 +08:00
import utils
import threading
def SafeDatabaseOperation(func):
def wrapper(self, *args, **kwargs):
with self.mutex:
# check database and acquire cursor
try:
self.check_database()
self.cursor = self.db.cursor()
except:
self.cursor = None
return (False, None)
# do real data work
try:
result = (True, func(self, *args, **kwargs))
self.cursor.close()
self.cursor = None
self.db.commit()
return result
except:
self.cursor.close()
self.cursor = None
self.db.rollback()
return (False, None)
return wrapper
2021-01-16 22:15:10 +08:00
class CalendarDatabase(object):
def __init__(self):
self.db = None
2021-01-19 22:20:11 +08:00
self.cursor = None
self.mutex = threading.Lock()
2021-01-16 22:15:10 +08:00
def open(self):
if (self.is_database_valid()):
raise Exception('Databade is opened')
if config.CustomConfig['database-type'] == 'sqlite':
self.db = sqlite3.connect(config.CustomConfig['database-config']['url'])
elif config.CustomConfig['database-type'] == 'mysql':
raise Exception('Not implemented database')
else:
raise Exception('Unknow database type')
def init(self, username, password):
if (self.is_database_valid()):
raise Exception('Databade is opened')
2021-01-19 22:20:11 +08:00
# establish tables
2021-01-16 22:15:10 +08:00
self.open()
2021-01-19 22:20:11 +08:00
cursor = self.db.cursor()
2021-01-16 22:15:10 +08:00
with open('sql/sqlite.sql', 'r', encoding='utf-8') as fsql:
cursor.executescript(fsql.read())
2021-01-19 22:20:11 +08:00
# finish init
cursor.execute('INSERT INTO user VALUES (?, ?, ?, ?, ?, ?);', (
username,
utils.ComputePasswordHash(password),
1,
utils.GenerateSalt(),
utils.GenerateToken(username),
0
))
cursor.close()
self.db.commit()
2021-01-16 22:15:10 +08:00
def close(self):
self.check_database()
self.db.close()
self.db = None
def check_database(self):
if (not self.is_database_valid()):
raise Exception('Databade is None')
def is_database_valid(self):
return not (self.db == None)
2021-01-19 22:20:11 +08:00
def get_username_from_token(self, token):
self.cursor.execute('SELECT [ccn_name] FROM user WHERE [ccn_token] = ? AND [ccn_tokenExpireOn] > ?;',(
token,
utils.GetCurrentTimestamp()
))
return self.cursor.fetchone()[0]
# =============================== # =============================== operation function
# =============================== common
@SafeDatabaseOperation
def common_salt(self, username):
salt = utils.GenerateSalt()
self.cursor.execute('UPDATE user SET [ccn_salt] = ? WHERE [ccn_name] = ?;', (
salt,
username
))
return salt
@SafeDatabaseOperation
def common_login(self, username, password):
self.cursor.execute('SELECT [ccn_password], [ccn_salt] FROM user WHERE [ccn_name] = ?;', (username, ))
(gotten_salt, gotten_password) = self.cursor.fetchone()
if password == utils.ComputePasswordHashWithSalt(gotten_password, gotten_salt):
token = utils.GenerateToken(username)
self.cursor.execute('UPDATE user SET [ccn_token] = ?, [ccn_tokenExpireOn] = ? WHERE [ccn_name] = ?;', (
token,
utils.GetCurrentTimestamp() + 60 * 60 * 24 * 2, # add 2 day from now
username
))
return token
else:
# return empty string to indicate fail to login
return ''
@SafeDatabaseOperation
def common_logout(self, token):
username = self.get_username_from_token(cur, token)
self.cursor.execute('UPDATE user SET [ccn_tokenExpireOn] = 0 WHERE [ccn_name] = ?;', (username, ))
return None
@SafeDatabaseOperation
def common_tokenValid(self, token):
# get user name have check the validation, don't do anything more.
self.get_username_from_token(token)
return result
@SafeDatabaseOperation
def common_isAdmin(self, token):
username = self.get_username_from_token(token)
self.cursor.execute('SELECT [ccn_isAdmin] FROM user WHERE [ccn_name] = ?;', (username, ))
result = self.cursor.fetchone()[0] == 1
return result
@SafeDatabaseOperation
def common_changePassword(self, token, newpassword):
username = self.get_username_from_token(token)
self.cursor.execute('UPDATE user SET [ccn_password] = ? WHERE [ccn_name] = ?;', (
newpassword,
username
))
return None
# =============================== calendar
# =============================== collection
# =============================== todo
# =============================== admin
2021-01-16 22:15:10 +08:00