The license.txt file has been replaced with LICENSE for quite a while now. INAL but it didn't seem accurate to say "hey, checkout license.txt although there's no such file". Apart from this, there were inconsistencies in the headers altogether...this change brings consistency.
69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
|
# License: MIT. See LICENSE
|
|
import hmac, hashlib
|
|
from urllib.parse import urlencode
|
|
from frappe import _
|
|
|
|
import frappe
|
|
import frappe.utils
|
|
|
|
def get_signed_params(params):
|
|
"""Sign a url by appending `&_signature=xxxxx` to given params (string or dict).
|
|
|
|
:param params: String or dict of parameters."""
|
|
if not isinstance(params, str):
|
|
params = urlencode(params)
|
|
|
|
signature = hmac.new(params.encode(), digestmod=hashlib.md5)
|
|
signature.update(get_secret().encode())
|
|
return params + "&_signature=" + signature.hexdigest()
|
|
|
|
def get_secret():
|
|
return frappe.local.conf.get("secret") or str(frappe.db.get_value("User", "Administrator", "creation"))
|
|
|
|
def verify_request():
|
|
"""Verify if the incoming signed request if it is correct."""
|
|
query_string = frappe.safe_decode(frappe.local.flags.signed_query_string or \
|
|
getattr(frappe.request, 'query_string', None))
|
|
|
|
valid = False
|
|
|
|
signature_string = '&_signature='
|
|
if signature_string in query_string:
|
|
params, signature = query_string.split(signature_string)
|
|
|
|
given_signature = hmac.new(params.encode('utf-8'), digestmod=hashlib.md5)
|
|
|
|
given_signature.update(get_secret().encode())
|
|
valid = signature == given_signature.hexdigest()
|
|
|
|
if not valid:
|
|
frappe.respond_as_web_page(_("Invalid Link"),
|
|
_("This link is invalid or expired. Please make sure you have pasted correctly."))
|
|
|
|
return valid
|
|
|
|
def get_url(cmd, params, nonce=None, secret=None):
|
|
if not nonce:
|
|
nonce = params
|
|
signature = get_signature(params, nonce, secret)
|
|
params['signature'] = signature
|
|
return frappe.utils.get_url("".join(['api/method/', cmd, '?', urlencode(params)]))
|
|
|
|
def get_signature(params, nonce, secret=None):
|
|
params = "".join((frappe.utils.cstr(p) for p in params.values()))
|
|
if not secret:
|
|
secret = frappe.local.conf.get("secret") or "secret"
|
|
|
|
signature = hmac.new(str(nonce), digestmod=hashlib.md5)
|
|
signature.update(secret)
|
|
signature.update(params)
|
|
return signature.hexdigest()
|
|
|
|
def verify_using_doc(doc, signature, cmd):
|
|
params = doc.get_signature_params()
|
|
return signature == get_signature(params, doc.get_nonce())
|
|
|
|
def get_url_using_doc(doc, cmd):
|
|
params = doc.get_signature_params()
|
|
return get_url(cmd, params, doc.get_nonce())
|