def getTokenNordVPN(): # Return a token that can be used on API calls token, renew, expiry, _ = getTokens() # If the expiry time is passed, renew the token if expiry.isdigit() and int(expiry) < now(): if renewNordVPN(renew): token, _, _, _ = getTokens() return token else: # Force an authenticate to happen token = "" # The authentication call is made during connection validation, which will validate everything and fetch # the tokens. If a reboot happens and the tokens disappear, then we need to force an authenticate again if token == "": addon = xbmcaddon.Addon(getID()) if authenticateNordVPN(addon.getSetting("vpn_provider_validated"), addon.getSetting("vpn_username_validated"), addon.getSetting("vpn_password_validated")): token, _, _, _ = getTokens() return token else: errorTrace("alternativeNord.py", "Couldn't authenticate or renew the user ID") resetTokens() raise RuntimeError("Couldn't get a user ID token") debugTrace("Using existing user ID token") return token
def sendAPI(command, command_text, api_data, check_response): # Common routine to send an API command try: response = "" rc = True rest_url = REQUEST_URL + command auth_token,_,_,_ = getTokens() # Login again if the token is blank and the command is not login anyway if auth_token == "" and not "=login" in command: debugTrace("Logging in again because auth token not valid") addon = xbmcaddon.Addon(getID()) rc = authenticateShellfire(addon.getSetting("vpn_provider"), addon.getSetting("vpn_username"), addon.getSetting("vpn_password")) auth_token,_,_,_ = getTokens() if auth_token == "" or not rc: raise Exception(command_text + " was not authorized") if ifHTTPTrace(): infoTrace("alternativeShellfire.py", command_text + " " + rest_url) else: debugTrace(command_text) req = urllib2.Request(rest_url, api_data, REQUEST_HEADERS) if not auth_token == "": req.add_header("x-authorization-token", auth_token) t_before = now() response = urllib2.urlopen(req) api_data = json.load(response) t_after = now() response.close() # Trace if the command took a long time if ifJSONTrace(): infoTrace("alternativeShellfire.py", "JSON received is \n" + json.dumps(api_data, indent=4)) if t_after - t_before > TIME_WARN: infoTrace("alternativeShellfire.py", command_text + " took " + str(t_after - t_before) + " seconds") # Check the response and fail if it's bad if check_response: if not api_data["status"] == "success": raise Exception(command_text + " returned bad response, " + api_data["status"]) except urllib2.HTTPError as e: errorTrace("alternativeShellfire.py", command_text + " failed") errorTrace("alternativeShellfire.py", "API call was " + rest_url) if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + json.dumps(api_data, indent=4)) errorTrace("alternativeShellfire.py", "Response was " + str(e.code) + " " + e.reason) errorTrace("alternativeShellfire.py", e.read()) rc = False except Exception as e: errorTrace("alternativeShellfire.py", command_text + " failed") errorTrace("alternativeShellfire.py", "API call was " + rest_url) if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + json.dumps(api_data, indent=4)) errorTrace("alternativeShellfire.py", "Response was " + str(type(e)) + " " + str(e)) rc = False return rc, api_data
def authenticateNordVPN(vpn_provider, userid, password): # Authenticate with the API and store the tokens returned # If the same credentials have been used before, don't bother authenticating _, _, _, creds = getTokens() if creds == vpn_provider + userid + password: debugTrace("Previous authentication was good") return True response = "" try: download_url = "https://api.nordvpn.com/v1/users/tokens" download_data = urllib.urlencode({ 'username': userid, 'password': password }) if ifHTTPTrace(): infoTrace( "alternativeNord.py", "Authenticating with VPN using " + download_url + ", " + download_data) else: debugTrace("Authenticating with VPN for user " + userid) req = urllib2.Request(download_url, download_data) t_before = now() response = urllib2.urlopen(req, timeout=10) user_data = json.load(response) t_after = now() response.close() if ifJSONTrace(): infoTrace("alternativeNord.py", "JSON received is \n" + json.dumps(user_data, indent=4)) if t_after - t_before > TIME_WARN: infoTrace( "alternativeNord.py", "Authenticating with VPN for " + userid + " took " + str(t_after - t_before) + " seconds") setTokens(user_data["token"], user_data["renew_token"], None) setTokens(user_data["token"], user_data["renew_token"], vpn_provider + userid + password) return True except urllib2.HTTPError as e: errorTrace("alternativeNord.py", "Couldn't authenticate with " + vpn_provider) errorTrace( "alternativeNord.py", "API call was " + download_url + ", " + download_data[:download_data.index("&password") + 10] + "********") errorTrace("alternativeNord.py", "Response was " + str(e.code) + " " + e.reason) errorTrace("alternativeNord.py", e.read()) except Exception as e: errorTrace("alternativeNord.py", "Couldn't authenticate with " + vpn_provider) errorTrace( "alternativeNord.py", "API call was " + download_url + ", " + download_data[:download_data.index("&password") + 10] + "********") errorTrace("alternativeNord.py", "Response was " + str(type(e)) + " " + str(e)) resetTokens() return False
def authenticateShellfire(vpn_provider, userid, password): # Authenticate with the API and store the tokens returned # If the same credentials have been used before, don't bother authenticating _,_,_, creds = getTokens() if creds == vpn_provider + userid + password: debugTrace("Previous authentication was good") return True # Get the authentication token to use on future calls resetTokens() rc, api_data = sendAPI("?action=login", "Authenticating with VPN", '{"email":"' + userid + '", "password":"******"}', True) if not rc: return False # Extract the auth token and store it auth_token = api_data["data"]["token"] if not auth_token == None: setTokens(auth_token, "", vpn_provider + userid + password) return True return False
def authenticateShellfire(vpn_provider, userid, password): # Authenticate with the API and store the tokens returned # If the same credentials have been used before, don't bother authenticating _, _, _, creds = getTokens() if creds == vpn_provider + userid + password: debugTrace("Previous authentication was good") return True # Get the authentication token to use on future calls resetTokens() rc, api_data = sendAPI( "?action=login", "Authenticating with VPN", '{"email":"' + userid + '", "password":"******"}', True) if not rc: return False # Extract the auth token and store it auth_token = api_data["data"]["token"] if not auth_token == None: setTokens(auth_token, "", vpn_provider + userid + password) return True return False
def sendAPI(command, command_text, api_data, check_response): # Common routine to send an API command try: response = "" rc = True rest_url = REQUEST_URL + command auth_token, _, _, _ = getTokens() # Login again if the token is blank and the command is not login anyway if auth_token == "" and not "=login" in command: debugTrace("Logging in again because auth token not valid") addon = xbmcaddon.Addon(getID()) rc = authenticateShellfire(addon.getSetting("vpn_provider"), addon.getSetting("vpn_username"), addon.getSetting("vpn_password")) auth_token, _, _, _ = getTokens() if auth_token == "" or not rc: raise Exception(command_text + " was not authorized") if ifHTTPTrace(): infoTrace("alternativeShellfire.py", command_text + " " + rest_url) else: debugTrace(command_text) req = urllib2.Request(rest_url, api_data, REQUEST_HEADERS) if not auth_token == "": req.add_header("x-authorization-token", auth_token) t_before = now() response = urllib2.urlopen(req) api_data = json.load(response) t_after = now() response.close() # Trace if the command took a long time if ifJSONTrace(): infoTrace("alternativeShellfire.py", "JSON received is \n" + json.dumps(api_data, indent=4)) if t_after - t_before > TIME_WARN: infoTrace( "alternativeShellfire.py", command_text + " took " + str(t_after - t_before) + " seconds") # Check the response and fail if it's bad if check_response: if not api_data["status"] == "success": raise Exception(command_text + " returned bad response, " + api_data["status"]) except urllib2.HTTPError as e: errorTrace("alternativeShellfire.py", command_text + " failed") errorTrace("alternativeShellfire.py", "API call was " + rest_url) if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + json.dumps(api_data, indent=4)) errorTrace("alternativeShellfire.py", "Response was " + str(e.code) + " " + e.reason) errorTrace("alternativeShellfire.py", e.read()) rc = False except Exception as e: errorTrace("alternativeShellfire.py", command_text + " failed") errorTrace("alternativeShellfire.py", "API call was " + rest_url) if not api_data == "": errorTrace("alternativeShellfire.py", "Data returned was \n" + json.dumps(api_data, indent=4)) errorTrace("alternativeShellfire.py", "Response was " + str(type(e)) + " " + str(e)) rc = False return rc, api_data