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
//! This module defines various methods and structs used for authenticating on the B2 server.
//!
//! Authentication is usually performed by calling the [`authorize`] method on the
//! [`B2Credentials`] struct, which returns a [`B2Authorization`].
//!
//!  [`authorize`]: struct.B2Credentials.html#method.authorize
//!  [`B2Credentials`]: struct.B2Credentials.html
//!  [`B2Authorization`]: struct.B2Authorization.html

use std::fmt;

use base64::{encode as b64encode};

use hyper;
use hyper::{Client};
use hyper::header::{Header, HeaderFormat};

use serde_json;

use B2Error;
use B2AuthHeader;

/// Contains the backblaze id and key needed to authorize access to the backblaze b2 api.
/// This struct derives [Deserialize][1], so a simple way to read this from a file would be:
///
/// ```rust,no_run
///extern crate serde;
///extern crate serde_json;
///use std::fs::File;
///
///# extern crate backblaze_b2;
///# use backblaze_b2::raw::authorize::B2Credentials;
///#
///# fn main() {
///serde_json::from_reader::<_,B2Credentials>(File::open("credentials.txt").unwrap()).unwrap();
///# }
/// ```
///
///  [1]: ../../../serde/trait.Deserialize.html
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct B2Credentials {
    pub id: String,
    pub key: String
}
impl B2Credentials {
    fn id_key(&self) -> String {
        format!("{}:{}", self.id, self.key)
    }
    /// This function returns the value of the Authorization header needed to perform a
    /// b2_authorize_account api call.
    pub fn auth_string(&self) -> String {
        format!("Basic {}", b64encode(&self.id_key()))
    }
    /// This function performs a [b2_authorize_account][1] api call to the backblaze api and returns an
    /// authorization token.
    ///
    /// # Errors
    /// This function returns a [`B2Error`] in case something goes wrong. Besides the standard
    /// non-authorization errors, this function can fail with [`is_credentials_issue`].
    ///
    ///  [1]: https://www.backblaze.com/b2/docs/b2_authorize_account.html
    ///  [`is_credentials_issue`]: ../../enum.B2Error.html#method.is_credentials_issue
    ///  [`B2Error`]: ../../enum.B2Error.html
    pub fn authorize(&self, client: &Client) -> Result<B2Authorization,B2Error> {
        let resp = try!(client.get("https://api.backblazeb2.com/b2api/v1/b2_authorize_account")
            .header(self.clone())
            .send());
        if resp.status != hyper::status::StatusCode::Ok {
            Err(B2Error::from_response(resp))
        } else {
            Ok(B2Authorization::from(self.id.clone(), try!(serde_json::from_reader(resp))))
        }
    }
}
impl HeaderFormat for B2Credentials {
    fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str(self.auth_string().as_str())
    }
}
impl Header for B2Credentials {
    fn header_name() -> &'static str {
        "Authorization"
    }
#[allow(unused_variables)]
    fn parse_header(raw: &[Vec<u8>]) -> hyper::Result<B2Credentials> {
        panic!("we are not the b2 server");
    }
}
#[derive(Serialize,Deserialize)]
#[serde(rename_all = "camelCase")]
struct B2AuthResponse {
    authorization_token: String,
    api_url: String,
    download_url: String,
    recommended_part_size: usize,
    absolute_minimum_part_size: usize
}
/// This struct contains the needed authorization to perform any b2 api call. It is typically
/// created using the [`authorize`] method on [`B2Credentials`].
///
///  [`authorize`]: struct.B2Credentials.html#method.authorize
///  [`B2Credentials`]: struct.B2Credentials.html
#[derive(Debug)]
pub struct B2Authorization {
    pub account_id: String,
    pub authorization_token: String,
    pub api_url: String,
    pub download_url: String,
    pub recommended_part_size: usize,
    pub absolute_minimum_part_size: usize
}
impl B2Authorization {
    fn from(id: String, resp: B2AuthResponse) -> B2Authorization {
        B2Authorization {
            account_id: id,
            authorization_token: resp.authorization_token,
            api_url: resp.api_url,
            download_url: resp.download_url,
            recommended_part_size: resp.recommended_part_size,
            absolute_minimum_part_size: resp.absolute_minimum_part_size
        }
    }
    /// Returns a hyper header that correctly authorizes an api call to backblaze.
    pub fn auth_header(&self) -> B2AuthHeader {
        B2AuthHeader(self.authorization_token.clone())
    }
}