Skip to content
This repository was archived by the owner on Oct 12, 2023. It is now read-only.

Commit

Permalink
Add argument type checking, more todo's, and add a .ui that should al…
Browse files Browse the repository at this point in the history
…ready have been
  • Loading branch information
melvyn2 committed Jul 16, 2020
1 parent 15b40f1 commit ebb5636
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 22 additions & 14 deletions PySteamAuth/AccountHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import json

import requests
import urllib.parse
from steam import webauth
from steam import webauth, guard
from PyQt5 import QtWidgets, QtGui
import json

import PyUIs
import Common
Expand All @@ -27,8 +27,11 @@
class Empty:
pass

# TODO move global sa into a file level global here

def refresh_session(sa): # TODO only run this when steammobile://lostauth

# TODO trigger only on steammobile://lostauth
def refresh_session(sa: guard.SteamAuthenticator, recursed: bool = False):
url = 'https://api.steampowered.com/IMobileAuthService/GetWGToken/v0001'
try:
r = requests.post(url, data={'access_token': urllib.parse.quote_plus(sa.secrets['Session']['OAuthToken'])})
Expand All @@ -40,15 +43,19 @@ def refresh_session(sa): # TODO only run this when steammobile://lostauth
except requests.exceptions.ConnectionError:
Common.error_popup('Failed to refresh session (connection error).', 'Warning')
return False
except (json.JSONDecodeError, KeyError):
Common.error_popup('Steam session expired. You will be prompted to sign back in.')
if full_refresh(sa):
return refresh_session(sa)
except (json.JSONDecodeError, KeyError) as e:
print(e)
if recursed:
Common.error_popup('Failed to use newly generated token.')
else:
return False
Common.error_popup('Steam session token expired. You will be prompted to sign back in.')
if full_refresh(sa):
return refresh_session(sa, recursed=True)
else:
return False


def full_refresh(sa):
def full_refresh(sa: guard.SteamAuthenticator):
mwa = get_mobilewebauth(sa, True)
if not mwa:
return False
Expand All @@ -59,7 +66,7 @@ def full_refresh(sa):
return True


def get_mobilewebauth(sa, force_login=True):
def get_mobilewebauth(sa: guard.SteamAuthenticator = None, force_username: bool = True):
if getattr(sa, 'backend', False) and sa.backend.logged_on:
return sa.backend
if 'Session' in sa.secrets.keys():
Expand All @@ -83,7 +90,7 @@ def get_mobilewebauth(sa, force_login=True):
login_ui = PyUIs.LogInDialog.Ui_Dialog()
login_ui.setupUi(login_dialog)
login_ui.buttonBox.rejected.connect(lambda: setattr(endfunc, 'endfunc', True))
login_ui.usernameBox.setDisabled((force_login and (sa is not None)))
login_ui.usernameBox.setDisabled((force_username and (sa is not None)))
if sa:
login_ui.usernameBox.setText(sa.secrets['account_name'])
# noinspection PyUnusedLocal
Expand Down Expand Up @@ -194,7 +201,8 @@ def get_mobilewebauth(sa, force_login=True):
break
if user.logged_on:
break
sa.backend = user
sa.secrets['Session']['OAuthToken'] = user.oauth_token
sa.secrets['Session']['SteamID'] = user.steam_id
# sa.backend = user
# sa.secrets['Session']['OAuthToken'] = user.oauth_token
# sa.secrets['Session']['SteamID'] = user.steam_id
# TODO save these on app close
return user
2 changes: 1 addition & 1 deletion PySteamAuth/Common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import PyUIs


def error_popup(message, header=None):
def error_popup(message: str or BaseException, header=None):
error_dialog = QtWidgets.QDialog()
error_ui = PyUIs.ErrorDialog.Ui_Dialog()
error_ui.setupUi(error_dialog)
Expand Down
55 changes: 29 additions & 26 deletions PySteamAuth/ConfirmationHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

import requests
import requests.cookies
import base64
import json
import re

import steam.guard
from typing import List

import requests
import requests.cookies

import Common


Expand All @@ -24,11 +28,11 @@ class Empty:


class Confirmation(object):
def __init__(self, conf_id, conf_key, conf_type, conf_creator, conf_icon_url, conf_description,
conf_sub_description, conf_time):
def __init__(self, conf_id: int, conf_key: int, conf_type: int, conf_creator: int, conf_icon_url: str,
conf_description: str, conf_sub_description: str, conf_time: int):
self.id = conf_id
self.key = conf_key
self.type = int(conf_type)
self.type = conf_type
type_switch = {
1: 'Generic',
2: 'Trade',
Expand All @@ -42,20 +46,20 @@ def __init__(self, conf_id, conf_key, conf_type, conf_creator, conf_icon_url, co
self.sub_description = conf_sub_description
self.time = conf_time

def accept(self, sa):
def accept(self, sa: steam.guard.SteamAuthenticator):
return confirm(sa, self, 'allow')

def deny(self, sa):
def deny(self, sa: steam.guard.SteamAuthenticator):
return confirm(sa, self, 'cancel')


def generate_query(tag, sa):
def generate_query(sa: steam.guard.SteamAuthenticator, tag: str):
return {'op': tag, 'p': sa.secrets['device_id'], 'a': sa.secrets['Session']['SteamID'],
'k': base64.b64encode(sa.get_confirmation_key(tag)).decode('utf-8'), 't': sa.get_time(),
'm': 'android', 'tag': tag}


def generate_cookiejar(sa):
def generate_cookiejar(sa: steam.guard.SteamAuthenticator):
jar = requests.cookies.RequestsCookieJar()
jar.set('mobileClientVersion', '0 (2.1.3)')
jar.set('mobileClient', 'android')
Expand All @@ -67,16 +71,16 @@ def generate_cookiejar(sa):
return jar


def fetch_confirmations(sa):
def fetch_confirmations(sa: steam.guard.SteamAuthenticator):
url = 'https://steamcommunity.com/mobileconf/conf'
data = generate_query('conf', sa)
data = generate_query(sa, 'conf')
try:
r = sa.backend.session.get(url, params="&".join("%s=%s" % (k, v) for k, v in data.items()))
except requests.exceptions.ConnectionError:
Common.error_popup('Connection Error.')
return []
# except requests.exceptions.InvalidSchema:
# TODO Finish this
# TODO Finish this, implement project wide
# pass

# Used for testing purposes
Expand All @@ -87,25 +91,25 @@ def fetch_confirmations(sa):
if '<div>Nothing to confirm</div>' in r.text:
return []
ret = []
pattern = '<div class=\"mobileconf_list_entry\" id=\"conf[0-9]+\" data-confid=\"(\d+)\" data-key=\"(\d+)\" ' \
'data-type=\"(\d)\" data-creator=\"(\d+)\" data-cancel=\"[a-zA-Z]+\" data-accept=\"[a-zA-Z]+\" >' \
'[\s]*?<div class=\"mobileconf_list_entry_content\">[\s]*?<div class=\"mobileconf_list_entry_icon\">' \
'[\s]*?(?:<div class=\"[a-zA-Z ]+\"><img src=\"(.*?)\" srcset=\".*? 1x, .*? 2x\"></div>)?[\s]*?</div>' \
'[\s]*?<div class=\"mobileconf_list_entry_description\">[\s]*?<div>(.*?)</div>[\s]*?<div>(.*?)</div>' \
'[\s]*?<div>(.*?)</div>[\s]*?</div>[\s]*?</div>'
# noinspection PyPep8
pattern = r'<div class=\"mobileconf_list_entry\" id=\"conf[0-9]+\" data-confid=\"(\d+)\" data-key=\"(\d+)\" ' \
r'data-type=\"(\d)\" data-creator=\"(\d+)\" data-cancel=\"[a-zA-Z]+\" data-accept=\"[a-zA-Z]+\" >' \
r'[\s]*?<div class=\"mobileconf_list_entry_content\">[\s]*?<div class=\"mobileconf_list_entry_icon\">' \
r'[\s]*?(?:<div class=\"[a-zA-Z ]+\"><img src=\"(.*?)\" srcset=\".*? 1x, .*? 2x\"></div>)?[\s]*?</div>' \
r'[\s]*?<div class=\"mobileconf_list_entry_description\">[\s]*?<div>(.*?)</div>[\s]*?<div>(.*?)</div>' \
r'[\s]*?<div>(.*?)</div>[\s]*?</div>[\s]*?</div>'
for i in re.findall(pattern, r.text):
ret.append(Confirmation(i[0], i[1], i[2], i[3], i[4].replace('.jpg', '_full.jpg'), re.sub('<[^<]+?>', '', i[5]),
i[6], i[7]))
return ret


def confirm(sa, conf, action):
def confirm(sa: steam.guard.SteamAuthenticator, conf: Confirmation, action: str):
url = 'https://steamcommunity.com/mobileconf/ajaxop'
data = generate_query(action, sa)
data = generate_query(sa, action)
data.update({'cid': conf.id, 'ck': conf.key})
jar = generate_cookiejar(sa)
try:
r = sa.backend.session.get(url, params="&".join("%s=%s" % (k, v) for k, v in data.items()), cookies=jar)
r = sa.backend.session.get(url, params="&".join("%s=%s" % (k, v) for k, v in data.items()))
except (requests.exceptions.ConnectionError, json.decoder.JSONDecodeError):
Common.error_popup('Connection error.')
return False
Expand All @@ -115,14 +119,13 @@ def confirm(sa, conf, action):
return False


def confirm_multi(sa, confs, action):
def confirm_multi(sa: steam.guard.SteamAuthenticator, confs: List[Confirmation], action: str):
url = 'https://steamcommunity.com/mobileconf/multiajaxop'
data = generate_query(action, sa)
data = generate_query(sa, action)
for i in confs:
data.update({'cid[]': i.id, 'ck[]': i.key})
jar = generate_cookiejar(sa)
try:
r = requests.post(url, data=data, cookies=jar)
r = sa.backend.requests.post(url, data=data)
except (requests.exceptions.ConnectionError, json.decoder.JSONDecodeError):
Common.error_popup('Connection error.')
return False
Expand Down
16 changes: 9 additions & 7 deletions PySteamAuth/FileHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import PyUIs
import Common

import sys
import os
import json
import hashlib

from typing import List

from PyQt5 import QtWidgets, QtCore
from steam import guard
from bpylist import archiver
Expand All @@ -30,6 +29,9 @@
from cryptography.hazmat.primitives.padding import PKCS7
from cryptography.hazmat.backends import default_backend

import PyUIs
import Common


class Empty(object):
pass
Expand Down Expand Up @@ -59,7 +61,7 @@ def load_manifest():
manifest.update({'selected_account': 0})


def load_entry(index=-1):
def load_entry(index: int = -1):
if index == -1:
index = manifest['selected_account']

Expand Down Expand Up @@ -91,7 +93,7 @@ def load_entry(index=-1):
return secrets


def save_entry(secrets, index=-1):
def save_entry(secrets: List, index: bool = -1):
if index == -1:
index = manifest['selected_account']
if manifest['encrypted']:
Expand All @@ -116,7 +118,7 @@ def save_entry(secrets, index=-1):
return False


def remove_entry(index=-1):
def remove_entry(index: bool = -1):
if index == -1:
index = manifest['selected_account']
os.remove(manifest['selected_account']['filename'])
Expand Down Expand Up @@ -202,7 +204,7 @@ def _handle_pw():
#
# def encrypt_entry():
# def _handle_pw():
# with open(os.path.join(mafiles_path, 'manifes')) # TODO use global manifest
# with open(os.path.join(mafiles_path, 'manifest.json')) # TODO use global manifest
# try:
# data = json.dumps(secrets, ensure_ascii=True).encode('ascii')
# iv = os.urandom(16)
Expand Down
Loading

0 comments on commit ebb5636

Please sign in to comment.