Example #1
0
def validate_oauth():
    from dataent.oauth import get_url_delimiter
    form_dict = dataent.local.form_dict
    authorization_header = dataent.get_request_header("Authorization").split(
        " ") if dataent.get_request_header("Authorization") else None
    if authorization_header and authorization_header[0].lower() == "bearer":
        from dataent.integrations.oauth2 import get_oauth_server
        token = authorization_header[1]
        r = dataent.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 = dataent.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:
            dataent.set_user(
                dataent.db.get_value("OAuth Bearer Token", token, "user"))
            dataent.local.form_dict = form_dict
Example #2
0
def get_url(uri=None, full_address=False):
    """get app url from request"""
    host_name = dataent.local.conf.host_name or dataent.local.conf.hostname

    if uri and (uri.startswith("http://") or uri.startswith("https://")):
        return uri

    if not host_name:
        if hasattr(dataent.local, "request"
                   ) and dataent.local.request and dataent.local.request.host:
            protocol = 'https://' if 'https' == dataent.get_request_header(
                'X-Forwarded-Proto', "") else 'http://'
            host_name = protocol + dataent.local.request.host

        elif dataent.local.site:
            protocol = 'http://'

            if dataent.local.conf.ssl_certificate:
                protocol = 'https://'

            elif dataent.local.conf.wildcard:
                domain = dataent.local.conf.wildcard.get('domain')
                if domain and dataent.local.site.endswith(
                        domain) and dataent.local.conf.wildcard.get(
                            'ssl_certificate'):
                    protocol = 'https://'

            host_name = protocol + dataent.local.site

        else:
            host_name = dataent.db.get_value("Website Settings",
                                             "Website Settings", "subdomain")

            if not host_name:
                host_name = "http://localhost"

    if host_name and not (host_name.startswith("http://")
                          or host_name.startswith("https://")):
        host_name = "http://" + host_name

    if not uri and full_address:
        uri = dataent.get_request_header("REQUEST_URI", "")

    port = dataent.conf.http_port or dataent.conf.webserver_port

    if not (dataent.conf.restart_supervisor_on_update
            or dataent.conf.restart_systemd_on_update
            ) and host_name and not url_contains_port(host_name) and port:
        host_name = host_name + ':' + str(port)

    url = urljoin(host_name, uri) if uri else host_name

    return url
Example #3
0
def verify_request():
	woocommerce_settings = dataent.get_doc("Woocommerce Settings")
	sig = base64.b64encode(
		hmac.new(
			woocommerce_settings.secret.encode('utf8'),
			dataent.request.data,
			hashlib.sha256
		).digest()
	)

	if dataent.request.data and \
		dataent.get_request_header("X-Wc-Webhook-Signature") and \
		not sig == bytes(dataent.get_request_header("X-Wc-Webhook-Signature").encode()):
			dataent.throw(_("Unverified Webhook Data"))
	dataent.set_user(woocommerce_settings.creation_user)
Example #4
0
    def innerfn(fn):
        settings = dataent.get_doc(doctype)

        if dataent.request and settings and settings.get(
                secret_key) and not dataent.flags.in_test:
            sig = base64.b64encode(
                hmac.new(
                    settings.get(secret_key).encode('utf8'),
                    dataent.request.data, hashlib.sha256).digest())

            if dataent.request.data and \
             dataent.get_request_header(hmac_key) and \
             not sig == bytes(dataent.get_request_header(hmac_key).encode()):
                dataent.throw(_("Unverified Webhook Data"))
            dataent.set_user(settings.modified_by)

        return fn
Example #5
0
def validate_auth_via_api_keys():
    """
	authentication using api key and api secret

	set user
	"""
    try:
        authorization_header = dataent.get_request_header(
            "Authorization", None).split(" ") if dataent.get_request_header(
                "Authorization") else None
        if authorization_header and authorization_header[0] == 'Basic':
            token = dataent.safe_decode(
                base64.b64decode(authorization_header[1])).split(":")
            validate_api_key_secret(token[0], token[1])
        elif authorization_header and authorization_header[0] == 'token':
            token = authorization_header[1].split(":")
            validate_api_key_secret(token[0], token[1])
    except Exception as e:
        raise e
Example #6
0
    def __init__(self):
        # Get Environment variables
        self.domain = dataent.request.host
        if self.domain and self.domain.startswith('www.'):
            self.domain = self.domain[4:]

        if dataent.get_request_header('X-Forwarded-For'):
            dataent.local.request_ip = (dataent.get_request_header(
                'X-Forwarded-For').split(",")[0]).strip()

        elif dataent.get_request_header('REMOTE_ADDR'):
            dataent.local.request_ip = dataent.get_request_header(
                'REMOTE_ADDR')

        else:
            dataent.local.request_ip = '127.0.0.1'

        # language
        self.set_lang()

        # load cookies
        dataent.local.cookie_manager = CookieManager()

        # set db
        self.connect()

        # login
        dataent.local.login_manager = LoginManager()

        if dataent.form_dict._lang:
            lang = get_lang_code(dataent.form_dict._lang)
            if lang:
                dataent.local.lang = lang

        self.validate_csrf_token()

        # write out latest cookies
        dataent.local.cookie_manager.init_cookies()

        # check status
        check_session_stopped()
Example #7
0
def authenticate_signature(r):
    """Returns True if the received signature matches the generated signature"""
    received_signature = dataent.get_request_header("Webhook-Signature")

    if not received_signature:
        return False

    for key in get_webhook_keys():
        computed_signature = hmac.new(key.encode("utf-8"), r.get_data(),
                                      hashlib.sha256).hexdigest()
        if hmac.compare_digest(str(received_signature), computed_signature):
            return True

    return False
Example #8
0
    def validate_csrf_token(self):
        if dataent.local.request and dataent.local.request.method == "POST":
            if not dataent.local.session: return
            if not dataent.local.session.data.csrf_token \
             or dataent.local.session.data.device=="mobile" \
             or dataent.conf.get('ignore_csrf', None):
                # not via boot
                return

            csrf_token = dataent.get_request_header("X-Dataent-CSRF-Token")
            if not csrf_token and "csrf_token" in dataent.local.form_dict:
                csrf_token = dataent.local.form_dict.csrf_token
                del dataent.local.form_dict["csrf_token"]

            if dataent.local.session.data.csrf_token != csrf_token:
                dataent.local.flags.disable_traceback = True
                dataent.throw(_("Invalid Request"), dataent.CSRFTokenError)
Example #9
0
def init_request(request):
    dataent.local.request = request
    dataent.local.is_ajax = dataent.get_request_header(
        "X-Requested-With") == "XMLHttpRequest"

    site = _site or request.headers.get(
        'X-Dataent-Site-Name') or get_site_name(request.host)
    dataent.init(site=site, sites_path=_sites_path)

    if not (dataent.local.conf and dataent.local.conf.db_name):
        # site does not exist
        raise NotFound

    if dataent.local.conf.get('maintenance_mode'):
        raise dataent.SessionStopped

    make_form_dict(request)

    dataent.local.http_request = dataent.auth.HTTPRequest()
Example #10
0
def authenticate_signature(post_url=None):
    """Returns True if the received signature matches the generated signature"""
    received_signature = dataent.get_request_header("X-Mandrill-Signature")

    # seems like a dummy post request
    if not received_signature:
        return False

    to_hash = get_post_url_for_hashing(post_url)
    for key in get_webhook_keys():
        # generate signature using the webhook key
        hashed = hmac.new(key.encode("utf-8"), to_hash, hashlib.sha1)
        generated_signature = hashed.digest().encode("base64").rstrip('\n')

        # matched => authenticated
        if received_signature == generated_signature:
            return True

    # no match => failure
    return False
Example #11
0
    def authenticate_client(self, request, *args, **kwargs):

        cookie_dict = get_cookie_dict_from_headers(request)

        #Get ClientID in URL
        if request.client_id:
            oc = dataent.get_doc("OAuth Client", request.client_id)
        else:
            #Extract token, instantiate OAuth Bearer Token and use clientid from there.
            if "refresh_token" in dataent.form_dict:
                oc = dataent.get_doc(
                    "OAuth Client",
                    dataent.db.get_value(
                        "OAuth Bearer Token",
                        {"refresh_token": dataent.form_dict["refresh_token"]},
                        'client'))
            elif "token" in dataent.form_dict:
                oc = dataent.get_doc(
                    "OAuth Client",
                    dataent.db.get_value("OAuth Bearer Token",
                                         dataent.form_dict["token"], 'client'))
            else:
                oc = dataent.get_doc(
                    "OAuth Client",
                    dataent.db.get_value(
                        "OAuth Bearer Token",
                        dataent.get_request_header("Authorization").split(" ")
                        [1], 'client'))
        try:
            request.client = request.client or oc.as_dict()
        except Exception as e:
            print("Failed body authentication: Application %s does not exist".
                  format(cid=request.client_id))

        return dataent.session.user == unquote(
            cookie_dict.get('user_id', "Guest"))
Example #12
0
def handle_exception(e):
    response = None
    http_status_code = getattr(e, "http_status_code", 500)
    return_as_message = False

    if dataent.get_request_header('Accept') and (
            dataent.local.is_ajax
            or 'application/json' in dataent.get_request_header('Accept')):
        # handle ajax responses first
        # if the request is ajax, send back the trace or error message
        response = dataent.utils.response.report_error(http_status_code)

    elif (http_status_code == 500 and isinstance(e, pymysql.InternalError)
          and e.args[0] in (ER.LOCK_WAIT_TIMEOUT, ER.LOCK_DEADLOCK)):
        http_status_code = 508

    elif http_status_code == 401:
        dataent.respond_as_web_page(
            _("Session Expired"),
            _("Your session has expired, please login again to continue."),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 403:
        dataent.respond_as_web_page(
            _("Not Permitted"),
            _("You do not have enough permissions to complete the action"),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    elif http_status_code == 404:
        dataent.respond_as_web_page(
            _("Not Found"),
            _("The resource you are looking for is not available"),
            http_status_code=http_status_code,
            indicator_color='red')
        return_as_message = True

    else:
        traceback = "<pre>" + dataent.get_traceback() + "</pre>"
        if dataent.local.flags.disable_traceback:
            traceback = ""

        dataent.respond_as_web_page("Server Error",
                                    traceback,
                                    http_status_code=http_status_code,
                                    indicator_color='red',
                                    width=640)
        return_as_message = True

    if e.__class__ == dataent.AuthenticationError:
        if hasattr(dataent.local, "login_manager"):
            dataent.local.login_manager.clear_cookies()

    if http_status_code >= 500:
        dataent.logger().error('Request Error', exc_info=True)
        make_error_snapshot(e)

    if return_as_message:
        response = dataent.website.render.render(
            "message", http_status_code=http_status_code)

    return response
Example #13
0
def _order(*args, **kwargs):
	woocommerce_settings = dataent.get_doc("Woocommerce Settings")
	if dataent.flags.woocomm_test_order_data:
		fd = dataent.flags.woocomm_test_order_data
		event = "created"

	elif dataent.request and dataent.request.data:
		verify_request()
		fd = json.loads(dataent.request.data)
		event = dataent.get_request_header("X-Wc-Webhook-Event")

	else:
		return "success"

	if event == "created":
		raw_billing_data = fd.get("billing")
		customer_woo_com_email = raw_billing_data.get("email")

		if dataent.get_value("Customer",{"woocommerce_email": customer_woo_com_email}):
			# Edit
			link_customer_and_address(raw_billing_data,1)
		else:
			# Create
			link_customer_and_address(raw_billing_data,0)


		items_list = fd.get("line_items")
		for item in items_list:

			item_woo_com_id = item.get("product_id")

			if dataent.get_value("Item",{"woocommerce_id": item_woo_com_id}):
				#Edit
				link_item(item,1)
			else:
				link_item(item,0)


		customer_name = raw_billing_data.get("first_name") + " " + raw_billing_data.get("last_name")

		new_sales_order = dataent.new_doc("Sales Order")
		new_sales_order.customer = customer_name

		created_date = fd.get("date_created").split("T")
		new_sales_order.transaction_date = created_date[0]

		new_sales_order.po_no = fd.get("id")
		new_sales_order.woocommerce_id = fd.get("id")
		new_sales_order.naming_series = woocommerce_settings.sales_order_series or "SO-WOO-"

		placed_order_date = created_date[0]
		raw_date = datetime.datetime.strptime(placed_order_date, "%Y-%m-%d")
		raw_delivery_date = dataent.utils.add_to_date(raw_date,days = 7)
		order_delivery_date_str = raw_delivery_date.strftime('%Y-%m-%d')
		order_delivery_date = str(order_delivery_date_str)

		new_sales_order.delivery_date = order_delivery_date
		default_set_company = dataent.get_doc("Global Defaults")
		company = raw_billing_data.get("company") or default_set_company.default_company
		found_company = dataent.get_doc("Company",{"name":company})
		company_abbr = found_company.abbr

		new_sales_order.company = company

		for item in items_list:
			woocomm_item_id = item.get("product_id")
			found_item = dataent.get_doc("Item",{"woocommerce_id": woocomm_item_id})

			ordered_items_tax = item.get("total_tax")

			new_sales_order.append("items",{
				"item_code": found_item.item_code,
				"item_name": found_item.item_name,
				"description": found_item.item_name,
				"delivery_date":order_delivery_date,
				"uom": woocommerce_settings.uom or _("Nos"),
				"qty": item.get("quantity"),
				"rate": item.get("price"),
				"warehouse": woocommerce_settings.warehouse or "Stores" + " - " + company_abbr
				})

			add_tax_details(new_sales_order,ordered_items_tax,"Ordered Item tax",0)

		# shipping_details = fd.get("shipping_lines") # used for detailed order
		shipping_total = fd.get("shipping_total")
		shipping_tax = fd.get("shipping_tax")

		add_tax_details(new_sales_order,shipping_tax,"Shipping Tax",1)
		add_tax_details(new_sales_order,shipping_total,"Shipping Total",1)

		new_sales_order.submit()

		dataent.db.commit()