#[cfg(not(any(
feature = "direct-authenticator",
feature = "unix-peer-credentials-authenticator",
feature = "jwt-svid-authenticator",
)))]
compile_error!("Please provide in at least one authenticator");
#[cfg(feature = "direct-authenticator")]
pub mod direct_authenticator;
#[cfg(feature = "unix-peer-credentials-authenticator")]
pub mod unix_peer_credentials_authenticator;
#[cfg(feature = "jwt-svid-authenticator")]
pub mod jwt_svid_authenticator;
use crate::front::listener::ConnectionMetadata;
use crate::utils::config::Admin;
use parsec_interface::operations::list_authenticators;
use parsec_interface::requests::request::RequestAuth;
use parsec_interface::requests::{AuthType, Result};
use std::fmt;
use std::ops::Deref;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ApplicationIdentity {
name: String,
auth: Auth,
}
pub const INTERNAL_APP_NAME: &str = "parsec";
impl fmt::Display for ApplicationIdentity {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"ApplicationIdentity: [name=\"{}\", auth=\"{}\"]",
self.name, self.auth
)
}
}
impl ApplicationIdentity {
pub fn new(name: String, authenticator_id: AuthType) -> ApplicationIdentity {
ApplicationIdentity {
name,
auth: authenticator_id.into(),
}
}
pub fn new_with_auth(name: String, auth: Auth) -> ApplicationIdentity {
ApplicationIdentity { name, auth }
}
pub fn new_internal() -> ApplicationIdentity {
ApplicationIdentity {
name: INTERNAL_APP_NAME.to_string(),
auth: Auth::Internal,
}
}
pub fn name(&self) -> &String {
&self.name
}
pub fn authenticator_id(&self) -> u8 {
self.auth.authenticator_id()
}
pub fn auth(&self) -> &Auth {
&self.auth
}
pub fn is_internal(&self) -> bool {
self.auth == Auth::Internal
}
}
#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
pub enum Auth {
Client(AuthType),
Internal,
}
pub const INTERNAL_AUTH_ID: i64 = 255;
impl Auth {
pub fn authenticator_id(&self) -> u8 {
match self {
Auth::Client(auth) => *auth as u8,
Auth::Internal => INTERNAL_AUTH_ID as u8,
}
}
}
impl From<AuthType> for Auth {
fn from(auth: AuthType) -> Self {
Auth::Client(auth)
}
}
impl fmt::Display for Auth {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Auth::Client(auth) => {
write!(f, "Client authenticator ({})", auth)
}
Auth::Internal => {
write!(f, "Internal service authenticator")
}
}
}
}
#[derive(Debug, Clone)]
pub struct Application {
identity: ApplicationIdentity,
is_admin: bool,
}
impl fmt::Display for Application {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Application {{identity: {}, is_admin: {}}}",
self.identity, self.is_admin
)
}
}
impl Application {
pub fn new(identity: ApplicationIdentity, is_admin: bool) -> Application {
Application { identity, is_admin }
}
pub fn identity(&self) -> &ApplicationIdentity {
&self.identity
}
pub fn is_admin(&self) -> &bool {
&self.is_admin
}
}
pub trait Authenticate {
fn describe(&self) -> Result<list_authenticators::AuthenticatorInfo>;
fn authenticate(
&self,
auth: &RequestAuth,
meta: Option<ConnectionMetadata>,
) -> Result<Application>;
}
#[derive(Debug, Clone, Default)]
struct AdminList(Vec<Admin>);
impl AdminList {
fn is_admin(&self, app_name: &str) -> bool {
self.iter().any(|admin| admin.name() == app_name)
}
}
impl Deref for AdminList {
type Target = Vec<Admin>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<Vec<Admin>> for AdminList {
fn from(admin_list: Vec<Admin>) -> Self {
AdminList(admin_list)
}
}