pub fn token<C, S, B>(
client_credentials: &Credentials<C>,
client: &mut S,
) -> AuthFuture<AccessToken2, S::Future>
where
C: AsRef<str>,
S: HttpService<B>,
B: From<&'static [u8]>,
{
let req = token_request(client_credentials.as_ref());
AuthFuture::new(client.call(req.map(Into::into)))
}
fn token_request(client_credentials: Credentials<&str>) -> http::Request<&'static [u8]> {
const URI: &str = "https://api.twitter.com/oauth2/token";
let authorization = basic_auth(client_credentials);
let application_www_form_urlencoded =
HeaderValue::from_static("application/x-www-form-urlencoded");
http::Request::post(Uri::from_static(URI))
.header(AUTHORIZATION, authorization)
.header(CONTENT_TYPE, application_www_form_urlencoded)
.body(&b"grant_type=client_credentials"[..])
.unwrap()
}
fn basic_auth(credentials: Credentials<&str>) -> String {
let b64len = (credentials.identifier.len() + credentials.secret.len()) / 3 * 4 + 4;
let mut authorization = String::with_capacity("Basic ".len() + b64len);
authorization.push_str("Basic ");
let mut enc = base64::write::EncoderStringWriter::from(authorization, base64::STANDARD);
enc.write_all(credentials.identifier.as_bytes()).unwrap();
enc.write_all(b":").unwrap();
enc.write_all(credentials.secret.as_bytes()).unwrap();
enc.into_inner()
}
mod private {
use bytes::Bytes;
pub trait AuthDeserialize: Sized {
fn deserialize(input: Bytes) -> Option<Self>;
}
}