add add_authenticator to steamapi module
This commit is contained in:
parent
e4d7ea4475
commit
2e4058cfca
3 changed files with 88 additions and 7 deletions
|
@ -1,5 +1,7 @@
|
|||
use crate::{steamapi::Session, SteamGuardAccount};
|
||||
use serde::Deserialize;
|
||||
use crate::{
|
||||
steamapi::{AddAuthenticatorResponse, Session},
|
||||
SteamGuardAccount,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt::Display;
|
||||
|
@ -55,11 +57,6 @@ fn generate_device_id() -> String {
|
|||
return format!("android:{}", uuid::Uuid::new_v4().to_string());
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct AddAuthenticatorResponse {
|
||||
pub response: SteamGuardAccount,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AccountLinkError {
|
||||
/// No phone number on the account
|
||||
|
|
|
@ -47,6 +47,7 @@ pub struct SteamGuardAccount {
|
|||
pub uri: String,
|
||||
pub fully_enrolled: bool,
|
||||
pub device_id: String,
|
||||
pub secret_1: String,
|
||||
#[serde(rename = "Session")]
|
||||
pub session: Option<steamapi::Session>,
|
||||
}
|
||||
|
@ -84,6 +85,7 @@ impl SteamGuardAccount {
|
|||
uri: String::from(""),
|
||||
fully_enrolled: false,
|
||||
device_id: String::from(""),
|
||||
secret_1: "".into(),
|
||||
session: Option::None,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,8 +12,11 @@ use std::iter::FromIterator;
|
|||
use std::str::FromStr;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::SteamGuardAccount;
|
||||
|
||||
lazy_static! {
|
||||
static ref STEAM_COOKIE_URL: Url = "https://steamcommunity.com".parse::<Url>().unwrap();
|
||||
static ref STEAM_API_BASE: String = "https://api.steampowered.com".into();
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
|
@ -340,6 +343,37 @@ impl SteamApiClient {
|
|||
pub fn add_phone_number(&self, phone_number: String) -> anyhow::Result<bool> {
|
||||
return self.phoneajax("add_phone_number", phone_number.as_str());
|
||||
}
|
||||
|
||||
/// Starts the authenticator linking process.
|
||||
/// This doesn't check any prereqisites to ensure the request will pass validation on Steam's side (eg. sms/email confirmations).
|
||||
/// A valid `Session` is required for this request. Cookies are not needed for this request, but they are set anyway.
|
||||
///
|
||||
/// Host: api.steampowered.com
|
||||
/// Endpoint: POST /ITwoFactorService/AddAuthenticator/v0001
|
||||
pub fn add_authenticator(&self, device_id: String) -> anyhow::Result<AddAuthenticatorResponse> {
|
||||
ensure!(matches!(self.session, Some(_)));
|
||||
let params = hashmap! {
|
||||
"access_token" => self.session.as_ref().unwrap().token.clone(),
|
||||
"steamid" => self.session.as_ref().unwrap().steam_id.to_string(),
|
||||
"authenticator_type" => "1".into(),
|
||||
"device_identifier" => device_id,
|
||||
"sms_phone_id" => "1".into(),
|
||||
};
|
||||
|
||||
let text = self
|
||||
.post(format!(
|
||||
"{}/ITwoFactorService/AddAuthenticator/v0001",
|
||||
STEAM_API_BASE.to_string()
|
||||
))
|
||||
.form(¶ms)
|
||||
.send()?
|
||||
.text()?;
|
||||
trace!("raw login response: {}", text);
|
||||
|
||||
let resp: AddAuthenticatorResponse = serde_json::from_str(text.as_str())?;
|
||||
|
||||
Ok(resp)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -380,3 +414,51 @@ fn test_login_response_parse() {
|
|||
);
|
||||
assert_eq!(oauth.webcookie, "6298070A226E5DAD49938D78BCF36F7A7118FDD5");
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct AddAuthenticatorResponse {
|
||||
pub response: AddAuthenticatorResponseInner,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct AddAuthenticatorResponseInner {
|
||||
/// Shared secret between server and authenticator
|
||||
pub shared_secret: String,
|
||||
/// Authenticator serial number (unique per token)
|
||||
pub serial_number: String,
|
||||
/// code used to revoke authenticator
|
||||
pub revocation_code: String,
|
||||
/// URI for QR code generation
|
||||
pub uri: String,
|
||||
/// Current server time
|
||||
pub server_time: u64,
|
||||
/// Account name to display on token client
|
||||
pub account_name: String,
|
||||
/// Token GID assigned by server
|
||||
pub token_gid: String,
|
||||
/// Secret used for identity attestation (e.g., for eventing)
|
||||
pub identity_secret: String,
|
||||
/// Spare shared secret
|
||||
pub secret_1: String,
|
||||
/// Result code
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
impl AddAuthenticatorResponse {
|
||||
pub fn to_steam_guard_account(&self) -> SteamGuardAccount {
|
||||
SteamGuardAccount {
|
||||
shared_secret: self.response.shared_secret,
|
||||
serial_number: self.response.serial_number,
|
||||
revocation_code: self.response.revocation_code,
|
||||
uri: self.response.uri,
|
||||
server_time: self.response.server_time,
|
||||
account_name: self.response.account_name,
|
||||
token_gid: self.response.token_gid,
|
||||
identity_secret: self.response.identity_secret,
|
||||
secret_1: self.response.secret_1,
|
||||
fully_enrolled: false,
|
||||
device_id: "".into(),
|
||||
session: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue