modality_auth_token/
token_user_file.rs

1//! A tiny UTF8 file format consisting of the lowercase hex-string representation of an auth token
2//! followed by a newline
3//! followed optionally by user identity string content
4use crate::{
5    decode_auth_token_hex, AuthToken, AuthTokenHexString, AuthTokenStringDeserializationError,
6};
7use std::collections::VecDeque;
8use std::fs;
9use std::path::Path;
10
11/// A UTF8 file. The first line contains the auth token hex string representation and a line break.
12/// All (optional) subsequent content represents the user identity
13pub const USER_AUTH_TOKEN_FILE_NAME: &str = ".user_auth_token";
14
15/// A UTF8 file. The first line contains the auth token hex string representation and a line break.
16/// All (optional) subsequent content represents the authorizing user identity
17pub const REFLECTOR_AUTH_TOKEN_DEFAULT_FILE_NAME: &str = ".modality-reflector-auth-token";
18
19pub fn write_user_auth_token_file(
20    path: &Path,
21    auth_token: AuthToken,
22) -> Result<(), std::io::Error> {
23    let mut value: String = AuthTokenHexString::from(auth_token).into();
24    value.push('\n');
25    fs::write(path, value.as_bytes())
26}
27
28pub struct UserAuthTokenFileContents {
29    pub auth_token: AuthToken,
30}
31
32/// Expects a UTF8 file.
33/// The first line contains the auth token hex string representation followed by a line break.
34/// If present, all subsequent content represents the user identity
35pub fn read_user_auth_token_file(
36    path: &Path,
37) -> Result<Option<UserAuthTokenFileContents>, TokenUserFileReadError> {
38    if path.exists() {
39        let contents = fs::read_to_string(path)?;
40        if contents.trim().is_empty() {
41            return Ok(None);
42        }
43        let mut lines: VecDeque<&str> = contents.lines().collect();
44        if let Some(hex_line) = lines.pop_front() {
45            let auth_token = decode_auth_token_hex(hex_line)?;
46            Ok(Some(UserAuthTokenFileContents { auth_token }))
47        } else {
48            Ok(None)
49        }
50    } else {
51        Ok(None)
52    }
53}
54
55#[derive(Debug, thiserror::Error)]
56pub enum TokenUserFileReadError {
57    #[error("IO Error")]
58    Io(
59        #[source]
60        #[from]
61        std::io::Error,
62    ),
63
64    #[error("Auth token representation error")]
65    AuthTokenRepresentation(
66        #[source]
67        #[from]
68        AuthTokenStringDeserializationError,
69    ),
70}