steamguard-cli/steamguard/src/steamapi.rs
2023-09-28 22:06:51 +00:00

371 lines
10 KiB
Rust

pub mod authentication;
pub mod phone;
pub mod twofactor;
use crate::transport::Transport;
use crate::{protobufs::service_twofactor::CTwoFactor_Time_Response, token::Jwt};
use serde::Deserialize;
pub use self::authentication::AuthenticationClient;
pub use self::phone::PhoneClient;
pub use self::twofactor::TwoFactorClient;
lazy_static! {
static ref STEAM_API_BASE: String = "https://api.steampowered.com".into();
}
/// Queries Steam for the current time. A convenience function around TwoFactorClient.
///
/// Endpoint: `/ITwoFactorService/QueryTime/v0001`
pub fn get_server_time<T: Transport>(client: T) -> anyhow::Result<CTwoFactor_Time_Response> {
let client = TwoFactorClient::new(client);
let resp = client.query_time()?;
if resp.result != EResult::OK {
return Err(anyhow::anyhow!("QueryTime failed: {:?}", resp));
}
Ok(resp.into_response_data())
}
pub trait BuildableRequest {
fn method() -> reqwest::Method;
fn requires_access_token() -> bool;
}
#[derive(Debug, Clone)]
pub struct ApiRequest<'a, T> {
api_interface: String,
api_method: String,
api_version: u32,
access_token: Option<&'a Jwt>,
request_data: T,
}
impl<'a, T: BuildableRequest> ApiRequest<'a, T> {
pub fn new(
api_interface: impl Into<String>,
api_method: impl Into<String>,
api_version: u32,
request_data: T,
) -> Self {
Self {
api_interface: api_interface.into(),
api_method: api_method.into(),
api_version,
access_token: None,
request_data,
}
}
pub fn with_access_token(mut self, access_token: &'a Jwt) -> Self {
self.access_token = Some(access_token);
self
}
pub fn access_token(&self) -> Option<&Jwt> {
self.access_token
}
pub(crate) fn build_url(&self) -> String {
format!(
"{}/{}/{}/v{}",
*STEAM_API_BASE, self.api_interface, self.api_method, self.api_version
)
}
pub(crate) fn request_data(&self) -> &T {
&self.request_data
}
}
#[derive(Debug, Clone)]
pub struct ApiResponse<T> {
pub(crate) result: EResult,
pub(crate) error_message: Option<String>,
pub(crate) response_data: T,
}
impl<T> ApiResponse<T> {
pub fn result(&self) -> EResult {
self.result
}
pub fn error_message(&self) -> Option<&String> {
self.error_message.as_ref()
}
pub fn response_data(&self) -> &T {
&self.response_data
}
pub fn into_response_data(self) -> T {
self.response_data
}
}
// TODO: generate from protobufs
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
pub enum EResult {
Invalid = 0,
OK = 1,
Fail = 2,
NoConnection = 3,
InvalidPassword = 5,
LoggedInElsewhere = 6,
InvalidProtocolVer = 7,
InvalidParam = 8,
FileNotFound = 9,
Busy = 10,
InvalidState = 11,
InvalidName = 12,
InvalidEmail = 13,
DuplicateName = 14,
AccessDenied = 15,
Timeout = 16,
Banned = 17,
AccountNotFound = 18,
InvalidSteamID = 19,
ServiceUnavailable = 20,
NotLoggedOn = 21,
Pending = 22,
EncryptionFailure = 23,
InsufficientPrivilege = 24,
LimitExceeded = 25,
Revoked = 26,
Expired = 27,
AlreadyRedeemed = 28,
DuplicateRequest = 29,
AlreadyOwned = 30,
IPNotFound = 31,
PersistFailed = 32,
LockingFailed = 33,
LogonSessionReplaced = 34,
ConnectFailed = 35,
HandshakeFailed = 36,
IOFailure = 37,
RemoteDisconnect = 38,
ShoppingCartNotFound = 39,
Blocked = 40,
Ignored = 41,
NoMatch = 42,
AccountDisabled = 43,
ServiceReadOnly = 44,
AccountNotFeatured = 45,
AdministratorOK = 46,
ContentVersion = 47,
TryAnotherCM = 48,
PasswordRequiredToKickSession = 49,
AlreadyLoggedInElsewhere = 50,
Suspended = 51,
Cancelled = 52,
DataCorruption = 53,
DiskFull = 54,
RemoteCallFailed = 55,
PasswordNotSetOrUnset = 56,
ExternalAccountUnlinked = 57,
PSNTicketInvalid = 58,
ExternalAccountAlreadyLinked = 59,
RemoteFileConflict = 60,
IllegalPassword = 61,
SameAsPreviousValue = 62,
AccountLogonDenied = 63,
CannotUseOldPassword = 64,
InvalidLoginAuthCode = 65,
AccountLogonDeniedNoMailSent = 66,
HardwareNotCapableOfIPT = 67,
IPTInitError = 68,
ParentalControlRestricted = 69,
FacebookQueryError = 70,
ExpiredLoginAuthCode = 71,
IPLoginRestrictionFailed = 72,
AccountLocked = 73,
AccountLogonDeniedVerifiedEmailRequired = 74,
NoMatchingURL = 75,
BadResponse = 76,
RequirePasswordReEntry = 77,
ValueOutOfRange = 78,
UnexpectedError = 79,
Disabled = 80,
InvalidCEGSubmission = 81,
RestrictedDevice = 82,
RegionLocked = 83,
RateLimitExceeded = 84,
AccountLoginDeniedNeedTwoFactor = 85,
ItemOrEntryHasBeenDeleted = 86,
AccountLoginDeniedThrottle = 87,
TwoFactorCodeMismatch = 88,
TwoFactorActivationCodeMismatch = 89,
AccountAssociatedToMultipleAccounts = 90,
NotModified = 91,
NoMobileDeviceAvailable = 92,
TimeNotSynced = 93,
SMSCodeFailed = 94,
AccountLimitExceeded = 95,
AccountActivityLimitExceeded = 96,
PhoneActivityLimitExceeded = 97,
RefundToWallet = 98,
EmailSendFailure = 99,
NotSettled = 100,
NeedCaptcha = 101,
GSLTDenied = 102,
GSOwnerDenied = 103,
InvalidItemType = 104,
IPBanned = 105,
GSLTExpired = 106,
InsufficientFunds = 107,
TooManyPending = 108,
NoSiteLicensesFound = 109,
WGNetworkSendExceeded = 110,
AccountNotFriends = 111,
LimitedUserAccount = 112,
CantRemoveItem = 113,
AccountDeleted = 114,
ExistingUserCancelledLicense = 115,
DeniedDueToCommunityCooldown = 116,
NoLauncherSpecified = 117,
MustAgreeToSSA = 118,
ClientNoLongerSupported = 119,
SteamRealmMismatch = 120,
InvalidSignature = 121,
ParseFailure = 122,
NoVerifiedPhone = 123,
InsufficientBattery = 124,
ChargerRequired = 125,
CachedCredentialInvalid = 126,
PhoneNumberIsVOIP = 127,
}
impl From<i32> for EResult {
fn from(value: i32) -> Self {
match value {
1 => EResult::OK,
2 => EResult::Fail,
3 => EResult::NoConnection,
5 => EResult::InvalidPassword,
6 => EResult::LoggedInElsewhere,
7 => EResult::InvalidProtocolVer,
8 => EResult::InvalidParam,
9 => EResult::FileNotFound,
10 => EResult::Busy,
11 => EResult::InvalidState,
12 => EResult::InvalidName,
13 => EResult::InvalidEmail,
14 => EResult::DuplicateName,
15 => EResult::AccessDenied,
16 => EResult::Timeout,
17 => EResult::Banned,
18 => EResult::AccountNotFound,
19 => EResult::InvalidSteamID,
20 => EResult::ServiceUnavailable,
21 => EResult::NotLoggedOn,
22 => EResult::Pending,
23 => EResult::EncryptionFailure,
24 => EResult::InsufficientPrivilege,
25 => EResult::LimitExceeded,
26 => EResult::Revoked,
27 => EResult::Expired,
28 => EResult::AlreadyRedeemed,
29 => EResult::DuplicateRequest,
30 => EResult::AlreadyOwned,
31 => EResult::IPNotFound,
32 => EResult::PersistFailed,
33 => EResult::LockingFailed,
34 => EResult::LogonSessionReplaced,
35 => EResult::ConnectFailed,
36 => EResult::HandshakeFailed,
37 => EResult::IOFailure,
38 => EResult::RemoteDisconnect,
39 => EResult::ShoppingCartNotFound,
40 => EResult::Blocked,
41 => EResult::Ignored,
42 => EResult::NoMatch,
43 => EResult::AccountDisabled,
44 => EResult::ServiceReadOnly,
45 => EResult::AccountNotFeatured,
46 => EResult::AdministratorOK,
47 => EResult::ContentVersion,
48 => EResult::TryAnotherCM,
49 => EResult::PasswordRequiredToKickSession,
50 => EResult::AlreadyLoggedInElsewhere,
51 => EResult::Suspended,
52 => EResult::Cancelled,
53 => EResult::DataCorruption,
54 => EResult::DiskFull,
55 => EResult::RemoteCallFailed,
56 => EResult::PasswordNotSetOrUnset,
57 => EResult::ExternalAccountUnlinked,
58 => EResult::PSNTicketInvalid,
59 => EResult::ExternalAccountAlreadyLinked,
60 => EResult::RemoteFileConflict,
61 => EResult::IllegalPassword,
62 => EResult::SameAsPreviousValue,
63 => EResult::AccountLogonDenied,
64 => EResult::CannotUseOldPassword,
65 => EResult::InvalidLoginAuthCode,
66 => EResult::AccountLogonDeniedNoMailSent,
67 => EResult::HardwareNotCapableOfIPT,
68 => EResult::IPTInitError,
69 => EResult::ParentalControlRestricted,
70 => EResult::FacebookQueryError,
71 => EResult::ExpiredLoginAuthCode,
72 => EResult::IPLoginRestrictionFailed,
73 => EResult::AccountLocked,
74 => EResult::AccountLogonDeniedVerifiedEmailRequired,
75 => EResult::NoMatchingURL,
76 => EResult::BadResponse,
77 => EResult::RequirePasswordReEntry,
78 => EResult::ValueOutOfRange,
79 => EResult::UnexpectedError,
80 => EResult::Disabled,
81 => EResult::InvalidCEGSubmission,
82 => EResult::RestrictedDevice,
83 => EResult::RegionLocked,
84 => EResult::RateLimitExceeded,
85 => EResult::AccountLoginDeniedNeedTwoFactor,
86 => EResult::ItemOrEntryHasBeenDeleted,
87 => EResult::AccountLoginDeniedThrottle,
88 => EResult::TwoFactorCodeMismatch,
89 => EResult::TwoFactorActivationCodeMismatch,
90 => EResult::AccountAssociatedToMultipleAccounts,
91 => EResult::NotModified,
92 => EResult::NoMobileDeviceAvailable,
93 => EResult::TimeNotSynced,
94 => EResult::SMSCodeFailed,
95 => EResult::AccountLimitExceeded,
96 => EResult::AccountActivityLimitExceeded,
97 => EResult::PhoneActivityLimitExceeded,
98 => EResult::RefundToWallet,
99 => EResult::EmailSendFailure,
100 => EResult::NotSettled,
101 => EResult::NeedCaptcha,
102 => EResult::GSLTDenied,
103 => EResult::GSOwnerDenied,
104 => EResult::InvalidItemType,
105 => EResult::IPBanned,
106 => EResult::GSLTExpired,
107 => EResult::InsufficientFunds,
108 => EResult::TooManyPending,
109 => EResult::NoSiteLicensesFound,
110 => EResult::WGNetworkSendExceeded,
111 => EResult::AccountNotFriends,
112 => EResult::LimitedUserAccount,
113 => EResult::CantRemoveItem,
114 => EResult::AccountDeleted,
115 => EResult::ExistingUserCancelledLicense,
116 => EResult::DeniedDueToCommunityCooldown,
117 => EResult::NoLauncherSpecified,
118 => EResult::MustAgreeToSSA,
119 => EResult::ClientNoLongerSupported,
120 => EResult::SteamRealmMismatch,
121 => EResult::InvalidSignature,
122 => EResult::ParseFailure,
123 => EResult::NoVerifiedPhone,
124 => EResult::InsufficientBattery,
125 => EResult::ChargerRequired,
126 => EResult::CachedCredentialInvalid,
127 => EResult::PhoneNumberIsVOIP,
_ => EResult::Invalid,
}
}
}