mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
basic implementation of audit logging
This commit is contained in:
parent
47d296cf12
commit
a9698d362f
13
setup.py
13
setup.py
@ -1,18 +1,15 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import binascii
|
||||
import getpass
|
||||
import os
|
||||
import base64
|
||||
import getpass
|
||||
import hashlib
|
||||
import os
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util import Counter
|
||||
|
||||
from builtins import input
|
||||
|
||||
import src.config_provider
|
||||
import src.sql
|
||||
import src.my_scrypt
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.Util import Counter
|
||||
import hashlib
|
||||
|
||||
config = src.config_provider.getConfig()
|
||||
src.sql.connect(config['Document']['documentPath'])
|
||||
|
8
src/audit_category.py
Normal file
8
src/audit_category.py
Normal file
@ -0,0 +1,8 @@
|
||||
UPDATE_CONTENT = 'CONTENT'
|
||||
CHANGE_POSITION = 'POSITION'
|
||||
CREATE_NOTE = 'CREATE'
|
||||
DELETE_NOTE = 'DELETE'
|
||||
CHANGE_PARENT = 'PARENT'
|
||||
ENCRYPTION = 'ENCRYPTION'
|
||||
CHANGE_PASSWORD = 'PASSWORD'
|
||||
SETTINGS = 'SETTINGS'
|
@ -5,9 +5,10 @@ from Crypto.Util import Counter
|
||||
|
||||
import sql
|
||||
import my_scrypt
|
||||
import audit_category
|
||||
|
||||
|
||||
def change_password(current_password, new_password):
|
||||
def change_password(current_password, new_password, request = None):
|
||||
current_password_hash = base64.b64encode(my_scrypt.getVerificationHash(current_password))
|
||||
|
||||
if current_password_hash != sql.getOption('password_verification_hash'):
|
||||
@ -49,6 +50,8 @@ def change_password(current_password, new_password):
|
||||
|
||||
sql.setOption('password_verification_hash', new_password_verification_key)
|
||||
|
||||
sql.addAudit(audit_category.CHANGE_PASSWORD, request)
|
||||
|
||||
sql.commit()
|
||||
|
||||
return {
|
||||
|
@ -10,7 +10,9 @@ from flask_login import login_required
|
||||
|
||||
from sql import delete
|
||||
from sql import execute, insert, commit
|
||||
from sql import getResults, getSingleResult, getOption
|
||||
from sql import getResults, getSingleResult, getOption, addAudit
|
||||
|
||||
import audit_category
|
||||
|
||||
notes_api = Blueprint('notes_api', __name__)
|
||||
|
||||
@ -66,6 +68,9 @@ def updateNote(note_id):
|
||||
now
|
||||
])
|
||||
|
||||
if note['detail']['encryption'] != detail['encryption']:
|
||||
addAudit(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'],
|
||||
@ -105,6 +110,8 @@ def deleteNote(note_id):
|
||||
delete("notes_tree", note_id)
|
||||
delete("notes", note_id)
|
||||
|
||||
addAudit(audit_category.DELETE_NOTE, request, note_id)
|
||||
|
||||
commit()
|
||||
return jsonify({})
|
||||
|
||||
@ -137,6 +144,8 @@ def createChild(parent_note_id):
|
||||
else:
|
||||
raise Exception('Unknown target: ' + note['target'])
|
||||
|
||||
addAudit(audit_category.CREATE_NOTE, request, noteId)
|
||||
|
||||
now = math.floor(time.time())
|
||||
|
||||
insert("notes", {
|
||||
|
@ -1,7 +1,9 @@
|
||||
from flask import Blueprint, jsonify
|
||||
from flask import request
|
||||
from flask_login import login_required
|
||||
|
||||
from sql import execute, commit
|
||||
import audit_category
|
||||
from sql import execute, commit, addAudit
|
||||
from sql import getSingleResult
|
||||
|
||||
notes_move_api = Blueprint('notes_move_api', __name__)
|
||||
@ -20,6 +22,8 @@ def moveToNote(note_id, parent_id):
|
||||
|
||||
execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [parent_id, new_note_pos, note_id])
|
||||
|
||||
addAudit(audit_category.CHANGE_PARENT, request, note_id)
|
||||
|
||||
commit()
|
||||
return jsonify({})
|
||||
|
||||
@ -32,6 +36,8 @@ def moveBeforeNote(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])
|
||||
|
||||
addAudit(audit_category.CHANGE_POSITION, request, note_id)
|
||||
|
||||
commit()
|
||||
|
||||
return jsonify({})
|
||||
@ -45,6 +51,8 @@ def moveAfterNote(note_id, after_note_id):
|
||||
|
||||
execute("update notes_tree set note_pid = ?, note_pos = ? where note_id = ?", [after_note['note_pid'], after_note['note_pos'] + 1, note_id])
|
||||
|
||||
addAudit(audit_category.CHANGE_POSITION, request, note_id)
|
||||
|
||||
commit()
|
||||
|
||||
return jsonify({})
|
||||
@ -53,5 +61,7 @@ def moveAfterNote(note_id, after_note_id):
|
||||
def setExpandedNote(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({})
|
@ -2,6 +2,7 @@ from flask import Blueprint, jsonify, request
|
||||
from flask_login import login_required
|
||||
|
||||
import sql
|
||||
import audit_category
|
||||
|
||||
settings_api = Blueprint('settings_api', __name__)
|
||||
|
||||
@ -25,7 +26,10 @@ def set_settings():
|
||||
req = request.get_json(force=True)
|
||||
|
||||
if req['name'] in allowed_options:
|
||||
sql.addAudit(audit_category.SETTINGS, request, None, sql.getOption(req['name']), req['value'], req['name'])
|
||||
|
||||
sql.setOption(req['name'], req['value'])
|
||||
|
||||
sql.commit()
|
||||
|
||||
return jsonify({})
|
||||
|
14
src/sql.py
14
src/sql.py
@ -1,6 +1,9 @@
|
||||
import base64
|
||||
import sqlite3
|
||||
|
||||
import math
|
||||
import time
|
||||
|
||||
conn = None
|
||||
|
||||
def dict_factory(cursor, row):
|
||||
@ -32,6 +35,17 @@ def setOption(name, value):
|
||||
def getOption(name):
|
||||
return getSingleResult("SELECT opt_value FROM options WHERE opt_name = ?", [name])['opt_value']
|
||||
|
||||
def addAudit(category, request = None, note_id = None, change_from = None, change_to = None, comment = None):
|
||||
now = math.floor(time.time())
|
||||
|
||||
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 delete(tablename, note_id):
|
||||
execute("DELETE FROM " + tablename + " WHERE note_id = ?", [note_id])
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
import base64
|
||||
import os
|
||||
|
||||
from flask import Blueprint, jsonify
|
||||
from flask_login import login_required
|
||||
|
||||
@ -44,5 +47,6 @@ def getTree():
|
||||
retObject['password_derived_key_salt'] = getOption('password_derived_key_salt')
|
||||
retObject['encrypted_data_key'] = getOption('encrypted_data_key')
|
||||
retObject['encryption_session_timeout'] = getOption('encryption_session_timeout')
|
||||
retObject['browser_id'] = base64.b64encode(os.urandom(8))
|
||||
|
||||
return jsonify(retObject)
|
@ -95,6 +95,11 @@ $(function(){
|
||||
globalEncryptionSessionTimeout = resp.encryption_session_timeout;
|
||||
globalEncryptedDataKey = resp.encrypted_data_key;
|
||||
|
||||
// add browser ID header to all AJAX requests
|
||||
$.ajaxSetup({
|
||||
headers: { 'x-browser-id': resp.browser_id }
|
||||
});
|
||||
|
||||
if (document.location.hash) {
|
||||
startNoteId = document.location.hash.substr(1); // strip initial #
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user