diff --git a/config.py b/config.py
index 339a19e0a..1127b72ae 100644
--- a/config.py
+++ b/config.py
@@ -3,6 +3,7 @@ import sys
from logbook import CRITICAL, DEBUG, ERROR, FingersCrossedHandler, INFO, Logger, NestedSetup, NullHandler, \
StreamHandler, TimedRotatingFileHandler, WARNING
+import hashlib
pyfalog = Logger(__name__)
@@ -43,6 +44,10 @@ LOGLEVEL_MAP = {
}
+def getClientSecret():
+ return hashlib.sha3_256("This is a secret, this will not remain in here for long".encode('utf-8')).hexdigest()
+
+
def isFrozen():
if hasattr(sys, 'frozen'):
return True
diff --git a/eos/db/saveddata/crest.py b/eos/db/saveddata/crest.py
index 28f77a983..035cdb60d 100644
--- a/eos/db/saveddata/crest.py
+++ b/eos/db/saveddata/crest.py
@@ -22,13 +22,17 @@ from sqlalchemy.orm import mapper
import datetime
from eos.db import saveddata_meta
-from eos.saveddata.crestchar import CrestChar
+from eos.saveddata.ssocharacter import SsoCharacter
-crest_table = Table("crest", saveddata_meta,
+sso_table = Table("ssoCharacter", saveddata_meta,
Column("ID", Integer, primary_key=True),
- Column("name", String, nullable=False, unique=True),
- Column("refresh_token", String, nullable=False),
- # These records aren't updated. Instead, they are dropped and created, hence we don't have a modified field
- Column("created", DateTime, nullable=True, default=datetime.datetime.now))
+ Column("client", String, nullable=False),
+ Column("characterID", Integer, nullable=False, unique=True),
+ Column("characterName", String, nullable=False, unique=True),
+ Column("refreshToken", String, nullable=False),
+ Column("accessToken", String, nullable=False),
+ Column("accessTokenExpires", DateTime, nullable=False),
+ Column("created", DateTime, nullable=True, default=datetime.datetime.now),
+ Column("modified", DateTime, nullable=True, onupdate=datetime.datetime.now))
-mapper(CrestChar, crest_table)
+mapper(SsoCharacter, sso_table)
diff --git a/eos/db/saveddata/queries.py b/eos/db/saveddata/queries.py
index 98902007f..b3c1840e8 100644
--- a/eos/db/saveddata/queries.py
+++ b/eos/db/saveddata/queries.py
@@ -27,7 +27,7 @@ from eos.db.saveddata.fit import projectedFits_table
from eos.db.util import processEager, processWhere
from eos.saveddata.price import Price
from eos.saveddata.user import User
-from eos.saveddata.crestchar import CrestChar
+from eos.saveddata.ssocharacter import SsoCharacter
from eos.saveddata.damagePattern import DamagePattern
from eos.saveddata.targetResists import TargetResists
from eos.saveddata.character import Character
@@ -467,27 +467,27 @@ def getProjectedFits(fitID):
raise TypeError("Need integer as argument")
-def getCrestCharacters(eager=None):
+def getSsoCharacters(eager=None):
eager = processEager(eager)
with sd_lock:
- characters = saveddata_session.query(CrestChar).options(*eager).all()
+ characters = saveddata_session.query(SsoCharacter).options(*eager).all()
return characters
-@cachedQuery(CrestChar, 1, "lookfor")
-def getCrestCharacter(lookfor, eager=None):
+@cachedQuery(SsoCharacter, 1, "lookfor")
+def getSsoCharacter(lookfor, eager=None):
if isinstance(lookfor, int):
if eager is None:
with sd_lock:
- character = saveddata_session.query(CrestChar).get(lookfor)
+ character = saveddata_session.query(SsoCharacter).get(lookfor)
else:
eager = processEager(eager)
with sd_lock:
- character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.ID == lookfor).first()
+ character = saveddata_session.query(SsoCharacter).options(*eager).filter(SsoCharacter.ID == lookfor).first()
elif isinstance(lookfor, str):
eager = processEager(eager)
with sd_lock:
- character = saveddata_session.query(CrestChar).options(*eager).filter(CrestChar.name == lookfor).first()
+ character = saveddata_session.query(SsoCharacter).options(*eager).filter(SsoCharacter.name == lookfor).first()
else:
raise TypeError("Need integer or string as argument")
return character
diff --git a/eos/saveddata/crestchar.py b/eos/saveddata/crestchar.py
deleted file mode 100644
index ce6ab14fe..000000000
--- a/eos/saveddata/crestchar.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# ===============================================================================
-# Copyright (C) 2010 Diego Duclos
-#
-# This file is part of eos.
-#
-# eos is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# eos is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with eos. If not, see .
-# ===============================================================================
-
-from sqlalchemy.orm import reconstructor
-
-
-# from tomorrow import threads
-
-
-class CrestChar(object):
- def __init__(self, id, name, refresh_token=None):
- self.ID = id
- self.name = name
- self.refresh_token = refresh_token
-
- @reconstructor
- def init(self):
- pass
diff --git a/eos/saveddata/ssocharacter.py b/eos/saveddata/ssocharacter.py
new file mode 100644
index 000000000..8fca830cb
--- /dev/null
+++ b/eos/saveddata/ssocharacter.py
@@ -0,0 +1,60 @@
+# ===============================================================================
+# Copyright (C) 2010 Diego Duclos
+#
+# This file is part of eos.
+#
+# eos is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 2 of the License, or
+# (at your option) any later version.
+#
+# eos is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with eos. If not, see .
+# ===============================================================================
+
+from sqlalchemy.orm import reconstructor
+import datetime
+import time
+
+# from tomorrow import threads
+
+
+class SsoCharacter(object):
+ def __init__(self, id, charID, name, client, accessToken, refreshToken=None):
+ self.ID = id
+ self.characterID = charID
+ self.characterName = name
+ self.client = client
+ self.accessToken = accessToken
+ self.refreshToken = refreshToken
+
+ @reconstructor
+ def init(self):
+ pass
+
+ def get_sso_data(self):
+ """ Little "helper" function to get formated data for esipy security
+ """
+ return {
+ 'access_token': self.accessToken,
+ 'refresh_token': self.refreshToken,
+ 'expires_in': (
+ self.accessTokenExpires - 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.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)
\ No newline at end of file
diff --git a/gui/mainFrame.py b/gui/mainFrame.py
index 2aa6bb750..735db0d80 100644
--- a/gui/mainFrame.py
+++ b/gui/mainFrame.py
@@ -662,16 +662,8 @@ class MainFrame(wx.Frame):
menu.Enable(menu.exportToEveId, not enable)
def ssoHandler(self, event):
- sCrest = Crest.getInstance()
- if sCrest.settings.get('mode') == CrestModes.IMPLICIT:
- if sCrest.implicitCharacter is not None:
- sCrest.logout()
- else:
- uri = sCrest.startServer()
- webbrowser.open(uri)
- else:
- dlg = CrestMgmt(self)
- dlg.Show()
+ dlg = CrestMgmt(self)
+ dlg.Show()
def exportToEve(self, event):
dlg = ExportToEve(self)
diff --git a/gui/mainMenuBar.py b/gui/mainMenuBar.py
index be9322010..8b5b77e60 100644
--- a/gui/mainMenuBar.py
+++ b/gui/mainMenuBar.py
@@ -28,8 +28,8 @@ import gui.globalEvents as GE
from gui.bitmap_loader import BitmapLoader
from logbook import Logger
-from service.crest import Crest
-from service.crest import CrestModes
+# from service.crest import Crest
+# from service.crest import CrestModes
pyfalog = Logger(__name__)
@@ -134,21 +134,19 @@ class MainMenuBar(wx.MenuBar):
preferencesItem.SetBitmap(BitmapLoader.getBitmap("preferences_small", "gui"))
windowMenu.Append(preferencesItem)
- self.sCrest = Crest.getInstance()
+ # self.sCrest = Crest.getInstance()
# CREST Menu
crestMenu = wx.Menu()
self.Append(crestMenu, "&CREST")
- if self.sCrest.settings.get('mode') != CrestModes.IMPLICIT:
- crestMenu.Append(self.ssoLoginId, "Manage Characters")
- else:
- crestMenu.Append(self.ssoLoginId, "Login to EVE")
+
+ crestMenu.Append(self.ssoLoginId, "Manage Characters")
crestMenu.Append(self.eveFittingsId, "Browse EVE Fittings")
crestMenu.Append(self.exportToEveId, "Export To EVE")
- if self.sCrest.settings.get('mode') == CrestModes.IMPLICIT or len(self.sCrest.getCrestCharacters()) == 0:
- self.Enable(self.eveFittingsId, False)
- self.Enable(self.exportToEveId, False)
+ # if self.sCrest.settings.get('mode') == CrestModes.IMPLICIT or len(self.sCrest.getCrestCharacters()) == 0:
+ self.Enable(self.eveFittingsId, False)
+ self.Enable(self.exportToEveId, False)
if not self.mainFrame.disableOverrideEditor:
windowMenu.AppendSeparator()
diff --git a/service/crest.py b/service/crest.py
index ff1765298..51c9f1309 100644
--- a/service/crest.py
+++ b/service/crest.py
@@ -8,7 +8,7 @@ import time
import eos.db
from eos.enum import Enum
-from eos.saveddata.crestchar import CrestChar
+from eos.saveddata.ssocharacter import SsoCharacter
import gui.globalEvents as GE
from service.settings import CRESTSettings
from service.server import StoppableHTTPServer, AuthHandler
@@ -100,40 +100,30 @@ class Crest(object):
return self.settings.get('server') == Servers.SISI
def delCrestCharacter(self, charID):
- char = eos.db.getCrestCharacter(charID)
+ char = eos.db.getSsoCharacter(charID)
del self.charCache[char.ID]
eos.db.remove(char)
wx.PostEvent(self.mainFrame, GE.SsoLogout(type=CrestModes.USER, numChars=len(self.charCache)))
def delAllCharacters(self):
- chars = eos.db.getCrestCharacters()
+ chars = eos.db.getSsoCharacters()
for char in chars:
eos.db.remove(char)
self.charCache = {}
wx.PostEvent(self.mainFrame, GE.SsoLogout(type=CrestModes.USER, numChars=0))
def getCrestCharacters(self):
- chars = eos.db.getCrestCharacters()
- # I really need to figure out that DB cache problem, this is ridiculous
- chars2 = [self.getCrestCharacter(char.ID) for char in chars]
- return chars2
+ chars = eos.db.getSsoCharacters()
+ return chars
def getCrestCharacter(self, charID):
"""
Get character, and modify to include the eve connection
"""
- if self.settings.get('mode') == CrestModes.IMPLICIT:
- if self.implicitCharacter.ID != charID:
- raise ValueError("CharacterID does not match currently logged in character.")
- return self.implicitCharacter
-
if charID in self.charCache:
return self.charCache.get(charID)
- char = eos.db.getCrestCharacter(charID)
- if char and not hasattr(char, "eve"):
- char.eve = EVE(**self.eve_options)
- char.eve.temptoken_authorize(refresh_token=char.refresh_token)
+ char = eos.db.getSsoCharacter(charID)
self.charCache[charID] = char
return char
diff --git a/service/esi.py b/service/esi.py
index 0125c42c4..0f375a591 100644
--- a/service/esi.py
+++ b/service/esi.py
@@ -8,7 +8,7 @@ import time
import eos.db
from eos.enum import Enum
-from eos.saveddata.crestchar import CrestChar
+from eos.saveddata.ssocharacter import CrestChar
import gui.globalEvents as GE
from service.settings import CRESTSettings
from service.server import StoppableHTTPServer, AuthHandler