From f49963dc6774871bd00a5f90d566917521605677 Mon Sep 17 00:00:00 2001 From: azivner Date: Sun, 22 Oct 2017 20:22:59 -0400 Subject: [PATCH] remove old python backend files --- src/__init__.py | 0 src/app.py | 54 ------- src/audit_api.py | 19 --- src/audit_category.py | 9 -- src/backup.py | 53 ------- src/change-password.py | 27 ---- src/change_password.py | 60 -------- src/config_provider.py | 7 - src/migration_api.py | 74 ---------- src/my_scrypt.py | 30 ---- src/notes_api.py | 199 ------------------------- src/notes_history_api.py | 22 --- src/notes_move_api.py | 70 --------- src/password_api.py | 16 -- src/routes.py | 101 ------------- src/settings_api.py | 39 ----- src/setup.py | 56 ------- src/sql.py | 93 ------------ src/templates/index.html | 276 ----------------------------------- src/templates/login.html | 50 ------- src/templates/migration.html | 57 -------- src/tree_api.py | 58 -------- src/utils.py | 6 - 23 files changed, 1376 deletions(-) delete mode 100644 src/__init__.py delete mode 100644 src/app.py delete mode 100644 src/audit_api.py delete mode 100644 src/audit_category.py delete mode 100644 src/backup.py delete mode 100644 src/change-password.py delete mode 100644 src/change_password.py delete mode 100644 src/config_provider.py delete mode 100644 src/migration_api.py delete mode 100644 src/my_scrypt.py delete mode 100644 src/notes_api.py delete mode 100644 src/notes_history_api.py delete mode 100644 src/notes_move_api.py delete mode 100644 src/password_api.py delete mode 100644 src/routes.py delete mode 100644 src/settings_api.py delete mode 100644 src/setup.py delete mode 100644 src/sql.py delete mode 100644 src/templates/index.html delete mode 100644 src/templates/login.html delete mode 100644 src/templates/migration.html delete mode 100644 src/tree_api.py delete mode 100644 src/utils.py diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/app.py b/src/app.py deleted file mode 100644 index c6cff93de..000000000 --- a/src/app.py +++ /dev/null @@ -1,54 +0,0 @@ -from flask import Flask -from flask_cors import CORS - -import config_provider -import routes -from audit_api import audit_api -from migration_api import migration_api -from notes_api import notes_api -from notes_history_api import notes_history_api -from notes_move_api import notes_move_api -from password_api import password_api -from settings_api import settings_api -from sql import connect, get_option -from tree_api import tree_api - -config = config_provider.get_config() - -documentPath = config['Document']['documentPath'] -connect(documentPath) - -flask_secret_key = get_option("flask_secret_key") - -if not flask_secret_key: - print("Application has not been setup yet. Run 'python setup.py' to finish setup.") - exit(1) - -app = Flask(__name__) -app.secret_key = flask_secret_key -app.register_blueprint(routes.routes) -app.register_blueprint(tree_api) -app.register_blueprint(notes_api) -app.register_blueprint(notes_move_api) -app.register_blueprint(password_api) -app.register_blueprint(settings_api) -app.register_blueprint(notes_history_api) -app.register_blueprint(audit_api) -app.register_blueprint(migration_api) - -CORS(app) - -routes.init(app) - -port = config['Network']['port'] -https = config['Network']['https'] -certPath = config['Network']['certPath'] -certKeyPath = config['Network']['certKeyPath'] - -if __name__ == "__main__": - ssl_context = None - - if https == "true": - ssl_context = (certPath, certKeyPath) - - app.run(host='0.0.0.0', port=port, ssl_context = ssl_context) \ No newline at end of file diff --git a/src/audit_api.py b/src/audit_api.py deleted file mode 100644 index 6cbd41ad3..000000000 --- a/src/audit_api.py +++ /dev/null @@ -1,19 +0,0 @@ -from flask import Blueprint, jsonify -from flask import request -from flask_login import login_required - -from sql import getSingleResult - -audit_api = Blueprint('audit_api', __name__) - - -@audit_api.route('/api/audit/', methods = ['GET']) -@login_required -def get_note(full_load_time): - browser_id = request.headers['x-browser-id'] - - count = getSingleResult("SELECT COUNT(*) AS 'count' FROM audit_log WHERE browser_id != ? AND date_modified >= ?", [browser_id, full_load_time])['count'] - - return jsonify({ - 'changed': count > 0 - }) \ No newline at end of file diff --git a/src/audit_category.py b/src/audit_category.py deleted file mode 100644 index 33c3e3e91..000000000 --- a/src/audit_category.py +++ /dev/null @@ -1,9 +0,0 @@ -UPDATE_CONTENT = 'CONTENT' -UPDATE_TITLE = 'TITLE' -CHANGE_POSITION = 'POSITION' -CREATE_NOTE = 'CREATE' -DELETE_NOTE = 'DELETE' -CHANGE_PARENT = 'PARENT' -ENCRYPTION = 'ENCRYPTION' -CHANGE_PASSWORD = 'PASSWORD' -SETTINGS = 'SETTINGS' \ No newline at end of file diff --git a/src/backup.py b/src/backup.py deleted file mode 100644 index a14257127..000000000 --- a/src/backup.py +++ /dev/null @@ -1,53 +0,0 @@ -import os -import re -from datetime import datetime -from shutil import copyfile - -import config_provider -import utils -from sql import get_option, set_option, commit - - -def regular_backup(): - now = utils.now_timestamp() - last_backup_date = int(get_option('last_backup_date')) - - if now - last_backup_date > 43200: - backup_now() - - cleanup_old_backups() - - -def backup_now(): - now = utils.now_timestamp() - - config = config_provider.get_config() - - document_path = config['Document']['documentPath'] - backup_directory = config['Backup']['backupDirectory'] - - date_str = datetime.utcnow().strftime("%Y-%m-%d %H:%M") - - copyfile(document_path, backup_directory + "/" + "backup-" + date_str + ".db") - - set_option('last_backup_date', now) - commit() - - -def cleanup_old_backups(): - now = datetime.utcnow() - config = config_provider.get_config() - backup_directory = config['Backup']['backupDirectory'] - - for file in os.listdir(backup_directory): - match = re.search(r"backup-([0-9 -:]+)\.db", file) - - if match: - date_str = match.group(1) - - date = datetime.strptime(date_str, "%Y-%m-%d %H:%M") - - if (now - date).days > 30: - print("Removing old backup - " + file) - - os.remove(backup_directory + "/" + file) \ No newline at end of file diff --git a/src/change-password.py b/src/change-password.py deleted file mode 100644 index 7561283d2..000000000 --- a/src/change-password.py +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/python - -import getpass - -import src.my_scrypt -import src.sql -import src.change_password - -config = src.config_provider.getConfig() -src.sql.connect(config['Document']['documentPath']) - -current_password = getpass.getpass(prompt="Enter current password: ") - -new_password1 = getpass.getpass(prompt="Enter new password: ") -new_password2 = getpass.getpass(prompt="Repeat the same password: ") - -if new_password1 != new_password2: - print('Entered passwords are not identical!') - exit(-1) - -ret = src.change_password.change_password(current_password, new_password1) - -if (ret['success']): - print("Changes committed. All encrypted notes were re-encrypted successfully with new password key.") - print("You can now start application and login with new password.") -else: - print(ret['message']) diff --git a/src/change_password.py b/src/change_password.py deleted file mode 100644 index 4cdb77acd..000000000 --- a/src/change_password.py +++ /dev/null @@ -1,60 +0,0 @@ -import base64 -import hashlib -from Crypto.Cipher import AES -from Crypto.Util import Counter - -import audit_category -import my_scrypt -import sql - - -def change_password(current_password, new_password, request = None): - current_password_hash = base64.b64encode(my_scrypt.get_verification_hash(current_password)) - - if current_password_hash != sql.get_option('password_verification_hash'): - return { - 'success': False, - 'message': "Given current password doesn't match hash" - } - - current_password_derived_key = my_scrypt.get_password_derived_key(current_password) - - new_password_verification_key = base64.b64encode(my_scrypt.get_verification_hash(new_password)) - new_password_encryption_key = my_scrypt.get_password_derived_key(new_password) - - def decrypt(encrypted_base64): - encrypted_bytes = base64.b64decode(encrypted_base64) - - aes = get_aes(current_password_derived_key) - return aes.decrypt(encrypted_bytes)[4:] - - def encrypt(plain_text): - aes = get_aes(new_password_encryption_key) - - digest = hashlib.sha256(plain_text).digest()[:4] - - encrypted_bytes = aes.encrypt(digest + plain_text) - - return base64.b64encode(encrypted_bytes) - - def get_aes(key): - return AES.new(key, AES.MODE_CTR, counter=Counter.new(128, initial_value=5)) - - encrypted_data_key = sql.get_option('encrypted_data_key') - - decrypted_data_key = decrypt(encrypted_data_key) - - new_encrypted_data_key = encrypt(decrypted_data_key) - - sql.set_option('encrypted_data_key', new_encrypted_data_key) - - sql.set_option('password_verification_hash', new_password_verification_key) - - sql.add_audit(audit_category.CHANGE_PASSWORD, request) - - sql.commit() - - return { - 'success': True, - 'new_encrypted_data_key': new_encrypted_data_key - } \ No newline at end of file diff --git a/src/config_provider.py b/src/config_provider.py deleted file mode 100644 index 915166e36..000000000 --- a/src/config_provider.py +++ /dev/null @@ -1,7 +0,0 @@ -import configparser - -def get_config(): - config = configparser.ConfigParser() - config.read('config.ini') - - return config \ No newline at end of file diff --git a/src/migration_api.py b/src/migration_api.py deleted file mode 100644 index 377be7dc9..000000000 --- a/src/migration_api.py +++ /dev/null @@ -1,74 +0,0 @@ -import os -import re - -import traceback - -from flask import Blueprint, jsonify -from flask_login import login_required - -from sql import get_option, set_option, commit, execute_script - -import backup - -APP_DB_VERSION = 0 - -MIGRATIONS_DIR = "src/migrations" - -migration_api = Blueprint('migration_api', __name__) - - -@migration_api.route('/api/migration', methods = ['GET']) -@login_required -def get_migration_info(): - return jsonify({ - 'db_version': int(get_option('db_version')), - 'app_db_version': APP_DB_VERSION - }) - - -@migration_api.route('/api/migration', methods = ['POST']) -@login_required -def run_migration(): - migrations = [] - - backup.backup_now() - - current_db_version = int(get_option('db_version')) - - for file in os.listdir(MIGRATIONS_DIR): - match = re.search(r"([0-9]{4})__([a-zA-Z0-9_ ]+)\.sql", file) - - if match: - db_version = int(match.group(1)) - - if db_version > current_db_version: - name = match.group(2) - - migration_record = { - 'db_version': db_version, - 'name': name - } - - migrations.append(migration_record) - - with open(MIGRATIONS_DIR + "/" + file, 'r') as sql_file: - sql = sql_file.read() - - try: - execute_script(sql) - - set_option('db_version', db_version) - commit() - - migration_record['success'] = True - except: - migration_record['success'] = False - migration_record['error'] = traceback.format_exc() - - break - - migrations.sort(key=lambda x: x['db_version']) - - return jsonify({ - 'migrations': migrations - }) diff --git a/src/my_scrypt.py b/src/my_scrypt.py deleted file mode 100644 index 8ed1a6e54..000000000 --- a/src/my_scrypt.py +++ /dev/null @@ -1,30 +0,0 @@ -import scrypt # pip install scrypt - -import sql - - -def get_verification_hash(password): - salt = sql.get_option('password_verification_salt') - - return get_scrypt_hash(password, salt) - - -def get_password_derived_key(password): - salt = sql.get_option('password_derived_key_salt') - - return get_scrypt_hash(password, salt) - - -def get_scrypt_hash(password, salt): - # scrypt doesn't like unicode strings - password = password.encode('ascii', 'ignore') - salt = salt.encode('ascii', 'ignore') - - hashed = scrypt.hash(password=password, - salt=salt, - N=16384, - r=8, - p=1, - buflen=32) - - return hashed diff --git a/src/notes_api.py b/src/notes_api.py deleted file mode 100644 index 7b02ba3ca..000000000 --- a/src/notes_api.py +++ /dev/null @@ -1,199 +0,0 @@ -import base64 -import random -import string - -from flask import Blueprint, jsonify -from flask import request -from flask_login import login_required - -import audit_category -import utils -from sql import delete -from sql import execute, insert, commit -from sql import getResults, getSingleResult, get_option, add_audit, deleteRecentAudits - -notes_api = Blueprint('notes_api', __name__) - - -@notes_api.route('/api/notes/', methods = ['GET']) -@login_required -def get_note(note_id): - execute("update options set opt_value = ? where opt_name = 'start_node'", [note_id]) - - detail = getSingleResult("select * from notes where note_id = ?", [note_id]) - - if detail['note_clone_id']: - note_id = detail['note_clone_id'] - detail = getSingleResult("select * from notes where note_id = ?", [note_id]) - - return jsonify({ - 'detail': detail, - 'formatting': getResults("select * from formatting where note_id = ? order by note_offset", [note_id]), - 'links': getResults("select * from links where note_id = ? order by note_offset", [note_id]), - 'images': getResults("select * from images where note_id = ? order by note_offset", [note_id]) - }) - - -@notes_api.route('/api/notes/', methods = ['PUT']) -@login_required -def update_note(note_id): - detail = getSingleResult("select * from notes where note_id = ?", [note_id]) - - if detail['note_clone_id']: - note_id = detail['note_clone_id'] - - note = request.get_json(force=True) - - now = utils.now_timestamp() - - history_snapshot_time_interval = float(get_option('history_snapshot_time_interval')) - - history_cutoff = now - history_snapshot_time_interval - - history = getSingleResult("select id from notes_history where note_id = ? and date_modified >= ?", [note_id, history_cutoff]) - - if history: - execute("update notes_history set note_title = ?, note_text = ?, encryption = ? where id = ?", [ - note['detail']['note_title'], - note['detail']['note_text'], - note['detail']['encryption'], - history['id'] - ]) - else: - execute("insert into notes_history (note_id, note_title, note_text, encryption, date_modified) values (?, ?, ?, ?, ?)", [ - note_id, - note['detail']['note_title'], - note['detail']['note_text'], - note['detail']['encryption'], - now - ]) - - if note['detail']['note_title'] != detail['note_title']: - deleteRecentAudits(audit_category.UPDATE_TITLE, request, note_id) - add_audit(audit_category.UPDATE_TITLE, request, note_id) - - if note['detail']['note_text'] != detail['note_text']: - deleteRecentAudits(audit_category.UPDATE_CONTENT, request, note_id) - add_audit(audit_category.UPDATE_CONTENT, request, note_id) - - if note['detail']['encryption'] != detail['encryption']: - add_audit(audit_category.ENCRYPTION, request, note_id, detail['encryption'], note['detail']['encryption']) - - execute("update notes set note_title = ?, note_text = ?, encryption = ?, date_modified = ? where note_id = ?", [ - note['detail']['note_title'], - note['detail']['note_text'], - note['detail']['encryption'], - now, - note_id]) - - delete("formatting", note_id) - - for fmt in note['formatting']: - insert("formatting", fmt) - - delete("images", note_id) - - for img in note['images']: - img['image_data'] = buffer(base64.b64decode(img['image_data'])) - - insert("images", img) - - delete("links", note_id) - - for link in note['links']: - insert("links", link) - - commit() - - return jsonify({}) - - -@notes_api.route('/api/notes/', methods = ['DELETE']) -@login_required -def delete_note(note_id): - children = getResults("select note_id from notes_tree where note_pid = ?", [note_id]) - - for child in children: - delete_note(child['note_id']) - - delete("notes_tree", note_id) - delete("notes", note_id) - - add_audit(audit_category.DELETE_NOTE, request, note_id) - - commit() - return jsonify({}) - - -@notes_api.route('/api/notes//children', methods = ['POST']) -@login_required -def create_child(parent_note_id): - note = request.get_json(force=True) - - noteId = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(22)) - - if parent_note_id == "root": - parent_note_id = "" - - new_note_pos = 0 - - if note['target'] == 'into': - res = getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ?', [parent_note_id]) - max_note_pos = res['max_note_pos'] - - if max_note_pos is None: # no children yet - new_note_pos = 0 - else: - new_note_pos = max_note_pos + 1 - elif note['target'] == 'after': - after_note = getSingleResult('select note_pos from notes_tree where note_id = ?', [note['target_note_id']]) - - new_note_pos = after_note['note_pos'] + 1 - - execute('update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ?', [parent_note_id, after_note['note_pos']]) - else: - raise Exception('Unknown target: ' + note['target']) - - add_audit(audit_category.CREATE_NOTE, request, noteId) - - now = utils.now_timestamp() - - insert("notes", { - 'note_id': noteId, - 'note_title': note['note_title'], - 'note_text': '', - 'note_clone_id': '', - 'date_created': now, - 'date_modified': now, - 'icon_info': 'pencil', - 'is_finished': 0, - 'encryption': note['encryption'] - }) - - insert("notes_tree", { - 'note_id': noteId, - 'note_pid': parent_note_id, - 'note_pos': new_note_pos, - 'is_expanded': 0 - }) - - commit() - - return jsonify({ - 'note_id': noteId - }) - - -@notes_api.route('/api/notes', methods = ['GET']) -@login_required -def search_notes(): - search = '%' + request.args['search'] + '%' - - result = getResults("select note_id from notes where note_title like ? or note_text like ?", [search, search]) - - noteIdList = [] - - for res in result: - noteIdList.append(res['note_id']) - - return jsonify(noteIdList) \ No newline at end of file diff --git a/src/notes_history_api.py b/src/notes_history_api.py deleted file mode 100644 index cd5d26d77..000000000 --- a/src/notes_history_api.py +++ /dev/null @@ -1,22 +0,0 @@ -from flask import Blueprint, jsonify -from flask_login import login_required - -from sql import getResults - -notes_history_api = Blueprint('notes_history_api', __name__) - - -@notes_history_api.route('/api/notes-history/', methods = ['GET']) -@login_required -def get_note_history(note_id): - history = getResults("select * from notes_history where note_id = ? order by date_modified desc", [note_id]) - - return jsonify(history) - - -@notes_history_api.route('/api/recent-changes/', methods = ['GET']) -@login_required -def get_recent_changes(): - recent_changes = getResults("select * from notes_history order by date_modified desc limit 1000") - - return jsonify(recent_changes) \ No newline at end of file diff --git a/src/notes_move_api.py b/src/notes_move_api.py deleted file mode 100644 index 616705bf5..000000000 --- a/src/notes_move_api.py +++ /dev/null @@ -1,70 +0,0 @@ -from flask import Blueprint, jsonify -from flask import request -from flask_login import login_required - -import audit_category -from sql import execute, commit, add_audit -from sql import getSingleResult - -notes_move_api = Blueprint('notes_move_api', __name__) - -@notes_move_api.route('/api/notes//moveTo/', methods = ['PUT']) -@login_required -def move_to_note(note_id, parent_id): - res = getSingleResult('select max(note_pos) as max_note_pos from notes_tree where note_pid = ?', [parent_id]) - max_note_pos = res['max_note_pos'] - new_note_pos = 0 - - if max_note_pos is None: # no children yet - new_note_pos = 0 - else: - new_note_pos = max_note_pos + 1 - - execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [parent_id, new_note_pos, note_id]) - - add_audit(audit_category.CHANGE_PARENT, request, note_id) - - commit() - return jsonify({}) - - -@notes_move_api.route('/api/notes//moveBefore/', methods = ['PUT']) -def move_before_note(note_id, before_note_id): - before_note = getSingleResult("select * from notes_tree where note_id = ?", [before_note_id]) - - if before_note <> None: - execute("update notes_tree set note_pos = note_pos + 1 where note_id = ?", [before_note_id]) - - execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [before_note['note_pid'], before_note['note_pos'], note_id]) - - add_audit(audit_category.CHANGE_POSITION, request, note_id) - - commit() - - return jsonify({}) - - -@notes_move_api.route('/api/notes//moveAfter/', methods = ['PUT']) -def move_after_note(note_id, after_note_id): - after_note = getSingleResult("select * from notes_tree where note_id = ?", [after_note_id]) - - if after_note <> None: - execute("update notes_tree set note_pos = note_pos + 1 where note_pid = ? and note_pos > ?", [after_note['note_pid'], after_note['note_pos']]) - - execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [after_note['note_pid'], after_note['note_pos'] + 1, note_id]) - - add_audit(audit_category.CHANGE_POSITION, request, note_id) - - commit() - - return jsonify({}) - - -@notes_move_api.route('/api/notes//expanded/', methods = ['PUT']) -def set_expanded_note(note_id, expanded): - execute("update notes_tree set is_expanded = ? where note_id = ?", [expanded, note_id]) - - # no audit here, not really important - - commit() - return jsonify({}) \ No newline at end of file diff --git a/src/password_api.py b/src/password_api.py deleted file mode 100644 index 72bebf18a..000000000 --- a/src/password_api.py +++ /dev/null @@ -1,16 +0,0 @@ -from flask import Blueprint, jsonify, request -from flask_login import login_required - -import change_password - -password_api = Blueprint('password_api', __name__) - - -@password_api.route('/api/password/change', methods = ['POST']) -@login_required -def change_password(): - req = request.get_json(force=True) - - result = change_password.change_password(req['current_password'], req['new_password']) - - return jsonify(result) diff --git a/src/routes.py b/src/routes.py deleted file mode 100644 index 458af5f14..000000000 --- a/src/routes.py +++ /dev/null @@ -1,101 +0,0 @@ -import base64 -import os - -from flask import render_template, redirect -from flask import request, send_from_directory, Blueprint -from flask_login import UserMixin, login_user, logout_user, LoginManager -from flask_login import login_required - -import my_scrypt -from migration_api import APP_DB_VERSION -from sql import get_option - - -class User(UserMixin): - pass - - -login_manager = LoginManager() -user = User() - - -def init(app): - login_manager.init_app(app) - login_manager.login_view = 'login_form' - - user.id = get_option('username') - - -routes = Blueprint('routes', __name__) - - -@routes.route('/login', methods=['GET']) -def login_form(): - return render_template('login.html') - - -@routes.route('/app', methods=['GET']) -@login_required -def show_app(): - db_version = int(get_option('db_version')) - - if db_version < APP_DB_VERSION: - return redirect('migration') - - return render_template('index.html') - - -@routes.route('/migration', methods=['GET']) -@login_required -def show_migration(): - return render_template('migration.html') - - -@routes.route('/logout', methods=['POST']) -@login_required -def logout(): - logout_user() - return redirect('login') - - -def verify_password(guessed_password): - hashed_password = base64.b64decode(get_option('password_verification_hash')) - - guess_hashed = my_scrypt.get_verification_hash(guessed_password) - - return guess_hashed == hashed_password - - -@routes.route('/login', methods=['POST']) -def login_post(): - guessedPassword = request.form['password'].encode('utf-8') - - if request.form['username'] == user.id and verify_password(guessedPassword): - rememberMe = True if 'remember-me' in request.form else False - - login_user(user, remember=rememberMe) - - return redirect('app') - else: - return render_template('login.html', failedAuth=True) - - -@routes.route('/stat/') -def send_stc(path): - return send_from_directory(os.path.join(os.getcwd(), 'static'), path) - - -@login_manager.user_loader -def load_user(user_id): - if user_id == user.id: - return user - else: - return None - - -@login_manager.unauthorized_handler -def unauthorized_handler(): - if request.path.startswith('/api'): - return 'Unauthorized', 401 - else: - return redirect('/login') \ No newline at end of file diff --git a/src/settings_api.py b/src/settings_api.py deleted file mode 100644 index 843adb4b9..000000000 --- a/src/settings_api.py +++ /dev/null @@ -1,39 +0,0 @@ -from flask import Blueprint, jsonify, request -from flask_login import login_required - -import sql -import audit_category - -settings_api = Blueprint('settings_api', __name__) - -ALLOWED_OPTIONS = ['encryption_session_timeout', 'history_snapshot_time_interval'] - - -@settings_api.route('/api/settings', methods = ['GET']) -@login_required -def get_settings(): - dict = {} - - settings = sql.getResults("SELECT opt_name, opt_value FROM options WHERE opt_name IN (%s)" % ',' . join('?' * len(ALLOWED_OPTIONS)), ALLOWED_OPTIONS) - - for set in settings: - dict[set['opt_name']] = set['opt_value'] - - return jsonify(dict) - - -@settings_api.route('/api/settings', methods = ['POST']) -@login_required -def set_settings(): - req = request.get_json(force=True) - - if req['name'] in ALLOWED_OPTIONS: - sql.add_audit(audit_category.SETTINGS, request, None, sql.get_option(req['name']), req['value'], req['name']) - - sql.set_option(req['name'], req['value']) - - sql.commit() - - return jsonify({}) - else: - return jsonify("not allowed option to set") \ No newline at end of file diff --git a/src/setup.py b/src/setup.py deleted file mode 100644 index 7b11430fa..000000000 --- a/src/setup.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python - -import base64 -import getpass -import hashlib -import os -from Crypto.Cipher import AES -from Crypto.Util import Counter - -from builtins import input - -import src.my_scrypt - -config = src.config_provider.getConfig() -src.sql.connect(config['Document']['documentPath']) - -username = src.sql.getOption("username") - -if username: - print("Application has been already set up.") - exit(1) - -print("Please provide your desired login credentials") - -username = input("Username: ") - -password1 = getpass.getpass() -password2 = getpass.getpass(prompt='Repeat the same password: ') - -if password1 == password2: - # urandom is secure enough, see https://docs.python.org/2/library/os.html - src.sql.setOption('flask_secret_key', base64.b64encode(os.urandom(32))) - src.sql.setOption('password_verification_salt', base64.b64encode(os.urandom(32))) - src.sql.setOption('password_derived_key_salt', base64.b64encode(os.urandom(32))) - - password_derived_key = src.my_scrypt.get_password_derived_key(password1) - - aes = AES.new(password_derived_key, AES.MODE_CTR, counter=Counter.new(128, initial_value=5)) - - data_key = os.urandom(32) - data_key_digest = hashlib.sha256(data_key).digest()[:4] - - encrypted_data_key = aes.encrypt(data_key_digest + data_key) - - src.sql.setOption('encrypted_data_key', base64.b64encode(encrypted_data_key)) - - verification_hash = src.my_scrypt.get_verification_hash(password1) - - src.sql.setOption('username', username) - src.sql.setOption('password_verification_hash', base64.b64encode(verification_hash)) - - src.sql.commit() - - print('Application has been set up. You can now login.') -else: - print('Entered passwords are not identical!') \ No newline at end of file diff --git a/src/sql.py b/src/sql.py deleted file mode 100644 index 3392f8f04..000000000 --- a/src/sql.py +++ /dev/null @@ -1,93 +0,0 @@ -import base64 -import sqlite3 - -import utils - -conn = None - - -def dict_factory(cursor, row): - d = {} - for idx, col in enumerate(cursor.description): - if isinstance(row[idx], buffer): - d[col[0]] = base64.b64encode(row[idx]) - else: - d[col[0]] = row[idx] - - return d - - -def connect(document_path): - global conn - conn = sqlite3.connect(document_path) - conn.row_factory = dict_factory - - -def insert(table_name, rec): - # FIXME: SQL injection! - keys = ','.join(rec.keys()) - question_marks = ','.join(list('?' * len(rec))) - values = tuple(rec.values()) - cursor = execute('INSERT INTO ' + table_name + ' (' + keys + ') VALUES (' + question_marks + ')', values) - return cursor.lastrowid - - -def set_option(name, value): - execute("UPDATE options SET opt_value = ? WHERE opt_name = ?", [value, name]) - - -def get_option(name): - return getSingleResult("SELECT opt_value FROM options WHERE opt_name = ?", [name])['opt_value'] - - -def add_audit(category, request=None, note_id=None, change_from=None, change_to=None, comment=None): - now = utils.now_timestamp() - - browser_id = None - - if request: - browser_id = request.headers['x-browser-id'] - - execute("INSERT INTO audit_log (date_modified, category, browser_id, note_id, change_from, change_to, comment)" - " VALUES (?, ?, ?, ?, ?, ?, ?)", [now, category, browser_id, note_id, change_from, change_to, comment]) - - -def deleteRecentAudits(category, request, note_id): - browser_id = request.headers['x-browser-id'] - - delete_cutoff = utils.now_timestamp() - 10 * 60; - - execute("DELETE FROM audit_log WHERE category = ? AND browser_id = ? AND note_id = ? AND date_modified > ?", - [category, browser_id, note_id, delete_cutoff]) - - -def delete(tablename, note_id): - execute("DELETE FROM " + tablename + " WHERE note_id = ?", [note_id]) - - -def execute(sql, params=[]): - cursor = conn.cursor() - cursor.execute(sql, params) - return cursor - - -def execute_script(sql): - cursor = conn.cursor() - cursor.executescript(sql) - return cursor - - -def getResults(sql, params=[]): - cursor = conn.cursor() - query = cursor.execute(sql, params) - return query.fetchall() - - -def getSingleResult(sql, params=()): - cursor = conn.cursor() - query = cursor.execute(sql, params) - return query.fetchone() - - -def commit(): - conn.commit() diff --git a/src/templates/index.html b/src/templates/index.html deleted file mode 100644 index 4923f36c9..000000000 --- a/src/templates/index.html +++ /dev/null @@ -1,276 +0,0 @@ - - - - - Trilium - - -
- - -
- - Create new top level note - - - - Collapse tree - - - - Collapse tree - - - - Search in notes - - - -
- -
-
- -
-
- - - - -   - - - - -
-
- -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/templates/login.html b/src/templates/login.html deleted file mode 100644 index 89c352064..000000000 --- a/src/templates/login.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - Login - - -
-
-
-

Trilium login

- - {% if failedAuth %} -
- Username and / or password are incorrect. Please try again. -
- {% endif %} - -
-
- -
- -
-
-
- -
- -
-
-
-
- -
-
-
- -
-
-
-
-
- - - - - \ No newline at end of file diff --git a/src/templates/migration.html b/src/templates/migration.html deleted file mode 100644 index 74e5e887c..000000000 --- a/src/templates/migration.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - Migration - - -
-

Migration

- - - - - - -
- - - - - - - - - - - \ No newline at end of file diff --git a/src/tree_api.py b/src/tree_api.py deleted file mode 100644 index 20aecc7c5..000000000 --- a/src/tree_api.py +++ /dev/null @@ -1,58 +0,0 @@ -import base64 -import os - -from flask import Blueprint, jsonify -from flask_login import login_required - -from sql import getResults, getSingleResult, get_option -import utils -import backup - -tree_api = Blueprint('tree_api', __name__) - - -@tree_api.route('/api/tree', methods = ['GET']) -@login_required -def get_tree(): - backup.regular_backup() - - notes = getResults("select " - "notes_tree.*, " - "COALESCE(clone.note_title, notes.note_title) as note_title, " - "notes.note_clone_id, " - "notes.encryption, " - "case when notes.note_clone_id is null or notes.note_clone_id = '' then 0 else 1 end as is_clone " - "from notes_tree " - "join notes on notes.note_id = notes_tree.note_id " - "left join notes as clone on notes.note_clone_id = clone.note_id " - "order by note_pid, note_pos") - - root_notes = [] - notes_map = {} - - for note in notes: - note['children'] = [] - - if not note['note_pid']: - root_notes.append(note) - - notes_map[note['note_id']] = note - - for note in notes: - if note['note_pid'] != "": - parent = notes_map[note['note_pid']] - - parent['children'].append(note) - parent['folder'] = True - - ret_object = { - 'notes': root_notes, - 'start_note_id': getSingleResult('select * from options where opt_name = "start_node"')['opt_value'], - 'password_verification_salt': get_option('password_verification_salt'), - 'password_derived_key_salt': get_option('password_derived_key_salt'), - 'encrypted_data_key': get_option('encrypted_data_key'), - 'encryption_session_timeout': get_option('encryption_session_timeout'), - 'browser_id': base64.b64encode(os.urandom(8)), 'full_load_time': utils.now_timestamp() - } - - return jsonify(ret_object) \ No newline at end of file diff --git a/src/utils.py b/src/utils.py deleted file mode 100644 index 6101144f3..000000000 --- a/src/utils.py +++ /dev/null @@ -1,6 +0,0 @@ -from datetime import datetime -import time - - -def now_timestamp(): - return int(time.mktime(datetime.utcnow().timetuple()))