From 6822047d5b8695ba59abff1000e9be1fd38b376b Mon Sep 17 00:00:00 2001 From: Mangesh-Khairnar Date: Thu, 14 Feb 2019 11:34:48 +0530 Subject: [PATCH] feat: check scope of doctype based on roles before anonymization --- frappe/hooks.py | 48 ++++++++++++++++++- .../personal_data_deletion_request.py | 5 +- .../personal_data_download_request.py | 7 ++- .../test_personal_data_download_request.py | 4 +- .../request_to_delete_data.json | 4 +- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/frappe/hooks.py b/frappe/hooks.py index 66af08820d..a393bde095 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -173,7 +173,7 @@ scheduler_events = { "frappe.email.doctype.auto_email_report.auto_email_report.send_daily", "frappe.core.doctype.feedback_request.feedback_request.delete_feedback_request", "frappe.core.doctype.activity_log.activity_log.clear_authentication_logs", - "frappe.website.doctype.personal_data_delete_request.personal_data_delete_request", + "frappe.website.doctype.personal_data_deletion_request.personal_data_deletion_request.remove_unverified_record", ], "daily_long": [ "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily", @@ -229,10 +229,56 @@ before_migrate = ['frappe.patches.v11_0.sync_user_permission_doctype_before_migr otp_methods = ['OTP App','Email','SMS'] user_privacy_documents = [ + { + 'doctype': 'User', + 'match_field': 'email', + 'personal_fields': ['first_name', 'middle_name', 'last_name', 'full_name', 'username', 'user_image', 'phone', + 'mobile_no', 'location', 'banner_image', 'interest', 'bio', 'email_signature', 'background_image'], + 'action': 'skip', + 'applies_to_website_user': 1 + }, + { + 'doctype': 'File', + 'match_field': 'attached_to_name', + 'personal_fields': ['file_name', 'file_url'], + 'action': 'skip' + }, + { + 'doctype': 'Email Group Member', + 'match_field': 'email', + 'action': 'delete' + }, + { + 'doctype': 'Email Unsubscribe', + 'match_field': 'email', + 'action': 'delete' + }, + { + 'doctype': 'Email Queue', + 'match_field': 'sender', + 'action': 'delete' + }, + { + 'doctype': 'Email Queue Recipient', + 'match_field': 'recipient', + 'action': 'delete' + }, { 'doctype': 'Contact', 'match_field': 'email_id', 'personal_fields': ['first_name', 'last_name', 'phone', 'mobile_no'], 'action': 'delete' }, + { + 'doctype': 'Communication', + 'match_field': 'sender', + 'personal_fields': ['sender_full_name', 'phone_no', 'content'], + 'action': 'delete' + }, + { + 'doctype': 'Communication', + 'match_field': 'recipients', + 'action': 'delete' + }, + ] \ No newline at end of file diff --git a/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py b/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py index da52c7970d..d22b783dc9 100644 --- a/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py +++ b/frappe/website/doctype/personal_data_deletion_request/personal_data_deletion_request.py @@ -30,13 +30,12 @@ class PersonalDataDeletionRequest(Document): def anonymize_data(self): if 'System Manager' not in frappe.get_roles(frappe.session.user) and self.status != 'Pending Approval': frappe.throw(_("You are not authorized to complete this action.")) - - scope = 'unrestricted' if 'Guest' in frappe.get_roles(self.email) else 'restricted' privacy_docs = frappe.get_hooks("user_privacy_documents") for ref_doc in privacy_docs: - if ref_doc['action'] == 'skip' and scope == 'restricted': + if ref_doc.get('applies_to_website_user') and 'Guest' not in frappe.get_roles(self.email): continue + frappe.db.sql("""UPDATE `tab{0}` SET `{1}` = '{2}' {3} WHERE `{1}` = '{4}' """.format(ref_doc['doctype'], ref_doc['match_field'], self.name,#nosec diff --git a/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py b/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py index 23ee331d69..1251e32ef1 100644 --- a/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py +++ b/frappe/website/doctype/personal_data_download_request/personal_data_download_request.py @@ -26,7 +26,7 @@ class PersonalDataDownloadRequest(Document): 'content': str(personal_data), 'is_private': 1 }) - f.save() + f.save(ignore_permissions=True) host_name = frappe.local.site frappe.sendmail(recipients= frappe.session.user, @@ -40,9 +40,8 @@ def get_user_data(user): hooks = frappe.get_hooks("user_privacy_documents") data = {} for hook in hooks: - d = [] - for email_field in hook.get('match_field'): - d += frappe.get_all(hook.get('doctype'), {email_field: user}, ["*"]) + d = data.get(hook.get('doctype'),[]) + d += frappe.get_all(hook.get('doctype'), {hook.get('match_field'): user}, ["*"]) if d: data.update({ hook.get('doctype'):d }) return data \ No newline at end of file diff --git a/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py b/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py index 9042946986..fc49f46f13 100644 --- a/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py +++ b/frappe/website/doctype/personal_data_download_request/test_personal_data_download_request.py @@ -15,11 +15,13 @@ class TestRequestPersonalData(unittest.TestCase): def test_user_data(self): user_data = get_user_data('test_privacy@example.com') expected_data = {'Contact': frappe.get_all('Contact', {'email_id':'test_privacy@example.com'},["*"])} - self.assertEqual(user_data, expected_data) + self.assertEqual({'Contact': user_data['Contact']}, expected_data) def test_file_and_email_creation(self): + frappe.set_user('test_privacy@example.com') download_request = frappe.get_doc({"doctype": 'Personal Data Download Request', 'user': 'test_privacy@example.com'}) download_request.save(ignore_permissions=True) + frappe.set_user('Administrator') f = frappe.get_all('File', {'attached_to_doctype':'Personal Data Download Request', 'attached_to_name': download_request.name}, diff --git a/frappe/website/web_form/request_to_delete_data/request_to_delete_data.json b/frappe/website/web_form/request_to_delete_data/request_to_delete_data.json index d2d543fdbe..f6d9d23628 100644 --- a/frappe/website/web_form/request_to_delete_data/request_to_delete_data.json +++ b/frappe/website/web_form/request_to_delete_data/request_to_delete_data.json @@ -10,14 +10,14 @@ "amount_based_on_field": 0, "creation": "2019-01-25 14:24:12.588810", "currency": "INR", - "doc_type": "Personal Data Delete Request", + "doc_type": "Personal Data Deletion Request", "docstatus": 0, "doctype": "Web Form", "idx": 0, "is_standard": 1, "login_required": 1, "max_attachment_size": 0, - "modified": "2019-02-03 20:07:18.254381", + "modified": "2019-02-12 15:40:28.543104", "modified_by": "Administrator", "module": "Website", "name": "request-to-delete-data",