mirror of
				https://github.com/zadam/trilium.git
				synced 2025-11-04 13:39:01 +01: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