From 205ae2675157a08496623dc923661f8b5ecd196c Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 10 Oct 2016 17:16:21 +0530 Subject: [PATCH] [fix] refactor integration services (#2087) * [fix] refactor integration services * [fix] patch fix * [fix] added redirect url. * [fix] custom redirect to and reditect message for paypal and service setup information * [minor][fix] remove ldap dependancy from requirements --- frappe/config/setup.py | 5 +- frappe/hooks.py | 2 +- .../integration_service.js | 132 ++-------- .../integration_service.json | 136 +--------- .../integration_service.py | 77 +----- .../doctype/dropbox_settings/__init__.py | 0 .../dropbox_settings/dropbox_settings.js | 64 +++++ .../dropbox_settings/dropbox_settings.json | 241 ++++++++++++++++++ .../dropbox_settings/dropbox_settings.py} | 185 +++++++------- .../dropbox_settings/test_dropbox_settings.py | 12 + .../doctype/ldap_settings/__init__.py | 0 .../doctype/ldap_settings/ldap_settings.js | 31 +++ .../doctype/ldap_settings/ldap_settings.json | 162 ++++++++++++ .../doctype/ldap_settings/ldap_settings.py | 168 ++++++++++++ .../doctype/paypal_settings/__init__.py | 0 .../paypal_settings/paypal_settings.js | 31 +++ .../paypal_settings/paypal_settings.json | 190 ++++++++++++++ .../paypal_settings/paypal_settings.py} | 174 +++++++------ .../doctype/razorpay_settings/__init__.py | 0 .../razorpay_settings/razorpay_settings.js | 33 +++ .../razorpay_settings/razorpay_settings.json | 137 ++++++++++ .../razorpay_settings/razorpay_settings.py} | 129 ++++++---- frappe/integrations/ldap_auth.py | 139 ---------- frappe/patches.txt | 1 + .../v7_1/refactor_integration_broker.py | 52 ++++ .../js/integrations/dropbox_integration.js | 48 ---- frappe/public/js/integrations/ldap_auth.js | 15 -- frappe/public/js/integrations/paypal.js | 21 -- .../pages/integrations/razorpay_checkout.py | 8 +- frappe/www/login.py | 2 +- requirements.txt | 1 - 31 files changed, 1433 insertions(+), 763 deletions(-) create mode 100644 frappe/integrations/doctype/dropbox_settings/__init__.py create mode 100644 frappe/integrations/doctype/dropbox_settings/dropbox_settings.js create mode 100644 frappe/integrations/doctype/dropbox_settings/dropbox_settings.json rename frappe/integrations/{dropbox_integration.py => doctype/dropbox_settings/dropbox_settings.py} (68%) create mode 100644 frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py create mode 100644 frappe/integrations/doctype/ldap_settings/__init__.py create mode 100644 frappe/integrations/doctype/ldap_settings/ldap_settings.js create mode 100644 frappe/integrations/doctype/ldap_settings/ldap_settings.json create mode 100644 frappe/integrations/doctype/ldap_settings/ldap_settings.py create mode 100644 frappe/integrations/doctype/paypal_settings/__init__.py create mode 100644 frappe/integrations/doctype/paypal_settings/paypal_settings.js create mode 100644 frappe/integrations/doctype/paypal_settings/paypal_settings.json rename frappe/integrations/{paypal.py => doctype/paypal_settings/paypal_settings.py} (63%) create mode 100644 frappe/integrations/doctype/razorpay_settings/__init__.py create mode 100644 frappe/integrations/doctype/razorpay_settings/razorpay_settings.js create mode 100644 frappe/integrations/doctype/razorpay_settings/razorpay_settings.json rename frappe/integrations/{razorpay.py => doctype/razorpay_settings/razorpay_settings.py} (74%) delete mode 100644 frappe/integrations/ldap_auth.py create mode 100644 frappe/patches/v7_1/refactor_integration_broker.py delete mode 100644 frappe/public/js/integrations/dropbox_integration.js delete mode 100644 frappe/public/js/integrations/ldap_auth.js delete mode 100644 frappe/public/js/integrations/paypal.js diff --git a/frappe/config/setup.py b/frappe/config/setup.py index 9dc8b1feaf..91cba064df 100644 --- a/frappe/config/setup.py +++ b/frappe/config/setup.py @@ -222,9 +222,8 @@ def get_data(): }, { "type": "doctype", - "name": "Dropbox Backup", - "description": _("Manage cloud backups on Dropbox"), - "hide_count": True + "name": "Integration Service", + "description": _("Centralize access to Integrations"), } ] }, diff --git a/frappe/hooks.py b/frappe/hooks.py index 441252eab8..3211a2f96c 100755 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -176,4 +176,4 @@ bot_parsers = [ setup_wizard_exception = "frappe.desk.page.setup_wizard.setup_wizard.email_setup_wizard_exception" before_write_file = "frappe.limits.validate_space_limit" -integration_services = ["PayPal", "Razorpay", "Dropbox Integration", "LDAP Auth"] +integration_services = ["PayPal", "Razorpay", "Dropbox", "LDAP"] diff --git a/frappe/integration_broker/doctype/integration_service/integration_service.js b/frappe/integration_broker/doctype/integration_service/integration_service.js index 9eea8bf6b6..04c407dc3e 100644 --- a/frappe/integration_broker/doctype/integration_service/integration_service.js +++ b/frappe/integration_broker/doctype/integration_service/integration_service.js @@ -1,6 +1,13 @@ // Copyright (c) 2016, Frappe Technologies and contributors // For license information, please see license.txt +frappe.provide("frappe.integration_service"); + +{% include 'frappe/integrations/doctype/razorpay_settings/razorpay_settings.js' %} +{% include 'frappe/integrations/doctype/paypal_settings/paypal_settings.js' %} +{% include 'frappe/integrations/doctype/dropbox_settings/dropbox_settings.js' %} +{% include 'frappe/integrations/doctype/ldap_settings/ldap_settings.js' %} + frappe.ui.form.on('Integration Service', { onload: function(frm) { frappe.call({ @@ -13,119 +20,36 @@ frappe.ui.form.on('Integration Service', { refresh: function(frm){ if (frm.doc.service){ - frm.events.load_js_resouce(frm); + frm.events.setup_custom_buttons(frm); + frm.events.setup_service_details(frm); } }, - - load_js_resouce: function(frm){ - frappe.call({ - method: 'frappe.integration_broker.doctype.integration_service.integration_service.get_js_resouce', - args: { - 'service': frm.doc.service - }, - callback: function(r) { - $(frm.fields_dict.custom_settings.wrapper).empty(); - - if (r.message.js){ - frm.clear_custom_buttons(); - frappe.require(r.message.js, function(){ - service_name = frm.doc.service.toLowerCase().replace(/ /g, "_"); - frappe.integration_service[service_name].load(frm); - - $(frm.fields_dict.scheduler_events_html.wrapper).empty(); - - if (frappe.integration_service[service_name].scheduler_job_helper) { - frm.scheduler_helper = frappe.integration_service[service_name].scheduler_job_helper(); - frm.events.render_scheduler_jobs(frm); - } - }) - } - - frm.events.load_parameters(frm); - } - }) - }, - load_parameters: function(frm) { - var form = frm; - - frappe.call({ - method: 'frappe.integration_broker.doctype.integration_service.integration_service.get_service_parameters', - args: { - 'service': frm.doc.service - }, - callback: function(r) { - frm.fields = r.message.parameters; - frm.scheduler_jobs = r.message.scheduled_jobs; - frm.events.show_properties(frm); - } + setup_custom_buttons: function(frm) { + frm.add_custom_button(__("{0} Settings", [frm.doc.service]), function(){ + frappe.set_route("List", frm.doc.service + " Settings"); }); - }, - - edit_settings: function(frm) { - frm.events.setup_dialog(frm); - }, - - setup_dialog: function(frm){ - var d = new frappe.ui.Dialog({ - title:__('Custom Settings'), - fields: frm.fields + + frm.add_custom_button(__("Show Log"), function(){ + frappe.route_options = {"integration_request_service": frm.doc.service}; + frappe.set_route("List", "Integration Request"); }); - - // set_value - if(frm.doc.custom_settings_json){ - d.set_values(JSON.parse(frm.doc.custom_settings_json)); - } - - d.set_primary_action(__("Set"), function() { - var btn = this; - var v = d.get_values(); - if(!v) return; - - frm.set_value("custom_settings_json", JSON.stringify(v)); - frm.refresh_field("custom_settings_json"); - d.hide(); - frm.events.show_properties(frm); - }) - - d.show(); }, - - show_properties:function(frm){ - var frm = frm; - var table_wrapper = frm.fields_dict.custom_settings.wrapper; - - frm.settings = frm.doc.custom_settings_json ? JSON.parse(frm.doc.custom_settings_json) : {}; + + setup_service_details: function(frm) { + var service_name = frm.doc.service.toLowerCase().replace(/ /g, "_"); + var service_handelr = service_name + "_settings"; + service_handelr = new frappe.integration_service[service_handelr](); + service_handelr.get_service_info(frm); - $(table_wrapper).empty(); - $(table_wrapper).append('\ - \ - \ - \ - \ - \ - \ - \ - \ -
Parameter Value
') - - frm.fields.forEach(function(d){ - var df = d; - $row = $("").appendTo($(table_wrapper).find("tbody")); - $("").appendTo($row).html(__(d.label)).css("font-size", "12px"); - pwd_length = frm.settings[d.fieldname] ? frm.settings[d.fieldname].length : 0 - value = (d.fieldtype == "Password") ? "*".repeat(pwd_length) : frm.settings[d.fieldname]; - $("").appendTo($row).html(value).css("font-size", "12px"); - }); + var scheduler_job_info = service_handelr.get_scheduler_job_info(); + frm.events.render_scheduler_jobs(frm, scheduler_job_info); - $(table_wrapper).find(".table-bordered").click(function(){ - frm.events.setup_dialog(frm); - }) }, - render_scheduler_jobs: function(frm) { + render_scheduler_jobs: function(frm, scheduler_job_info) { var schduler_job_view = frm.fields_dict.scheduler_events_html.wrapper; - + $(schduler_job_view).empty(); $(schduler_job_view).append('\ \ @@ -137,8 +61,8 @@ frappe.ui.form.on('Integration Service', { \ \
') - - $.each(frm.scheduler_helper, function(evnt, help){ + + $.each(scheduler_job_info, function(evnt, help){ $row = $("").appendTo($(schduler_job_view).find("tbody")); $("").appendTo($row).html(evnt).css("font-size", "12px"); $("").appendTo($row).html(help).css("font-size", "12px"); diff --git a/frappe/integration_broker/doctype/integration_service/integration_service.json b/frappe/integration_broker/doctype/integration_service/integration_service.json index a57e236f01..774a3d287f 100644 --- a/frappe/integration_broker/doctype/integration_service/integration_service.json +++ b/frappe/integration_broker/doctype/integration_service/integration_service.json @@ -70,34 +70,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "use_test_account", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Use Test Account", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "column_break_4", - "fieldtype": "Column Break", + "fieldname": "section_break_3", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -143,109 +117,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "section_break_4", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "custom_settings", - "fieldtype": "HTML", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "edit_settings", - "fieldtype": "Button", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "Edit Settings", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "custom_settings_json", - "fieldtype": "Code", - "hidden": 1, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "label": "", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -308,7 +179,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2016-09-24 05:48:04.652766", + "modified": "2016-10-06 06:14:48.271314", "modified_by": "Administrator", "module": "Integration Broker", "name": "Integration Service", @@ -325,6 +196,7 @@ "export": 1, "if_owner": 0, "import": 0, + "is_custom": 0, "permlevel": 0, "print": 1, "read": 1, diff --git a/frappe/integration_broker/doctype/integration_service/integration_service.py b/frappe/integration_broker/doctype/integration_service/integration_service.py index 1ce2a58dbb..0d52637528 100644 --- a/frappe/integration_broker/doctype/integration_service/integration_service.py +++ b/frappe/integration_broker/doctype/integration_service/integration_service.py @@ -13,35 +13,16 @@ from frappe.utils import get_request_session class IntegrationService(Document): def on_update(self): if self.enabled: - self.enable_service() - self.install_fixtures() - - def get_controller(self): - if not getattr(self, '_controller', None): - self._controller = get_integration_controller(self.service, setup=False) - return self._controller - - def get_parameters(self): - parameters = {} - if self.custom_settings_json: - parameters = json.loads(self.custom_settings_json) - return parameters + if not self.flags.ignore_mandatory: + self.enable_service() + self.install_fixtures() def install_fixtures(self): pass def enable_service(self): - if not self.flags.ignore_mandatory: - self.get_controller().enable(self.get_parameters(), self.use_test_account) - - def setup_events_and_parameters(self): - self.parameters = [] - for d in self.get_controller().parameters_template: - self.parameters.append({'label': d.label, "value": d.value}) - - self.events = [] - for d in self.get_controller()._events: - self.parameters.append({'event': d.event, 'enabled': d.enabled}) + service_doc = "{0} Settings".format(self.service) + frappe.get_doc(service_doc).enable() #rest request handler def get_request(self, url, auth=None, data=None): @@ -99,46 +80,12 @@ class IntegrationService(Document): return integration_request -@frappe.whitelist() -def get_service_parameters(service): - controller = get_integration_controller(service, setup=False) - return { - 'parameters': controller.parameters_template, - } - -@frappe.whitelist() -def get_js_resouce(service): - controller = get_integration_controller(service, setup=False) - return { - "js": getattr(controller, "js", "") - } - -def get_integration_controller(service_name, setup=True): +def get_integration_controller(service_name): '''Returns integration controller module from app_name.integrations.{service}''' - def load_from_app(app, service_name): - try: - controller_module = frappe.get_module("{app}.integrations.{service}" - .format(app=app, service=service_name.strip().lower().replace(' ','_'))) - controller = controller_module.Controller(setup=setup) - - # make default properites and frappe._dictify - for key in ('events', 'parameters_template'): - tmp = [] - for d in getattr(controller, key, []): - tmp.append(frappe._dict(d)) - setattr(controller, key, tmp) - - return controller - - except ImportError: - pass - - for app in frappe.get_installed_apps(): - controller = load_from_app(app, service_name) - if controller: - return controller - - frappe.throw(_("Module {service} not found".format(service=service_name))) + try: + return frappe.get_doc("{0} Settings".format(service_name)) + except Exception: + frappe.throw(_("Module {service} not found".format(service=service_name))) @frappe.whitelist() def get_integration_services(): @@ -150,11 +97,11 @@ def get_integration_services(): def trigger_integration_service_events(): for service in frappe.get_all("Integration Service", filters={"enabled": 1}, fields=["name"]): - controller = get_integration_controller(service.name, setup=False) + controller = get_integration_controller(service.name) if hasattr(controller, "scheduled_jobs"): for job in controller.scheduled_jobs: for event, handlers in job.items(): for handler in handlers: if handler not in get_jobs(): - enqueue(handler, queue='short', event=event) + enqueue(handler, queue='short', event=event) \ No newline at end of file diff --git a/frappe/integrations/doctype/dropbox_settings/__init__.py b/frappe/integrations/doctype/dropbox_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js new file mode 100644 index 0000000000..c9427e8183 --- /dev/null +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.js @@ -0,0 +1,64 @@ +// Copyright (c) 2016, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.provide("frappe.integration_service") + +frappe.ui.form.on('Dropbox Settings', { + refresh: function(frm) { + frm.clear_custom_buttons(); + frm.events.take_backup(frm); + }, + + allow_dropbox_access: function(frm) { + if (frm.doc.app_access_key && frm.doc.app_secret_key) { + frappe.call({ + method: "frappe.integrations.doctype.dropbox_settings.dropbox_settings.get_dropbox_authorize_url", + freeze: true, + callback: function(r) { + if(!r.exc) { + frm.save(); + window.open(r.message.url); + } + } + }) + } + else { + frappe.msgprint(__("Please enter values for App Access Key and App Secret Key")) + } + }, + + take_backup: function(frm) { + if (frm.doc.app_access_key && frm.doc.app_secret_key && frm.doc.dropbox_access_key && frm.doc.dropbox_access_secret) { + frm.add_custom_button(__("Take Backup Now"), function(frm){ + frappe.call({ + method: "frappe.integrations.dropbox_integration.take_backup", + freeze: true + }) + }).addClass("btn-primary") + } + } +}); + +frappe.integration_service.dropbox_settings = Class.extend({ + init: function(frm) { + + }, + + get_scheduler_job_info: function() { + return { + "Daily": "Take backup of database and files to dropbox on daily basis", + "Weekly": "Take backup of database and files to dropbox on weekly basis" + } + }, + + get_service_info: function(frm) { + frappe.call({ + method: "frappe.integrations.doctype.dropbox_settings.dropbox_settings.get_service_details", + callback: function(r){ + var integration_service_help = frm.fields_dict.integration_service_help.wrapper; + $(integration_service_help).empty(); + $(integration_service_help).append(r.message); + } + }) + } +}) diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json new file mode 100644 index 0000000000..e597410033 --- /dev/null +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.json @@ -0,0 +1,241 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-09-21 10:12:57.399174", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "System", + "editable_grid": 1, + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "send_notifications_to", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Send Notifications To", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "backup_frequency", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Backup Frequency", + "length": 0, + "no_copy": 0, + "options": "\nDaily\nWeekly", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "app_access_key", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "App Access Key", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "app_secret_key", + "fieldtype": "Password", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "App Secret Key", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow_dropbox_access", + "fieldtype": "Button", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Allow Dropbox Access", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "dropbox_access_key", + "fieldtype": "Password", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Dropbox Access Key", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "dropbox_access_secret", + "fieldtype": "Password", + "hidden": 1, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Dropbox Access Secret", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 1, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2016-09-22 03:55:40.716643", + "modified_by": "Administrator", + "module": "Integrations", + "name": "Dropbox Settings", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 1, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/frappe/integrations/dropbox_integration.py b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py similarity index 68% rename from frappe/integrations/dropbox_integration.py rename to frappe/integrations/doctype/dropbox_settings/dropbox_settings.py index c38b408a88..3400971087 100644 --- a/frappe/integrations/dropbox_integration.py +++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py @@ -1,58 +1,20 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals import frappe +import os from frappe import _ -from frappe.integration_broker.integration_controller import IntegrationController -from frappe.utils import (cint, split_emails, get_request_site_address, cstr, - get_files_path, get_backups_path, encode) -import os, json from frappe.utils.backups import new_backup from frappe.utils.background_jobs import enqueue +from frappe.utils import (cint, split_emails, get_request_site_address, cstr, + get_files_path, get_backups_path, encode) +from frappe.integration_broker.doctype.integration_service.integration_service import IntegrationService ignore_list = [".DS_Store"] -class Controller(IntegrationController): - service_name = 'Dropbox Integration' - parameters_template = [ - { - "label": "App Access Key", - 'fieldname': 'app_access_key', - 'reqd': 1, - 'default': '', - 'fieldtype': "Data" - }, - { - "label": "App Secret Key", - 'fieldname': 'app_secret_key', - 'reqd': 1, - 'default': '', - 'fieldtype': "Password" - }, - { - "label": "Dropbox Access Key", - 'fieldname': 'dropbox_access_key', - 'reqd': 1, - 'default': '****', - 'fieldtype': "Password" - }, - { - "label": "Dropbox Secret Key", - 'fieldname': 'dropbox_access_secret', - 'reqd': 1, - 'default': '****', - 'fieldtype': "Password" - }, - { - "label": "Backup Frequency", - "fieldname": "backup_frequency", - "options": "\nDaily\nWeekly", - "default": "", - "reqd": 1, - "fieldtype":'Select' - } - ] - - js = "assets/frappe/js/integrations/dropbox_integration.js" - - # do also changes in dropbox_integration.js scheduler job helper +class DropboxSettings(IntegrationService): scheduled_jobs = [ { "daily_long": [ @@ -64,10 +26,17 @@ class Controller(IntegrationController): } ] - def enable(self, parameters, use_test_account=0): + def validate(self): + if not self.flags.ignore_mandatory: + self.validate_dropbox_credentails() + + def on_update(self): + pass + + def enable(self): """ enable service """ - self.parameters = parameters - self.validate_dropbox_credentails() + if not self.flags.ignore_mandatory: + self.validate_dropbox_credentails() def validate_dropbox_credentails(self): try: @@ -80,30 +49,71 @@ class Controller(IntegrationController): from dropbox import session except: raise Exception(_("Please install dropbox python module")) - parameters = frappe._dict(self.parameters) - if not (parameters["app_access_key"] or parameters["app_secret_key"]): + + if not (self.app_access_key or self.app_secret_key): raise Exception(_("Please set Dropbox access keys in your site config")) - - sess = session.DropboxSession(parameters["app_access_key"], parameters["app_secret_key"], "app_folder") + + sess = session.DropboxSession(self.app_access_key, + self.get_password(fieldname="app_secret_key", raise_exception=False), "app_folder") return sess +@frappe.whitelist() +def get_service_details(): + return """ +
+ Steps to enable dropbox backup service: +
    +
  1. Create a dropbox app then get App Key and App Secret, + + https://www.dropbox.com/developers/apps + +
  2. +
    +
  3. Setup credentials on Dropbox Settings doctype. + Click on + + top right corner +
  4. +
    +
  5. After settings up App key and App Secret, generate access token + +
  6. +
    +
  7. + After saving settings, + + Dropbox Integration Service and Save a document. +
  8. +
+

+ After enabling service, system will take backup of files and database on daily or weekly basis + as per set on Dropbox Settings page and upload it to your dropbox. +

+
+ """ + #get auth token @frappe.whitelist() def get_dropbox_authorize_url(): - doc = frappe.get_doc("Integration Service", "Dropbox Integration") - Controller.parameters = json.loads(doc.custom_settings_json) - - sess = Controller().get_dropbox_session() + doc = frappe.get_doc("Dropbox Settings") + sess = doc.get_dropbox_session() request_token = sess.obtain_request_token() - setup_parameter({ + doc.update({ "dropbox_access_key": request_token.key, "dropbox_access_secret": request_token.secret - }, doc) + }) + + doc.save(ignore_permissions=False) return_address = get_request_site_address(True) \ - + "?cmd=frappe.integrations.dropbox_integration.dropbox_callback" + + "?cmd=frappe.integrations.doctype.dropbox_settings.dropbox_settings.dropbox_callback" url = sess.build_authorize_url(request_token, return_address) @@ -113,34 +123,20 @@ def get_dropbox_authorize_url(): "dropbox_access_secret": request_token.secret } -def setup_parameter(request_token, doc): - parameters = Controller().parameters - - for key in ["dropbox_access_key", "dropbox_access_secret"]: - for parameter in Controller().parameters: - if key == parameter: - parameters[key] = request_token[key] - - doc.custom_settings_json = json.dumps(parameters) - doc.save(ignore_permissions=True) - frappe.db.commit() - @frappe.whitelist(allow_guest=True) def dropbox_callback(oauth_token=None, not_approved=False): - doc = frappe.get_doc("Integration Service", "Dropbox Integration") - Controller.parameters = json.loads(doc.custom_settings_json) + doc = frappe.get_doc("Dropbox Settings") - parameters = Controller().get_parameters() if not not_approved: - if parameters["dropbox_access_key"]==oauth_token: - sess = Controller().get_dropbox_session() - sess.set_request_token(parameters["dropbox_access_key"], parameters["dropbox_access_secret"]) + if doc.get_password(fieldname="dropbox_access_key", raise_exception=False)==oauth_token: + sess = doc.get_dropbox_session() + sess.set_request_token(doc.get_password(fieldname="dropbox_access_key", raise_exception=False), + doc.get_password(fieldname="dropbox_access_secret", raise_exception=False)) + access_token = sess.obtain_access_token() - setup_parameter({ - "dropbox_access_key": access_token.key, - "dropbox_access_secret": access_token.secret - }, doc) + frappe.db.set_value("Dropbox Settings", None, "dropbox_access_key", access_token.key) + frappe.db.set_value("Dropbox Settings", None, "dropbox_access_secret", access_token.secret) frappe.db.commit() else: @@ -157,7 +153,7 @@ def dropbox_callback(oauth_token=None, not_approved=False): @frappe.whitelist() def take_backup(): "Enqueue longjob for taking backup to dropbox" - enqueue("frappe.integrations.dropbox_integration.take_backup_to_dropbox", queue='long') + enqueue("frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backup_to_dropbox", queue='long') frappe.msgprint(_("Queued for backup. It may take a few minutes to an hour.")) def take_backups_daily(): @@ -167,16 +163,13 @@ def take_backups_weekly(): take_backups_if("Weekly") def take_backups_if(freq): - custom_settings_json = frappe.db.get_value("Dropbox Backup", None, "custom_settings_json") - if custom_settings_json: - custom_settings_json = json.loads(custom_settings_json) - if custom_settings_json["backup_frequency"] == freq: - take_backup_to_dropbox() + if frappe.db.get_value("Dropbox Settings", None, "backup_frequency") == freq: + take_backup_to_dropbox() def take_backup_to_dropbox(): did_not_upload, error_log = [], [] try: - if cint(frappe.db.get_value("Integration Service", "Dropbox Integration", "enabled")): + if cint(frappe.db.get_value("Integration Service", "Dropbox", "enabled")): did_not_upload, error_log = backup_to_dropbox() if did_not_upload: raise Exception @@ -235,13 +228,11 @@ def backup_to_dropbox(): def get_dropbox_client(previous_dropbox_client=None): from dropbox import client - doc = frappe.get_doc("Integration Service", "Dropbox Integration") - Controller.parameters = json.loads(doc.custom_settings_json) - - sess = Controller().get_dropbox_session() + doc = frappe.get_doc("Dropbox Settings") + sess = doc.get_dropbox_session() - parameters = Controller().get_parameters() - sess.set_token(parameters["dropbox_access_key"], parameters["dropbox_access_secret"]) + sess.set_token(doc.get_password(fieldname="dropbox_access_key", raise_exception=False), + doc.get_password(fieldname="dropbox_access_secret", raise_exception=False)) dropbox_client = client.DropboxClient(sess) diff --git a/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py b/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py new file mode 100644 index 0000000000..40540af8b8 --- /dev/null +++ b/frappe/integrations/doctype/dropbox_settings/test_dropbox_settings.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +# test_records = frappe.get_test_records('Dropbox Settings') + +class TestDropboxSettings(unittest.TestCase): + pass diff --git a/frappe/integrations/doctype/ldap_settings/__init__.py b/frappe/integrations/doctype/ldap_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.js b/frappe/integrations/doctype/ldap_settings/ldap_settings.js new file mode 100644 index 0000000000..81b8daa745 --- /dev/null +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.js @@ -0,0 +1,31 @@ +// Copyright (c) 2016, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.provide("frappe.integration_service") + +frappe.ui.form.on('LDAP Settings', { + refresh: function(frm) { + + } +}); + +frappe.integration_service.ldap_settings = Class.extend({ + init: function(frm) { + + }, + + get_scheduler_job_info: function() { + return {} + }, + + get_service_info: function(frm) { + frappe.call({ + method: "frappe.integrations.doctype.ldap_settings.ldap_settings.get_service_details", + callback: function(r){ + var integration_service_help = frm.fields_dict.integration_service_help.wrapper; + $(integration_service_help).empty(); + $(integration_service_help).append(r.message); + } + }) + } +}) \ No newline at end of file diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.json b/frappe/integrations/doctype/ldap_settings/ldap_settings.json new file mode 100644 index 0000000000..a9166b91e5 --- /dev/null +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.json @@ -0,0 +1,162 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-09-22 04:16:48.829658", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "System", + "editable_grid": 1, + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "ldap_server_url", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "LDAP Server Url", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "organizational_unit", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Organizational Unit", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "base_dn", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Base Distinguished Name (DN)", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "password", + "fieldtype": "Password", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Password for Base DN", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 1, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2016-09-22 04:31:42.998441", + "modified_by": "Administrator", + "module": "Integrations", + "name": "LDAP Settings", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 1, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/frappe/integrations/doctype/ldap_settings/ldap_settings.py b/frappe/integrations/doctype/ldap_settings/ldap_settings.py new file mode 100644 index 0000000000..07d0fd73c4 --- /dev/null +++ b/frappe/integrations/doctype/ldap_settings/ldap_settings.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import cstr, cint +from frappe.integration_broker.doctype.integration_service.integration_service import IntegrationService + +class LDAPSettings(IntegrationService): + def on_update(self): + pass + + def validate(self): + if not self.flags.ignore_mandatory: + self.validate_ldap_credentails() + + def enable(self): + if not self.flags.ignore_mandatory: + self.validate_ldap_credentails() + + def validate_ldap_credentails(self): + try: + import ldap + conn = ldap.initialize(self.ldap_server_url) + conn.simple_bind_s(self.base_dn, self.get_password(raise_exception=False)) + raise ImportError + except ImportError: + msg = """ +
+ Seems ldap is not installed on system.
+ Guidelines to install ldap dependancies and python package, + Click here, + +
+ """ + frappe.throw(msg, title="LDAP Not Installed") + + except ldap.LDAPError: + conn.unbind_s() + frappe.throw("Incorrect UserId or Password") + +@frappe.whitelist() +def get_service_details(): + return """ +
+

Steps to configure Service +

    +
  1. Setup credentials on LDAP settings doctype + Click on + + top right corner +
    + To setup LDAP you need, +
      +
    • Server URL & Port : ldap://ldap.forumsys.com:389
    • +
    • Base Distinguished Name : cn=read-only-admin,dc=example,dc=com
    • +
    • Organisational Unit : ou=mathematicians,dc=example,dc=com
    • +
    • Password : Base DN password
    • +
    +
  2. +
    +
  3. + After saving settings, + + LDAP Integration Service and Save a document. +
  4. +
+
+ """ + +def get_ldap_settings(): + try: + settings = frappe.get_doc("LDAP Settings") + + settings.update({ + "enabled": cint(frappe.db.get_value("Integration Service", "LDAP", "enabled")), + "method": "frappe.integrations.doctype.ldap_settings.ldap_settings.login" + }) + return settings + except Exception: + # this will return blank settings + return frappe._dict() + +@frappe.whitelist(allow_guest=True) +def login(): + #### LDAP LOGIN LOGIC ##### + args = frappe.form_dict + user = authenticate_ldap_user(args.usr, args.pwd) + + frappe.local.login_manager.user = user.name + frappe.local.login_manager.post_login() + + # because of a GET request! + frappe.db.commit() + +def authenticate_ldap_user(user=None, password=None): + dn = None + params = {} + settings = get_ldap_settings() + + try: + import ldap + except: + msg = """ +
+ {{_("Seems ldap is not installed on system")}}.
+ Click here, + {{_("Guidelines to install ldap dependancies and python")}} +
+ """ + frappe.throw(msg, title="LDAP Not Installed") + + conn = ldap.initialize(settings.ldap_server_url) + + try: + # simple_bind_s is synchronous binding to server, it takes two param DN and password + conn.simple_bind_s(settings.base_dn, settings.get_password(raise_exception=False)) + + #search for surnames beginning with a + #available options for how deep a search you want. + #LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL,LDAP_SCOPE_SUBTREE, + result = conn.search_s(settings.organizational_unit, ldap.SCOPE_SUBTREE, + "uid=*{0}".format(user)) + + print result + + for dn, r in result: + dn = cstr(dn) + params["email"] = cstr(r['mail'][0]) + params["username"] = cstr(r['uid'][0]) + params["first_name"] = cstr(r['cn'][0]) + + if dn: + conn.simple_bind_s(dn, password) + return create_user(params) + else: + frappe.throw(_("Not a valid LDAP user")) + + except ldap.LDAPError: + conn.unbind_s() + frappe.throw(_("Incorrect UserId or Password")) + +def create_user(params): + if frappe.db.exists("User", params["email"]): + return frappe.get_doc("User", params["email"]) + + else: + params.update({ + "doctype": "User", + "send_welcome_email": 0, + "language": "", + "user_type": "System User", + "user_roles": [{ + "role": _("Blogger") + }] + }) + + user = frappe.get_doc(params).insert(ignore_permissions=True) + frappe.db.commit() + + return user \ No newline at end of file diff --git a/frappe/integrations/doctype/paypal_settings/__init__.py b/frappe/integrations/doctype/paypal_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/integrations/doctype/paypal_settings/paypal_settings.js b/frappe/integrations/doctype/paypal_settings/paypal_settings.js new file mode 100644 index 0000000000..602b04743f --- /dev/null +++ b/frappe/integrations/doctype/paypal_settings/paypal_settings.js @@ -0,0 +1,31 @@ +// Copyright (c) 2016, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.provide("frappe.integration_service") + +frappe.ui.form.on('PayPal Settings', { + refresh: function(frm) { + + } +}); + +frappe.integration_service.paypal_settings = Class.extend({ + init: function(frm) { + + }, + + get_scheduler_job_info: function() { + return {} + }, + + get_service_info: function(frm) { + frappe.call({ + method: "frappe.integrations.doctype.paypal_settings.paypal_settings.get_service_details", + callback: function(r){ + var integration_service_help = frm.fields_dict.integration_service_help.wrapper; + $(integration_service_help).empty(); + $(integration_service_help).append(r.message); + } + }) + } +}) \ No newline at end of file diff --git a/frappe/integrations/doctype/paypal_settings/paypal_settings.json b/frappe/integrations/doctype/paypal_settings/paypal_settings.json new file mode 100644 index 0000000000..44e032d0cf --- /dev/null +++ b/frappe/integrations/doctype/paypal_settings/paypal_settings.json @@ -0,0 +1,190 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-09-21 08:03:01.009852", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "System", + "editable_grid": 1, + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "api_username", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "API Username", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "api_password", + "fieldtype": "Password", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "API Password", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "signature", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Signature", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "Check this if you are testing your payment using the Sandbox API", + "fieldname": "paypal_sandbox", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Use Sandbox", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "Mention transaction completion page URL", + "fieldname": "redirect_to", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Redirect To", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 1, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2016-09-26 02:00:45.145155", + "modified_by": "Administrator", + "module": "Integrations", + "name": "PayPal Settings", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 1, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/frappe/integrations/paypal.py b/frappe/integrations/doctype/paypal_settings/paypal_settings.py similarity index 63% rename from frappe/integrations/paypal.py rename to frappe/integrations/doctype/paypal_settings/paypal_settings.py index 69144b1e02..56b59dcbb4 100644 --- a/frappe/integrations/paypal.py +++ b/frappe/integrations/doctype/paypal_settings/paypal_settings.py @@ -1,6 +1,15 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt +# Copyright (c) 2015, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +import json +from frappe import _ +from frappe.utils import get_url, call_hook_method +from urllib import urlencode +from frappe.integration_broker.doctype.integration_service.integration_service import IntegrationService +import urllib """ # Integrating PayPal @@ -11,7 +20,7 @@ Example: from frappe.integration_broker.doctype.integration_service.integration_service import get_integration_controller - controller = get_integration_controller("PayPal", setup=False) + controller = get_integration_controller("PayPal") controller().validate_transaction_currency(currency) ### 2. Redirect for payment @@ -48,79 +57,49 @@ Example: payment_status - payment gateway will put payment status on callback. For paypal payment status parameter is one from: [Completed, Cancelled, Failed] -""" -from __future__ import unicode_literals -import frappe -import json -from frappe import _ -from urllib import urlencode -from frappe.utils import get_url, call_hook_method -from frappe.integration_broker.integration_controller import IntegrationController - -class Controller(IntegrationController): - service_name = 'PayPal' - parameters_template = [ - { - "label": "API Username", - 'fieldname': 'api_username', - 'fieldtype': 'Data', - 'reqd': 1 - }, - { - "label": "API Password", - 'fieldname': 'api_password', - 'fieldtype': "Password", - 'reqd': 1 - }, - { - "label": "Signature", - "fieldname": "signature", - 'fieldtype': "Data", - "reqd": 1 - } - ] +More Details: +
For details on how to get your API credentials, follow this link: https://developer.paypal.com/docs/classic/api/apiCredentials/
- js = "assets/frappe/js/integrations/paypal.js" +""" +class PayPalSettings(IntegrationService): + service_name = "PayPal" + supported_currencies = ["AUD", "BRL", "CAD", "CZK", "DKK", "EUR", "HKD", "HUF", "ILS", "JPY", "MYR", "MXN", "TWD", "NZD", "NOK", "PHP", "PLN", "GBP", "RUB", "SGD", "SEK", "CHF", "THB", "TRY", "USD"] - - def enable(self, parameters, use_test_account=0): + + def validate(self): + if not self.flags.ignore_mandatory: + self.validate_paypal_credentails() + + def on_update(self): + pass + + def enable(self): call_hook_method('payment_gateway_enabled', gateway=self.service_name) - self.parameters = parameters - self.validate_paypal_credentails(use_test_account) - - def get_settings(self): - if not hasattr(self, "parameters"): - parameters = frappe.db.get_value("Integration Service", self.service_name, - ["custom_settings_json"]) - self.parameters = json.loads(parameters) + if not self.flags.ignore_mandatory: + self.validate_paypal_credentails() - return frappe._dict(self.parameters) - def validate_transaction_currency(self, currency): if currency not in self.supported_currencies: frappe.throw(_("Please select another payment method. {0} does not support transactions in currency '{1}'").format(self.service_name, currency)) - - def get_paypal_params_and_url(self, use_test_account=None): - use_test_account = frappe.db.get_value("Integration Service", self.service_name, ["use_test_account"]) - paypal_settings = frappe._dict(self.get_settings()) - + + def get_paypal_params_and_url(self): params = { - "USER": paypal_settings.api_username, - "PWD": paypal_settings.api_password, - "SIGNATURE": paypal_settings.signature, + "USER": self.api_username, + "PWD": self.get_password(fieldname="api_password", raise_exception=False), + "SIGNATURE": self.signature, "VERSION": "98", "METHOD": "GetPalDetails" } - api_url = "https://api-3t.sandbox.paypal.com/nvp" if use_test_account else "https://api-3t.paypal.com/nvp" + api_url = "https://api-3t.sandbox.paypal.com/nvp" if self.paypal_sandbox else "https://api-3t.paypal.com/nvp" return params, api_url - def validate_paypal_credentails(self, use_test_account): - params, url = self.get_paypal_params_and_url(use_test_account) + def validate_paypal_credentails(self): + params, url = self.get_paypal_params_and_url() params = urlencode(params) try: @@ -131,12 +110,11 @@ class Controller(IntegrationController): except Exception: frappe.throw(_("Invalid payment gateway credentials")) - + def get_payment_url(self, **kwargs): - use_test_account = frappe.db.get_value("Integration Service", self.service_name, ["use_test_account"]) response = self.execute_set_express_checkout(kwargs["amount"], kwargs["currency"]) - if use_test_account: + if self.paypal_sandbox: return_url = "https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}" else: return_url = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token={0}" @@ -169,15 +147,53 @@ class Controller(IntegrationController): return response +@frappe.whitelist() +def get_service_details(): + return """ +
+

Steps to configure Service +

    +
  1. Get PayPal api credentials from link: + + https://developer.paypal.com/docs/classic/api/apiCredentials/ + +
  2. +
    +
  3. Setup credentials on PayPal settings doctype. + Click on + + top right corner +
  4. +
    +
  5. + After saving settings, + + PayPal Integration Service and Save a document. +
  6. +
    +
  7. + To view PayPal payment logs, + +
  8. +
+
+ """ + @frappe.whitelist(allow_guest=True, xss_safe=True) def get_express_checkout_details(token): - params, url = Controller().get_paypal_params_and_url() + doc = frappe.get_doc("PayPal Settings") + params, url = doc.get_paypal_params_and_url() params.update({ "METHOD": "GetExpressCheckoutDetails", "TOKEN": token }) - response = Controller().post_request(url, data=params) + response = doc.post_request(url, data=params) if response.get("ACK")[0] != "Success": frappe.respond_as_web_page(_("Something went wrong"), @@ -200,10 +216,14 @@ def get_express_checkout_details(token): def confirm_payment(token): redirect = True status_changed_to, redirect_to = None, None + doc = frappe.get_doc("PayPal Settings") integration_request = frappe.get_doc("Integration Request", token) data = json.loads(integration_request.data) - - params, url = Controller().get_paypal_params_and_url() + + redirect_to = data.get('redirect_to') or None + redirect_message = data.get('redirect_message') or None + + params, url = doc.get_paypal_params_and_url() params.update({ "METHOD": "DoExpressCheckoutPayment", "PAYERID": data.get("payerid"), @@ -213,7 +233,7 @@ def confirm_payment(token): "PAYMENTREQUEST_0_CURRENCYCODE": data.get("currency").upper() }) - response = Controller().post_request(url, data=params) + response = doc.post_request(url, data=params) if response.get("ACK")[0] == "Success": update_integration_request_status(token, { @@ -222,21 +242,22 @@ def confirm_payment(token): }, "Completed") if data.get("reference_doctype") and data.get("reference_docname"): - redirect_to = frappe.get_doc(data.get("reference_doctype"), data.get("reference_docname")).run_method("on_payment_authorized", "Completed") - - if not redirect_to: - if data.get('redirect_to'): - redirect_to = data.get('redirect_to') - - redirect_to = redirect_to or get_url("/integrations/payment-success") + redirect_url = frappe.get_doc(data.get("reference_doctype"), data.get("reference_docname")).run_method("on_payment_authorized", "Completed") + if not redirect_url: + redirect_url = '/integrations/payment-success' else: - redirect_to = get_url("/integrations/payment-failed") + redirect_url = "/integrations/payment-failed" + + if redirect_to: + redirect_url += '?' + urllib.urlencode({'redirect_to': redirect_to}) + if redirect_message: + redirect_url += '&' + urllib.urlencode({'redirect_message': redirect_message}) # this is done so that functions called via hooks can update flags.redirect_to if redirect: frappe.local.response["type"] = "redirect" - frappe.local.response["location"] = redirect_to + frappe.local.response["location"] = get_url(redirect_to) def update_integration_request_status(token, data, status, error=False): frappe.get_doc("Integration Request", token).update_status(data, status) @@ -244,7 +265,8 @@ def update_integration_request_status(token, data, status, error=False): @frappe.whitelist(allow_guest=True, xss_safe=True) def get_checkout_url(**kwargs): try: - return Controller().get_payment_url(**kwargs) + doc = frappe.get_doc("PayPal Settings") + return doc.get_payment_url(**kwargs) except Exception: frappe.respond_as_web_page(_("Something went wrong"), _("Looks like something is wrong with this site's Paypal configuration. Don't worry! No payment has been made from your Paypal account."), diff --git a/frappe/integrations/doctype/razorpay_settings/__init__.py b/frappe/integrations/doctype/razorpay_settings/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js new file mode 100644 index 0000000000..9c61aba6af --- /dev/null +++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.js @@ -0,0 +1,33 @@ +// Copyright (c) 2016, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.provide("frappe.integration_service") + +frappe.ui.form.on('Razorpay Settings', { + refresh: function(frm) { + + } +}); + +frappe.integration_service.razorpay_settings = Class.extend({ + init: function(frm) { + + }, + + get_scheduler_job_info: function() { + return { + "Execute on every few minits of interval": " Captures all authorised payments" + } + }, + + get_service_info: function(frm) { + frappe.call({ + method: "frappe.integrations.doctype.razorpay_settings.razorpay_settings.get_service_details", + callback: function(r){ + var integration_service_help = frm.fields_dict.integration_service_help.wrapper; + $(integration_service_help).empty(); + $(integration_service_help).append(r.message); + } + }) + } +}) \ No newline at end of file diff --git a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.json b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.json new file mode 100644 index 0000000000..a0aeb0b3b7 --- /dev/null +++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.json @@ -0,0 +1,137 @@ +{ + "allow_copy": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2016-09-20 03:44:03.799402", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "System", + "editable_grid": 1, + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "api_key", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "API Key", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "api_secret", + "fieldtype": "Password", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "API Secret", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "Mention transaction completion page URL", + "fieldname": "redirect_to", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "label": "Redirect To", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 1, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2016-09-26 02:00:03.604912", + "modified_by": "Administrator", + "module": "Integrations", + "name": "Razorpay Settings", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 1, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_seen": 0 +} \ No newline at end of file diff --git a/frappe/integrations/razorpay.py b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py similarity index 74% rename from frappe/integrations/razorpay.py rename to frappe/integrations/doctype/razorpay_settings/razorpay_settings.py index 04b1d400d9..4ac5464742 100644 --- a/frappe/integrations/razorpay.py +++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py @@ -1,6 +1,13 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors -# License: GNU General Public License v3. See license.txt +# Copyright (c) 2015, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.utils import get_url, call_hook_method +from frappe import _ +import urllib, json +from frappe.integration_broker.doctype.integration_service.integration_service import IntegrationService """ # Integrating RazorPay @@ -50,31 +57,11 @@ payment_status - payment gateway will put payment status on callback. For razorpay payment status is Authorized """ -from __future__ import unicode_literals -import frappe -from frappe import _ -import urllib, json -from frappe.utils import get_url, call_hook_method -from frappe.integration_broker.integration_controller import IntegrationController -class Controller(IntegrationController): - service_name = 'Razorpay' - parameters_template = [ - { - "label": "API Key", - 'fieldname': 'api_key', - 'fieldtype': "Data", - 'reqd': 1 - }, - { - "label": "API Secret", - 'fieldname': 'api_secret', - 'fieldtype': "Password", - 'reqd': 1 - } - ] - - # do also changes in razorpay.js scheduler job helper +class RazorpaySettings(IntegrationService): + service_name = "Razorpay" + supported_currencies = ["INR"] + scheduled_jobs = [ { "all": [ @@ -82,48 +69,41 @@ class Controller(IntegrationController): ] } ] - - js = "assets/frappe/js/integrations/razorpay.js" - - supported_currencies = ["INR"] - - def enable(self, parameters, use_test_account=0): + + def validate(self): + if not self.flags.ignore_mandatory: + self.validate_razorpay_credentails() + + def on_update(self): + pass + + def enable(self): call_hook_method('payment_gateway_enabled', gateway='Razorpay') - self.parameters = parameters - self.validate_razorpay_credentails() + if not self.flags.ignore_mandatory: + self.validate_razorpay_credentails() + def validate_razorpay_credentails(self): - razorpay_settings = self.get_settings() - - if razorpay_settings.get("api_key"): + if self.api_key and self.api_secret: try: self.get_request(url="https://api.razorpay.com/v1/payments", - auth=(razorpay_settings.api_key, razorpay_settings.api_secret)) + auth=(self.api_key, self.get_password(fieldname="api_secret", raise_exception=False))) except Exception: frappe.throw(_("Seems API Key or API Secret is wrong !!!")) - + def validate_transaction_currency(self, currency): if currency not in self.supported_currencies: frappe.throw(_("Please select another payment method. {0} does not support transactions in currency '{1}'").format(self.service_name, currency)) def get_payment_url(self, **kwargs): return get_url("./integrations/razorpay_checkout?{0}".format(urllib.urlencode(kwargs))) - - def get_settings(self): - if hasattr(self, "parameters"): - return frappe._dict(self.parameters) - - custom_settings_json = frappe.db.get_value("Integration Service", "Razorpay", "custom_settings_json") - - if custom_settings_json: - return frappe._dict(json.loads(custom_settings_json)) - + def create_request(self, data): self.data = frappe._dict(data) try: - self.integration_request = super(Controller, self).create_request(self.data, "Host", \ - self.service_name) + self.integration_request = super(RazorpaySettings, self).create_request(self.data, "Host", \ + "Razorpay") return self.authorize_payment() except Exception: @@ -139,7 +119,6 @@ class Controller(IntegrationController): The money is deducted from the customer’s account, but will not be transferred to the merchant’s account until it is explicitly captured by merchant. """ - settings = self.get_settings() data = json.loads(self.integration_request.data) redirect_to = data.get('notes', {}).get('redirect_to') or None @@ -198,8 +177,8 @@ def capture_payment(is_sandbox=False, sanbox_response=None): Note: Attempting to capture a payment whose status is not authorized will produce an error. """ - controller = frappe.get_doc("Integration Service", "Razorpay") - settings = controller.get_parameters() + controller = frappe.get_doc("Razorpay Settings") + for doc in frappe.get_all("Integration Request", filters={"status": "Authorized", "integration_request_service": "Razorpay"}, fields=["name", "data"]): try: @@ -208,7 +187,7 @@ def capture_payment(is_sandbox=False, sanbox_response=None): else: data = json.loads(doc.data) resp = controller.post_request("https://api.razorpay.com/v1/payments/{0}/capture".format(data.get("razorpay_payment_id")), - auth=(settings["api_key"], settings["api_secret"]), data={"amount": data.get("amount")}) + auth=(controller.api_key, controller.get_password("api_secret")), data={"amount": data.get("amount")}) if resp.get("status") == "captured": frappe.db.set_value("Integration Request", doc.name, "status", "Completed") @@ -221,9 +200,47 @@ def capture_payment(is_sandbox=False, sanbox_response=None): @frappe.whitelist(allow_guest=True, xss_safe=True) def get_checkout_url(**kwargs): try: - return Controller().get_payment_url(**kwargs) + return frappe.get_doc("Razorpay Settings").get_payment_url(**kwargs) except Exception: frappe.respond_as_web_page(_("Something went wrong"), _("Looks like something is wrong with this site's Razorpay configuration. Don't worry! No payment has been made."), success=False, http_status_code=frappe.ValidationError.http_status_code) + + +@frappe.whitelist() +def get_service_details(): + return """ +
+

Steps to configure Service +

    +
  1. Get Razorpay api credentials by login to: + + https://razorpay.com/ + +
  2. +
    +
  3. Setup credentials on Razorpay Settings doctype. + Click on + + top right corner +
  4. +
    +
  5. + After saving settings, + + Razorpay Integration Service and Save a document. +
  6. +
    +
  7. + To view Razorpays payment logs, + +
  8. +
+
+ """ \ No newline at end of file diff --git a/frappe/integrations/ldap_auth.py b/frappe/integrations/ldap_auth.py deleted file mode 100644 index 4a3c887850..0000000000 --- a/frappe/integrations/ldap_auth.py +++ /dev/null @@ -1,139 +0,0 @@ -import frappe -import ldap, json -from frappe.integration_broker.integration_controller import IntegrationController -from frappe import _ -from frappe.utils import cstr, cint - -class Controller(IntegrationController): - service_name = 'LDAP Auth' - parameters_template = [ - { - "label": "LDAP Server Url", - "fieldname": "ldap_server_url", - "reqd": 1, - "fieldtype": "Data" - }, - { - "label": "Organizational Unit", - "fieldname": "organizational_unit", - "reqd": 1, - "fieldtype": "Data" - }, - { - "label": "Base Distinguished Name (DN)", - "fieldname": "base_dn", - "reqd": 1, - "fieldtype": "Data" - }, - { - "label": "Password for Base DN", - "fieldname": "password", - "reqd": 1, - "fieldtype": "Password" - }, - { - "label": "Sync frequency from ldap to frappe", - "fieldname": "sync_frequency", - "reqd": 1, - "fieldtype": "Select", - "options": "\nDaily\nWeekly", - } - ] - - js = "assets/frappe/js/integrations/ldap_auth.js" - - def enable(self, parameters, use_test_account=0): - self.parameters = parameters - self.validate_ldap_credentails() - - def validate_ldap_credentails(self): - ldap_settings = self.get_settings() - try: - conn = ldap.initialize(ldap_settings.get('ldap_server_url')) - conn.simple_bind_s(ldap_settings.get("base_dn"), ldap_settings.get("password")) - except ldap.LDAPError: - conn.unbind_s() - frappe.throw("Incorrect UserId or Password") - - def get_settings(self): - return frappe._dict(self.parameters) - -def get_ldap_settings(): - try: - doc = frappe.get_doc("Integration Service", "LDAP Auth") - settings = json.loads(doc.custom_settings_json) - settings.update({ - "enabled": cint(doc.enabled), - "method": "frappe.integrations.ldap_auth.login" - }) - return settings - except Exception: - # this will return blank settings - return frappe._dict() - -@frappe.whitelist(allow_guest=True) -def login(): - #### LDAP LOGIN LOGIC ##### - args = frappe.form_dict - user = authenticate_ldap_user(args.usr, args.pwd) - - frappe.local.login_manager.user = user.name - frappe.local.login_manager.post_login() - - # because of a GET request! - frappe.db.commit() - -def authenticate_ldap_user(user=None, password=None): - dn = None - params = {} - settings = get_ldap_settings() - conn = ldap.initialize(settings.get('ldap_server_url')) - print settings - try: - # simple_bind_s is synchronous binding to server, it takes two param DN and password - conn.simple_bind_s(settings.get("base_dn"), settings.get("password")) - print "here" - #search for surnames beginning with a - #available options for how deep a search you want. - #LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL,LDAP_SCOPE_SUBTREE, - result = conn.search_s(settings.get("organizational_unit"), ldap.SCOPE_SUBTREE, - "uid=*{0}".format(user)) - - print result - - for dn, r in result: - dn = cstr(dn) - params["email"] = cstr(r['mail'][0]) - params["username"] = cstr(r['uid'][0]) - params["first_name"] = cstr(r['cn'][0]) - - if dn: - conn.simple_bind_s(dn, password) - return create_user(params) - else: - frappe.throw(_("Not a valid LDAP user")) - - except ldap.LDAPError: - conn.unbind_s() - frappe.throw(_("Incorrect UserId or Password")) - -def create_user(params): - if frappe.db.exists("User", params["email"]): - return frappe.get_doc("User", params["email"]) - - else: - params.update({ - "doctype": "User", - "send_welcome_email": 0, - "language": "", - "user_type": "System User", - "user_roles": [{ - "role": _("Blogger") - }] - }) - - user = frappe.get_doc(params).insert(ignore_permissions=True) - frappe.db.commit() - - return user - \ No newline at end of file diff --git a/frappe/patches.txt b/frappe/patches.txt index d5ca70fef3..52bebcb925 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -143,3 +143,4 @@ execute:frappe.core.doctype.language.language.update_language_names() execute:frappe.db.set_value("Print Settings", "Print Settings", "add_draft_heading", 1) frappe.patches.v7_0.cleanup_list_settings execute:frappe.db.set_default('language', '') +frappe.patches.v7_1.refactor_integration_broker diff --git a/frappe/patches/v7_1/refactor_integration_broker.py b/frappe/patches/v7_1/refactor_integration_broker.py new file mode 100644 index 0000000000..8c9aaa6795 --- /dev/null +++ b/frappe/patches/v7_1/refactor_integration_broker.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +import json + +def execute(): + for doctype_name in ["Razorpay Log", "Razorpay Payment", "Razorpay Settings"]: + delete_doc("DocType", doctype_name) + + reload_doctypes() + setup_services() + +def delete_doc(doctype, doctype_name): + frappe.delete_doc(doctype, doctype_name) + +def reload_doctypes(): + for doctype in ("razorpay_settings", "paypal_settings", "dropbox_settings", "ldap_settings"): + frappe.reload_doc("integrations", "doctype", doctype) + +def setup_services(): + for service in [{"old_name": "Razorpay", "new_name": "Razorpay"}, + {"old_name": "PayPal", "new_name": "PayPal"}, + {"old_name": "Dropbox Integration", "new_name": "Dropbox"}, + {"old_name": "LDAP Auth", "new_name": "LDAP"}]: + + try: + service_doc = frappe.get_doc("Integration Service", service["old_name"]) + settings = json.loads(service_doc.custom_settings_json) + + service_settings = frappe.new_doc("{0} Settings".format(service["new_name"])) + service_settings.update(settings) + + service_settings.flags.ignore_mandatory = True + service_settings.save(ignore_permissions=True) + + if service["old_name"] in ["Dropbox Integration", "LDAP Auth"]: + delete_doc("Integration Service", service["old_name"]) + + new_service_doc = frappe.get_doc({ + "doctype": "Integration Service", + "service": service["new_name"], + "enabled": 1 + }) + + new_service_doc.flags.ignore_mandatory = True + new_service_doc.save(ignore_permissions=True) + + except Exception: + pass diff --git a/frappe/public/js/integrations/dropbox_integration.js b/frappe/public/js/integrations/dropbox_integration.js deleted file mode 100644 index 9e77f4421f..0000000000 --- a/frappe/public/js/integrations/dropbox_integration.js +++ /dev/null @@ -1,48 +0,0 @@ -frappe.provide("frappe.integration_service") - -frappe.integration_service.dropbox_integration = { - load: function(frm) { - new frappe.integration_service.DropboxIntegration(frm) - }, - scheduler_job_helper: function(){ - return { - "Daily": "Take backup of database and files to dropbox on daily basis", - "Weekly": "Take backup of database and files to dropbox on weekly basis" - } - } -} - -frappe.integration_service.DropboxIntegration = Class.extend({ - init: function(frm) { - this.frm = frm; - this.frm.toggle_display("use_test_account", false); - if(this.frm.doc.service == "Dropbox Integration" && this.frm.doc.enabled && !this.frm.doc.__islocal){ - this.allow_dropbox_acess(frm); - this.take_backup(frm); - } - }, - - allow_dropbox_acess: function(frm) { - this.frm.add_custom_button(__("Allow Dropbox Access"), function(frm){ - frappe.call({ - method: "frappe.integrations.dropbox_integration.get_dropbox_authorize_url", - freeze: true, - callback: function(r) { - if(!r.exc) { - window.open(r.message.url); - } - } - }) - }).addClass("btn-primary") - }, - - take_backup: function(frm) { - var me = this; - this.frm.add_custom_button(__("Take Backup Now"), function(frm){ - frappe.call({ - method: "frappe.integrations.dropbox_integration.take_backup", - freeze: true - }) - }).addClass("btn-primary") - } -}) diff --git a/frappe/public/js/integrations/ldap_auth.js b/frappe/public/js/integrations/ldap_auth.js deleted file mode 100644 index f7cdadec9c..0000000000 --- a/frappe/public/js/integrations/ldap_auth.js +++ /dev/null @@ -1,15 +0,0 @@ -frappe.provide("frappe.integration_service") - -frappe.integration_service.ldap_auth = { - load: function(frm) { - new frappe.integration_service.ldapAuth(frm) - } -} - -frappe.integration_service.ldapAuth = Class.extend({ - init:function(frm){ - this.frm = frm; - this.frm.toggle_display("use_test_account", false); - } -}) - \ No newline at end of file diff --git a/frappe/public/js/integrations/paypal.js b/frappe/public/js/integrations/paypal.js deleted file mode 100644 index a922d1a301..0000000000 --- a/frappe/public/js/integrations/paypal.js +++ /dev/null @@ -1,21 +0,0 @@ -frappe.provide("frappe.integration_service") - -frappe.integration_service.paypal = { - load: function(frm) { - new frappe.integration_service.PayPal(frm) - } -} - -frappe.integration_service.PayPal = Class.extend({ - init:function(frm){ - this.frm = frm; - this.show_logs(); - }, - show_logs: function(){ - this.frm.add_custom_button(__("Show Log"), function(frm){ - frappe.route_options = {"integration_request_service": "PayPal"}; - frappe.set_route("List", "Integration Request"); - }).addClass("btn-primary") - } -}) - \ No newline at end of file diff --git a/frappe/templates/pages/integrations/razorpay_checkout.py b/frappe/templates/pages/integrations/razorpay_checkout.py index 61d28754ee..1c76f1fae4 100644 --- a/frappe/templates/pages/integrations/razorpay_checkout.py +++ b/frappe/templates/pages/integrations/razorpay_checkout.py @@ -6,8 +6,6 @@ from frappe import _ from frappe.utils import flt import json -from frappe.integrations.razorpay import Controller - no_cache = 1 no_sitemap = 1 @@ -16,7 +14,7 @@ expected_keys = ('amount', 'title', 'description', 'reference_doctype', 'referen def get_context(context): context.no_cache = 1 - context.api_key = Controller().get_settings().api_key + context.api_key = frappe.db.get_value("Razorpay Settings", None, "api_key") # all these keys exist in form_dict if not (set(expected_keys) - set(frappe.form_dict.keys())): @@ -43,4 +41,6 @@ def make_payment(razorpay_payment_id, options, reference_doctype, reference_docn "reference_doctype": reference_doctype }) - return Controller().create_request(data) + data = frappe.get_doc("Razorpay Settings").create_request(data) + frappe.db.commit() + return data diff --git a/frappe/www/login.py b/frappe/www/login.py index c67aea4491..a37d5ffb19 100644 --- a/frappe/www/login.py +++ b/frappe/www/login.py @@ -8,7 +8,7 @@ from frappe.utils.oauth import get_oauth2_authorize_url, get_oauth_keys, login_v import json from frappe import _ from frappe.auth import LoginManager -from frappe.integrations.ldap_auth import get_ldap_settings +from frappe.integrations.doctype.ldap_settings.ldap_settings import get_ldap_settings no_cache = True diff --git a/requirements.txt b/requirements.txt index a1ddcd120a..c198014550 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,4 +38,3 @@ zxcvbn psutil unittest-xml-reporting xlwt -python-ldap