diff --git a/frappe/api.py b/frappe/api.py index 9c693ab406..9a8b4989f8 100644 --- a/frappe/api.py +++ b/frappe/api.py @@ -178,20 +178,25 @@ def validate_auth_via_api_keys(): def validate_api_key_secret(api_key, api_secret, frappe_authorization_source=None): """ frappe_authorization_source to provide api key and secret for a doctype apart from User """ if not frappe_authorization_source: - frappe_authorization_source = 'User' - doc = frappe.db.get_value( - doctype=frappe_authorization_source, - filters={"api_key": api_key}, - fieldname=["name"] - ) - form_dict = frappe.local.form_dict - doc_secret = frappe.utils.password.get_decrypted_password(frappe_authorization_source, doc, fieldname="api_secret") - if api_secret == doc_secret: - fieldname = 'name' if frappe_authorization_source == 'User' else 'user' - if frappe_authorization_source == 'User': - fieldname = 'name' - else: - fieldname = 'user' - user = frappe.db.get_value(frappe_authorization_source, doc, fieldname) - frappe.set_user(user) - frappe.local.form_dict = form_dict \ No newline at end of file + user = frappe.db.get_value( + doctype="User", + filters={"api_key": api_key}, + fieldname=["name"] + ) + form_dict = frappe.local.form_dict + user_secret = frappe.utils.password.get_decrypted_password ("User", user, fieldname='api_secret') + if api_secret == user_secret: + frappe.set_user(user) + frappe.local.form_dict = form_dict + else: + doc = frappe.db.get_value( + doctype=frappe_authorization_source, + filters={"api_key": api_key}, + fieldname=["name"] + ) + form_dict = frappe.local.form_dict + doc_secret = frappe.utils.password.get_decrypted_password (frappe_authorization_source, doc, fieldname='api_secret') + if api_secret == doc_secret: + user = frappe.db.get_value(frappe_authorization_source, doc, 'user') + frappe.set_user(user) + frappe.local.form_dict = form_dict \ No newline at end of file diff --git a/frappe/events_streaming/doctype/event_consumer/event_consumer.json b/frappe/events_streaming/doctype/event_consumer/event_consumer.json index b349781998..3c9fcf076b 100644 --- a/frappe/events_streaming/doctype/event_consumer/event_consumer.json +++ b/frappe/events_streaming/doctype/event_consumer/event_consumer.json @@ -6,7 +6,10 @@ "engine": "InnoDB", "field_order": [ "subscribed_doctypes", - "callback_url" + "callback_url", + "user", + "api_key", + "api_secret" ], "fields": [ { @@ -21,11 +24,29 @@ "fieldname": "subscribed_doctypes", "fieldtype": "Table", "label": "Subscribed Doctypes", - "options": "Event Subscribed DocType", + "options": "Event Subscribed DocType" + }, + { + "fieldname": "api_key", + "fieldtype": "Data", + "label": "API Key", + "read_only": 1 + }, + { + "fieldname": "api_secret", + "fieldtype": "Password", + "label": "API Secret", + "read_only": 1 + }, + { + "fieldname": "user", + "fieldtype": "Link", + "label": "Event Subscriber", + "options": "User", "reqd": 1 } ], - "modified": "2019-08-29 21:00:03.302463", + "modified": "2019-09-08 22:25:29.141335", "modified_by": "Administrator", "module": "Events Streaming", "name": "Event Consumer", diff --git a/frappe/events_streaming/doctype/event_consumer/event_consumer.py b/frappe/events_streaming/doctype/event_consumer/event_consumer.py index dbeda7217c..25e6c38ba1 100644 --- a/frappe/events_streaming/doctype/event_consumer/event_consumer.py +++ b/frappe/events_streaming/doctype/event_consumer/event_consumer.py @@ -3,8 +3,30 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe +import requests +import time +import json from frappe.model.document import Document +from frappe.frappeclient import FrappeClient class EventConsumer(Document): pass + +@frappe.whitelist(allow_guest=True) +def register_consumer(event_consumer, subscribed_doctypes, user): + consumer = frappe.new_doc('Event Consumer') + consumer.callback_url = event_consumer + consumer.user = user + subscribed_doctypes = json.loads(subscribed_doctypes) + + for entry in subscribed_doctypes: + consumer.append('subscribed_doctypes',{ + 'ref_doctype': entry + }) + api_key = frappe.generate_hash(length=10) + api_secret = frappe.generate_hash(length=10) + consumer.api_key = api_key + consumer.api_secret = api_secret + consumer.insert(ignore_permissions = True) + return (api_key, api_secret) \ No newline at end of file diff --git a/frappe/events_streaming/doctype/event_producer/event_producer.json b/frappe/events_streaming/doctype/event_producer/event_producer.json index e1eaf13ff0..916acfca4b 100644 --- a/frappe/events_streaming/doctype/event_producer/event_producer.json +++ b/frappe/events_streaming/doctype/event_producer/event_producer.json @@ -7,7 +7,10 @@ "field_order": [ "producer_url", "subscribed_doctypes", - "last_update" + "last_update", + "user", + "api_key", + "api_secret" ], "fields": [ { @@ -22,18 +25,35 @@ "fieldname": "subscribed_doctypes", "fieldtype": "Table", "label": "Subscribed Doctypes", - "options": "Event Subscribed DocType", - "reqd": 1 + "options": "Event Subscribed DocType" }, { "fieldname": "last_update", "fieldtype": "Data", "label": "Last Update", - "read_only": 1, + "read_only": 1 + }, + { + "fieldname": "api_key", + "fieldtype": "Data", + "label": "API Key", + "read_only": 1 + }, + { + "fieldname": "api_secret", + "fieldtype": "Password", + "label": "API Secret", + "read_only": 1 + }, + { + "fieldname": "user", + "fieldtype": "Link", + "label": "Event Subscriber", + "options": "User", "reqd": 1 } ], - "modified": "2019-08-30 12:17:30.264969", + "modified": "2019-09-08 22:25:42.372289", "modified_by": "Administrator", "module": "Events Streaming", "name": "Event Producer", diff --git a/frappe/events_streaming/doctype/event_producer/event_producer.py b/frappe/events_streaming/doctype/event_producer/event_producer.py index 8194ce348a..ebc3f28007 100644 --- a/frappe/events_streaming/doctype/event_producer/event_producer.py +++ b/frappe/events_streaming/doctype/event_producer/event_producer.py @@ -11,31 +11,34 @@ from frappe.frappeclient import FrappeClient class EventProducer(Document): def after_insert(self): - self.update_event_consumer() + self.create_event_consumer() def on_update(self): - self.update_event_consumer() - - def update_event_consumer(self): producer_site = get_producer_site(self.producer_url) - try: - event_consumer = producer_site.get_doc('Event Consumer', get_current_node()) - event_consumer.subscribed_doctypes = [] - for entry in self.subscribed_doctypes: - event_consumer.subscribed_doctypes.append({ - 'ref_doctype': entry.ref_doctype - }) - event_consumer.event_subscriber = self.event_subscriber - producer_site.update(event_consumer) - except Exception: - consumer = frappe.new_doc('Event Consumer') - consumer.callback_url = get_current_node() - for entry in self.subscribed_doctypes: - consumer.append('subscribed_doctypes', { - 'ref_doctype': entry.ref_doctype - }) - consumer.event_subscriber = self.event_subscriber - producer_site.insert(consumer) + event_consumer = producer_site.get_doc('Event Consumer', get_current_node()) + event_consumer.subscribed_doctypes = [] + for entry in self.subscribed_doctypes: + event_consumer.subscribed_doctypes.append({ + 'ref_doctype': entry.ref_doctype + }) + event_consumer.user = self.user + producer_site.update(event_consumer) + + def create_event_consumer(self): + '''register event consumer on producer site''' + producer_site = FrappeClient(self.producer_url) + subscribed_doctypes = [] + for entry in self.subscribed_doctypes: + subscribed_doctypes.append(entry.ref_doctype) + (api_key, api_secret) = producer_site.post_request({ + 'cmd': 'frappe.events_streaming.doctype.event_consumer.event_consumer.register_consumer', + 'event_consumer': get_current_node(), + 'subscribed_doctypes': json.dumps(subscribed_doctypes), + 'user': self.user + }) + self.db_set('api_key', api_key) + self.db_set('api_secret', api_secret) + def get_current_node(): current_node = frappe.utils.get_url() @@ -46,7 +49,13 @@ def get_current_node(): return current_node def get_producer_site(producer_url): - producer_site = FrappeClient(producer_url, 'Administrator', 'root') + producer_doc = frappe.get_doc('Event Producer', producer_url) + producer_site = FrappeClient( + url=producer_url, + api_key=producer_doc.api_key, + api_secret=producer_doc.get_password('api_secret'), + frappe_authorization_source='Event Consumer' + ) return producer_site @frappe.whitelist() diff --git a/frappe/events_streaming/doctype/event_subscribed_doctype/event_subscribed_doctype.json b/frappe/events_streaming/doctype/event_subscribed_doctype/event_subscribed_doctype.json index 77fe2d97f2..b4ca4294c9 100644 --- a/frappe/events_streaming/doctype/event_subscribed_doctype/event_subscribed_doctype.json +++ b/frappe/events_streaming/doctype/event_subscribed_doctype/event_subscribed_doctype.json @@ -17,10 +17,10 @@ } ], "istable": 1, - "modified": "2019-08-29 11:35:00.625815", + "modified": "2019-09-08 20:52:52.660698", "modified_by": "Administrator", "module": "Events Streaming", - "name": "Event Subscribed DocType", + "name": "Event Subscribed Doctype", "owner": "Administrator", "permissions": [], "quick_entry": 1, diff --git a/frappe/frappeclient.py b/frappe/frappeclient.py index 13015821ac..e9f3578349 100644 --- a/frappe/frappeclient.py +++ b/frappe/frappeclient.py @@ -58,9 +58,10 @@ class FrappeClient(object): token = b64encode('{}:{}'. format(api_key, api_secret)) auth_header = {'Authorization': 'Basic {}'.format(token)} self.session.headers.update(auth_header) - if frappe_authorization_source: - auth_source = {'Frappe-Authorization-Source': frappe_authorization_source} - self.session.headers.update(auth_source) + if not frappe_authorization_source: + frappe_authorization_source = 'User' + auth_source = {'Frappe-Authorization-Source': frappe_authorization_source} + self.session.headers.update(auth_source) def logout(self): '''Logout session'''