fix: event consumer authentication
This commit is contained in:
parent
dff86d5c23
commit
ee2e1936d3
7 changed files with 132 additions and 54 deletions
|
|
@ -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
|
||||
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
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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'''
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue