Exemplo n.º 1
0
    def _create_api_call(self, req):
        call = None
        try:
            # Parse the request path
            path = req.path
            if self._request_strip_prefix and path.startswith(
                self._request_strip_prefix
            ):
                path = path[len(self._request_strip_prefix) :]
            endpoint_version, endpoint_name = ServiceRepo.parse_endpoint_path(path)

            # Resolve authorization: if cookies contain an authorization token, use it as a starting point.
            # in any case, request headers always take precedence.
            auth_cookie = req.cookies.get(
                config.get("apiserver.auth.session_auth_cookie_name")
            )
            headers = (
                {}
                if not auth_cookie
                else {"Authorization": f"{AuthType.bearer_token} {auth_cookie}"}
            )
            headers.update(
                list(req.headers.items())
            )  # add (possibly override with) the headers

            # Construct call instance
            call = APICall(
                endpoint_name=endpoint_name,
                remote_addr=req.remote_addr,
                endpoint_version=endpoint_version,
                headers=headers,
                files=req.files,
                host=req.host,
                auth_cookie=auth_cookie,
            )

        except PathParsingError as ex:
            call = self._call_or_empty_with_error(call, req, ex.args[0], 400)
            call.log_api = False
        except BadRequest as ex:
            call = self._call_or_empty_with_error(call, req, ex.description, 400)
        except BaseError as ex:
            call = self._call_or_empty_with_error(
                call, req, ex.msg, ex.code, ex.subcode
            )
        except Exception as ex:
            log.exception("Error creating call")
            call = self._call_or_empty_with_error(
                call, req, ex.args[0] if ex.args else type(ex).__name__, 500
            )

        return call
Exemplo n.º 2
0
    def before_request(self):
        if request.method == "OPTIONS":
            return "", 200
        if "/static/" in request.path:
            return

        try:
            call = self._create_api_call(request)
            load_data_callback = partial(self._load_call_data, req=request)
            content, content_type = ServiceRepo.handle_call(
                call, load_data_callback=load_data_callback
            )

            if call.result.redirect:
                response = redirect(call.result.redirect.url, call.result.redirect.code)
            else:
                headers = None
                if call.result.filename:
                    headers = {
                        "Content-Disposition": f"attachment; filename={call.result.filename}"
                    }

                response = Response(
                    content,
                    mimetype=content_type,
                    status=call.result.code,
                    headers=headers,
                )

            if call.result.cookies:
                for key, value in call.result.cookies.items():
                    kwargs = config.get("apiserver.auth.cookies")
                    if value is None:
                        kwargs = kwargs.copy()
                        kwargs["max_age"] = 0
                        kwargs["expires"] = 0
                        response.set_cookie(key, "", **kwargs)
                    else:
                        response.set_cookie(key, value, **kwargs)

            return response
        except Exception as ex:
            log.exception(f"Failed processing request {request.url}: {ex}")
            return f"Failed processing request {request.url}", 500
Exemplo n.º 3
0
    def get_token_for_user(
        user_id: str,
        company_id: str = None,
        expiration_sec: int = None,
        entities: dict = None,
    ) -> GetTokenResponse:

        with translate_errors_context():
            query = dict(id=user_id)

            if company_id:
                query.update(company=company_id)

            user = User.objects(**query).first()
            if not user:
                raise errors.bad_request.InvalidUserId(**query)

            company_id = company_id or user.company
            company = Company.objects(id=company_id).only("id", "name").first()
            if not company:
                raise errors.bad_request.InvalidId(
                    "invalid company associated with user", company=company)

            identity = Identity(
                user=user_id,
                company=company_id,
                role=user.role,
                user_name=user.name,
                company_name=company.name,
            )

            token = Token.create_encoded_token(
                identity=identity,
                entities=entities,
                expiration_sec=expiration_sec,
                api_version=str(ServiceRepo.max_endpoint_version()),
                server_version=str(get_version()),
                server_build=str(get_build_number()),
                feature_set="basic",
            )

            return GetTokenResponse(token=token.decode("ascii"))
Exemplo n.º 4
0
 def _load_services(self):
     ServiceRepo.load("services")
     log.info(f"Exposed Services: {' '.join(ServiceRepo.endpoint_names())}")
Exemplo n.º 5
0
    def before_request(self):
        if request.method == "OPTIONS":
            return "", 200
        if "/static/" in request.path:
            return

        if request.content_encoding:
            return f"Content encoding is not supported ({request.content_encoding})", 415

        try:
            call = self._create_api_call(request)
            load_data_callback = partial(self._load_call_data, req=request)
            content, content_type, company = ServiceRepo.handle_call(
                call, load_data_callback=load_data_callback
            )

            if call.result.redirect:
                response = redirect(call.result.redirect.url, call.result.redirect.code)
            else:
                headers = None
                if call.result.filename:
                    headers = {
                        "Content-Disposition": f"attachment; filename={call.result.filename}"
                    }

                response = Response(
                    content,
                    mimetype=content_type,
                    status=call.result.code,
                    headers=headers,
                )

            if call.result.cookies:
                for key, value in call.result.cookies.items():
                    kwargs = config.get("apiserver.auth.cookies").copy()
                    if value is None:
                        # Removing a cookie
                        kwargs["max_age"] = 0
                        kwargs["expires"] = 0
                        value = ""
                    elif not company:
                        # Setting a cookie, let's try to figure out the company
                        # noinspection PyBroadException
                        try:
                            company = Token.decode_identity(value).company
                        except Exception:
                            pass

                    if company:
                        try:
                            # use no default value to allow setting a null domain as well
                            kwargs["domain"] = config.get(f"apiserver.auth.cookies_domain_override.{company}")
                        except KeyError:
                            pass

                    response.set_cookie(key, value, **kwargs)

            return response
        except Exception as ex:
            log.exception(f"Failed processing request {request.url}: {ex}")
            return f"Failed processing request {request.url}", 500
Exemplo n.º 6
0
def info_2_8(call: APICall):
    info(call)
    call.result.data["api_version"] = str(ServiceRepo.max_endpoint_version())
Exemplo n.º 7
0
def get_endpoints(call: APICall):
    call.result.data = ServiceRepo.endpoints_summary()