Skip to content

Commit

Permalink
Temporary Fix of Steam Auth Change
Browse files Browse the repository at this point in the history
  • Loading branch information
hhhhhojeihsu committed Feb 14, 2025
1 parent d866b14 commit 693fd93
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 16 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/check-test-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.9"]
python-version: ["3.12"]
os: [ubuntu-latest, windows-latest]

steps:
Expand Down Expand Up @@ -64,9 +64,9 @@ jobs:
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
# stop the build if there are Python syntax errors or undefined names
ruff check --select=E9,F63,F7,F82 --target-version=py39 .
ruff check --select=E9,F63,F7,F82 --target-version=py312 .
# default set of ruff rules with GitHub Annotations
ruff check --target-version=py39 .
ruff check --target-version=py312 .
- name: Run Tests
run: |
python -m pytest
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ authors = [
]
description = "Steam Cloud Save Downloader"
readme = "README.md"
requires-python = ">=3.9"
requires-python = ">=3.12"
classifiers = [
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
Expand All @@ -36,4 +36,4 @@ packages = ["steamCloudSaveDownloader"]

[tool.ruff]
select = ["E9", "F63", "F7", "F82"]
target-version= "py39"
target-version= "py312"
4 changes: 2 additions & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
steampy>=1.1.2,<2
steampy>=1.2.0,<2
requests>=2.28.2,<3
beautifulsoup4>=4.12.2,<5
discord-webhook>=1.1.0,<2
pyinstaller>=5.11.0,<6
pyinstaller>=6.12.0,<7
ruff>=0.0.270,<1
pre-commit>=3.3.2,<4
build>=0.10.0,<1
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
steampy>=1.1.2,<2
steampy>=1.2.0,<2
#steam[client]>=1.4.4,<2
requests>=2.28.2,<3
beautifulsoup4>=4.12.2,<5
Expand Down
64 changes: 56 additions & 8 deletions steamCloudSaveDownloader/auth.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#import steam.webauth as wa
from http import HTTPStatus
from steampy.login import LoginExecutor
from steampy import guard
Expand Down Expand Up @@ -36,6 +35,59 @@ def _update_steam_guard_mail_override(self, login_response: requests.Response) -

guard.generate_one_time_code = generate_one_time_code_override

# 2025/2/14 Hotfix
from rsa import PublicKey
from steampy.exceptions import ApiException
def _fetch_rsa_params_override(self, current_number_of_repetitions: int = 0) -> dict:
self.session.get(SteamUrl.COMMUNITY_URL)
request_data = {'account_name': self.username}
response = self._api_call('GET', 'IAuthenticationService', 'GetPasswordRSAPublicKey', params=request_data)

if response.status_code == HTTPStatus.OK and 'response' in response.json():
key_data = response.json()['response']
# Steam may return an empty 'response' value even if the status is 200
if 'publickey_mod' in key_data and 'publickey_exp' in key_data and 'timestamp' in key_data:
rsa_mod = int(key_data['publickey_mod'], 16)
rsa_exp = int(key_data['publickey_exp'], 16)
return {'rsa_key': PublicKey(rsa_mod, rsa_exp), 'rsa_timestamp': key_data['timestamp']}

maximal_number_of_repetitions = 5
if current_number_of_repetitions < maximal_number_of_repetitions:
return self._fetch_rsa_params(current_number_of_repetitions + 1)

raise ApiException(f'Could not obtain rsa-key. Status code: {response.status_code}')
LoginExecutor._fetch_rsa_params = _fetch_rsa_params_override

def _perform_redirects_override(self, response_dict: dict) -> None:
parameters = response_dict.get('transfer_info')
if parameters is None:
raise Exception('Cannot perform redirects after login, no parameters fetched')
for pass_data in parameters:
pass_data['params'].update({'steamID': response_dict['steamID']})
multipart_fields = {
key: (None, str(value))
for key, value in pass_data['params'].items()
}
self.session.post(pass_data['url'], files = multipart_fields)
LoginExecutor._perform_redirects = _perform_redirects_override

from requests import Response
def _finalize_login_override(self) -> Response:
community_domain = SteamUrl.COMMUNITY_URL[8:]
sessionid = self.session.cookies.get_dict(domain=community_domain)['sessionid']
redir = f'{SteamUrl.COMMUNITY_URL}/login/home/?goto='
files = {
'nonce': (None, self.refresh_token),
'sessionid': (None, sessionid),
'redir': (None, redir)
}
headers = {
'Referer': redir,
'Origin': 'https://steamcommunity.com'
}
return self.session.post("https://login.steampowered.com/jwt/finalizelogin", headers = headers, files = files)
LoginExecutor._finalize_login = _finalize_login_override

class auth:
s_session_filename = 'session.sb'
def __init__(
Expand Down Expand Up @@ -78,7 +130,7 @@ def new_session(self, username:str):
self.password,
self.two_factor_code,
self.session)
self.login_executor.login()
sess = self.login_executor.login()
except Exception as e:
raise err(err_enum.LOGIN_FAIL)

Expand All @@ -87,6 +139,7 @@ def new_session(self, username:str):
pickle.dump(self.login_executor, f)
os.umask(prev_umask)
print("Login success. Please rerun scsd to start downloading")
print(self.session.cookies.items())

def get_session_path(self):
return os.path.join(self.data_dir, auth.s_session_filename)
Expand All @@ -100,12 +153,7 @@ def refresh_session(self):
with open(self.get_session_path(), 'rb') as f:
self.login_executor = pickle.load(f)

sessionid = self.login_executor.session.cookies.get('sessionid', domain='store.steampowered.com')
redir = f'{SteamUrl.COMMUNITY_URL}/login/home/?goto='
finalized_data = {'nonce': self.login_executor.refresh_token, 'sessionid': sessionid, 'redir': redir}
finalized_response = self.login_executor.session.post(SteamUrl.LOGIN_URL + '/jwt/finalizelogin', data=finalized_data)

self.login_executor._perform_redirects(finalized_response.json())
self.login_executor._perform_redirects(self.login_executor._finalize_login().json())

with open(self.get_session_path(), 'wb') as f:
pickle.dump(self.login_executor, f)

0 comments on commit 693fd93

Please sign in to comment.