Get encrypted refresh tokens working
This commit is contained in:
19
config.py
19
config.py
@@ -5,6 +5,8 @@ from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger,
|
||||
StreamHandler, TimedRotatingFileHandler, WARNING
|
||||
import hashlib
|
||||
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
# Load variable overrides specific to distribution type
|
||||
@@ -34,6 +36,8 @@ gameDB = None
|
||||
logPath = None
|
||||
loggingLevel = None
|
||||
logging_setup = None
|
||||
cipher = None
|
||||
clientHash = None
|
||||
|
||||
ESI_AUTH_PROXY = "http://localhost:5015" # "https://blitzmann.pythonanywhere.com" // need to get this set up, and actually put on it's own domain
|
||||
ESI_CACHE = 'esi_cache'
|
||||
@@ -48,7 +52,7 @@ LOGLEVEL_MAP = {
|
||||
|
||||
|
||||
def getClientSecret():
|
||||
return hashlib.sha3_256("This is a secret, this will not remain in here for long".encode('utf-8')).hexdigest()
|
||||
return clientHash
|
||||
|
||||
|
||||
def isFrozen():
|
||||
@@ -90,6 +94,8 @@ def defPaths(customSavePath=None):
|
||||
global gameDB
|
||||
global saveInRoot
|
||||
global logPath
|
||||
global cipher
|
||||
global clientHash
|
||||
|
||||
pyfalog.debug("Configuring Pyfa")
|
||||
|
||||
@@ -114,6 +120,17 @@ def defPaths(customSavePath=None):
|
||||
|
||||
__createDirs(savePath)
|
||||
|
||||
# get cipher object based on secret key of this client (stores encryption cipher for ESI refresh token)
|
||||
secret_file = os.path.join(savePath, "{}.secret".format(hashlib.sha3_256(pyfaPath.encode('utf-8')).hexdigest()))
|
||||
if not os.path.exists(secret_file):
|
||||
with open(secret_file, "wb") as _file:
|
||||
_file.write(Fernet.generate_key())
|
||||
|
||||
with open(secret_file, 'rb') as fp:
|
||||
key = fp.read()
|
||||
clientHash = hashlib.sha3_256(key).hexdigest()
|
||||
cipher = Fernet(key)
|
||||
|
||||
# if isFrozen():
|
||||
# os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
# os.environ["SSL_CERT_FILE"] = os.path.join(pyfaPath, "cacert.pem")
|
||||
|
||||
@@ -31,8 +31,10 @@ class SsoCharacter(object):
|
||||
self.client = client
|
||||
self.accessToken = accessToken
|
||||
self.refreshToken = refreshToken
|
||||
self.accessTokenExpires = None
|
||||
self.esi_client = None
|
||||
|
||||
|
||||
@reconstructor
|
||||
def init(self):
|
||||
self.esi_client = None
|
||||
@@ -47,14 +49,3 @@ class SsoCharacter(object):
|
||||
self.accessTokenExpires - datetime.datetime.utcnow()
|
||||
).total_seconds()
|
||||
}
|
||||
|
||||
def update_token(self, tokenResponse):
|
||||
""" helper function to update token data from SSO response """
|
||||
self.accessToken = tokenResponse['access_token']
|
||||
self.accessTokenExpires = datetime.datetime.fromtimestamp(
|
||||
time.time() + tokenResponse['expires_in'],
|
||||
)
|
||||
if 'refresh_token' in tokenResponse:
|
||||
self.refreshToken = tokenResponse['refresh_token']
|
||||
if self.esi_client is not None:
|
||||
self.esi_client.security.update_token(tokenResponse)
|
||||
@@ -16,7 +16,7 @@ import gui.globalEvents as GE
|
||||
|
||||
from logbook import Logger
|
||||
import calendar
|
||||
from service.esi import Esi, CrestModes
|
||||
from service.esi import Esi
|
||||
|
||||
pyfalog = Logger(__name__)
|
||||
|
||||
|
||||
@@ -83,7 +83,6 @@ import webbrowser
|
||||
import wx.adv
|
||||
|
||||
from service.esi import Esi
|
||||
from service.esi import CrestModes
|
||||
from gui.crestFittings import CrestFittings, ExportToEve, CrestMgmt
|
||||
|
||||
disableOverrideEditor = False
|
||||
|
||||
@@ -10,6 +10,7 @@ import json
|
||||
import os
|
||||
|
||||
import eos.db
|
||||
import datetime
|
||||
from eos.enum import Enum
|
||||
from eos.saveddata.ssocharacter import SsoCharacter
|
||||
import gui.globalEvents as GE
|
||||
@@ -104,7 +105,7 @@ class Esi(object):
|
||||
char = eos.db.getSsoCharacter(id, config.getClientSecret())
|
||||
if char is not None and char.esi_client is None:
|
||||
char.esi_client = Esi.genEsiClient()
|
||||
char.esi_client.security.update_token(char.get_sso_data())
|
||||
char.esi_client.security.update_token(Esi.get_sso_data(char))
|
||||
return char
|
||||
|
||||
def getSkills(self, id):
|
||||
@@ -144,6 +145,26 @@ class Esi(object):
|
||||
resp = char.esi_client.request(op)
|
||||
return resp.data
|
||||
|
||||
@staticmethod
|
||||
def get_sso_data(char):
|
||||
""" Little "helper" function to get formated data for esipy security
|
||||
"""
|
||||
return {
|
||||
'access_token': char.accessToken,
|
||||
'refresh_token': config.cipher.decrypt(char.refreshToken).decode(),
|
||||
'expires_in': (char.accessTokenExpires - datetime.datetime.utcnow()).total_seconds()
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def update_token(char, tokenResponse):
|
||||
""" helper function to update token data from SSO response """
|
||||
char.accessToken = tokenResponse['access_token']
|
||||
char.accessTokenExpires = datetime.datetime.fromtimestamp(time.time() + tokenResponse['expires_in'])
|
||||
if 'refresh_token' in tokenResponse:
|
||||
char.refreshToken = config.cipher.encrypt(tokenResponse['refresh_token'].encode())
|
||||
if char.esi_client is not None:
|
||||
char.esi_client.security.update_token(tokenResponse)
|
||||
|
||||
def stopServer(self):
|
||||
pyfalog.debug("Stopping Server")
|
||||
self.httpd.stop()
|
||||
@@ -200,7 +221,7 @@ class Esi(object):
|
||||
if currentCharacter is None:
|
||||
currentCharacter = SsoCharacter(cdata['CharacterID'], cdata['CharacterName'], config.getClientSecret())
|
||||
currentCharacter.esi_client = Esi.genEsiClient(esisecurity)
|
||||
currentCharacter.update_token(auth_response) # this also sets the esi security token
|
||||
Esi.update_token(currentCharacter, auth_response) # this also sets the esi security token
|
||||
|
||||
eos.db.save(currentCharacter)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user