Merge pull request #12895 from revant/feat-auth-hooks
feat(hooks): auth hooks
This commit is contained in:
commit
85cbdf7683
4 changed files with 32 additions and 32 deletions
|
|
@ -1,12 +1,10 @@
|
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# MIT License. See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
import json
|
||||
|
||||
from six.moves.urllib.parse import urlencode, urlparse
|
||||
from urllib.parse import urlencode, urlparse
|
||||
|
||||
import frappe
|
||||
import frappe.client
|
||||
|
|
@ -14,6 +12,7 @@ import frappe.handler
|
|||
from frappe import _
|
||||
from frappe.utils.response import build_response
|
||||
|
||||
|
||||
def handle():
|
||||
"""
|
||||
Handler for `/api` methods
|
||||
|
|
@ -38,9 +37,6 @@ def handle():
|
|||
`/api/resource/{doctype}/{name}?run_method={method}` will run a whitelisted controller method
|
||||
"""
|
||||
|
||||
|
||||
validate_auth()
|
||||
|
||||
parts = frappe.request.path[1:].split("/",3)
|
||||
call = doctype = name = None
|
||||
|
||||
|
|
@ -116,7 +112,7 @@ def handle():
|
|||
frappe.local.form_dict['fields'] = json.loads(frappe.local.form_dict['fields'])
|
||||
frappe.local.form_dict.setdefault('limit_page_length', 20)
|
||||
frappe.local.response.update({
|
||||
"data": frappe.call(
|
||||
"data": frappe.call(
|
||||
frappe.client.get_list,
|
||||
doctype,
|
||||
**frappe.local.form_dict
|
||||
|
|
@ -140,6 +136,7 @@ def handle():
|
|||
|
||||
return build_response("json")
|
||||
|
||||
|
||||
def get_request_form_data():
|
||||
if frappe.local.form_dict.data is None:
|
||||
data = frappe.safe_decode(frappe.local.request.get_data())
|
||||
|
|
@ -148,25 +145,18 @@ def get_request_form_data():
|
|||
|
||||
return frappe.parse_json(data)
|
||||
|
||||
|
||||
def validate_auth():
|
||||
if frappe.get_request_header("Authorization") is None:
|
||||
return
|
||||
|
||||
VALID_AUTH_PREFIX_TYPES = ['basic', 'bearer', 'token']
|
||||
VALID_AUTH_PREFIX_STRING = ", ".join(VALID_AUTH_PREFIX_TYPES).title()
|
||||
|
||||
"""
|
||||
Authenticate and sets user for the request.
|
||||
"""
|
||||
authorization_header = frappe.get_request_header("Authorization", str()).split(" ")
|
||||
authorization_type = authorization_header[0].lower()
|
||||
|
||||
if len(authorization_header) == 1:
|
||||
frappe.throw(_('Invalid Authorization headers, add a token with a prefix from one of the following: {0}.').format(VALID_AUTH_PREFIX_STRING), frappe.InvalidAuthorizationHeader)
|
||||
|
||||
if authorization_type == "bearer":
|
||||
if len(authorization_header) == 2:
|
||||
validate_oauth(authorization_header)
|
||||
elif authorization_type in VALID_AUTH_PREFIX_TYPES:
|
||||
validate_auth_via_api_keys(authorization_header)
|
||||
else:
|
||||
frappe.throw(_('Invalid Authorization Type {0}, must be one of {1}.').format(authorization_type, VALID_AUTH_PREFIX_STRING), frappe.InvalidAuthorizationPrefix)
|
||||
|
||||
validate_auth_via_hooks()
|
||||
|
||||
|
||||
def validate_oauth(authorization_header):
|
||||
|
|
@ -177,8 +167,8 @@ def validate_oauth(authorization_header):
|
|||
authorization_header (list of str): The 'Authorization' header containing the prefix and token
|
||||
"""
|
||||
|
||||
from frappe.oauth import get_url_delimiter
|
||||
from frappe.integrations.oauth2 import get_oauth_server
|
||||
from frappe.oauth import get_url_delimiter
|
||||
|
||||
form_dict = frappe.local.form_dict
|
||||
token = authorization_header[1]
|
||||
|
|
@ -192,14 +182,13 @@ def validate_oauth(authorization_header):
|
|||
|
||||
try:
|
||||
required_scopes = frappe.db.get_value("OAuth Bearer Token", token, "scopes").split(get_url_delimiter())
|
||||
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
|
||||
except AttributeError:
|
||||
frappe.throw(_("Invalid Bearer token, please provide a valid access token with prefix 'Bearer'."), frappe.InvalidAuthorizationToken)
|
||||
pass
|
||||
|
||||
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
|
||||
|
||||
|
||||
def validate_auth_via_api_keys(authorization_header):
|
||||
|
|
@ -222,8 +211,7 @@ def validate_auth_via_api_keys(authorization_header):
|
|||
except binascii.Error:
|
||||
frappe.throw(_("Failed to decode token, please provide a valid base64-encoded token."), frappe.InvalidAuthorizationToken)
|
||||
except (AttributeError, TypeError, ValueError):
|
||||
frappe.throw(_("Invalid token, please provide a valid token with prefix 'Basic' or 'Token'."), frappe.InvalidAuthorizationToken)
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def validate_api_key_secret(api_key, api_secret, frappe_authorization_source=None):
|
||||
|
|
@ -248,3 +236,8 @@ def validate_api_key_secret(api_key, api_secret, frappe_authorization_source=Non
|
|||
if frappe.local.login_manager.user in ('', 'Guest'):
|
||||
frappe.set_user(user)
|
||||
frappe.local.form_dict = form_dict
|
||||
|
||||
|
||||
def validate_auth_via_hooks():
|
||||
for auth_hook in frappe.get_hooks('auth_hooks', []):
|
||||
frappe.get_attr(auth_hook)()
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ def application(request):
|
|||
frappe.recorder.record()
|
||||
frappe.monitor.start()
|
||||
frappe.rate_limiter.apply()
|
||||
frappe.api.validate_auth()
|
||||
|
||||
if request.method == "OPTIONS":
|
||||
response = Response()
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import frappe
|
|||
import frappe.utils
|
||||
import frappe.sessions
|
||||
from frappe.utils import cint
|
||||
from frappe.api import validate_auth
|
||||
from frappe import _, is_whitelisted
|
||||
from frappe.utils.response import build_response
|
||||
from frappe.utils.csvutils import build_csv_response
|
||||
|
|
@ -24,7 +23,7 @@ ALLOWED_MIMETYPES = ('image/png', 'image/jpeg', 'application/pdf', 'application/
|
|||
|
||||
def handle():
|
||||
"""handle request"""
|
||||
validate_auth()
|
||||
|
||||
cmd = frappe.local.form_dict.cmd
|
||||
data = None
|
||||
|
||||
|
|
|
|||
|
|
@ -312,6 +312,13 @@ user_data_fields = [
|
|||
}}
|
||||
]
|
||||
|
||||
# Authentication and authorization
|
||||
# --------------------------------
|
||||
|
||||
# auth_hooks = [
|
||||
# "{app_name}.auth.validate"
|
||||
# ]
|
||||
|
||||
"""
|
||||
|
||||
desktop_template = """# -*- coding: utf-8 -*-
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue