@@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json | |||
from .exceptions import * | |||
from .utils.jinja import get_jenv, get_template, render_template | |||
__version__ = '7.1.10' | |||
__version__ = '7.1.11' | |||
__title__ = "Frappe Framework" | |||
local = Local() | |||
@@ -10,7 +10,6 @@ from frappe.utils.response import build_response | |||
from frappe import _ | |||
from urlparse import urlparse | |||
from urllib import urlencode | |||
from frappe.integration_broker.oauth2 import oauth_server | |||
def handle(): | |||
""" | |||
@@ -36,25 +35,7 @@ def handle(): | |||
`/api/resource/{doctype}/{name}?run_method={method}` will run a whitelisted controller method | |||
""" | |||
form_dict = frappe.local.form_dict | |||
authorization_header = frappe.get_request_header("Authorization").split(" ") if frappe.get_request_header("Authorization") else None | |||
if authorization_header and authorization_header[0].lower() == "bearer": | |||
token = authorization_header[1] | |||
r = frappe.request | |||
parsed_url = urlparse(r.url) | |||
access_token = { "access_token": token} | |||
uri = parsed_url.scheme + "://" + parsed_url.netloc + parsed_url.path + "?" + urlencode(access_token) | |||
http_method = r.method | |||
body = r.get_data() | |||
headers = r.headers | |||
required_scopes = frappe.db.get_value("OAuth Bearer Token", token, "scopes").split(";") | |||
valid, oauthlib_request = oauth_server.verify_request(uri, http_method, body, headers, required_scopes) | |||
if valid: | |||
frappe.set_user(frappe.db.get_value("OAuth Bearer Token", token, "user")) | |||
frappe.local.form_dict = form_dict | |||
validate_oauth() | |||
parts = frappe.request.path[1:].split("/",3) | |||
call = doctype = name = None | |||
@@ -146,3 +127,25 @@ def handle(): | |||
raise frappe.DoesNotExistError | |||
return build_response("json") | |||
def validate_oauth(): | |||
form_dict = frappe.local.form_dict | |||
authorization_header = frappe.get_request_header("Authorization").split(" ") if frappe.get_request_header("Authorization") else None | |||
if authorization_header and authorization_header[0].lower() == "bearer": | |||
from frappe.integration_broker.oauth2 import get_oauth_server | |||
token = authorization_header[1] | |||
r = frappe.request | |||
parsed_url = urlparse(r.url) | |||
access_token = { "access_token": token} | |||
uri = parsed_url.scheme + "://" + parsed_url.netloc + parsed_url.path + "?" + urlencode(access_token) | |||
http_method = r.method | |||
body = r.get_data() | |||
headers = r.headers | |||
required_scopes = frappe.db.get_value("OAuth Bearer Token", token, "scopes").split(";") | |||
valid, oauthlib_request = get_oauth_server().verify_request(uri, http_method, body, headers, required_scopes) | |||
if valid: | |||
frappe.set_user(frappe.db.get_value("OAuth Bearer Token", token, "user")) | |||
frappe.local.form_dict = form_dict |
@@ -57,7 +57,14 @@ class Report(Document): | |||
if self.report_type in ('Query Report', 'Script Report'): | |||
# query and script reports | |||
data = frappe.desk.query_report.run(self.name, filters=filters, user=user) | |||
out.append([d.split(':')[0] for d in data.get('columns')]) | |||
columns_list = [] | |||
for d in data.get('columns'): | |||
if isinstance(d, dict): | |||
columns_list.append(d.get('label')) | |||
else: | |||
columns_list.append(d.split(':')[0]) | |||
out.append(columns_list) | |||
out += data.get('result') | |||
else: | |||
# standard report | |||
@@ -60,9 +60,19 @@ frappe.ui.form.on('Auto Email Report', { | |||
<tr><th style="width: 50%">'+__('Filter')+'</th><th>'+__('Value')+'</th></tr>\ | |||
</thead><tbody></tbody></table>').appendTo(wrapper); | |||
$('<p class="text-muted small">' + __("Click table to edit") + '</p>').appendTo(wrapper); | |||
var filters = JSON.parse(frm.doc.filters || '{}'); | |||
var report_filters = frappe.query_reports[frm.doc.report].filters; | |||
report_filters_list = [] | |||
$.each(report_filters, function(key, val){ | |||
// Remove break fieldtype from the filters | |||
if(val.fieldtype != 'Break') { | |||
report_filters_list.push(val) | |||
} | |||
}) | |||
report_filters = report_filters_list; | |||
report_filters.forEach(function(f) { | |||
$('<tr><td>' + f.label + '</td><td>'+ frappe.format(filters[f.fieldname], f) +'</td></tr>') | |||
.appendTo(table.find('tbody')); | |||
@@ -6,10 +6,12 @@ from urllib import quote, urlencode | |||
from urlparse import urlparse | |||
from frappe.integrations.doctype.oauth_provider_settings.oauth_provider_settings import get_oauth_settings | |||
#Variables required across requests | |||
oauth_validator = OAuthWebRequestValidator() | |||
oauth_server = WebApplicationServer(oauth_validator) | |||
credentials = None | |||
def get_oauth_server(): | |||
if not getattr(frappe.local, 'oauth_server', None): | |||
oauth_validator = OAuthWebRequestValidator() | |||
frappe.local.oauth_server = WebApplicationServer(oauth_validator) | |||
return frappe.local.oauth_server | |||
def get_urlparams_from_kwargs(param_kwargs): | |||
arguments = param_kwargs | |||
@@ -29,10 +31,10 @@ def approve(*args, **kwargs): | |||
headers = r.headers | |||
try: | |||
scopes, credentials = oauth_server.validate_authorization_request(uri, http_method, body, headers) | |||
scopes, frappe.flags.oauth_credentials = get_oauth_server().validate_authorization_request(uri, http_method, body, headers) | |||
headers, body, status = oauth_server.create_authorization_response(uri=credentials['redirect_uri'], \ | |||
body=body, headers=headers, scopes=scopes, credentials=credentials) | |||
headers, body, status = get_oauth_server().create_authorization_response(uri=frappe.flags.oauth_credentials['redirect_uri'], \ | |||
body=body, headers=headers, scopes=scopes, credentials=frappe.flags.oauth_credentials) | |||
uri = headers.get('Location', None) | |||
frappe.local.response["type"] = "redirect" | |||
@@ -50,7 +52,7 @@ def authorize(*args, **kwargs): | |||
params = get_urlparams_from_kwargs(kwargs) | |||
request_url = urlparse(frappe.request.url) | |||
success_url = request_url.scheme + "://" + request_url.netloc + "/api/method/frappe.integration_broker.oauth2.approve?" + params | |||
failure_url = frappe.form_dict["redirect_uri"] + "?error=access_denied" | |||
failure_url = frappe.form_dict["redirect_uri"] + "?error=access_denied" | |||
if frappe.session['user']=='Guest': | |||
#Force login, redirect to preauth again. | |||
@@ -65,9 +67,9 @@ def authorize(*args, **kwargs): | |||
body = r.get_data() | |||
headers = r.headers | |||
scopes, credentials = oauth_server.validate_authorization_request(uri, http_method, body, headers) | |||
scopes, frappe.flags.oauth_credentials = get_oauth_server().validate_authorization_request(uri, http_method, body, headers) | |||
skip_auth = frappe.db.get_value("OAuth Client", credentials['client_id'], "skip_authorization") | |||
skip_auth = frappe.db.get_value("OAuth Client", frappe.flags.oauth_credentials['client_id'], "skip_authorization") | |||
unrevoked_tokens = frappe.get_all("OAuth Bearer Token", filters={"status":"Active"}) | |||
if skip_auth or (oauth_settings["skip_authorization"] == "Auto" and len(unrevoked_tokens)): | |||
@@ -100,7 +102,7 @@ def get_token(*args, **kwargs): | |||
headers = r.headers | |||
try: | |||
headers, body, status = oauth_server.create_token_response(uri, http_method, body, headers, credentials) | |||
headers, body, status = get_oauth_server().create_token_response(uri, http_method, body, headers, frappe.flags.oauth_credentials) | |||
frappe.local.response = frappe._dict(json.loads(body)) | |||
except FatalClientError as e: | |||
return e | |||
@@ -113,9 +115,9 @@ def revoke_token(*args, **kwargs): | |||
http_method = r.method | |||
body = r.form | |||
headers = r.headers | |||
headers, body, status = oauth_server.create_revocation_response(uri, headers=headers, body=body, http_method=http_method) | |||
headers, body, status = get_oauth_server().create_revocation_response(uri, headers=headers, body=body, http_method=http_method) | |||
frappe.local.response['http_status_code'] = status | |||
if status == 200: | |||
return "success" | |||
@@ -355,7 +355,7 @@ fieldset[disabled] .form-control { | |||
} | |||
/* jquery ui */ | |||
.ui-datepicker { | |||
z-index: 100 !important; | |||
z-index: 9999 !important; | |||
} | |||
.ui-datepicker .ui-datepicker-header { | |||
border-radius: 0px !important; | |||
@@ -781,13 +781,19 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||
toggle_delete: function() { | |||
var me = this; | |||
if (this.$page.find(".list-delete:checked").length) { | |||
var no_of_checked_items = this.$page.find(".list-delete:checked").length; | |||
if (no_of_checked_items) { | |||
this.page.set_primary_action(__("Delete"), function() { me.delete_items() }, | |||
"octicon octicon-trashcan"); | |||
this.page.btn_primary.addClass("btn-danger"); | |||
this.page.checked_items_status.text(no_of_checked_items == 1 | |||
? __("1 item selected") | |||
: __("{0} items selected", [no_of_checked_items])) | |||
this.page.checked_items_status.removeClass("hide"); | |||
} else { | |||
this.page.btn_primary.removeClass("btn-danger"); | |||
this.set_primary_action(); | |||
this.page.checked_items_status.addClass("hide"); | |||
} | |||
}, | |||
@@ -12,6 +12,7 @@ | |||
</div> | |||
<div class="text-right col-md-5 col-sm-4 col-xs-6 page-actions"> | |||
<!-- ID and icon buttons --> | |||
<span class="checked-items-status text-ellipsis text-muted small hide hidden-xs hidden-sm" style="margin-right: 20px;">## items selected</span> | |||
<h6 class="text-ellipsis sub-heading hide text-muted"></h6> | |||
<span class="page-icon-group hide hidden-xs hidden-sm"></span> | |||
@@ -80,6 +80,7 @@ frappe.ui.Page = Class.extend({ | |||
this.page_actions = this.wrapper.find(".page-actions"); | |||
this.checked_items_status = this.page_actions.find(".checked-items-status"); | |||
this.btn_primary = this.page_actions.find(".primary-action"); | |||
this.btn_secondary = this.page_actions.find(".btn-secondary"); | |||
@@ -146,7 +146,7 @@ textarea.form-control { | |||
/* jquery ui */ | |||
.ui-datepicker { | |||
z-index: 100 !important; | |||
z-index: 9999 !important; | |||
} | |||
.ui-datepicker .ui-datepicker-header { | |||