facebook_access_token/
lib.rs

1//! [Ref](https://developers.facebook.com/docs/facebook-login/guides/access-tokens)
2
3use core::time::Duration;
4
5//
6//
7//
8// https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived
9pub const LONG_LIVED_USER_ACCESS_TOKEN_LIFETIME: Duration = Duration::from_secs(3600 * 24 * 60);
10pub const SHORT_LIVED_USER_ACCESS_TOKEN_LIFETIME_MIN: Duration = Duration::from_secs(3600);
11pub const SHORT_LIVED_USER_ACCESS_TOKEN_LIFETIME_MAX: Duration = Duration::from_secs(3600 * 2);
12
13wrapping_macro::wrapping_string! {
14    #[derive(Debug, Clone, PartialEq, Eq)]
15    pub struct LongLivedUserAccessToken(String);
16}
17
18wrapping_macro::wrapping_string! {
19    #[derive(Debug, Clone, PartialEq, Eq)]
20    pub struct ShortLivedUserAccessToken(String);
21}
22
23wrapping_macro::wrapping_string! {
24    #[derive(Debug, Clone, PartialEq, Eq)]
25    pub struct UserAccessToken(String);
26}
27
28impl From<LongLivedUserAccessToken> for UserAccessToken {
29    fn from(t: LongLivedUserAccessToken) -> Self {
30        Self(t.into_inner())
31    }
32}
33
34impl From<&LongLivedUserAccessToken> for UserAccessToken {
35    fn from(t: &LongLivedUserAccessToken) -> Self {
36        Self(t.inner().into())
37    }
38}
39
40impl From<ShortLivedUserAccessToken> for UserAccessToken {
41    fn from(t: ShortLivedUserAccessToken) -> Self {
42        Self(t.into_inner())
43    }
44}
45
46impl From<&ShortLivedUserAccessToken> for UserAccessToken {
47    fn from(t: &ShortLivedUserAccessToken) -> Self {
48        Self(t.inner().into())
49    }
50}
51
52//
53//
54//
55wrapping_macro::wrapping_string! {
56    #[derive(Debug, Clone, PartialEq, Eq)]
57    pub struct AppAccessToken(String);
58}
59
60impl AppAccessToken {
61    pub fn with_app_secret(app_id: u64, app_secret: impl AsRef<str>) -> Self {
62        Self(format!("{}|{}", app_id, app_secret.as_ref()))
63    }
64
65    pub fn app_id_and_app_secret(&self) -> Option<(u64, &str)> {
66        let mut split = self.0.split('|');
67        if let Some(app_id) = split.next().and_then(|x| x.parse::<u64>().ok()) {
68            if let Some(app_secret) =
69                split
70                    .next()
71                    .and_then(|x| if x.is_empty() { None } else { Some(x) })
72            {
73                if split.next().is_none() {
74                    return Some((app_id, app_secret));
75                }
76            }
77        }
78        None
79    }
80}
81
82//
83//
84//
85/*
86Get from https://graph.facebook.com/v15.0/me?fields=id%2Cname%2Caccounts%7Bid%2Cname%2Caccess_token%7D&access_token=YOUR_SHORT_LIVED_OR_LONG_LIVED_USER_ACCESS_TOKEN
87PageAccessToken expires == UserAccessToken expires
88*/
89wrapping_macro::wrapping_string! {
90    #[derive(Debug, Clone, PartialEq, Eq)]
91    pub struct PageAccessToken(String);
92}
93
94//
95//
96//
97wrapping_macro::wrapping_string! {
98    #[derive(Debug, Clone, PartialEq, Eq)]
99    pub struct ClientAccessToken(String);
100}
101
102impl ClientAccessToken {
103    pub fn new(app_id: u64, client_token: impl AsRef<str>) -> Self {
104        Self(format!("{}|{}", app_id, client_token.as_ref()))
105    }
106}
107
108//
109//
110//
111/*
112https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-session-info
113does not grant access to user data
114calling the debug_token endpoint to verify that it is valid
115*/
116//
117wrapping_macro::wrapping_string! {
118    #[derive(Debug, Clone, PartialEq, Eq)]
119    pub struct UserSessionInfoAccessToken(String);
120}
121
122//
123wrapping_macro::wrapping_string! {
124    #[derive(Debug, Clone, PartialEq, Eq)]
125    pub struct PageSessionInfoAccessToken(String);
126}
127
128//
129//
130//
131wrapping_macro::wrapping_int! {
132    #[derive(Debug, Clone, PartialEq, Eq)]
133    pub struct AccessTokenExpiresIn(usize);
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn test_app_access_token() {
142        assert_eq!(
143            AppAccessToken::with_app_secret(1, "x").app_id_and_app_secret(),
144            Some((1, "x"))
145        );
146        assert_eq!(
147            AppAccessToken::from("1|y").app_id_and_app_secret(),
148            Some((1, "y"))
149        );
150        assert!(AppAccessToken::from("1").app_id_and_app_secret().is_none());
151        assert!(AppAccessToken::from("1|").app_id_and_app_secret().is_none());
152        assert!(AppAccessToken::from("|x").app_id_and_app_secret().is_none());
153    }
154}