blob: b2159ff8f2119eafdf2dea7a0091856f64e0cb5b [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use failure::format_err;
use fidl::endpoints::ClientEnd;
use fidl_fuchsia_auth::{AuthProviderConfig, AuthProviderMarker, Status};
use futures::future::{ready as fready, FutureObj};
use std::collections::HashMap;
use std::sync::Arc;
use token_manager::{AuthProviderConnection, TokenManagerError};
/// A type capable of launching components implementing the `AuthProviderFactory` interface and
/// acquiring `AuthProvider` connections from them component. Launching is performed on demand
/// and components are reused across calls.
#[derive(Clone)]
pub struct AuthProviderSupplier {
/// A map from auth_provider_type to a `AuthProviderConnection` used to launch the associated
/// component.
auth_provider_connections: Arc<HashMap<String, AuthProviderConnection>>,
}
impl AuthProviderSupplier {
/// Creates a new `AuthProviderSupplier` from the supplied vector of `AuthProviderConfig`
/// objects.
pub fn new(auth_provider_configs: Vec<AuthProviderConfig>) -> Self {
AuthProviderSupplier {
auth_provider_connections: Arc::new(
auth_provider_configs
.into_iter()
.map(|apc| {
(
apc.auth_provider_type.clone(),
AuthProviderConnection::from_config(apc),
)
})
.collect(),
),
}
}
}
impl token_manager::AuthProviderSupplier for AuthProviderSupplier {
/// Asynchronously creates an `AuthProvider` for the requested `auth_provider_type` and
/// returns the `ClientEnd` for communication with it.
fn get<'a>(
&'a self, auth_provider_type: &'a str,
) -> FutureObj<'a, Result<ClientEnd<AuthProviderMarker>, TokenManagerError>> {
let auth_provider_connection: &AuthProviderConnection =
match self.auth_provider_connections.get(auth_provider_type) {
Some(apc) => apc,
None => {
let err = TokenManagerError::new(Status::AuthProviderServiceUnavailable)
.with_cause(format_err!("Unknown auth provider {}", auth_provider_type));
return FutureObj::new(Box::new(fready(Err(err))));
}
};
FutureObj::new(Box::new(auth_provider_connection.get()))
}
}