yup_oauth2/
helper.rs

1//! Helper functions allowing you to avoid writing boilerplate code for common operations, such as
2//! parsing JSON or reading files.
3
4// Copyright (c) 2016 Google Inc (lewinb@google.com).
5//
6// Refer to the project root for licensing information.
7use crate::authorized_user::AuthorizedUserSecret;
8use crate::external_account::ExternalAccountSecret;
9use crate::types::{ApplicationSecret, ConsoleApplicationSecret};
10
11#[cfg(feature = "service-account")]
12use crate::service_account::ServiceAccountKey;
13
14use std::io;
15use std::path::Path;
16
17/// Read an application secret from a file.
18pub async fn read_application_secret<P: AsRef<Path>>(path: P) -> io::Result<ApplicationSecret> {
19    parse_application_secret(tokio::fs::read(path).await?)
20}
21
22/// Read an application secret from a JSON string.
23pub fn parse_application_secret<S: AsRef<[u8]>>(secret: S) -> io::Result<ApplicationSecret> {
24    let decoded: ConsoleApplicationSecret =
25        serde_json::from_slice(secret.as_ref()).map_err(|e| {
26            io::Error::new(
27                io::ErrorKind::InvalidData,
28                format!("Bad application secret: {}", e),
29            )
30        })?;
31
32    if let Some(web) = decoded.web {
33        Ok(web)
34    } else if let Some(installed) = decoded.installed {
35        Ok(installed)
36    } else {
37        Err(io::Error::new(
38            io::ErrorKind::InvalidData,
39            "Unknown application secret format",
40        ))
41    }
42}
43
44/// Read a service account key from a JSON file. You can download the JSON keys from the Google
45/// Cloud Console or the respective console of your service provider.
46#[cfg(feature = "service-account")]
47pub async fn read_service_account_key<P: AsRef<Path>>(path: P) -> io::Result<ServiceAccountKey> {
48    let key = tokio::fs::read(path).await?;
49    parse_service_account_key(key)
50}
51
52#[cfg(feature = "service-account")]
53/// Read a service account key from a JSON string.
54pub fn parse_service_account_key<S: AsRef<[u8]>>(key: S) -> io::Result<ServiceAccountKey> {
55    serde_json::from_slice(key.as_ref()).map_err(|e| {
56        io::Error::new(
57            io::ErrorKind::InvalidData,
58            format!("Bad service account key: {}", e),
59        )
60    })
61}
62
63/// Read an authorized user secret from a JSON file. You can obtain it by running on the client:
64/// `gcloud auth application-default login`.
65/// The file should be on Windows in: `%APPDATA%/gcloud/application_default_credentials.json`
66/// for other systems: `$HOME/.config/gcloud/application_default_credentials.json`.
67pub async fn read_authorized_user_secret<P: AsRef<Path>>(
68    path: P,
69) -> io::Result<AuthorizedUserSecret> {
70    let key = tokio::fs::read(path).await?;
71    serde_json::from_slice(&key).map_err(|e| {
72        io::Error::new(
73            io::ErrorKind::InvalidData,
74            format!("Bad authorized user secret: {}", e),
75        )
76    })
77}
78
79/// Read an external account secret from a JSON file.
80pub async fn read_external_account_secret<P: AsRef<Path>>(
81    path: P,
82) -> io::Result<ExternalAccountSecret> {
83    let key = tokio::fs::read(path).await?;
84    serde_json::from_slice(&key).map_err(|e| {
85        io::Error::new(
86            io::ErrorKind::InvalidData,
87            format!("Bad external account secret: {}", e),
88        )
89    })
90}
91
92pub(crate) fn join<T>(pieces: &[T], separator: &str) -> String
93where
94    T: AsRef<str>,
95{
96    let mut iter = pieces.iter();
97    let first = match iter.next() {
98        Some(p) => p,
99        None => return String::new(),
100    };
101    let num_separators = pieces.len() - 1;
102    let pieces_size: usize = pieces.iter().map(|p| p.as_ref().len()).sum();
103    let size = pieces_size + separator.len() * num_separators;
104    let mut result = String::with_capacity(size);
105    result.push_str(first.as_ref());
106    for p in iter {
107        result.push_str(separator);
108        result.push_str(p.as_ref());
109    }
110    debug_assert_eq!(size, result.len());
111    result
112}