def setUp(self): """ Generate a Response object and set our tested server result string """ self.response = ResponseJson() self.response.set_response(self.tested_server_result)
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
def test_fault_non_existing_folder_batch_json(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 = RequestJson() 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 = ResponseJson() comm.send_request(request, response) self.check_response( response )
class TestResponseJson(TestCase): """ Response class tests """ tested_server_result = '{ "Header": { "context": { "_jsns": "urn:zimbra" ' \ '} }, "Body": { "GetVersionInfoResponse": { ' \ '"info": [{ "type": "NETWORK", "version": "8.0' \ '.5_GA_5839.NETWORK", "release": "20130910124124",' \ ' "buildDate": "20130910-1244", ' \ '"host": "zre-ubuntu12-64", "platform": ' \ '"UBUNTU12_64", "majorversion": "8", ' \ '"minorversion": "0", "microversion": "5" }], ' \ '"_jsns": "urn:zimbraAdmin" } }, ' \ '"_jsns": "urn:zimbraSoap" }' """ The result we test against (coming from a GetVersionInfoRequest) """ response = None """ Our response object """ def setUp(self): """ Generate a Response object and set our tested server result string """ self.response = ResponseJson() self.response.set_response(self.tested_server_result) def test_get_body(self): """ Checks the body against a pickled expectation """ expected_result = '(dp0\nVGetVersionInfoResponse\np1\n(' \ 'dp2\nVinfo\np3\n(lp4\n(' \ 'dp5\nVmajorversion\np6\nV8\np7\nsVbuildDate\np8' \ '\nV20130910-1244\np9\nsVmicroversion\np10\nV5\np11' \ '\nsVplatform\np12\nVUBUNTU12_64\np13\nsVhost\np14' \ '\nVzre-ubuntu12-64\np15\nsVversion\np16\nV8.0' \ '.5_GA_5839' \ '.NETWORK\np17\nsVrelease\np18\nV20130910124124' \ '\np19\nsVtype\np20\nVNETWORK\np21\nsVminorversion' \ '\np22\nV0\np23\nsasV_jsns\np24\nVurn:zimbraAdmin' \ '\np25\nss.' self.assertEqual(expected_result, pickle.dumps(self.response.get_body())) def test_get_header(self): expected_result = '(dp0\nVcontext\np1\n(' \ 'dp2\nV_jsns\np3\nVurn:zimbra\np4\nss.' self.assertEqual(expected_result, pickle.dumps(self.response.get_header())) def test_is_batch(self): self.assertFalse( self.response.is_batch(), "Is_Batch hasn't returned False, rather than %s" % (str(self.response.is_batch()))) def test_get_batch(self): self.assertIsNone(self.response.get_batch(), "get_batch hasn't returned None") def test_get_response(self): expected_result = '(dp0\nVGetVersionInfoResponse\np1\n(' \ 'dp2\nVinfo\np3\n(' \ 'dp4\nVmajorversion\np5\nV8\np6\nsVbuildDate\np7' \ '\nV20130910-1244\np8\nsVmicroversion\np9\nV5\np10' \ '\nsVplatform\np11\nVUBUNTU12_64\np12\nsVhost\np13' \ '\nVzre-ubuntu12-64\np14\nsVversion\np15\nV8.0' \ '.5_GA_5839' \ '.NETWORK\np16\nsVrelease\np17\nV20130910124124' \ '\np18\nsVtype\np19\nVNETWORK\np20\nsVminorversion' \ '\np21\nV0\np22\nsss.' self.assertEqual(expected_result, pickle.dumps(self.response.get_response()))
class TestResponseJson(TestCase): """ Response class tests """ tested_server_result = '{ "Header": { "context": { "_jsns": "urn:zimbra" ' \ '} }, "Body": { "GetVersionInfoResponse": { ' \ '"info": { "type": "NETWORK", "version": "8.0' \ '.5_GA_5839.NETWORK", "release": "20130910124124",' \ ' "buildDate": "20130910-1244", ' \ '"host": "zre-ubuntu12-64", "platform": ' \ '"UBUNTU12_64", "majorversion": "8", ' \ '"minorversion": "0", "microversion": "5" }, ' \ '"_jsns": "urn:zimbraAdmin" } }, ' \ '"_jsns": "urn:zimbraSoap" }' """ The result we test against (coming from a GetVersionInfoRequest) """ response = None """ Our response object """ def setUp(self): """ Generate a Response object and set our tested server result string """ self.response = ResponseJson() self.response.set_response(self.tested_server_result) def test_get_body(self): """ Checks the body against a pickled expectation """ expected_result = { "GetVersionInfoResponse": { "info": { "majorversion": "8", "buildDate": "20130910-1244", "microversion": "5", "platform": "UBUNTU12_64", "host": "zre-ubuntu12-64", "version": "8.0.5_GA_5839.NETWORK", "release": "20130910124124", "type": "NETWORK", "minorversion": "0" } } } self.assertEqual(expected_result, self.response.get_body()) def test_get_header(self): expected_result = {"context": {}} self.assertEqual(expected_result, self.response.get_header()) def test_is_batch(self): self.assertFalse( self.response.is_batch(), "Is_Batch hasn't returned False, rather than %s" % (str(self.response.is_batch()))) def test_get_batch(self): self.assertIsNone(self.response.get_batch(), "get_batch hasn't returned None") def test_get_response(self): expected_result = { "GetVersionInfoResponse": { "info": { "majorversion": "8", "buildDate": "20130910-1244", "microversion": "5", "platform": "UBUNTU12_64", "host": "zre-ubuntu12-64", "version": "8.0.5_GA_5839.NETWORK", "release": "20130910124124", "type": "NETWORK", "minorversion": "0" } } } self.assertEqual(expected_result, self.response.get_response())
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
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']
class TestResponseJson(TestCase): """ Response class tests """ tested_server_result = '{ "Header": { "context": { "_jsns": "urn:zimbra" ' \ '} }, "Body": { "GetVersionInfoResponse": { ' \ '"info": [{ "type": "NETWORK", "version": "8.0' \ '.5_GA_5839.NETWORK", "release": "20130910124124",' \ ' "buildDate": "20130910-1244", ' \ '"host": "zre-ubuntu12-64", "platform": ' \ '"UBUNTU12_64", "majorversion": "8", ' \ '"minorversion": "0", "microversion": "5" }], ' \ '"_jsns": "urn:zimbraAdmin" } }, ' \ '"_jsns": "urn:zimbraSoap" }' """ The result we test against (coming from a GetVersionInfoRequest) """ response = None """ Our response object """ def setUp(self): """ Generate a Response object and set our tested server result string """ self.response = ResponseJson() self.response.set_response(self.tested_server_result) def test_get_body(self): """ Checks the body against a pickled expectation """ expected_result = '(dp0\nVGetVersionInfoResponse\np1\n(' \ 'dp2\nVinfo\np3\n(lp4\n(' \ 'dp5\nVmajorversion\np6\nV8\np7\nsVbuildDate\np8' \ '\nV20130910-1244\np9\nsVmicroversion\np10\nV5\np11' \ '\nsVplatform\np12\nVUBUNTU12_64\np13\nsVhost\np14' \ '\nVzre-ubuntu12-64\np15\nsVversion\np16\nV8.0' \ '.5_GA_5839' \ '.NETWORK\np17\nsVrelease\np18\nV20130910124124' \ '\np19\nsVtype\np20\nVNETWORK\np21\nsVminorversion' \ '\np22\nV0\np23\nsasV_jsns\np24\nVurn:zimbraAdmin' \ '\np25\nss.' self.assertEqual( expected_result, pickle.dumps(self.response.get_body()) ) def test_get_header(self): expected_result = '(dp0\nVcontext\np1\n(' \ 'dp2\nV_jsns\np3\nVurn:zimbra\np4\nss.' self.assertEqual( expected_result, pickle.dumps(self.response.get_header()) ) def test_is_batch(self): self.assertFalse( self.response.is_batch(), "Is_Batch hasn't returned False, rather than %s" % ( str(self.response.is_batch()) ) ) def test_get_batch(self): self.assertIsNone( self.response.get_batch(), "get_batch hasn't returned None" ) def test_get_response(self): expected_result = '(dp0\nVGetVersionInfoResponse\np1\n(' \ 'dp2\nVinfo\np3\n(' \ 'dp4\nVmajorversion\np5\nV8\np6\nsVbuildDate\np7' \ '\nV20130910-1244\np8\nsVmicroversion\np9\nV5\np10' \ '\nsVplatform\np11\nVUBUNTU12_64\np12\nsVhost\np13' \ '\nVzre-ubuntu12-64\np14\nsVversion\np15\nV8.0' \ '.5_GA_5839' \ '.NETWORK\np16\nsVrelease\np17\nV20130910124124' \ '\np18\nsVtype\np19\nVNETWORK\np20\nsVminorversion' \ '\np21\nV0\np22\nsss.' self.assertEqual( expected_result, pickle.dumps(self.response.get_response()) )
class TestResponseJson(TestCase): """ Response class tests """ tested_server_result = '{ "Header": { "context": { "_jsns": "urn:zimbra" ' \ '} }, "Body": { "GetVersionInfoResponse": { ' \ '"info": { "type": "NETWORK", "version": "8.0' \ '.5_GA_5839.NETWORK", "release": "20130910124124",' \ ' "buildDate": "20130910-1244", ' \ '"host": "zre-ubuntu12-64", "platform": ' \ '"UBUNTU12_64", "majorversion": "8", ' \ '"minorversion": "0", "microversion": "5" }, ' \ '"_jsns": "urn:zimbraAdmin" } }, ' \ '"_jsns": "urn:zimbraSoap" }' """ The result we test against (coming from a GetVersionInfoRequest) """ response = None """ Our response object """ def setUp(self): """ Generate a Response object and set our tested server result string """ self.response = ResponseJson() self.response.set_response(self.tested_server_result) def test_get_body(self): """ Checks the body against a pickled expectation """ expected_result = { "GetVersionInfoResponse": { "info": { "majorversion": "8", "buildDate": "20130910-1244", "microversion": "5", "platform": "UBUNTU12_64", "host": "zre-ubuntu12-64", "version": "8.0.5_GA_5839.NETWORK", "release": "20130910124124", "type": "NETWORK", "minorversion": "0" } } } self.assertEqual( expected_result, self.response.get_body() ) def test_get_header(self): expected_result = { "context": { } } self.assertEqual( expected_result, self.response.get_header() ) def test_is_batch(self): self.assertFalse( self.response.is_batch(), "Is_Batch hasn't returned False, rather than %s" % ( str(self.response.is_batch()) ) ) def test_get_batch(self): self.assertIsNone( self.response.get_batch(), "get_batch hasn't returned None" ) def test_get_response(self): expected_result = { "GetVersionInfoResponse": { "info": { "majorversion": "8", "buildDate": "20130910-1244", "microversion": "5", "platform": "UBUNTU12_64", "host": "zre-ubuntu12-64", "version": "8.0.5_GA_5839.NETWORK", "release": "20130910124124", "type": "NETWORK", "minorversion": "0" } } } self.assertEqual( expected_result, self.response.get_response() )
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()))