1use std::collections::BTreeMap;
4
5use serde::Deserialize;
6
7use super::TokenStore;
8use super::types::{App, OAuth1Token, StoreFile, Token, TokenType};
9use crate::error::Result;
10
11#[derive(Debug, Deserialize)]
14struct LegacyStore {
15 oauth2_tokens: Option<BTreeMap<String, Token>>,
16 #[serde(rename = "oauth1_tokens")]
17 oauth1_token: Option<Token>,
18 bearer_token: Option<Token>,
19}
20
21#[derive(Debug, Deserialize)]
24#[allow(dead_code)] struct TwurlrcProfile {
26 username: Option<String>,
27 consumer_key: Option<String>,
28 consumer_secret: Option<String>,
29 token: Option<String>,
30 secret: Option<String>,
31}
32
33#[derive(Debug, Deserialize)]
34struct TwurlrcConfig {
35 profiles: Option<BTreeMap<String, BTreeMap<String, TwurlrcProfile>>>,
36 bearer_tokens: Option<BTreeMap<String, String>>,
37}
38
39impl TokenStore {
42 pub(crate) fn load_from_data(&mut self, data: &[u8]) {
44 if let Ok(sf) = serde_yaml::from_slice::<StoreFile>(data)
46 && !sf.apps.is_empty()
47 {
48 self.apps = sf.apps;
49 self.default_app = sf.default_app;
50 return;
51 }
52
53 if let Ok(legacy) = serde_json::from_slice::<LegacyStore>(data) {
55 let app = App {
56 client_id: String::new(),
57 client_secret: String::new(),
58 default_user: String::new(),
59 redirect_uri: String::new(),
60 oauth2_tokens: legacy.oauth2_tokens.unwrap_or_default(),
61 oauth1_token: legacy.oauth1_token,
62 bearer_token: legacy.bearer_token,
63 unnamed_oauth2_token: None,
64 };
65 self.apps.insert("default".to_string(), app);
66 self.default_app = "default".to_string();
67 let _ = self.save_to_file();
69 }
70 }
71
72 pub fn import_from_twurlrc(&mut self, file_path: &std::path::Path) -> Result<()> {
78 let data = std::fs::read(file_path)?;
79 let twurlrc: TwurlrcConfig = serde_yaml::from_slice(&data)?;
80
81 let app = self.active_app_or_create();
82
83 if let Some(profiles) = &twurlrc.profiles {
85 'outer: for consumer_keys in profiles.values() {
86 if let Some((consumer_key, profile)) = consumer_keys.iter().next() {
87 if app.oauth1_token.is_none() {
88 app.oauth1_token = Some(Token {
89 token_type: TokenType::Oauth1,
90 bearer: None,
91 oauth2: None,
92 oauth1: Some(OAuth1Token {
93 access_token: profile.token.clone().unwrap_or_default(),
94 token_secret: profile.secret.clone().unwrap_or_default(),
95 consumer_key: consumer_key.clone(),
96 consumer_secret: profile
97 .consumer_secret
98 .clone()
99 .unwrap_or_default(),
100 }),
101 });
102 }
103 break 'outer;
104 }
105 }
106 }
107
108 if let Some(bearer_tokens) = &twurlrc.bearer_tokens
110 && let Some(bearer_token) = bearer_tokens.values().next()
111 {
112 app.bearer_token = Some(Token {
113 token_type: TokenType::Bearer,
114 bearer: Some(bearer_token.clone()),
115 oauth2: None,
116 oauth1: None,
117 });
118 }
119
120 self.save_to_file()
121 }
122}