1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
pub mod property_map;
pub use property_map::PropertyMap;
use std::fmt::{Debug, Formatter, Write};
use chrono::{DateTime, Utc};
use multimap::MultiMap;
use oauth2::RefreshToken;
use serde::{Deserialize, Deserializer, Serialize};
use serde::de::{Error, SeqAccess, Visitor};
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize)]
pub struct Property {
pub name: String,
pub value: String,
pub signature: Option<String>
}
#[derive(Debug, Serialize, Deserialize)]
pub struct PlayerProfile {
#[serde(with = "uuid::serde::simple")]
pub id: Uuid,
pub name: String,
#[serde(default, skip_serializing_if = "MultiMap::is_empty", with = "property_map")]
pub properties: MultiMap<String, Property>
}
#[derive(Serialize, Deserialize)]
pub(super) struct Token {
pub value: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub expire: Option<DateTime<Utc>>
}
struct RedactedValue;
impl Debug for RedactedValue {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("[redacted]")
}
}
impl Debug for Token {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Token")
.field("value", &RedactedValue)
.field("expire", &self.expire)
.finish()
}
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum SkinState {
Active,
Inactive
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum SkinVariant {
Classic,
Slim
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SkinInfo {
pub id: Uuid,
pub state: SkinState,
pub url: String,
pub texture_key: Option<String>,
pub variant: Option<SkinVariant>,
pub alias: Option<String>
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MinecraftPlayerInfo {
#[serde(with = "uuid::serde::simple")]
pub id: Uuid,
pub name: String,
#[serde(default)]
pub skins: Vec<SkinInfo>,
#[serde(default)]
pub capes: Vec<SkinInfo>,
#[serde(default)]
pub demo: bool,
#[serde(default)]
pub legacy: bool,
// todo: profile actions (idk the format)
}
#[derive(Debug, Serialize, Deserialize)]
pub struct MsaUser {
#[serde(skip_serializing_if = "Option::is_none")]
pub player_profile: Option<PlayerProfile>,
pub xuid: Option<Uuid>,
pub gamertag: Option<String>,
#[serde(skip)] // this information is transient
pub player_info: Option<MinecraftPlayerInfo>,
pub(super) client_id: oauth2::ClientId,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub(super) is_azure_client_id: bool,
pub(super) mc_token: Option<Token>,
pub(super) xbl_token: Option<Token>,
pub(super) refresh_token: Option<RefreshToken>
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "type")]
pub enum User {
Dummy(PlayerProfile),
MSA(MsaUser)
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AuthenticationDatabase {
pub users: Vec<User>
}
|