diff --git a/frappe/core/doctype/transaction_log/__init__.py b/frappe/core/doctype/transaction_log/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/frappe/core/doctype/transaction_log/readme.md b/frappe/core/doctype/transaction_log/readme.md deleted file mode 100644 index 09162ef4f0..0000000000 --- a/frappe/core/doctype/transaction_log/readme.md +++ /dev/null @@ -1,16 +0,0 @@ -# Transaction Log Changelog - -## v1.0.0 -Initial version - -The line hash summarizes: -- The index of the row -- The timestamp -- The document raw data - -The chain hash summarizes: -- The previous line hash -- The current line hash - -## v1.0.1 -Modification of the timestamp fieldtype from "Time" to "Datetime" \ No newline at end of file diff --git a/frappe/core/doctype/transaction_log/test_transaction_log.py b/frappe/core/doctype/transaction_log/test_transaction_log.py deleted file mode 100644 index 0b2ffdd508..0000000000 --- a/frappe/core/doctype/transaction_log/test_transaction_log.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright (c) 2018, Frappe Technologies and Contributors -# License: MIT. See LICENSE -import hashlib - -import frappe -from frappe.tests import IntegrationTestCase - - -class TestTransactionLog(IntegrationTestCase): - def test_validate_chaining(self): - frappe.get_doc( - { - "doctype": "Transaction Log", - "reference_doctype": "Test Doctype", - "document_name": "Test Document 1", - "data": "first_data", - } - ).insert(ignore_permissions=True) - - second_log = frappe.get_doc( - { - "doctype": "Transaction Log", - "reference_doctype": "Test Doctype", - "document_name": "Test Document 2", - "data": "second_data", - } - ).insert(ignore_permissions=True) - - third_log = frappe.get_doc( - { - "doctype": "Transaction Log", - "reference_doctype": "Test Doctype", - "document_name": "Test Document 3", - "data": "third_data", - } - ).insert(ignore_permissions=True) - - sha = hashlib.sha256() - sha.update( - frappe.safe_encode(str(third_log.transaction_hash)) - + frappe.safe_encode(str(second_log.chaining_hash)) - ) - - self.assertEqual(sha.hexdigest(), third_log.chaining_hash) diff --git a/frappe/core/doctype/transaction_log/transaction_log.js b/frappe/core/doctype/transaction_log/transaction_log.js deleted file mode 100644 index 8f22b859f7..0000000000 --- a/frappe/core/doctype/transaction_log/transaction_log.js +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies and contributors -// For license information, please see license.txt - -frappe.ui.form.on("Transaction Log", {}); diff --git a/frappe/core/doctype/transaction_log/transaction_log.json b/frappe/core/doctype/transaction_log/transaction_log.json deleted file mode 100644 index ffe5b13eb4..0000000000 --- a/frappe/core/doctype/transaction_log/transaction_log.json +++ /dev/null @@ -1,124 +0,0 @@ -{ - "actions": [], - "creation": "2018-02-06 11:48:51.270524", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "row_index", - "section_break_2", - "reference_doctype", - "document_name", - "column_break_5", - "timestamp", - "checksum_version", - "section_break_8", - "previous_hash", - "transaction_hash", - "chaining_hash", - "data", - "amended_from" - ], - "fields": [ - { - "fieldname": "row_index", - "fieldtype": "Data", - "label": "Row Index", - "read_only": 1 - }, - { - "fieldname": "section_break_2", - "fieldtype": "Section Break" - }, - { - "fieldname": "reference_doctype", - "fieldtype": "Data", - "label": "Reference Document Type", - "read_only": 1 - }, - { - "fieldname": "document_name", - "fieldtype": "Data", - "label": "Document Name", - "read_only": 1 - }, - { - "fieldname": "column_break_5", - "fieldtype": "Column Break" - }, - { - "fieldname": "timestamp", - "fieldtype": "Datetime", - "label": "Timestamp", - "read_only": 1 - }, - { - "fieldname": "checksum_version", - "fieldtype": "Data", - "label": "Checksum Version", - "read_only": 1 - }, - { - "fieldname": "section_break_8", - "fieldtype": "Section Break" - }, - { - "fieldname": "previous_hash", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Previous Hash", - "read_only": 1 - }, - { - "fieldname": "transaction_hash", - "fieldtype": "Small Text", - "label": "Transaction Hash", - "read_only": 1 - }, - { - "fieldname": "chaining_hash", - "fieldtype": "Small Text", - "hidden": 1, - "label": "Chaining Hash", - "read_only": 1 - }, - { - "fieldname": "data", - "fieldtype": "Long Text", - "hidden": 1, - "label": "Data", - "read_only": 1 - }, - { - "fieldname": "amended_from", - "fieldtype": "Link", - "label": "Amended From", - "no_copy": 1, - "options": "Transaction Log", - "print_hide": 1, - "read_only": 1 - } - ], - "in_create": 1, - "links": [], - "modified": "2024-03-23 16:03:59.373102", - "modified_by": "Administrator", - "module": "Core", - "name": "Transaction Log", - "owner": "Administrator", - "permissions": [ - { - "email": 1, - "export": 1, - "print": 1, - "read": 1, - "report": 1, - "role": "Administrator", - "share": 1 - } - ], - "sort_field": "creation", - "sort_order": "DESC", - "states": [], - "track_changes": 1 -} \ No newline at end of file diff --git a/frappe/core/doctype/transaction_log/transaction_log.py b/frappe/core/doctype/transaction_log/transaction_log.py deleted file mode 100644 index ab1ef6e5ca..0000000000 --- a/frappe/core/doctype/transaction_log/transaction_log.py +++ /dev/null @@ -1,86 +0,0 @@ -# Copyright (c) 2021, Frappe Technologies and contributors -# License: MIT. See LICENSE - -import hashlib - -import frappe -from frappe.model.document import Document -from frappe.query_builder import DocType -from frappe.utils import cint, now_datetime - - -class TransactionLog(Document): - # begin: auto-generated types - # This code is auto-generated. Do not modify anything in this block. - - from typing import TYPE_CHECKING - - if TYPE_CHECKING: - from frappe.types import DF - - amended_from: DF.Link | None - chaining_hash: DF.SmallText | None - checksum_version: DF.Data | None - data: DF.LongText | None - document_name: DF.Data | None - previous_hash: DF.SmallText | None - reference_doctype: DF.Data | None - row_index: DF.Data | None - timestamp: DF.Datetime | None - transaction_hash: DF.SmallText | None - # end: auto-generated types - - def before_insert(self): - index = get_current_index() - self.row_index = index - self.timestamp = now_datetime() - if index != 1: - prev_hash = frappe.get_all( - "Transaction Log", filters={"row_index": str(index - 1)}, pluck="chaining_hash", limit=1 - ) - if prev_hash: - self.previous_hash = prev_hash[0] - else: - self.previous_hash = "Indexing broken" - else: - self.previous_hash = self.hash_line() - self.transaction_hash = self.hash_line() - self.chaining_hash = self.hash_chain() - self.checksum_version = "v1.0.1" - - def hash_line(self): - sha = hashlib.sha256() - sha.update( - frappe.safe_encode(str(self.row_index)) - + frappe.safe_encode(str(self.timestamp)) - + frappe.safe_encode(str(self.data)) - ) - return sha.hexdigest() - - def hash_chain(self): - sha = hashlib.sha256() - sha.update( - frappe.safe_encode(str(self.transaction_hash)) + frappe.safe_encode(str(self.previous_hash)) - ) - return sha.hexdigest() - - -def get_current_index(): - series = DocType("Series") - current = ( - frappe.qb.from_(series).where(series.name == "TRANSACTLOG").for_update().select("current") - ).run() - - if current and current[0][0] is not None: - current = current[0][0] - - frappe.db.sql( - """UPDATE `tabSeries` - SET `current` = `current` + 1 - where `name` = 'TRANSACTLOG'""" - ) - current = cint(current) + 1 - else: - frappe.db.sql("INSERT INTO `tabSeries` (name, current) VALUES ('TRANSACTLOG', 1)") - current = 1 - return current diff --git a/frappe/core/page/permission_manager/permission_manager.py b/frappe/core/page/permission_manager/permission_manager.py index 08bc2f3dab..bf4f150c59 100644 --- a/frappe/core/page/permission_manager/permission_manager.py +++ b/frappe/core/page/permission_manager/permission_manager.py @@ -22,7 +22,7 @@ from frappe.permissions import ( ) from frappe.utils.user import get_users_with_role as _get_user_with_role -not_allowed_in_permission_manager = ["DocType", "Patch Log", "Module Def", "Transaction Log"] +not_allowed_in_permission_manager = ["DocType", "Patch Log", "Module Def"] @frappe.whitelist() diff --git a/frappe/core/report/transaction_log_report/__init__.py b/frappe/core/report/transaction_log_report/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/frappe/core/report/transaction_log_report/transaction_log_report.js b/frappe/core/report/transaction_log_report/transaction_log_report.js deleted file mode 100644 index f8f132a6d1..0000000000 --- a/frappe/core/report/transaction_log_report/transaction_log_report.js +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (c) 2019, Frappe Technologies and contributors -// For license information, please see license.txt - -frappe.query_reports["Transaction Log Report"] = { - onload: function (query_report) { - query_report.add_make_chart_button = function () { - // - }; - }, -}; diff --git a/frappe/core/report/transaction_log_report/transaction_log_report.json b/frappe/core/report/transaction_log_report/transaction_log_report.json deleted file mode 100644 index 6d6fb78360..0000000000 --- a/frappe/core/report/transaction_log_report/transaction_log_report.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "add_total_row": 0, - "creation": "2018-03-15 18:37:48.783779", - "disabled": 0, - "docstatus": 0, - "doctype": "Report", - "idx": 0, - "is_standard": "Yes", - "modified": "2018-12-27 18:10:29.785415", - "modified_by": "Administrator", - "module": "Core", - "name": "Transaction Log Report", - "owner": "Administrator", - "prepared_report": 0, - "ref_doctype": "Transaction Log", - "report_name": "Transaction Log Report", - "report_type": "Script Report", - "roles": [ - { - "role": "Administrator" - }, - { - "role": "System Manager" - } - ] -} \ No newline at end of file diff --git a/frappe/core/report/transaction_log_report/transaction_log_report.py b/frappe/core/report/transaction_log_report/transaction_log_report.py deleted file mode 100644 index ef017f73b4..0000000000 --- a/frappe/core/report/transaction_log_report/transaction_log_report.py +++ /dev/null @@ -1,117 +0,0 @@ -# Copyright (c) 2021, Frappe Technologies and contributors -# License: MIT. See LICENSE - -import hashlib - -import frappe -from frappe import _ -from frappe.utils import format_datetime - - -def execute(filters=None): - columns, data = get_columns(filters), get_data(filters) - - return columns, data - - -def get_data(filters=None): - result = [] - logs = frappe.get_all("Transaction Log", fields=["*"], order_by="creation desc") - - for l in logs: - row_index = int(l.row_index) - if row_index > 1: - previous_hash = frappe.get_all( - "Transaction Log", - fields=["chaining_hash"], - filters={"row_index": row_index - 1}, - ) - if not previous_hash: - integrity = False - else: - integrity = check_data_integrity( - l.chaining_hash, l.transaction_hash, l.previous_hash, previous_hash[0]["chaining_hash"] - ) - - result.append( - [ - _(str(integrity)), - _(l.reference_doctype), - l.document_name, - l.owner, - l.modified_by, - format_datetime(l.timestamp, "YYYYMMDDHHmmss"), - ] - ) - else: - result.append( - [ - _("First Transaction"), - _(l.reference_doctype), - l.document_name, - l.owner, - l.modified_by, - format_datetime(l.timestamp, "YYYYMMDDHHmmss"), - ] - ) - - return result - - -def check_data_integrity(chaining_hash, transaction_hash, registered_previous_hash, previous_hash): - if registered_previous_hash != previous_hash: - return False - - calculated_chaining_hash = calculate_chain(transaction_hash, previous_hash) - - if calculated_chaining_hash != chaining_hash: - return False - else: - return True - - -def calculate_chain(transaction_hash, previous_hash): - sha = hashlib.sha256() - sha.update(transaction_hash.encode("utf-8") + previous_hash.encode("utf-8")) - return sha.hexdigest() - - -def get_columns(filters=None): - return [ - { - "label": _("Chain Integrity"), - "fieldname": "chain_integrity", - "fieldtype": "Data", - "width": 150, - }, - { - "label": _("Reference Doctype"), - "fieldname": "reference_doctype", - "fieldtype": "Data", - "width": 150, - }, - { - "label": _("Reference Name"), - "fieldname": "reference_name", - "fieldtype": "Data", - "width": 150, - }, - { - "label": _("Owner"), - "fieldname": "owner", - "fieldtype": "Data", - "width": 100, - }, - { - "label": _("Modified By"), - "fieldname": "modified_by", - "fieldtype": "Data", - "width": 100, - }, - { - "label": _("Timestamp"), - "fieldname": "timestamp", - "fieldtype": "Data", - "width": 100, - }, - ]