Esempio n. 1
0
    def setUp(self):
        """ Generate a Response object and set our tested server result string
        """

        self.response = ResponseXml()
        self.response.set_response(self.tested_server_result)

        self.response_multi = ResponseXml()
        self.response_multi.set_response(self.tested_server_result_multi_value)
Esempio n. 2
0
    def request(self, request_name, params=None, context=None, urn=None, opts={}):
        """ Send a single request to Zimbra; return the response as native python data. """
        if 'xml' in opts and opts['xml']:
            request, response = RequestXml(), ResponseXml()
        else:
            request, response = RequestJson(), ResponseJson()

        try:
            if urn == None:
                urn = urn_for_request(request_name)
            request.add_request(request_name, params or {}, "urn:"+urn)
            if context:
                request.set_context_params(context)
            request.set_auth_token(self.token)
        except:
            log.exception("failed to build request: request_name=%s, params=%s, context=%s",
                          request_name, params, context)
            return None
        if opts['debug']:
            if isinstance(request, RequestXml):
                print xml.dom.minidom.parseString(request.get_request()).toprettyxml(indent=".   ")
            else:
                pprint.pprint(yaml.load(request.get_request()))

        try:
            self.comm.send_request(request, response)
        except urllib2.HTTPError as e:
            requestbody = request.get_request()
            responsebody = e.read()
            log.error('''send_request HTTP Error %s: %s; request="%s" response="%s"''',
                          e.code, e.reason, requestbody, responsebody)
            if isinstance(request, RequestXml):
                requestdoc = xml.dom.minidom.parseString(requestbody)
                print "REQUEST=", requestdoc.toprettyxml(indent=".   ")
            else:
                print "REQUEST=\n", pprint.pformat(yaml.load(requestbody))
            if isinstance(response, ResponseXml):
                responsedoc = xml.dom.minidom.parseString(responsebody)
                print "RESPONSE=", responsedoc.toprettyxml(indent=".   ")
            else:
                print "RESPONSE=\n", pprint.pformat(yaml.load(responsebody))
            return None
        except Exception as e:
            log.exception("send_request failed (%s): request=%s", type(e), request.get_request())
            return None
        if response.is_fault():
            log.error("send_request returned fault: request=%s, response=%s",
                      request.get_request(), response.get_response())
            return None
        info = response.get_response()
        return info
Esempio n. 3
0
    def test_fault_non_existing_folder_batch_xml(self):

        """ Request a non existing folder multiple times to get multiple
        faults
        """

        config = get_config()

        if config.getboolean('fault_test', 'enabled'):

            comm = Communication(config.get('fault_test', 'url'))

            token = auth.authenticate(config.get('fault_test', 'url'),
                                      config.get('fault_test', 'account'),
                                      config.get('fault_test', 'preauthkey'),
                                      config.get('fault_test', 'account_by'))

            request = RequestXml()

            request.set_auth_token(token)

            request.enable_batch()

            request.add_request(
                "GetFolderRequest",
                {
                    "folder": {
                        "path": config.get('fault_test', 'folder')
                    }
                },
                "urn:zimbraMail"
            )

            request.add_request(
                "GetFolderRequest",
                {
                    "folder": {
                        "path": config.get('fault_test', 'folder')
                    }
                },
                "urn:zimbraMail"
            )

            response = ResponseXml()

            comm.send_request(request, response)

            self.check_response(
                response
            )
Esempio n. 4
0
def authenticate(url,
                 account,
                 key,
                 by='name',
                 expires=0,
                 timestamp=None,
                 timeout=None,
                 request_type="xml",
                 admin_auth=False,
                 use_password=False,
                 raise_on_error=False):
    """ Authenticate to the Zimbra server

    :param url: URL of Zimbra SOAP service
    :param account: The account to be authenticated against
    :param key: The preauth key of the domain of the account or a password (if
      admin_auth or use_password is True)
    :param by: If the account is specified as a name, an ID or a
      ForeignPrincipal
    :param expires: When the token expires (or 0 for default expiration)
    :param timestamp: When the token was requested (None for "now")
    :param timeout: Timeout for the communication with the server. Defaults
      to the urllib2-default
    :param request_type: Which type of request to use ("xml" (default) or
      "json")
    :param admin_auth: This request should authenticate and generate an admin
      token. The "key"-parameter therefore holds the admin password (implies
      use_password)
    :param use_password: The "key"-parameter holds a password. Do a password-
      based user authentication.
    :param raise_on_error: Should I raise an exception when an authentication
      error occurs or just return None?
    :return: The authentication token or None
    :rtype: str or None or unicode
    """

    if timestamp is None:
        timestamp = int(time.time()) * 1000

    pak = ""
    if not admin_auth:
        pak = preauth.create_preauth(account, key, by, expires, timestamp)

    if request_type == 'xml':

        auth_request = RequestXml()

    else:

        auth_request = RequestJson()

    request_data = {'account': {'by': by, '_content': account}}

    ns = "urn:zimbraAccount"

    if admin_auth:

        ns = "urn:zimbraAdmin"

        request_data['password'] = key

    elif use_password:

        request_data['password'] = {"_content": key}

    else:

        request_data['preauth'] = {
            'timestamp': timestamp,
            'expires': expires,
            '_content': pak
        }

    auth_request.add_request('AuthRequest', request_data, ns)

    server = Communication(url, timeout)

    if request_type == 'xml':

        response = ResponseXml()

    else:

        response = ResponseJson()

    server.send_request(auth_request, response)

    if response.is_fault():

        if raise_on_error:

            raise AuthenticationFailed(
                "Cannot authenticate user: (%s) %s" %
                (response.get_fault_code(), response.get_fault_message()))

        return None

    return response.get_response()['AuthResponse']['authToken']['_content']
Esempio n. 5
0
    def send_request(self, request, response=None):
        """ Send the request.

        Sends the request and retrieves the results, formats them and returns
         them in a dict or a list (when it's a batchresponse). If something
         goes wrong, raises a SoapFailure or a HTTPError on system-side
         failures. Note: AuthRequest raises an HTTPError on failed
         authentications!

        :param request: The request to send
        :type request: pythonzimbra.request.Request
        :param response: A prebuilt response object
        :type response: pythonzimbra.response.Response
        :raises: pythonzimbra.exceptions.communication.SoapFailure or
                urllib2.HTTPError
        """

        local_response = None

        if response is None:

            if request.request_type == "json":

                local_response = ResponseJson()

            elif request.request_type == "xml":

                local_response = ResponseXml()

            else:

                raise UnknownRequestType()

        try:

            server_request = ur.urlopen(self.url,
                                        request.get_request().encode("utf-8"),
                                        self.timeout)

            server_response = server_request.read()

            if isinstance(server_response, bytes):

                server_response = server_response.decode("utf-8")

            if response is None:

                local_response.set_response(server_response)

            else:

                response.set_response(server_response)

        except ue.HTTPError as e:

            if e.code == 500:

                # 500 codes normally returns a SoapFault, that we can use

                server_response = e.fp.read()

                if isinstance(server_response, bytes):

                    server_response = server_response.decode("utf-8")

                if response is None:

                    local_response.set_response(server_response)

                else:

                    response.set_response(server_response)

            else:

                raise e

        if response is None:
            return local_response
Esempio n. 6
0
    def run_admin_test(self, request_type):
        """ Actually do the work
        """

        config = get_config()

        if config.getboolean("admin_request_test", "enabled"):

            # Run only if enabled

            token = authenticate(config.get("admin_request_test", "admin_url"),
                                 config.get("admin_request_test",
                                            "admin_account"),
                                 config.get("admin_request_test",
                                            "admin_password"),
                                 config.get("admin_request_test",
                                            "admin_account_by"),
                                 admin_auth=True,
                                 request_type=request_type)

            if token is None:

                self.fail("Authentication with the configured settings "
                          "was not successful")

            # Create an account

            comm = Communication(config.get("admin_request_test", "admin_url"))

            if request_type == "xml":

                request = RequestXml()

            else:

                request = RequestJson()

            request.set_auth_token(token)

            request.add_request(
                "CreateAccountRequest", {
                    "name": config.get("admin_request_test", "test_account"),
                    "password": config.get("admin_request_test",
                                           "test_password")
                }, "urn:zimbraAdmin")

            if request_type == "xml":

                response = ResponseXml()

            else:

                response = ResponseJson()

            comm.send_request(request, response)

            if response.is_fault():

                self.fail(
                    "CreateAccount faulted. (%s) %s" %
                    (response.get_fault_code(), response.get_fault_message()))

            account_id = response.get_response(
            )["CreateAccountResponse"]["account"]["id"]

            # Try to log in as the new account

            user_token = authenticate(config.get("admin_request_test", "url"),
                                      config.get("admin_request_test",
                                                 "test_account"),
                                      config.get("admin_request_test",
                                                 "test_password"),
                                      "name",
                                      request_type=request_type,
                                      use_password=True)

            if user_token is None:

                self.fail("Cannot log in as the test user.")

            # Remove account

            request.clean()
            response.clean()
            request.set_auth_token(token)

            request.add_request("DeleteAccountRequest", {"id": account_id},
                                "urn:zimbraAdmin")

            comm.send_request(request, response)

            if response.is_fault():

                self.fail(
                    "Cannot remove test account: (%s) %s" %
                    (response.get_fault_code(), response.get_fault_message()))