Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac build fix #11

Open
wants to merge 111 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
111 commits
Select commit Hold shift + click to select a range
9ef4340
Add protobuff files
LauraRozier Mar 16, 2023
029e695
Add (improvised) missing files
LauraRozier Mar 16, 2023
98e3444
Update bindings
LauraRozier Mar 16, 2023
e0b914f
Fix AttributeError('out_of_game_heartbeat_seconds')
LauraRozier Mar 16, 2023
cb9f8c3
Update README.md
TheSentry Apr 10, 2023
0d24e8a
implemented the RSA call.
ABaumher Apr 30, 2023
4f39c71
actually staging the changes this time, lol
ABaumher Apr 30, 2023
4edb254
Updated enums to the current version available. Continued modificatio…
ABaumher Apr 30, 2023
d0c2a14
Updated protocol buffer message files to work with auth. Merged chang…
ABaumher May 2, 2023
0b16bfc
updated the EMsg constants. They were out of date
ABaumher May 2, 2023
77474d5
minor changes to protobuf client. Prototyping new workflow. Preparing…
ABaumher May 4, 2023
6cc7ecb
Updated bugfixes to a version that runs in GOG Galaxy. This still req…
ABaumher May 4, 2023
b61273b
Got the RSA Key all the way back to the Backend, so we can change the…
ABaumher May 4, 2023
58c8f29
Update that gets the password RSA key for the user. Implements the ba…
ABaumher May 5, 2023
7498c57
Maybe breaking. Looking for an old message i wrote, so i need this ba…
ABaumher May 5, 2023
da90375
updated consts, protobuf, protocol buffer to report modern os types (…
ABaumher May 5, 2023
83a69a1
Testing various changes. This will break at some point before hitting…
ABaumher May 6, 2023
76ccfca
Breaking Change: Renamed types.py so Visual Studio would stop complai…
ABaumher May 6, 2023
708083c
adding type hints, mostly. need to track down where job_list was adde…
ABaumher May 6, 2023
141eed8
Public Key data comes back in hexidecimal, so that is now handled pro…
ABaumher May 6, 2023
0eef845
Full login with no SteamGuard test. Likely will require a few bugfixe…
ABaumher May 6, 2023
dc762dd
Login processed properly, goes to confirm to get the tokens, and none…
ABaumher May 7, 2023
0285aa2
Merged in Thibmo's fixes and proto files. this is not a complete merg…
ABaumher May 7, 2023
4429a71
Dealing with getting the proto files properly parsed and built so the…
ABaumher May 8, 2023
3cd0b49
Added Protos. Updated Tasks.py to properly import them. They still do…
ABaumher May 8, 2023
91f2670
Reverted py files to what they were before merging with Thibmo's fork.
ABaumher May 8, 2023
95bbacf
Updated the protobuf list to the files we currently use. There are a …
ABaumher May 8, 2023
f65f179
Figured out how to handle conflicts with the service messages. we sho…
ABaumher May 8, 2023
e4cf9bd
Finally found the version of protoc the old version was using. we can…
ABaumher May 9, 2023
a44be78
Updates throughout the code base. Preparing for full auth workflow an…
ABaumher May 10, 2023
a135724
Full integration of all parts of new auth flow implemented. Bugfixing…
ABaumher May 10, 2023
d9641f3
Bugs Fixed. Now logs in, but no other messages are sent. needs a Clie…
ABaumher May 10, 2023
0d50163
Experimental branch; i don't want to break something on the main fix.…
ABaumher May 10, 2023
7922c28
Added a readme for alpha testers
ABaumher May 10, 2023
452d83a
Update README_ALPHA.md
ABaumher May 10, 2023
dc6adcd
Attempt to fix issue raised by HiddenAnomaly
ABaumher May 10, 2023
d008b6c
preparing to call old client login method. preparing to remove public…
ABaumher May 11, 2023
825de45
Merge branch 'remove_public_profiles_backend' into AuthFix
ABaumher May 11, 2023
5869ef9
Finished removing public profiles. Started adding the token login cal…
ABaumher May 11, 2023
81e3a66
Fixed a few issues created by removing public backend
ABaumher May 11, 2023
f506150
Getting persistent login to work. Fixed a few errors.
ABaumher May 11, 2023
b8f9a0e
Removed logger info for packet information. This massively bloated th…
ABaumher May 11, 2023
0bcaf03
fix mobile confirm flow. not pretty but should work
May 11, 2023
8946473
Enable job processing - achievements, collections, game times
slo May 11, 2023
6f1aa9e
Merge pull request #1 from don-de-marco/AuthFix
ABaumher May 12, 2023
398c39d
bugfix. trying to stay logged in. failing. Currently, the stay logged…
ABaumher May 12, 2023
ad838f2
disabled cache login. Wrote comments explaining it
ABaumher May 12, 2023
e45d0e5
Temporary "fix" that removes the job_list so the code will work again.
ABaumher May 12, 2023
a656d12
Persistent login now works.
ABaumher May 15, 2023
167aa0f
Remove guard data requirements, as they were breaking mobile login
ABaumher May 15, 2023
fe25334
(try to) fix the conflicting protobuf files situation
May 13, 2023
33908dc
fix proto2 syntax statement
May 13, 2023
46c3370
Bugfix to properly recover when refresh token expires or is revoked.
ABaumher May 15, 2023
921bd72
Update README_ALPHA.md
ABaumher May 15, 2023
6869909
Update README_ALPHA.md
ABaumher May 15, 2023
7f01fc0
Update README_ALPHA.md
ABaumher May 15, 2023
d75bf9c
Update README_ALPHA.md
ABaumher May 15, 2023
4647e5f
Update README_ALPHA.md
ABaumher May 15, 2023
5805697
Update README.md
ABaumher May 15, 2023
8521a9b
Update protobuf_steammessages.txt
ABaumher May 15, 2023
86a709e
Merge pull request #1 from don-de-marco/abaumher-rebase
ABaumher May 15, 2023
6aa370d
Update README.md
ABaumher May 16, 2023
9873e50
Update README.md
ABaumher May 16, 2023
e0a78a1
Update README.md
ABaumher May 16, 2023
374dbd2
added install.txt so readme works properly
ABaumher May 16, 2023
e0a00a5
Update the install so it works properly. Merge changes that i didn't …
ABaumher May 16, 2023
04ff339
Fix the readme and install.txt so they now work
ABaumher May 16, 2023
7b23678
Actually fixed it this time. Requires galaxy plugin in install
ABaumher May 16, 2023
3b7c90e
Added beautiful soup to app requirements so it does not crash. fixed …
ABaumher May 16, 2023
9435073
revert app.txt change. remove user_profile, which caused the conflict…
ABaumher May 16, 2023
e511960
Bugfix so mobile code works correctly
ABaumher May 17, 2023
3f242fe
updated translate error to log the error received so we can more easi…
ABaumher May 17, 2023
8cfb1c4
bugfix for mobile confirm. If you hit continue before confirming, it …
ABaumher May 17, 2023
bc8af72
Reverted UI so it's user and password. cleaned up the css and html so…
ABaumher May 18, 2023
6d5e8e3
fixes multiple bugs: a residual debug that caused errors on a failed …
ABaumher May 18, 2023
4247b66
missed a pair of errors related to removing user name from pages.
ABaumher May 18, 2023
cb6f315
Mobile confirm bugfix, html now displays errors properly.
ABaumher May 18, 2023
050f9e1
Attempting to refactor all the code to work with mobile confirm. I st…
ABaumher May 18, 2023
45d450b
fallback on mobile confirm should now work.
ABaumher May 18, 2023
4b3f3ff
Bugfixes (again). Email code works again.
ABaumher May 18, 2023
1ede3a7
Tracked down a bug where the client would silently crash if you revok…
ABaumher May 19, 2023
276cabe
bugfix, priority list was sorting ascending, wanted descending.
ABaumher May 19, 2023
37762fd
Multiple bugfixes. Mobile confirm should finally work (though, probab…
ABaumher May 20, 2023
50ceaab
Bugfix. Wrapping recv in a task was done improperly. it's now fixed. …
ABaumher May 20, 2023
c8b8a7b
Updated the ui for mobile confirm for clarity. link now uses the prop…
ABaumher May 20, 2023
bb47e90
Experiemental Resend Code implementation. Two Factor expire now kicks…
ABaumher May 21, 2023
9e226de
Revert "Updated the ui for mobile confirm for clarity. link now uses …
ABaumher May 21, 2023
e2d6f6c
Revert "Experiemental Resend Code implementation. Two Factor expire n…
ABaumher May 21, 2023
23423d9
Reverts all the changes made to try to fix the resend issue. We now j…
ABaumher May 21, 2023
b68aff8
Merge pull request #4 from ABaumher/revert_pls
ABaumher May 21, 2023
cd5133a
hopefully fixed error message for login page after a timeout
ABaumher May 21, 2023
05a1615
Updated index with a message explaining what happens when email times…
ABaumher May 21, 2023
a137cd5
some fixes to readme, move pip req to reqs file, fix start of pytest
MisterZeus May 22, 2023
30369f8
Merge pull request #5 from ABaumher/mobile_confirm_refactor
ABaumher May 22, 2023
236ab56
Update README.md
ABaumher May 22, 2023
f93ea59
Update README.md
ABaumher May 22, 2023
9c700b7
Merge branch 'master' into master
MisterZeus May 22, 2023
489230c
check whether users have py installed
MisterZeus May 22, 2023
3aa2cfa
Merge branch 'master' of https://github.com/MisterZeus/galaxy-integra…
MisterZeus May 22, 2023
a51a0fc
remove exeprobe, make if simpler
MisterZeus May 22, 2023
23ef0c0
readme tweaks
MisterZeus May 22, 2023
3a03a84
Merge pull request #3 from MisterZeus/master
ABaumher May 23, 2023
eb8879b
Update gitignore to ignore zip files, so it excudes the release. reim…
ABaumher May 23, 2023
432e77c
Temporary fix for achievements sync. Limit simultaneous jobs.
wwMRd May 25, 2023
3da5c06
Merge pull request #8 from wwMRd/achievements_temp_fix
ABaumher May 26, 2023
5231719
Added .DStore to ignore list
bgebhardt May 29, 2023
e3bb216
Revert "Added .DStore to ignore list"
bgebhardt May 29, 2023
6a253d0
Added mac-related .dot files
bgebhardt May 29, 2023
9ab4a60
updated required pip-tools
bgebhardt May 29, 2023
dbd6f45
Updated mac build instructions
bgebhardt May 29, 2023
33d791d
Added instructions to setup protobuf compiling on Mac
bgebhardt May 29, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Attempting to refactor all the code to work with mobile confirm. I st…
…ill need to update the website, but for now this should fix the bugs
  • Loading branch information
ABaumher committed May 18, 2023
commit 050f9e1ae9e7eeea4088794643261925bdb0b530
3 changes: 0 additions & 3 deletions galaxy-integration-steam.pyproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
<Content Include="current_version.json" />
<Content Include="galaxy-integration-steam.pyproj" />
<Content Include="LICENSE" />
<Content Include="protobuf_files\merged\resolved_service_messages.proto" />
<Content Include="protobuf_files\protobuf_steammessages.txt" />
<Content Include="protobuf_files\protobuf_webui.txt" />
<Content Include="protobuf_files\proto\encrypted_app_ticket.proto" />
Expand Down Expand Up @@ -158,8 +157,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="protobuf_files\" />
<Folder Include="protobuf_files\merged\" />
<Folder Include="protobuf_files\conflicts\" />
<Folder Include="protobuf_files\proto\" />
<Folder Include="requirements\" />
<Folder Include="src" />
Expand Down
140 changes: 37 additions & 103 deletions src/backend_steam_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
import logging
import ssl
from contextlib import suppress
from typing import Callable, List, Any, Dict, Union
from typing import Callable, List, Any, Dict, Union, Coroutine
from urllib import parse
from pprint import pformat

from asyncio import Task

from galaxy.api.errors import (
AuthenticationRequired,
Expand Down Expand Up @@ -51,7 +52,7 @@
)

from steam_network.utils import next_step_response_simple
from steam_network.enums import UserActionRequired, AuthCall, DisplayUriHelper, TwoFactorMethod
from steam_network.enums import UserActionRequired, AuthCall, DisplayUriHelper, TwoFactorMethod, to_url_string

logger = logging.getLogger(__name__)

Expand All @@ -73,46 +74,33 @@ def avatar_url_from_avatar_hash(a_hash: str):


class SteamNetworkBackend(BackendInterface):
#def __init__(
# self,
# *,
# http_client: HttpClient,
# ssl_context: ssl.SSLContext,
# persistent_storage_state: PersistentCacheState,
# persistent_cache: Dict[str, Any],
# update_user_presence: Callable[[UserPresence], None],
# store_credentials: Callable[[Dict[str, Any]], None],
# add_game: Callable[[Game], None],
#) -> None:
def __init__(self, http_client: HttpClient, ssl_context: ssl.SSLContext,
persistent_storage_state: PersistentCacheState, persistent_cache: Dict[str, Any], update_user_presence: Callable[[UserPresence], None],
store_credentials: Callable[[Dict[str, Any]], None], add_game: Callable[[Game], None]):

self._add_game = add_game
self._persistent_cache = persistent_cache
self._persistent_storage_state = persistent_storage_state
self._add_game : Callable[[Game], None] = add_game
self._persistent_cache : Dict[str, Any] = persistent_cache
self._persistent_storage_state : PersistentCacheState = persistent_storage_state

self._store_credentials = store_credentials
self._authentication_cache = AuthenticationCache()
self._user_info_cache = UserInfoCache()
self._store_credentials : Callable[[Dict[str, Any]], None] = store_credentials
self._authentication_cache : AuthenticationCache = AuthenticationCache()
self._user_info_cache : UserInfoCache = UserInfoCache()

self._games_cache = GamesCache()
self._translations_cache = dict()
self._stats_cache = StatsCache()
self._times_cache = TimesCache()
self._friends_cache = FriendsCache()
self._games_cache : GamesCache = GamesCache()
self._translations_cache : Dict[int, str] = dict()
self._stats_cache :StatsCache = StatsCache()
self._times_cache : TimesCache = TimesCache()
self._friends_cache : FriendsCache = FriendsCache()

async def user_presence_update_handler(user_id: str, proto_user_info: ProtoUserInfo):
update_user_presence(
user_id,
await presence_from_user_info(proto_user_info, self._translations_cache),
)

self._friends_cache.updated_handler = user_presence_update_handler
self._friends_cache.updated_handler : Callable[[str, ProtoUserInfo], Coroutine[Any, Any, None]] = user_presence_update_handler

local_machine_cache = LocalMachineCache(
self._persistent_cache, self._persistent_storage_state
)
local_machine_cache : LocalMachineCache = LocalMachineCache(self._persistent_cache, self._persistent_storage_state)

steam_http_client = SteamHttpClient(http_client)
self._websocket_client = WebSocketClient(
Expand All @@ -128,9 +116,8 @@ async def user_presence_update_handler(user_id: str, proto_user_info: ProtoUserI
local_machine_cache,
)

self._update_owned_games_task = asyncio.create_task(asyncio.sleep(0))
self._owned_games_parsed = None
self._auth_data = None
self._update_owned_games_task : Task[None] = asyncio.create_task(asyncio.sleep(0))
self._owned_games_parsed : bool = False

self._load_persistent_cache()

Expand Down Expand Up @@ -199,9 +186,9 @@ async def pass_login_credentials(self, step, credentials, cookies):
if (DisplayUriHelper.LOGIN.EndUri() in end_uri):
return await self._handle_login_finished(credentials)
elif (DisplayUriHelper.TWO_FACTOR_MAIL.EndUri() in end_uri):
return await self._handle_steam_guard(credentials, DisplayUriHelper.TWO_FACTOR_MAIL)
return await self._handle_steam_guard(credentials, TwoFactorMethod.EmailCode, DisplayUriHelper.TWO_FACTOR_MAIL)
elif (DisplayUriHelper.TWO_FACTOR_MOBILE.EndUri() in end_uri):
return await self._handle_steam_guard(credentials, DisplayUriHelper.TWO_FACTOR_MOBILE)
return await self._handle_steam_guard(credentials, TwoFactorMethod.PhoneCode, DisplayUriHelper.TWO_FACTOR_MOBILE)
elif (DisplayUriHelper.TWO_FACTOR_CONFIRM.EndUri() in end_uri):
return await self._handle_steam_guard_check(DisplayUriHelper.TWO_FACTOR_MOBILE) #the fallback should be chosen based on the allowed_confirmations and not be hard-coded here
else:
Expand All @@ -221,28 +208,37 @@ async def _handle_login_finished(self, credentials) -> Union[NextStep, Authentic
#we still don't have the 2FA Confirmation. that's actually required for NoAction, but instead of waiting for us to input 2FA, it immediately returns what we need.
return await self._handle_steam_guard_none()
elif (result == UserActionRequired.TwoFactorRequired):
method = self._authentication_cache.two_factor_method
allowed_methods = self._authentication_cache.two_factor_allowed_methods
method, msg = allowed_methods[0]
if (method == TwoFactorMethod.Nothing):
result = await self._handle_steam_guard_none()
elif (method == TwoFactorMethod.PhoneCode):
return next_step_response_simple(DisplayUriHelper.TWO_FACTOR_MOBILE)
elif (method == TwoFactorMethod.EmailCode):
return next_step_response_simple(DisplayUriHelper.TWO_FACTOR_MAIL)
elif (method == TwoFactorMethod.PhoneConfirm):
return next_step_response_simple(DisplayUriHelper.TWO_FACTOR_CONFIRM)
#determine if we have a fallback.
fallback = TwoFactorMethod.Unknown #default to no.

if len(allowed_methods) > 1:
fallback = allowed_methods[1]

fallbackStr = to_url_string(fallback) #convert it to a string we can pass to the url

return next_step_response_simple(DisplayUriHelper.TWO_FACTOR_CONFIRM, False, fallbackMethod=fallbackStr, message=msg)
else:
raise UnknownBackendResponse()
else:
return next_step_response_simple(DisplayUriHelper.LOGIN, True)
#result here should be password, or unathorized.

async def _handle_steam_guard(self, credentials, fallback: DisplayUriHelper) -> Union[NextStep, Authentication]:
async def _handle_steam_guard(self, credentials, method: TwoFactorMethod, fallback: DisplayUriHelper) -> Union[NextStep, Authentication]:
parsed_url = parse.urlsplit(credentials["end_uri"])
params = parse.parse_qs(parsed_url.query)
if ("code" not in params):
return next_step_response_simple(fallback, True)
code = params["code"][0]
await self._websocket_client.communication_queues["websocket"].put({'mode': AuthCall.UPDATE_TWO_FACTOR, 'two-factor-code' : code })
await self._websocket_client.communication_queues["websocket"].put({'mode': AuthCall.UPDATE_TWO_FACTOR, 'two-factor-code' : code, 'two-factor-method' : method })
result = await self._get_websocket_auth_step()
if (result == UserActionRequired.NoActionConfirmLogin):
return await self._handle_steam_guard_check(fallback)
Expand All @@ -268,7 +264,7 @@ async def _handle_steam_guard_check(self, fallback: DisplayUriHelper) -> Union[N
elif (result == UserActionRequired.NoActionConfirmToken):
return await self._finish_auth_process()
#returned if we somehow got here but poll did not succeed. If we get here, the code should have been successfully input so this should never happen.
elif(result == UserActionRequired.NoActionConfirmLogin):
elif(result == UserActionRequired.NoActionConfirmLogin or result == UserActionRequired.TwoFactorRequired):
logger.info("Mobile Confirm did not complete. This is likely due to user error, but if not, this is something worth checking.")
return next_step_response_simple(fallback, True)
elif (result == UserActionRequired.TwoFactorExpired):
Expand All @@ -278,15 +274,16 @@ async def _handle_steam_guard_check(self, fallback: DisplayUriHelper) -> Union[N

#in the case of confirm, this needs to be called directly, because the user clicks a button saying "i confirmed it on steam's end"
#but, to handle edge cases (expired, they lied), we need to potentially display a page again.
async def _handle_2FA_PollOnce(self) -> UserActionRequired:
async def _handle_2FA_PollOnce(self, is_confirm : bool = False) -> UserActionRequired:
""" Poll the steam authentication to see if we are logged in yet, and return whatever action is required.

If the poll succeeds, but we aren't logged in yet (waiting on a code or mobile confirm), it returns UserActionRequired.NoActionConfirmLogin
If the poll succeeds and we are logged in, it returns UserActionRequired.NoActionConfirmToken
If the poll fails with the Result "Expired", returns UserActionRequired.TwoFactorExpired
If the poll otherwise fails, it return UserActionRequired.InvalidAuthData
"""
await self._websocket_client.communication_queues["websocket"].put({'mode': AuthCall.POLL_TWO_FACTOR})
await self._websocket_client.communication_queues["websocket"].put({'mode': AuthCall.POLL_TWO_FACTOR, 'is-confirm' : is_confirm})

#can return NoActionConfirmToken, NoActionConfirmLogin (poll succeeded, but we haven't logged in ye)
return await self._get_websocket_auth_step()

Expand All @@ -307,69 +304,6 @@ async def _finish_auth_process(self) -> Authentication:
logger.warning("User Info Cache not initialized after normal login. Unexpected")
raise UnknownBackendResponse()

#async def _handle_login_finished(self, credentials):
# parsed_url = parse.urlsplit(credentials["end_uri"])

# params = parse.parse_qs(parsed_url.query)
# if "username" not in params or "password" not in params:
# return next_step_response(StartUri.LOGIN_FAILED, EndUri.LOGIN_FINISHED)

# username = params["username"][0]
# password = params["password"][0]
# self._user_info_cache.account_username = username
# self._auth_data = [username, password]
# await self._websocket_client.communication_queues["websocket"].put({"password": password})
# result = await self._get_websocket_auth_step()
# if result == UserActionRequired.NoActionRequired:
# self._auth_data = None
# self._store_credentials(self._user_info_cache.to_dict())
# return await self._check_public_profile()
# if result == UserActionRequired.EmailTwoFactorInputRequired:
# return next_step_response(StartUri.TWO_FACTOR_MAIL, EndUri.TWO_FACTOR_MAIL_FINISHED)
# if result == UserActionRequired.PhoneTwoFactorInputRequired:
# return next_step_response(StartUri.TWO_FACTOR_MOBILE, EndUri.TWO_FACTOR_MOBILE_FINISHED)
# else:
# return next_step_response(StartUri.LOGIN_FAILED, EndUri.LOGIN_FINISHED)

#async def _handle_two_step(self, params, fail, finish):
# if "code" not in params:
# return next_step_response(fail, finish)

# two_factor = params["code"][0]
# await self._websocket_client.communication_queues["websocket"].put(
# {"password": self._auth_data[1], "two_factor": two_factor}
# )
# result = await self._get_websocket_auth_step()
# logger.info(f"2fa result {result}")
# if result != UserActionRequired.NoActionRequired:
# return next_step_response(fail, finish)
# else:
# self._auth_data = None
# self._store_credentials(self._user_info_cache.to_dict())
# return await self._check_public_profile()

#async def _handle_two_step_mobile_finished(self, credentials):
# parsed_url = parse.urlsplit(credentials["end_uri"])
# params = parse.parse_qs(parsed_url.query)
# return await self._handle_two_step(
# params, StartUri.TWO_FACTOR_MOBILE_FAILED, EndUri.TWO_FACTOR_MOBILE_FINISHED
# )

#async def _handle_two_step_email_finished(self, credentials):
# parsed_url = parse.urlsplit(credentials["end_uri"])
# params = parse.parse_qs(parsed_url.query)

# if "resend" in params:
# await self._websocket_client.communication_queues["websocket"].put(
# {"password": self._auth_data[1]}
# )
# await self._get_websocket_auth_step() # Clear the queue
# return next_step_response(StartUri.TWO_FACTOR_MAIL, EndUri.TWO_FACTOR_MAIL_FINISHED)

# return await self._handle_two_step(
# params, StartUri.TWO_FACTOR_MAIL_FAILED, EndUri.TWO_FACTOR_MAIL_FINISHED
# )

async def authenticate(self, stored_credentials=None):
self._steam_run_task = asyncio.create_task(self._websocket_client.run())
if stored_credentials is None:
Expand Down
44 changes: 29 additions & 15 deletions src/steam_network/authentication_cache.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional
from typing import Optional, List, Tuple, Dict
from .enums import TwoFactorMethod


Expand All @@ -8,17 +8,13 @@ class AuthenticationCache:
This 'cache' is not designed to persist in any manner. it's simply a data-storage device.
"""
def __init__(self):
self._two_factor_method : Optional[TwoFactorMethod] = None
#pairs of Two Factor methods and their any related message if provided. This is not a dict because we prioritize different methods and therefore a sorted list of tuples makes more sense than a dict.
self._two_factor_allowed_methods : Optional[List[Tuple[TwoFactorMethod, str]]]
self._error_message: Optional[str] = None #used to display specific errors. Things like "passcode expired" or "password incorrect" or "username does not exist"
self._status_message: Optional[str] = None #used to display status-related information to the user. this may be something like: "confirmation email sent to 'user@domain.com'"

@property
def two_factor_method(self):
return self._two_factor_method

@two_factor_method.setter
def two_factor_method(self, val):
self._two_factor_method = val
def two_factor_allowed_methods(self):
return self._two_factor_allowed_methods

@property
def error_message(self):
Expand All @@ -28,10 +24,28 @@ def error_message(self):
def error_message(self, val):
self._error_message = val

@property
def status_message(self):
return self._status_message
#provides a priority for our list based on two factor method
def _auth_priority(methodPair : Tuple[TwoFactorMethod, str]) -> int:
method, _ = methodPair
if (method == TwoFactorMethod.Unknown):
return 0
elif (method == TwoFactorMethod.Nothing):
return 1
elif (method == TwoFactorMethod.EmailCode):
return 2
elif (method == TwoFactorMethod.PhoneCode):
return 3
elif (method == TwoFactorMethod.PhoneConfirm):
return 4
else:
return -1

def update_authentication_cache(self, two_factor_dict: Dict[TwoFactorMethod, str], error_message: str):
self._error_message = error_message
self._two_factor_allowed_methods = []
for (key, value) in two_factor_dict.items():
self._two_factor_allowed_methods.append((key, value))

self._two_factor_allowed_methods.sort(key=self._auth_priority)


@status_message.setter
def status_message(self, val):
self._status_message = val
12 changes: 12 additions & 0 deletions src/steam_network/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,18 @@ def to_helpful_string(method:TwoFactorMethod) -> str:
else: #if TwoFactorMethod.InvalidAuthData or an invalid number
return "<unknown>"

def to_url_string(method:TwoFactorMethod) -> str:
if (method == TwoFactorMethod.Nothing):
return "none"
elif (method == TwoFactorMethod.EmailCode):
return "email code"
elif (method == TwoFactorMethod.PhoneCode):
return "phone code"
elif (method == TwoFactorMethod.PhoneConfirm):
return "phone confirmation"
else: #if TwoFactorMethod.InvalidAuthData or an invalid number
return "unknown"

def to_UserAction(method: TwoFactorMethod) -> UserActionRequired:
if (method == TwoFactorMethod.Nothing):
return UserActionRequired.NoActionConfirmLogin
Expand Down
2 changes: 1 addition & 1 deletion src/steam_network/presence.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def _translate_string(game_id, string, translations_cache):
return token.value


async def _translate_presence(user_info, status, token_list):
async def _translate_presence(user_info, status : str , token_list):
replaced = True
max_depth = 10
current_depth = 0
Expand Down
Loading