def test_get_associated_private_mainline(self, settings, AsyncHTTPClient): self.standard_setup(settings, AsyncHTTPClient) callback = Mock() homestead.get_associated_privates(PUBLIC_URI, callback) self.mock_httpclient.fetch.assert_called_once_with( 'http://homestead/associatedprivate/sip%3Apub%40foo.bar', callback, method='GET')
def display_user(public_id, short=False, quiet=False): success = True callback = Callback() if not short: conditional_print(not quiet, "Public User ID %s:" % (public_id)) homestead.get_associated_privates(public_id, callback) response = callback.wait()[0] public_id_missing = (response.code == 404) if response.code == 200: private_ids = json.loads(response.body) for private_id in private_ids['private_ids']: homestead.get_digest(private_id, callback) response = callback.wait()[0] if response.code == 200: av = json.loads(response.body) if 'digest_ha1' in av: password = av['digest_ha1'] if 'plaintext_password' in av: password += " (%s)" % (av['plaintext_password'],) if short: conditional_print(not quiet, "%s/%s: %s" % (public_id, private_id, password)) else: conditional_print(not quiet, " Private User ID %s:" % (private_id,)) conditional_print(not quiet, " HA1 digest: %s" % (password,)) else: _log.error("Failed to retrieve digest for private ID %s - HTTP status code %d", private_id, response.code) success = False else: _log.error("Failed to retrieve private IDs for public ID %s - HTTP status code %d", public_id, response.code) success = False # Default to True so that if we don't check, we may still report that no # information was found. filter_criteria_missing = True if not short: homestead.get_filter_criteria(public_id, callback) response = callback.wait()[0] filter_criteria_missing = (response.code == 404) if response.code == 200: ifc = xml.dom.minidom.parseString(response.body) ifc_str = ifc.toprettyxml(indent=" ") ifc_str = "\n".join(filter(lambda l: l.strip() != "", ifc_str.split("\n"))) ifc_str = " " + ifc_str.replace("\n", "\n ") conditional_print(not quiet, " iFC:") conditional_print(not quiet, ifc_str) else: _log.error("Failed to retrieve iFC for public ID %s - HTTP status code %d", public_id, response.code) success = False if filter_criteria_missing and public_id_missing: _log.error("Failed to find any information for public ID %s.", public_id) return success
def display_user(public_id, short=False, quiet=False): success = True callback = Callback() if not short: conditional_print(not quiet, "Public User ID %s:" % (public_id)) homestead.get_associated_privates(public_id, callback) response = callback.wait()[0] public_id_missing = (response.code == 404) if response.code == 200: private_ids = json.loads(response.body) for private_id in private_ids['private_ids']: homestead.get_digest(private_id, callback) response = callback.wait()[0] if response.code == 200: av = json.loads(response.body) if 'digest_ha1' in av: password = av['digest_ha1'] if 'plaintext_password' in av: password += " (%s)" % (av['plaintext_password'],) if short: conditional_print(not quiet, "%s/%s: %s" % (public_id, private_id, password)) else: conditional_print(not quiet, " Private User ID %s:" % (private_id,)) conditional_print(not quiet, " HA1 digest: %s" % (password,)) else: _log.error("Failed to retrieve digest for private ID %s - HTTP status code %d", private_id, response.code) success = False else: _log.error("Failed to retrieve private IDs for public ID %s - HTTP status code %d", public_id, response.code) success = False # Default to True so that if we don't check, we may still report that no # information was found. filter_criteria_missing = True if not short: homestead.get_filter_criteria(public_id, callback) response = callback.wait()[0] filter_criteria_missing = (response.code == 404) if response.code == 200: ifc = defusedxml.minidom.parseString(response.body) ifc_str = ifc.toprettyxml(indent=" ") ifc_str = "\n".join(filter(lambda l: l.strip() != "", ifc_str.split("\n"))) ifc_str = " " + ifc_str.replace("\n", "\n ") conditional_print(not quiet, " iFC:") conditional_print(not quiet, ifc_str) else: _log.error("Failed to retrieve iFC for public ID %s - HTTP status code %d", public_id, response.code) success = False if filter_criteria_missing and public_id_missing: _log.error("Failed to find any information for public ID %s.", public_id) return success
def post(self, username, sip_uri): """Resets the password for the given SIP URI.""" user_id = self.get_and_check_user_id(username) self.check_number_ownership(sip_uri, user_id) self.sip_password = utils.generate_sip_password() # Fetch private ID from Homestead for this public ID self._request_group = HTTPCallbackGroup(self.on_get_privates_success, self.on_get_privates_failure) homestead.get_associated_privates(sip_uri, self._request_group.callback())
def test_get_associated_private_mainline(self, settings, AsyncHTTPClient): self.standard_setup(settings, AsyncHTTPClient) callback = Mock() homestead.get_associated_privates(PUBLIC_URI, callback) self.mock_httpclient.fetch.assert_called_once_with( 'http://homestead/public/sip%3Apub%40foo.bar/associated_private_ids', callback, method='GET', follow_redirects=False, allow_ipv6=True)
def test_get_associated_private_mainline(self, settings, AsyncHTTPClient): self.standard_setup(settings, AsyncHTTPClient) callback = Mock() homestead.get_associated_privates(PUBLIC_URI, callback) self.mock_httpclient.fetch.assert_called_once_with( 'http://homestead/public/sip%3Apub%40foo.bar/associated_private_ids', ANY, method='GET', follow_redirects=False, allow_ipv6=True)
def remove_public_id(db_sess, sip_uri, on_success, on_failure, force_delete): """ Looks up the private id related to the sip_uri, and then the public ids related the retrieved private id. If there are multiple public ids, then only the sip_uri is is removed from Homestead, and the association to its private id is destroyed. If this is the only public id associated with the private id, then both the private and public ids are removed from Homestead along with their associations """ def _on_get_privates_success(responses): _log.debug("Got related private ids") # Body is of format {"private_ids": ["<private_id_1>", "<private_id_2>"...]} parsed_body = json.loads(responses[0].body) # We only support one private id per public id, so only pull out first in list private_id = parsed_body["private_ids"][0] request_group2 = HTTPCallbackGroup( partial(_on_get_publics_success, private_id), on_failure) homestead.get_associated_publics(private_id, request_group2.callback()) def _on_get_publics_success(private_id, responses): _log.debug("Got related public ids") parsed_body = json.loads(responses[0].body) public_ids = parsed_body["associated_public_ids"] if (utils.sip_public_id_to_private(sip_uri) == private_id and len(public_ids) > 1): # Do not permit deletion of an original public identity if others exist # otherwise another may claim the same private id from the pool _log.error( "Failed to delete default public ID %s while other IDs are attached to the same private ID" % sip_uri) _log.error("Other public IDs are %s" % ", ".join(public_ids)) on_failure(responses[0]) else: # Only delete the digest if there is only a single private identity # associated with our sip_uri (i.e. this is the last public id) delete_digest = (len(public_ids) == 1) _delete_number(db_sess, sip_uri, private_id, delete_digest, on_success, on_failure, force_delete) def _on_get_privates_failure(response): if (response.code == 404) or force_delete: # The number has no records in Homestead _log.debug("Failed to retrieve private IDs for a public ID") _log.debug("Returning %s to the pool" % sip_uri) numbers.remove_owner(db_sess, sip_uri) db_sess.commit() on_success({}) else: # pragma: no cover _log.warn("Non-404 response - not returning number to pool") on_failure(response) request_group = HTTPCallbackGroup(_on_get_privates_success, _on_get_privates_failure) homestead.get_associated_privates(sip_uri, request_group.callback())
def post(self, username, sip_uri): """Resets the password for the given SIP URI.""" user_id = self.get_and_check_user_id(username) self.check_number_ownership(sip_uri, user_id) self.sip_digest_realm = utils.sip_uri_to_domain(sip_uri) self.sip_password = utils.generate_sip_password() # Fetch private ID from Homestead for this public ID self._request_group = HTTPCallbackGroup(self.on_get_privates_success, self.on_get_privates_failure) homestead.get_associated_privates(sip_uri, self._request_group.callback())
def validate_line(sip_uri): """ Validate details about line in homestead """ print "Validating %s " % sip_uri # Verify the private id exists for this line exists in homestead, delete the line otherwise global pending_requests pending_requests += 1 delete_line = number_deleter(None, sip_uri) homestead.get_associated_privates(sip_uri, create_get_handler(sip_uri, on_found=ensure_digest_exists, on_not_found=delete_line))
def remove_public_id(db_sess, sip_uri, on_success, on_failure, force_delete): """ Looks up the private id related to the sip_uri, and then the public ids related the retrieved private id. If there are multiple public ids, then only the sip_uri is is removed from Homestead, and the association to its private id is destroyed. If this is the only public id associated with the private id, then both the private and public ids are removed from Homestead along with their associations """ def _on_get_privates_success(responses): _log.debug("Got related private ids") # Body is of format {"private_ids": ["<private_id_1>", "<private_id_2>"...]} parsed_body = json.loads(responses[0].body) # We only support one private id per public id, so only pull out first in list private_id = parsed_body["private_ids"][0] request_group2 = HTTPCallbackGroup(partial(_on_get_publics_success, private_id), on_failure) homestead.get_associated_publics(private_id, request_group2.callback()) def _on_get_publics_success(private_id, responses): _log.debug("Got related public ids") parsed_body = json.loads(responses[0].body) public_ids = parsed_body["associated_public_ids"] if utils.sip_public_id_to_private(sip_uri) == private_id and len(public_ids) > 1: # Do not permit deletion of an original public identity if others exist # otherwise another may claim the same private id from the pool _log.error( "Failed to delete default public ID %s while other IDs are attached to the same private ID" % sip_uri ) _log.error("Other public IDs are %s" % ", ".join(public_ids)) on_failure(responses[0]) else: # Only delete the digest if there is only a single private identity # associated with our sip_uri (i.e. this is the last public id) delete_digest = len(public_ids) == 1 _delete_number(db_sess, sip_uri, private_id, delete_digest, on_success, on_failure, force_delete) def _on_get_privates_failure(response): if (response.code == 404) or force_delete: # The number has no records in Homestead _log.debug("Failed to retrieve private IDs for a public ID") _log.debug("Returning %s to the pool" % sip_uri) numbers.remove_owner(db_sess, sip_uri) db_sess.commit() on_success({}) else: _log.warn("Non-404 response - not returning number to pool") on_failure(response) request_group = HTTPCallbackGroup(_on_get_privates_success, _on_get_privates_failure) homestead.get_associated_privates(sip_uri, request_group.callback())
def validate_line(sip_uri): """ Validate details about line in homestead """ print "Validating %s " % sip_uri # Verify the private id exists for this line exists in homestead, delete the line otherwise global pending_requests pending_requests += 1 delete_line = number_deleter(None, sip_uri) homestead.get_associated_privates( sip_uri, create_get_handler(sip_uri, on_found=ensure_digest_exists, on_not_found=delete_line))
def invalidate_line(sip_uri): """ Try to get private id and then delete all details from Homestead """ print "Invalidating %s " % sip_uri # Verify the private id exists for this line exists in homestead, delete the line otherwise global pending_requests pending_requests += 1 delete_line = number_deleter(None, sip_uri) def extract_private_and_delete(sip_uri, **kwargs): private_id = kwargs["private_ids"][0] delete_line_with_private = number_deleter(private_id, sip_uri) delete_line_with_private() homestead.get_associated_privates(sip_uri, create_get_handler(sip_uri, on_found=extract_private_and_delete, on_not_found=delete_line))
def get(self, username): """Retrieve list of phone numbers.""" user_id = self.get_and_check_user_id(username) self._numbers = numbers.get_numbers(self.db_session(), user_id) if len(self._numbers) == 0: self.finish({"numbers": []}) return for number in self._numbers: number["number_id"] = number["number_id"].hex number["sip_uri"] = number["number"] number["sip_username"] = utils.sip_uri_to_phone_number(number["number"]) number["domain"] = utils.sip_uri_to_domain(number["number"]) number["number"] = utils.sip_uri_to_phone_number(number["number"]) number["formatted_number"] = format_phone_number(number["number"]) _request_group = HTTPCallbackGroup(partial(self._on_get_success, number["sip_uri"]), self._on_get_failure) # We only store the public identities in Ellis, and must query # Homestead for the associated private identities homestead.get_associated_privates(number["sip_uri"], _request_group.callback())
def invalidate_line(sip_uri): """ Try to get private id and then delete all details from Homestead """ print "Invalidating %s " % sip_uri # Verify the private id exists for this line exists in homestead, delete the line otherwise global pending_requests pending_requests += 1 delete_line = number_deleter(None, sip_uri) def extract_private_and_delete(sip_uri, **kwargs): private_id = kwargs["private_ids"][0] delete_line_with_private = number_deleter(private_id, sip_uri) delete_line_with_private() homestead.get_associated_privates( sip_uri, create_get_handler(sip_uri, on_found=extract_private_and_delete, on_not_found=delete_line))
def get(self, username): """Retrieve list of phone numbers.""" user_id = self.get_and_check_user_id(username) self._numbers = numbers.get_numbers(self.db_session(), user_id) if len(self._numbers) == 0: self.finish({"numbers": []}) return for number in self._numbers: number["number_id"] = number["number_id"].hex number["sip_uri"] = number["number"] number["sip_username"] = utils.sip_uri_to_phone_number( number["number"]) number["domain"] = utils.sip_uri_to_domain(number["number"]) number["number"] = utils.sip_uri_to_phone_number(number["number"]) number["formatted_number"] = format_phone_number(number["number"]) _request_group = HTTPCallbackGroup( partial(self._on_get_success, number["sip_uri"]), partial(self._on_get_failure, number["sip_uri"])) # We only store the public identities in Ellis, and must query # Homestead for the associated private identities homestead.get_associated_privates(number["sip_uri"], _request_group.callback())