예제 #1
0
def send_email(email, template, kwargs):
    """Send an email via the mailgun service."""
    maildir = os.path.join(topdir, 'emails')
    env = jinja2.Environment(loader=jinja2.FileSystemLoader(maildir))
    template = env.get_template(template)
    rendered = template.render(**kwargs)
    headers, message = parse_email(rendered)
    mailargs = {'to': email,
                'from': app.config['MAIL_FROM'],
                'bcc': app.config.get('MAIL_BCC'),
                'text': message}
    mailargs.update(headers)
    conn = HTTPSConnection('api.mailgun.net', 443)
    conn.connect()
    auth = b64enc('api:{0[MAILGUN_KEY]}'.format(app.config))
    headers = {'Authorization': 'Basic {0}'.format(auth),
               'Accept': 'application/json',
               'Content-type': 'application/x-www-form-urlencoded'}
    url = '/v2/{0[MAILGUN_DOMAIN]}/messages'.format(app.config)
    body = urlencode(mailargs)
    conn.request('POST', url, body, headers)
    resp = conn.getresponse()
    if resp.status != 200:
        raise RuntimeError('could not send email')
    conn.close()
예제 #2
0
def get_auth_token(host, clientid, clientsecret, 
                   proxy_host=None, proxy_port=None):
    queryurl = '/oauth/access_token'
    if proxy_host and proxy_port:
        connection = HTTPSConnection(proxy_host, proxy_port)
        connection.set_tunnel(host, 443)
    else:
        connection = HTTPSConnection(host)
    authtoken = base64.b64encode(six.b('{0}:{1}'.format(clientid, clientsecret)))
    authstring = b"Basic %s" % (authtoken,)
    header = {"Authorization": authstring}
    params = urlencode({'grant_type': 'client_credentials'})
    connection.request("POST", queryurl, params, header)
    response = connection.getresponse()
    jsondata = bytes(response.read()).decode('utf-8')
    data = json.loads(str(jsondata))
    try:
        key = data['access_token']
    except KeyError:
        print("We're having trouble getting a session token.  Please check your API key.")
        print("Error output: ")
        print(data)
        sys.exit()
    finally:
        connection.close()
    return key
예제 #3
0
def getBestServer(servers):
    """Perform a speedtest.net latency request to determine which
    speedtest.net server has the lowest latency
    """

    results = {}
    for server in servers:
        cum = []
        url = '%s/latency.txt' % os.path.dirname(server['url'])
        urlparts = urlparse(url)
        for i in range(0, 3):
            try:
                if urlparts[0] == 'https':
                    h = HTTPSConnection(urlparts[1])
                else:
                    h = HTTPConnection(urlparts[1])
                headers = {'User-Agent': user_agent}
                start = timeit.default_timer()
                h.request("GET", urlparts[2], headers=headers)
                r = h.getresponse()
                total = (timeit.default_timer() - start)
            except (HTTPError, URLError, socket.error):
                cum.append(3600)
                continue
            text = r.read(9)
            if int(r.status) == 200 and text == 'test=test'.encode():
                cum.append(total)
            else:
                cum.append(3600)
            h.close()
        avg = round((sum(cum) / 6) * 1000, 3)
        results[avg] = server
    fastest = sorted(results.keys())[0]
    best = results[fastest]
    best['latency'] = fastest

    return best
예제 #4
0
def apihit(host,conntype,authtoken,queryurl,reqbody,
           proxy_host=None, proxy_port=None):
    retdata = ''
    if proxy_host and proxy_port:
        connection = HTTPSConnection(proxy_host, proxy_port)
        connection.set_tunnel(host, 443)
    else:
        connection = HTTPSConnection(host)
    tokenheader = {"Authorization": 'Bearer ' + authtoken, "Content-type": "application/json", "Accept": "text/plain"}
    if conntype == "GET":
        connection.request(conntype, queryurl, '', tokenheader)
    else:
        connection.request(conntype, queryurl, json.dumps(reqbody), tokenheader)
    response = connection.getresponse()
    respbody = response.read().decode('ascii', 'ignore')
    try:
        jsondata = respbody.decode()
        retdata = json.loads(jsondata)
    except AttributeError:
        retdata = json.loads(respbody)
    except:
        raise
    connection.close()
    return retdata
예제 #5
0
class HessianProxy(object):
    def __init__(self,
                 service_uri,
                 credentials=None,
                 key_file=None,
                 cert_file=None,
                 timeout=10,
                 buffer_size=65535,
                 error_factory=lambda x: x,
                 overload=False,
                 version=1):
        self.version = version

        self._headers = list()
        self._headers.append((
            'User-Agent',
            'python-hessian/' + __version__,
        ))
        self._headers.append((
            'Content-Type',
            'application/x-hessian',
        ))

        if sys.version_info < (2, 6):
            warn('HessianProxy timeout not enforceable before Python 2.6',
                 RuntimeWarning,
                 stacklevel=2)
            kwargs = {}
        else:
            kwargs = {'timeout': timeout}

        if six.PY2:
            kwargs['strict'] = True

        self._uri = urlparse(service_uri)
        if self._uri.scheme == 'http':
            self._client = HTTPConnection(self._uri.hostname, self._uri.port
                                          or 80, **kwargs)
        elif self._uri.scheme == 'https':
            self._client = HTTPSConnection(self._uri.hostname,
                                           self._uri.port or 443,
                                           key_file=key_file,
                                           cert_file=cert_file,
                                           **kwargs)
        else:
            raise NotImplementedError(
                "HessianProxy only supports http:// and https:// URIs")

        # autofill credentials if they were passed via url instead of kwargs
        if (self._uri.username and self._uri.password) and not credentials:
            credentials = (self._uri.username, self._uri.password)

        if credentials:
            auth = 'Basic ' + base64.b64encode(':'.join(credentials))
            self._headers.append(('Authorization', auth))

        self._buffer_size = buffer_size
        self._error_factory = error_factory
        self._overload = overload
        self._parser = Parser()

    class __RemoteMethod(object):
        # dark magic for autoloading methods
        def __init__(self, caller, method):
            self.__caller = caller
            self.__method = method

        def __call__(self, *args):
            return self.__caller(self.__method, args)

    def __getattr__(self, method):
        return self.__RemoteMethod(self, method)

    def __repr__(self):
        return "<pyhessian.client.HessianProxy(\"%s\")>" % (
            self._uri.geturl(), )

    def __str__(self):
        return self.__repr__()

    def __call__(self, method, args):
        try:
            self._client.putrequest('POST', self._uri.path)
            for header in self._headers:
                self._client.putheader(*header)

            request = encode_object(
                Call(method,
                     args,
                     overload=self._overload,
                     version=self.version))
            self._client.putheader("Content-Length", str(len(request)))
            self._client.endheaders()
            self._client.send(six.binary_type(request))

            response = self._client.getresponse()
            if response.status != 200:
                raise ProtocolError(self._uri.geturl(), response.status,
                                    response.reason)

            length = response.getheader('Content-Length', -1)
            if length == '0':
                raise ProtocolError(self._uri.geturl(), 'FATAL:',
                                    'Server sent zero-length response')

            reply = self._parser.parse_stream(
                BufferedReader(response, buffer_size=self._buffer_size))
            self._client.close()

            if isinstance(reply.value, Fault):
                raise self._error_factory(reply.value)
            else:
                return reply.value
        except:
            self._client.close()
            raise
class TestLicenseClient(object):
    def __init__(self, parser=None):
        # type: (Optional[ArgumentParser]) -> None
        """
		Class constructor for the test license client and HTMLParser
		"""
        self.log = logging.getLogger("License_Client")
        self.setup_logging()

        self.parser = parser
        self.license_server_url = 'license.univention.de'
        self.license_filename = 'ValidTest.license'

        self.connection = None  # type: Optional[HTTPSConnection]
        self.server_username = '******'
        self.server_password = ''
        self.secret_file = '/etc/license.secret'
        self.cookie = ''
        self.license_shop = 'testing'

        self.license_params = {
            "kundeUnternehmen": "Univention",
            "kundeEmail": "*****@*****.**",
            "BaseDN": "",
            "EndDate": "",
            "Servers": 50,
            "Support": 0,
            "PremiumSupport": 0,
            "Users": 50,
            "ManagedClients": 50,
            "CorporateClients": 50,
            "VirtualDesktopUsers": 0,
            "VirtualDesktopClients": 0,
            "Type": "UCS",
        }  # type: Dict[str, Any]

    def setup_logging(self):
        # type: () -> None
        """
		Creates and configures the logger with an INFO level
		"""
        self.log.setLevel(logging.INFO)
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(
            logging.Formatter(
                "%(asctime)s - %(name)s - %(levelname)s - %(message)s"))
        self.log.addHandler(ch)

    def create_connection(self):
        # type: () -> None
        """
		Creates a HTTPS connection instance on a default port (443)
		to the 'self.license_server_url'
		"""
        self.log.debug("In 'create_connection'")
        self.connection = HTTPSConnection(self.license_server_url)

    def close_connection(self):
        # type: () -> None
        """
		Closes the license server connection if the connection instance
		was created
		"""
        self.log.debug("In 'close_connection'")
        if self.connection:
            try:
                self.connection.close()
            except HTTPException as exc:
                self.log.exception(
                    "An HTTP Exception occurred while closing the connection: '%s'",
                    exc)

    def get_server_password(self, secret_file='/etc/license.secret'):
        # type: (str) -> None
        """
		Opens and reads the 'secret_file'. Saves the result to a
		'self.server_password'
		"""
        self.log.debug("In 'get_server_password': secret_file='%s'",
                       secret_file)
        if not path.exists(secret_file):
            self.log.critical(
                "The '%s' secret file does not exist, cannot proceed without password",
                secret_file)
            raise CredentialsMissing("The '%s' secret file does not exist" %
                                     secret_file)
        try:
            with open(secret_file, 'r') as password:
                self.server_password = password.read()
        except (IOError, ValueError) as exc:
            self.log.exception(
                "Failed to get the password from the '%s', an error occurred: %r",
                secret_file, exc)
            exit(1)
        if not self.server_password:
            self.log.critical(
                "The password to access the license service cannot be empty")
            exit(1)

    def get_cookie(self):
        # type: () -> None
        """
		Makes a POST request with 'self.server_username' and
		'self.server_password' into login forms and saves the
		cookie from the response received.
		"""
        self.log.debug("In 'get_cookie' method")
        body = {
            "username": self.server_username,
            "password": self.server_password,
        }
        headers = {
            "Content-type": "application/x-www-form-urlencoded",
            "Accept": "text/plain",
        }

        response = self.make_post_request('/shop/%s/' % (self.license_shop, ),
                                          urlencode(body), headers)
        self.log.debug(
            "The response status is '%s', reason is '%s', headers are '%s'",
            response.status, response.reason, response.getheaders())

        self.cookie = response.getheader('set-cookie')
        if not ('sessionid' in self.cookie):
            self.log.critical(
                "The 'sessionid' field was not found in the received cookie: '%s'",
                self.cookie)
            exit(1)
        # extracting only the 'sessionid' part of the cookie:
        self.cookie = self.cookie[:self.cookie.find(';')]
        self.log.debug("The cookie is: '%s'", self.cookie)
        # reading the response to avoid 'ResponseNotReady' exception later:
        response.read()

    def make_post_request(self, url, body, headers):
        # type: (str, str, Dict[str, str]) -> HTTPResponse
        """
		Makes a POST request with the given 'url', 'body', 'headers' and
		returns the response
		"""
        self.log.debug(
            "In 'make_post_request' method: url='%s', body='%s', headers='%s'",
            url, body, headers)
        assert self.connection
        try:
            self.connection.request("POST", url, body, headers)
            return self.connection.getresponse()
        except HTTPException as exc:
            self.log.exception(
                "An HTTP Exception occurred while making '%s' POST request: '%s'",
                url, exc)
            exit(1)

    def make_get_request(self, url, headers):
        # type: (str, Dict[str, str]) -> HTTPResponse
        """
		Makes a GET request with the given 'url', 'headers' and
		returns the response
		"""
        self.log.debug("In 'make_get_request' method: url='%s', headers='%s'",
                       url, headers)
        assert self.connection
        try:
            self.connection.request("GET", url, headers=headers)
            return self.connection.getresponse()
        except HTTPException as exc:
            self.log.exception(
                "An HTTP Exception occurred while making '%s' GET request: '%s'",
                url, exc)
            exit(1)

    def get_the_license(self, body):
        # type: (str) -> None
        """
		Processes the given 'body' with HTMLParser to find the link
		to a created license file and downloads the license after.
		"""
        self.log.debug("In 'get_the_license' method: body='%s'", body)
        parser = ShopParser(self.log)
        parser.feed(body)  # process the response 'body' for license link
        if not parser.link_to_license:
            self.log.critical(
                "The link to the license file was not found in the body from server: '%s'",
                body)
            exit(1)
        self.download_license_file(parser.link_to_license)

    def order_a_license(self):
        # type: () -> str
        """
		Makes a POST request with encoded 'self.license_params' as a body to
		order a new license. Returns the response body.
		"""
        self.log.debug("In 'order_a_license' method")
        body = self.license_params
        headers = {
            "Cookie": self.cookie,
            "Content-type": "application/x-www-form-urlencoded",
        }

        response = self.make_post_request(
            '/shop/%s/order' % (self.license_shop, ), urlencode(body), headers)
        assert response.status == 202
        return self.get_body(response)

    def get_body(self, response):
        # type: (HTTPResponse) -> str
        self.log.debug(
            "The response status is '%s', reason is '%s', headers are '%s'",
            response.status, response.reason, response.getheaders())
        content_type = response.getheader('Content-Type')
        mimetype, options = cgi.parse_header(content_type)
        encoding = options.get("charset", "ascii")
        return response.read().decode(encoding, "replace")

    def download_license_file(self, link_to_license):
        # type: (str) -> None
        """
		Downloads the license located at `filename` and saves it
		to the file with a 'self.license_filename'
		"""
        self.log.debug("In 'download_license_file' method")
        headers = {
            "Cookie": self.cookie,
            "Accept": "text/plain",
        }
        response = self.make_get_request(
            '/shop/%s/%s' % (self.license_shop, link_to_license), headers)
        try:
            body = self.get_body(response)
            with open(self.license_filename, 'w') as license_file:
                license_file.write(body)
            self.log.info("The license was written to file '%s'",
                          self.license_filename)
        except (IOError, ValueError) as exc:
            self.log.exception(
                "An error happened while writing the downloaded license to a file '%s': '%s'",
                self.license_filename, exc)
            exit(1)

    def check_date_format(self):
        # type: () -> None
        """
		Checks if the 'EndDate' format is correct.
		"""
        try:
            if self.license_params['EndDate'] != 'unlimited':
                datetime.strptime(self.license_params['EndDate'], '%d.%m.%Y')
        except ValueError as exc:
            self.log.exception(
                "The 'EndDate' for the license has a wrong format, supported format is 'dd.mm.yyyy': %r",
                exc)
            exit(1)

    def update_with_parsed_args(self, args):
        # type: (Dict[str, Any]) -> None
        """
		Updates the loglevel and license filename settings if given
		among the parsed arguments. Merges parsed data with default
		license parameters.
		"""
        log_level = args.pop('LogLevel')
        if log_level:
            numeric_level = getattr(logging, log_level.upper(), None)
            if isinstance(numeric_level, int):
                self.log.setLevel(numeric_level)
            else:
                self.log.info(
                    "The LogLevel was not changed, unknown '%s' log level given",
                    log_level)

        self.license_shop = args.pop('shop')
        self.server_username = args.pop('username')
        self.secret_file = args.pop('secret_file')
        license_file = args.pop('FileName')
        if license_file:
            self.license_filename = license_file
        self.log.debug("The filename for the license will be '%s'",
                       self.license_filename)

        # merging parsed args with the default values:
        self.license_params.update(
            (key, val) for key, val in args.items() if val is not None)
        self.log.info("Requested license parameters are: '%s'",
                      self.license_params)

    def process_cmd_arguments(self):
        # type: () -> None
        """
		Populates self.parser class with positional and optional arguments and
		processes the user input, checks the date format and than merges it
		with the default values in the 'self.license_params' dictionary
		"""
        self.log.debug("In 'process_cmd_arguments' method")
        assert self.parser
        self.parser.add_argument("BaseDN", help="A base DN for the license")
        self.parser.add_argument(
            "EndDate",
            help=
            "The date till which the license will be valid (max 1 year from now)"
        )
        self.parser.add_argument(
            "-f",
            "--FileName",
            help="The filename to be used for the issued license",
            default="ValidTest.license")
        self.parser.add_argument(
            "-s",
            "--Servers",
            type=int,
            help="Max amount of servers allowed with the license",
            default=50)
        self.parser.add_argument(
            "-u",
            "--Users",
            type=int,
            help="Max amount of users allowed with the license",
            default=50)
        self.parser.add_argument(
            "-mc",
            "--ManagedClients",
            type=int,
            help="Max amount of managed clients allowed with the license",
            default=50)
        self.parser.add_argument(
            "-cc",
            "--CorporateClients",
            type=int,
            help="Max amount of corporate clients allowed with the license",
            default=50)
        self.parser.add_argument("-ll",
                                 "--LogLevel",
                                 help="Logging level",
                                 choices=("INFO", "DEBUG", "ERROR",
                                          "CRITICAL"),
                                 default="INFO")
        self.parser.add_argument("--shop",
                                 help="The shop",
                                 default=self.license_shop)
        self.parser.add_argument("--username",
                                 help="username",
                                 default=self.server_username)
        self.parser.add_argument("--secret-file",
                                 help="password file",
                                 default=self.secret_file)

        opts = self.parser.parse_args()
        args = vars(opts)  # converting Namespace to a dictionary
        self.log.debug("Parsed arguments are: '%s'", args)
        self.update_with_parsed_args(args)

    def main(self, base_dn="", end_date="", server_url="", license_file=""):
        # type: (str, str, str, str) -> None
        """
		A method to order and download a test license from the license server.
		'base_dn' and 'end_date' should be provided if argument parser is
		not used.
		'server_url' is an optional argument for the license shop server.
		'license_file' is an optional argument for the license filename.
		"""
        self.log.debug(
            "In 'main' method: server_url='%s', license_file='%s', base_dn='%s', end_date='%s'",
            server_url, license_file, base_dn, end_date)
        if self.parser:
            self.process_cmd_arguments()
        elif base_dn and end_date:
            self.license_params['BaseDN'] = base_dn
            self.license_params['EndDate'] = end_date
        else:
            self.log.error(
                "The 'BaseDN' or/and 'EndDate' were not provided for the license to create"
            )
            exit(1)

        self.check_date_format()

        if server_url:
            self.license_server_url = server_url
        if license_file:
            self.license_filename = license_file
        self.get_server_password(self.secret_file)
        try:
            self.create_connection()
            self.get_cookie()
            self.get_the_license(self.order_a_license())
        finally:
            self.close_connection()
예제 #7
0
class HessianProxy(object):

    def __init__(self, service_uri, credentials=None, key_file=None,
            cert_file=None, timeout=10, buffer_size=65535,
            error_factory=lambda x: x, overload=False, version=1):
        self.version = version

        self._headers = list()
        self._headers.append(('User-Agent', 'python-hessian/' + __version__,))
        self._headers.append(('Content-Type', 'application/x-hessian',))

        if sys.version_info < (2, 6):
            warn('HessianProxy timeout not enforceable before Python 2.6', RuntimeWarning, stacklevel=2)
            kwargs = {}
        else:
            kwargs = {'timeout': timeout}

        if six.PY2:
            kwargs['strict'] = True

        self._uri = urlparse(service_uri)
        if self._uri.scheme == 'http':
            self._client = HTTPConnection(self._uri.hostname,
                                          self._uri.port or 80,
                                          **kwargs)
        elif self._uri.scheme == 'https':
            self._client = HTTPSConnection(self._uri.hostname,
                                           self._uri.port or 443,
                                           key_file=key_file,
                                           cert_file=cert_file,
                                           **kwargs)
        else:
            raise NotImplementedError("HessianProxy only supports http:// and https:// URIs")

        # autofill credentials if they were passed via url instead of kwargs
        if (self._uri.username and self._uri.password) and not credentials:
            credentials = (self._uri.username, self._uri.password)

        if credentials:
            auth = 'Basic ' + base64.b64encode(':'.join(credentials))
            self._headers.append(('Authorization', auth))

        self._buffer_size = buffer_size
        self._error_factory = error_factory
        self._overload = overload
        self._parser = Parser()

    class __RemoteMethod(object):
        # dark magic for autoloading methods
        def __init__(self, caller, method):
            self.__caller = caller
            self.__method = method
        def __call__(self, *args):
            return self.__caller(self.__method, args)

    def __getattr__(self, method):
        return self.__RemoteMethod(self, method)

    def __repr__(self):
        return "<pyhessian.client.HessianProxy(\"%s\")>" % (self._uri.geturl(),)

    def __str__(self):
        return self.__repr__()

    def __call__(self, method, args):
        try:
            self._client.putrequest('POST', self._uri.path)
            for header in self._headers:
                self._client.putheader(*header)

            request = encode_object(Call(method, args, overload=self._overload, version=self.version))
            self._client.putheader("Content-Length", str(len(request)))
            self._client.endheaders()
            self._client.send(six.binary_type(request))

            response = self._client.getresponse()
            if response.status != 200:
                raise ProtocolError(self._uri.geturl(), response.status, response.reason)

            length = response.getheader('Content-Length', -1)
            if length == '0':
                raise ProtocolError(self._uri.geturl(), 'FATAL:', 'Server sent zero-length response')

            reply = self._parser.parse_stream(BufferedReader(response, buffer_size=self._buffer_size))
            self._client.close()

            if isinstance(reply.value, Fault):
                raise self._error_factory(reply.value)
            else:
                return reply.value
        except:
            self._client.close()
            raise
예제 #8
0
    counter[0] += 1


if __name__ == '__main__':
    url = '/prust/wikipedia-movie-data/master/movies.json'
    endpoint = HTTPSConnection('raw.githubusercontent.com',
                               '443',
                               context=ssl._create_unverified_context())
    try:
        ts1 = datetime.datetime.now().timestamp()
        print('start time=' + str(ts1))
        endpoint.request('GET', url)
        response = endpoint.getresponse()

        tokenizer = JsonTokenizer(response, 'ISO-8859-1', 65536)

        JsonDecoder()\
            .tokenizer(tokenizer)\
            .root_class_name('Data')\
            .event_handler(lambda e, p: handle_event(e, p, counter))\
            .predicate('genres') \
            .with_snake_cased_props()\
            .decode()

        ts2 = datetime.datetime.now().timestamp()
        print('end time=' + str(ts2))
        print('delta=' + str(ts2 - ts1))
    finally:
        endpoint.close()
    print('total events count=' + str(counter[0]))