mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-04 02:34:13 +02:00
steam login
This commit is contained in:
parent
6e456a6596
commit
fc5cd1d24f
12 changed files with 926 additions and 70 deletions
|
|
@ -2,3 +2,4 @@ pub mod chat;
|
|||
pub mod demo;
|
||||
pub mod player;
|
||||
pub mod steam_id;
|
||||
pub mod user;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
use maud::Render;
|
||||
use serde::{Serialize, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::database::HasValueRef;
|
||||
use sqlx::error::BoxDynError;
|
||||
use sqlx::{Database, Decode, Type};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Write;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::fmt::{Display, Write};
|
||||
use steamid_ng::SteamID;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum SteamId {
|
||||
Id(u64),
|
||||
Raw(Cow<'static, str>),
|
||||
|
|
@ -51,25 +51,20 @@ impl SteamId {
|
|||
let id = SteamID::from_steam3(s)?;
|
||||
Ok(SteamId::Id(id.into()))
|
||||
}
|
||||
|
||||
pub fn steamid64(&self) -> String {
|
||||
match self {
|
||||
SteamId::Id(id) => format!("{}", id),
|
||||
SteamId::Raw(raw) => raw.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for SteamId {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
SteamId::Id(id) => SteamID::from(*id).fmt(f),
|
||||
SteamId::Raw(raw) => raw.fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for SteamId {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
SteamId::Id(id) => serializer.collect_str(&SteamID::from(*id).steam3()),
|
||||
SteamId::Raw(raw) => serializer.collect_str(raw),
|
||||
SteamId::Id(id) => Debug::fmt(&SteamID::from(*id), f),
|
||||
SteamId::Raw(raw) => Debug::fmt(raw, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -107,12 +102,18 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for SteamId {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
SteamId::Id(id) => write!(f, "{id}"),
|
||||
SteamId::Raw(raw) => write!(f, "{raw}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for SteamId {
|
||||
fn render_to(&self, buffer: &mut String) {
|
||||
match self {
|
||||
SteamId::Id(id) => write!(buffer, "{id}").unwrap(),
|
||||
SteamId::Raw(raw) => buffer.push_str(raw),
|
||||
}
|
||||
write!(buffer, "{self}").unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
80
src/data/user.rs
Normal file
80
src/data/user.rs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
use crate::data::steam_id::SteamId;
|
||||
use crate::Result;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::Rng;
|
||||
use reqwest::get;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{query, Executor, Postgres};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
pub steam_id: SteamId,
|
||||
pub name: String,
|
||||
pub token: String,
|
||||
}
|
||||
|
||||
impl User {
|
||||
pub async fn get(
|
||||
connection: impl Executor<'_, Database = Postgres> + Copy,
|
||||
steam_id: SteamId,
|
||||
) -> Result<Self> {
|
||||
let user = query!(
|
||||
r#"SELECT
|
||||
token as "token!", name as "name!"
|
||||
FROM users_named WHERE steamid = $1"#,
|
||||
steam_id.steamid64()
|
||||
)
|
||||
.fetch_optional(connection)
|
||||
.await?;
|
||||
|
||||
if let Some(user) = user {
|
||||
Ok(User {
|
||||
steam_id,
|
||||
token: user.token,
|
||||
name: user.name,
|
||||
})
|
||||
} else {
|
||||
let profile = Self::fetch(&steam_id).await?;
|
||||
let token: String = rand::thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(64)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
|
||||
query!(
|
||||
r#"INSERT INTO users(steamid, name, avatar, token)
|
||||
VALUES($1, $2, $3, $4)"#,
|
||||
steam_id.steamid64(),
|
||||
profile.name,
|
||||
profile.avatar,
|
||||
token
|
||||
)
|
||||
.execute(connection)
|
||||
.await?;
|
||||
Ok(User {
|
||||
steam_id,
|
||||
token,
|
||||
name: profile.name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch(steam_id: &SteamId) -> Result<Profile> {
|
||||
let response = get(format!(
|
||||
"https://steamcommunity.com/profiles/{steam_id}?xml=1"
|
||||
))
|
||||
.await?
|
||||
.error_for_status()?
|
||||
.text()
|
||||
.await?;
|
||||
Ok(quick_xml::de::from_str(&response)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Profile {
|
||||
#[serde(rename = "steamID")]
|
||||
name: String,
|
||||
#[serde(rename = "avatarMedium")]
|
||||
avatar: String,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue