def log_on(self): """ Logs on to a website, using an url. First checks if the channel requires log on. If so and it's not already logged on, it should handle the log on. That part should be implemented by the specific channel. More arguments can be passed on, but must be handled by custom code. After a successful log on the self.loggedOn property is set to True and True is returned. :return: indication if the login was successful. :rtype: bool """ if self.__idToken: return True # check if there is a refresh token # refresh token: viervijfzes_refresh_token refresh_token = AddonSettings.get_setting("viervijfzes_refresh_token") client = AwsIdp("eu-west-1_dViSsKM5Y", "6s1h851s8uplco5h6mqh1jac8m", proxy=self.proxy, logger=Logger.instance()) if refresh_token: id_token = client.renew_token(refresh_token) if id_token: self.__idToken = id_token return True else: Logger.info("Extending token for VierVijfZes failed.") # username: viervijfzes_username username = AddonSettings.get_setting("viervijfzes_username") # password: viervijfzes_password v = Vault() password = v.get_setting("viervijfzes_password") if not username or not password: XbmcWrapper.show_dialog( title=None, lines=LanguageHelper.get_localized_string( LanguageHelper.MissingCredentials), ) return False id_token, refresh_token = client.authenticate(username, password) if not id_token or not refresh_token: Logger.error("Error getting a new token. Wrong password?") return False self.__idToken = id_token AddonSettings.set_setting("viervijfzes_refresh_token", refresh_token) return True
def __get_application_key(self): """ Gets the decrypted application key that is used for all the encryption. :return: The decrypted application key that is used for all the encryption. :rtype: bytes """ application_key_encrypted = AddonSettings.get_setting( Vault.__APPLICATION_KEY_SETTING, store=LOCAL) # The key was never in the local store the value was None. It was "" if it was reset. if application_key_encrypted is None: application_key_encrypted = AddonSettings.get_setting( Vault.__APPLICATION_KEY_SETTING, store=KODI) if not application_key_encrypted: return None Logger.info("Moved ApplicationKey to local storage") AddonSettings.set_setting(Vault.__APPLICATION_KEY_SETTING, application_key_encrypted, store=LOCAL) # Still no application key? Then there was no key! if application_key_encrypted == "" or application_key_encrypted is None: return None vault_incorrect_pin = LanguageHelper.get_localized_string( LanguageHelper.VaultIncorrectPin) pin = XbmcWrapper.show_key_board( heading=LanguageHelper.get_localized_string( LanguageHelper.VaultInputPin), hidden=True) if not pin: XbmcWrapper.show_notification("", vault_incorrect_pin, XbmcWrapper.Error) raise RuntimeError("Incorrect Retrospect PIN specified") pin_key = self.__get_pbk(pin) application_key = self.__decrypt(application_key_encrypted, pin_key) if not application_key.startswith(Vault.__APPLICATION_KEY_SETTING): Logger.critical("Invalid Retrospect PIN") XbmcWrapper.show_notification("", vault_incorrect_pin, XbmcWrapper.Error) raise RuntimeError("Incorrect Retrospect PIN specified") application_key_value = application_key[ len(Vault.__APPLICATION_KEY_SETTING) + 1:] Logger.info("Successfully decrypted the ApplicationKey.") if PY2: return application_key_value # We return bytes on Python 3 return application_key_value.encode()
def log_off(self, username): """ Check if the user with the given name is currently authenticated. :param str username: The username to log off :returns: Indication of success :rtype: bool """ # clean older data UriHandler.delete_cookie(domain=".sso.rtl.nl") AddonSettings.set_setting(self.__setting_signature, "", store=LOCAL) return True
def __extract_session_data(self, logon_data): """ :param logon_data: :return: :rtype: AuthenticationResult """ logon_json = json.loads(logon_data) result_code = logon_json.get("statusCode") Logger.trace("Logging in returned: %s", result_code) if result_code != 200: Logger.error("Error loging in: %s - %s", logon_json.get("errorMessage"), logon_json.get("errorDetails")) return AuthenticationResult(None) user_name = logon_json.get("profile", {}).get("email") or None signature_setting = logon_json.get("sessionInfo", {}).get("login_token") if signature_setting: Logger.info("Found 'login_token'. Saving it.") AddonSettings.set_setting(self.__setting_signature, signature_setting.split("|")[0], store=LOCAL) self.__signature = logon_json.get("UIDSignature") self.__user_id = logon_json.get("UID") self.__signature_timestamp = logon_json.get("signatureTimestamp") # TODO: is this correct? has_premium = logon_json.\ get("data", {}).\ get("authorization", {}).\ get("rtlxl_premium", {}).\ get("subscription", {}).\ get("id") == "premium" # The channels are not interesting # premium_channels = logon_json.get_value( # "data", "authorization", "Stievie_free", "channels") return AuthenticationResult(user_name, has_premium=has_premium)
def reset(): """ Resets the Vault and Retrospect Machine key, making all encrypted values useless. :rtype: None """ ok = XbmcWrapper.show_yes_no(LanguageHelper.get_localized_string(LanguageHelper.VaultReset), LanguageHelper.get_localized_string(LanguageHelper.VaultResetConfirm)) if not ok: Logger.debug("Aborting Reset Vault") return Logger.info("Resetting the vault to a new initial state.") AddonSettings.set_setting(Vault.__APPLICATION_KEY_SETTING, "", store=LOCAL) # create a vault instance so we initialize a new one with a new PIN. Vault() return
def set_setting(self, setting_id, setting_name=None, setting_action_id=None): """ Reads a value for a setting from the keyboard and encrypts it in the Kodi Add-on settings. The settingActionId defaults to <settingId>_set :param str setting_id: The ID for the Kodi Add-on setting to set. :param str setting_name: The name to display in the keyboard. :param str setting_action_id: The name of setting that shows the ***** if an value was encrypted. :rtype: None """ Logger.info("Encrypting value for setting '%s'", setting_id) input_value = XbmcWrapper.show_key_board( "", LanguageHelper.get_localized_string( LanguageHelper.VaultSpecifySetting) % (setting_name or setting_id, )) if input_value is None: Logger.debug("Setting of encrypted value cancelled.") return value = "%s=%s" % (setting_id, input_value) encrypted_value = self.__encrypt(value, Vault.__Key) if setting_action_id is None: setting_action_id = "%s_set" % (setting_id, ) Logger.debug("Updating '%s' and '%s'", setting_id, setting_action_id) AddonSettings.set_setting(setting_id, encrypted_value) if input_value: AddonSettings.set_setting(setting_action_id, "******") else: AddonSettings.set_setting(setting_action_id, "") Logger.info("Successfully encrypted value for setting '%s'", setting_id) return
def change_pin(self, application_key=None): """ Stores an existing ApplicationKey using a new PIN. :param bytes application_key: an existing ApplicationKey that will be stored. If none specified, the existing ApplicationKey of the Vault will be used. :return: Indication of success. :rtype: bool """ Logger.info("Updating the ApplicationKey with a new PIN") if self.__newKeyGeneratedInConstructor: Logger.info("A key was just generated, no need to change PINs.") return True if application_key is None: Logger.debug("Using the ApplicationKey from the vault.") application_key = Vault.__Key else: Logger.debug("Using the ApplicationKey from the input parameter.") if not application_key: raise ValueError("No ApplicationKey specified.") # Now we get a new PIN and (re)encrypt pin = XbmcWrapper.show_key_board( heading=LanguageHelper.get_localized_string( LanguageHelper.VaultNewPin), hidden=True) if not pin: XbmcWrapper.show_notification( "", LanguageHelper.get_localized_string(LanguageHelper.VaultNoPin), XbmcWrapper.Error) return False pin2 = XbmcWrapper.show_key_board( heading=LanguageHelper.get_localized_string( LanguageHelper.VaultRepeatPin), hidden=True) if pin != pin2: Logger.critical("Mismatch in PINs") XbmcWrapper.show_notification( "", LanguageHelper.get_localized_string( LanguageHelper.VaultPinsDontMatch), XbmcWrapper.Error) return False if PY2: encrypted_key = "%s=%s" % (self.__APPLICATION_KEY_SETTING, application_key) else: # make it text to store encrypted_key = "%s=%s" % (self.__APPLICATION_KEY_SETTING, application_key.decode()) # let's generate a pin using the scrypt password-based key derivation pin_key = self.__get_pbk(pin) encrypted_key = self.__encrypt(encrypted_key, pin_key) AddonSettings.set_setting(Vault.__APPLICATION_KEY_SETTING, encrypted_key, store=LOCAL) Logger.info("Successfully updated the Retrospect PIN") return True