def test_device_token_expired(self): settings = Settings(TestBase.US_app_id) settings.set_device_token({"accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOiIyMDE1LTExLTExVDAzOjM0OjU4LjE2Mjg2NzlaIiwibCI6ImJiYmJ2LnJwZGJ2eGJnR3JNZyIsImEiOiJiYmJiYmMueGdqYnZQZHdrbGx3IiwidSI6bnVsbCwiZCI6ImJsai5sRHBGd0tNc2dGRk0ifQ.l4ob5liSYfgI25mnysjRHpgCYr1yCzayC4XjHJOv4v0", "accessTokenExpires": self.past_javascript_access_token_expires()}) client = buddy.init(TestBase.US_app_id, TestBase.US_app_key, "test_device_token_expired") buddy.post("/metrics/events/key", {}) self.assertIsNotNone(client.get_access_token_string())
def test_bad_device_token(self): settings = Settings(TestBase.US_app_id) settings.set_device_token({"accessToken": "bad device token", "accessTokenExpires": self.future_javascript_access_token_expires()}) client = buddy.init(TestBase.US_app_id, TestBase.US_app_key, "test_bad_device_token") buddy.post("/metrics/events/key", {}) self.assertIsNotNone(client.get_access_token_string())
def test_Settings_access_token_expired(self): settings = Settings(Test3._app_id) json = {"accessToken": Test3._access_token, "accessTokenExpires": self.past_javascript_access_token_expires(), "serviceRoot": Test3._service_root} settings.set_device_token(json) self.assertEqual(settings.access_token_string, None)
class BuddyClient(object): exception_name = u"exception" _result_name = u"result" _hardware_info_file_name = "/proc/cpuinfo" def __init__(self, app_id, app_key): self._app_id = app_id self._app_key = app_key self._settings = Settings(self._app_id) self._session = requests.Session() self._session.auth = Auth(self, self._settings) self._last_location = None self._service_exception = Events() self._authentication_needed = Events() self._connection_changed = Events() self._connection_retry = Thread(target=self.__connection_retry_method) self._connection_level = Connection.on @property def app_id(self): return self._app_id @property def app_key(self): return self._app_key @property def last_location(self): return self._last_location @last_location.setter def last_location(self, value): self._last_location = value @property def current_user_id(self): return self._settings.user_id @property def service_exception(self): return self._service_exception @property def authentication_needed(self): return self._authentication_needed @property def connection_changed(self): return self._connection_changed def get_access_token_string(self): if self._settings.access_token_string is None: self.__register_device() return self._settings.access_token_string def __register_device(self): response = self.__handle_dictionary_request(requests.post, "/devices", { "appId": self.app_id, "appKey": self.app_key, "platform": BuddyClient.__get_platform(), "model": BuddyClient.__get_model(), "osVersion": BuddyClient.__get_os_version(), "uniqueId": self.__get_unique_id(), }) if response[BuddyClient.exception_name] is None: self._settings.set_device_token(response[BuddyClient._result_name]) @staticmethod def __get_platform(): return sys.platform @staticmethod def __get_model(): hardware = BuddyClient.__get_cpuinfo("Hardware") revision = BuddyClient.__get_cpuinfo("Revision") if hardware is None: return "Hardware info not available" else: return hardware + "-" + revision @staticmethod def __get_os_version(): return platform.release() def __get_unique_id(self): unique_id = BuddyClient.__get_cpuinfo("Serial") if unique_id is None: unique_id = uuid.getnode() return unique_id @staticmethod def __get_cpuinfo(key): try: with open(BuddyClient._hardware_info_file_name, "r") as hardware_file: for line in hardware_file: if line.startswith(key): return line.splitlines()[0].split(": ")[1] except: return None def get(self, path, parameters): return self.__handle_parameters_request(self._session.get, path, parameters) def delete(self, path, parameters): return self.__handle_parameters_request(self._session.delete, path, parameters) def patch(self, path, dictionary): return self.__handle_dictionary_request(self._session.patch, path, dictionary) def post(self, path, dictionary, file=None): return self.__handle_dictionary_request(self._session.post, path, dictionary, file) def put(self, path, dictionary): return self.__handle_dictionary_request(self._session.put, path, dictionary) def create_user(self, user_name, password, first_name=None, last_name=None, email=None, gender=None, date_of_birth=None, tag=None): response = self.__handle_dictionary_request(self._session.post, "/users", { "username": user_name, "password": password, "firstName": first_name, "lastName": last_name, "email": email, "gender": gender, "dateOfBirth": date_of_birth, "tag": tag }) if response[BuddyClient.exception_name] is None: self._settings.set_user(response[BuddyClient._result_name]) return response def login_user(self, user_name, password): response = self.__handle_dictionary_request(self._session.post, "/users/login", { "username": user_name, "password": password, }) if response[BuddyClient.exception_name] is None: self._settings.set_user(response[BuddyClient._result_name]) return response def logout_user(self): self._settings.set_user(None) def __handle_parameters_request(self, verb, path, parameters=None): self.__handle_last_location(parameters) def closure(): return verb(self._settings.service_root + path, params=parameters) return self.__handle_request(closure) def __handle_dictionary_request(self, verb, path, dictionary, file=None): self.__handle_last_location(dictionary) def closure(): if file is None: return verb(self._settings.service_root + path, json=dictionary) else: return verb(self._settings.service_root + path, json=dictionary, files={"data": ("data",) + file}) return self.__handle_request(closure) def __handle_last_location(self, dictionary): if self.last_location is not None and dictionary is not None: dictionary["location"] = "%s, %s" % self.last_location def __handle_request(self, closure): response = None try: response = closure() except requests.RequestException as exception: return self.__handle_connection_exception(exception) except Exception as exception: return self.__handle_exception(exception) else: return self.__handle_response(response) def __handle_connection_exception(self, exception): self.__set_connection_level(Connection.off) if not self._connection_retry.isAlive(): self._connection_retry.start() return self.__handle_exception(exception) def __set_connection_level(self, connection_level): if self._connection_level is not connection_level: self._connection_level = connection_level self._connection_changed.on_change(self._connection_level) def __handle_exception(self, exception): self._service_exception.on_change(exception) return {BuddyClient.exception_name: exception} def __handle_response(self, response): if response.status_code == 401 or response.status_code == 403: self._authentication_needed.on_change() json_response = response.json() json_response[BuddyClient.exception_name] = None return json_response def __connection_retry_method(self): successful = False try: while not successful: try: requests.get(self._settings.service_root + "/service/ping") except requests.RequestException: successful = False else: successful = True finally: self.__set_connection_level(Connection.on)