-
-
Save Alloyed/03b96626518fa280240643baaf6049cb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// itch api | |
#[derive(Serialize, Deserialize, Debug)] | |
#[serde(rename_all = "snake_case")] | |
struct ItchUser { | |
username: String, | |
display_name: String, | |
id: u32, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
#[serde(rename_all = "snake_case")] | |
enum ItchMeRaw { | |
User(ItchUser), | |
Errors(Vec<String>), | |
} | |
type ItchMe = Result<ItchUser, Vec<String>>; | |
impl From<ItchMeRaw> for ItchMe { | |
fn from(json: ItchMeRaw) -> ItchMe { | |
match json { | |
ItchMeRaw::Errors(messages) => Err(messages), | |
ItchMeRaw::User(user) => Ok(user), | |
} | |
} | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
#[serde(rename_all = "snake_case")] | |
struct ItchDownloadKey { | |
id: u32, | |
} | |
#[derive(Serialize, Deserialize, Debug)] | |
#[serde(rename_all = "snake_case")] | |
enum ItchDownloadKeysRaw { | |
DownloadKey(ItchDownloadKey), | |
Errors(Vec<String>), | |
} | |
type ItchDownloadKeys = Result<ItchDownloadKey, Vec<String>>; | |
impl From<ItchDownloadKeysRaw> for ItchDownloadKeys { | |
fn from(json: ItchDownloadKeysRaw) -> ItchDownloadKeys { | |
match json { | |
ItchDownloadKeysRaw::Errors(messages) => Err(messages), | |
ItchDownloadKeysRaw::DownloadKey(key) => Ok(key), | |
} | |
} | |
} | |
// end itch api | |
#[derive(PartialEq, Eq, Hash, Clone)] | |
pub enum AccountKey { | |
NoAuth(String), | |
Itch(u32), | |
} | |
pub enum Account { | |
NoAuth { | |
display_name: String, | |
}, | |
Itch { | |
display_name: String, | |
account_name: String, | |
user_id: u32, | |
}, | |
} | |
impl Account { | |
pub fn create_and_verify( | |
player: PlayerKey, | |
auth: &api::AuthData, | |
) -> Box<dyn Future<Item = Account, Error = api::AuthError>> { | |
match auth { | |
api::AuthData::NoAuth { display_name } => { | |
let auth_required = cfg::get_value(|c| c.auth.required); | |
if auth_required { | |
Box::new(future::err(api::AuthError::InvalidService)) | |
} else { | |
Box::new(future::ok(Account::NoAuth { | |
display_name: display_name.clone(), | |
})) | |
} | |
} | |
api::AuthData::Itch { auth_token } => { | |
let auth_future = { | |
let cli = HTTP_CLIENT.lock().unwrap(); | |
cli.get("https://itch.io/api/1/jwt/me") | |
.bearer_auth(auth_token) | |
.send() | |
.map_err(|e| { | |
warn!("querying itch.io failed: {}", e); | |
api::AuthError::ServiceFailed | |
}) | |
.and_then(|mut response| { | |
response.json::<ItchMe>().map_err(|e| { | |
warn!("itch.io returned not-serializable output: {}", e); | |
api::AuthError::InternalError | |
}) | |
}) | |
.and_then(move |me: ItchMe| { | |
me.map_err(|e| { | |
debug!("getting userid for player {:?} failed: {:?}", player, e); | |
api::AuthError::BadCredentials | |
}) | |
}) | |
}; | |
let (api_key, maybe_game_id) = | |
cfg::get_value(|c| (c.auth.itch_api_key.clone(), c.auth.itch_game_id)); | |
match maybe_game_id { | |
// No game id, having a valid auth is enough | |
None => Box::new(auth_future.map(|me| Account::Itch { | |
display_name: me.display_name, | |
account_name: me.username, | |
user_id: me.id, | |
})), | |
// Yes game id, fetch and check against the user's keys for this game | |
Some(game_id) => Box::new(auth_future.and_then(move |me| { | |
let itch_id = me.id; | |
let cli = HTTP_CLIENT.lock().unwrap(); | |
cli.get(&format!( | |
"https://itch.io/api/1/key/game/{}/download_keys", | |
game_id | |
)) | |
.bearer_auth(api_key) | |
.query(&[("user_id", me.id)]) | |
.send() | |
.map_err(|e| { | |
warn!("querying itch.io failed: {}", e); | |
api::AuthError::ServiceFailed | |
}) | |
.and_then(|mut response| { | |
response.json::<ItchDownloadKeys>().map_err(|e| { | |
warn!("itch returned not-serializable output: {}", e); | |
api::AuthError::InternalError | |
}) | |
}) | |
.and_then(move |keys: ItchDownloadKeys| { | |
keys.map_err(move |e| { | |
debug!( | |
"querying download keys for itch user {} failed: {:?}", | |
itch_id, e | |
); | |
api::AuthError::BadCredentials | |
}) | |
}) | |
.map(|_keys| Account::Itch { | |
display_name: me.display_name, | |
account_name: me.username, | |
user_id: me.id, | |
}) | |
})), | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment