[ Avaa Bypassed ]




Upload:

Command:

www-data@18.218.241.211: ~ $
import abc
import json
import os
from posixpath import join as urljoin
from typing import Any, Dict, Optional, Tuple, Type
from urllib import error
from urllib.parse import urlencode

from uaclient import config, exceptions, system, util, version


class UAServiceClient(metaclass=abc.ABCMeta):

    url_timeout = 30  # type: Optional[int]
    # Cached serviceclient_url_responses if provided in uaclient.conf
    # via features: {serviceclient_url_responses: /some/file.json}
    _response_overlay = None  # type: Dict[str, Any]

    @property
    @abc.abstractmethod
    def api_error_cls(self) -> Type[Exception]:
        """Set in subclasses to the type of API error raised"""
        pass

    @property
    @abc.abstractmethod
    def cfg_url_base_attr(self) -> str:
        """String in subclasses, the UAConfig attribute containing base url"""
        pass

    def __init__(self, cfg: Optional[config.UAConfig] = None) -> None:
        if not cfg:
            self.cfg = config.UAConfig()
        else:
            self.cfg = cfg

    def headers(self):
        return {
            "user-agent": "UA-Client/{}".format(version.get_version()),
            "accept": "application/json",
            "content-type": "application/json",
        }

    def request_url(
        self,
        path,
        data=None,
        headers=None,
        method=None,
        query_params=None,
        log_response_body: bool = True,
        timeout: Optional[int] = None,
    ):
        path = path.lstrip("/")
        if not headers:
            headers = self.headers()
        if headers.get("content-type") == "application/json" and data:
            data = json.dumps(data, cls=util.DatetimeAwareJSONEncoder).encode(
                "utf-8"
            )
        url = urljoin(getattr(self.cfg, self.cfg_url_base_attr), path)
        fake_response, fake_headers = self._get_fake_responses(url)
        if fake_response:
            return fake_response, fake_headers  # URL faked by uaclient.conf
        if query_params:
            # filter out None values
            filtered_params = {
                k: v for k, v in sorted(query_params.items()) if v is not None
            }
            url += "?" + urlencode(filtered_params)
        timeout_to_use = timeout if timeout is not None else self.url_timeout
        try:
            response, headers = util.readurl(
                url=url,
                data=data,
                headers=headers,
                method=method,
                timeout=timeout_to_use,
                log_response_body=log_response_body,
            )
        except error.URLError as e:
            body = None
            if hasattr(e, "body"):
                body = e.body  # type: ignore
            elif hasattr(e, "read"):
                body = e.read().decode("utf-8")  # type: ignore
            if body:
                try:
                    error_details = json.loads(
                        body, cls=util.DatetimeAwareJSONDecoder
                    )
                except ValueError:
                    error_details = None
                if error_details:
                    raise self.api_error_cls(e, error_details)
            raise exceptions.UrlError(
                e, code=getattr(e, "code", None), headers=headers, url=url
            )
        return response, headers

    def _get_response_overlay(self, url: str):
        """Return a list of fake response dicts for a given URL.

        serviceclient_url_responses in uaclient.conf should be a path
        to a json file which contains a dictionary keyed by full URL path.
        Each value will be a list of dicts representing each faked response
        for the given URL.

            The response dict item will have a code: <HTTP_STATUS_CODE> and
               response: "some string of content".
            The JSON string below fakes the available_resources URL on the
            contract server:
            '{"https://contracts.canonical.com/v1/resources": \
               [{"code": 200, "response": {"key": "val1", "key2": "val2"}}]}'

        :return: List of dicts for each faked response matching the url, or
           and empty list when no matching url found.
        """
        if self._response_overlay is not None:
            # Cache it so we don't re-read config every readurl call
            return self._response_overlay.get(url, [])
        response_overlay_path = self.cfg.features.get(
            "serviceclient_url_responses"
        )
        if not response_overlay_path:
            self._response_overlay = {}
        elif not os.path.exists(response_overlay_path):
            self._response_overlay = {}
        else:
            self._response_overlay = json.loads(
                system.load_file(response_overlay_path)
            )
        return self._response_overlay.get(url, [])

    def _get_fake_responses(
        self, url: str
    ) -> Tuple[Optional[Dict[str, Any]], Optional[Dict[str, str]]]:
        """Return response and headers if faked for this URL in uaclient.conf.

        :return: A tuple of response and header dicts if the URL has an overlay
            response defined. Return (None, {}) otherwise.

        :raises exceptions.URLError: When faked response "code" is != 200.
            URLError reason will be "response" value and any optional
            "headers" provided.
        """
        responses = self._get_response_overlay(url)
        if not responses:
            return None, {}
        if len(responses) == 1:
            # When only one respose is defined, repeat it for all calls
            response = responses[0]
        else:
            # When multiple responses defined pop the first one off the list.
            response = responses.pop(0)
        if response["code"] == 200:
            return response["response"], response.get("headers", {})
        # Must be an error
        e = error.URLError(response["response"])
        url_exception = exceptions.UrlError(
            e,
            code=response["code"],
            headers=response.get("headers", {}),
            url=url,
        )

        if response.get("type") == "contract":
            raise exceptions.ContractAPIError(
                url_exception,
                error_response=response["response"],
            )
        else:
            raise url_exception

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
api Folder 0755
clouds Folder 0755
daemon Folder 0755
entitlements Folder 0755
files Folder 0755
jobs Folder 0755
__init__.py File 0 B 0644
actions.py File 8.19 KB 0644
apt.py File 25.74 KB 0644
apt_news.py File 6.33 KB 0644
cli.py File 64.22 KB 0644
config.py File 24.5 KB 0644
contract.py File 27.47 KB 0644
contract_data_types.py File 9.38 KB 0644
data_types.py File 10.3 KB 0644
defaults.py File 2.46 KB 0644
event_logger.py File 7.75 KB 0644
exceptions.py File 13.56 KB 0644
gpg.py File 813 B 0644
livepatch.py File 11.03 KB 0644
lock.py File 3.58 KB 0644
log.py File 1.89 KB 0644
messages.py File 38.47 KB 0644
pip.py File 756 B 0644
security.py File 48.75 KB 0644
security_status.py File 24.19 KB 0644
serviceclient.py File 6.22 KB 0644
snap.py File 4.06 KB 0644
status.py File 25.73 KB 0644
system.py File 17.09 KB 0644
types.py File 308 B 0644
util.py File 20.3 KB 0644
version.py File 2.81 KB 0644
yaml.py File 642 B 0644