summaryrefslogtreecommitdiffstats
path: root/src/auth/types.rs
blob: b9cdaada492ccfcec38b4192dca9cca88d8150aa (plain) (blame)
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
130
pub mod property_map;
pub use property_map::PropertyMap;

use std::fmt::{Debug, Formatter};
use chrono::{DateTime, Utc};
use multimap::MultiMap;
use oauth2::RefreshToken;
use serde::{Deserialize, Serialize};
use uuid::Uuid;

#[derive(Debug, Serialize, Deserialize)]
pub struct Property {
    pub name: String,
    pub value: String,
    
    #[serde(skip_serializing_if = "Option::is_none")]
    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: PropertyMap
}

#[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<String>,
    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", rename_all = "lowercase")]
pub enum User {
    Dummy(PlayerProfile),
    MSA(Box<MsaUser>)
}

#[derive(Debug, Serialize, Deserialize)]
pub struct AuthenticationDatabase {
    pub users: Vec<User>
}