pub trait MappingBackendUserSecrets: MappingSystemUserId + MappingBackendUserIds {
// Provided methods
fn create_non_admin_backend_user_secrets(
&self,
secret_handling: NonAdministrativeSecretHandling,
) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, Error> { ... }
fn load_non_admin_backend_user_secrets(
&self,
secret_handling: NonAdministrativeSecretHandling,
filter: NonAdminBackendUserIdFilter,
) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, Error> { ... }
}Expand description
An interface to create and load secrets for backend users in user mapping implementations.
Implementations are required to also implement MappingBackendUserIds and
MappingSystemUserId
§Example
use signstar_config::{
Error,
SystemUserId,
config::{
BackendUserIdFilter,
BackendUserIdKind,
MappingBackendUserIds,
MappingBackendUserSecrets,
MappingSystemUserId,
},
};
use signstar_crypto::{passphrase::Passphrase, traits::UserWithPassphrase};
#[derive(Debug)]
struct ExampleCreds {
pub id: u8,
pub passphrase: Passphrase,
}
impl UserWithPassphrase for ExampleCreds {
fn user(&self) -> String {
self.id.to_string()
}
fn passphrase(&self) -> &Passphrase {
&self.passphrase
}
}
#[derive(Debug)]
enum ExampleUserMapping {
Admin {
backend_id: u8,
},
Backup {
backend_id: u8,
system_user: SystemUserId,
},
Metrics {
backend_id: u8,
system_user: SystemUserId,
},
Signer {
backend_id: u8,
system_user: SystemUserId,
},
}
impl ExampleUserMapping {
pub fn backend_user_id(&self) -> u8 {
match self {
Self::Admin { backend_id }
| Self::Backup { backend_id, .. }
| Self::Metrics { backend_id, .. }
| Self::Signer { backend_id, .. } => *backend_id,
}
}
}
impl MappingBackendUserIds for ExampleUserMapping {
fn backend_user_ids(&self, filter: BackendUserIdFilter) -> Vec<String> {
match self {
Self::Admin { backend_id, .. } => {
if [BackendUserIdKind::Admin, BackendUserIdKind::Any]
.contains(&filter.backend_user_id_kind)
{
return vec![backend_id.to_string()];
}
}
Self::Backup { backend_id, .. } => {
if [
BackendUserIdKind::Any,
BackendUserIdKind::Backup,
BackendUserIdKind::NonAdmin,
]
.contains(&filter.backend_user_id_kind)
{
return vec![backend_id.to_string()];
}
}
Self::Metrics { backend_id, .. } => {
if [
BackendUserIdKind::Any,
BackendUserIdKind::Metrics,
BackendUserIdKind::NonAdmin,
]
.contains(&filter.backend_user_id_kind)
{
return vec![backend_id.to_string()];
}
}
Self::Signer { backend_id, .. } => {
if [
BackendUserIdKind::Any,
BackendUserIdKind::Signing,
BackendUserIdKind::NonAdmin,
]
.contains(&filter.backend_user_id_kind)
{
return vec![backend_id.to_string()];
}
}
}
Vec::new()
}
fn backend_user_with_passphrase(
&self,
name: &str,
passphrase: Passphrase,
) -> Result<Box<dyn UserWithPassphrase>, Error> {
let backend_user_id = self.backend_user_id();
if backend_user_id.to_string() != name {
return Err(
signstar_config::config::TraitsError::BackendUserIdMismatch {
expected: name.to_string(),
actual: backend_user_id.to_string(),
}
.into(),
);
}
Ok(Box::new(ExampleCreds {
id: backend_user_id,
passphrase,
}))
}
fn backend_users_with_new_passphrase(
&self,
filter: BackendUserIdFilter,
) -> Vec<Box<dyn UserWithPassphrase>> {
if let Some(backend_id) = match self {
Self::Admin { backend_id, .. } => {
if [BackendUserIdKind::Admin, BackendUserIdKind::Any]
.contains(&filter.backend_user_id_kind)
{
Some(*backend_id)
} else {
None
}
}
Self::Backup { backend_id, .. } => {
if [
BackendUserIdKind::Any,
BackendUserIdKind::Backup,
BackendUserIdKind::NonAdmin,
]
.contains(&filter.backend_user_id_kind)
{
Some(*backend_id)
} else {
None
}
}
Self::Metrics { backend_id, .. } => {
if [
BackendUserIdKind::Any,
BackendUserIdKind::Metrics,
BackendUserIdKind::NonAdmin,
]
.contains(&filter.backend_user_id_kind)
{
Some(*backend_id)
} else {
None
}
}
Self::Signer { backend_id, .. } => {
if [
BackendUserIdKind::Any,
BackendUserIdKind::Signing,
BackendUserIdKind::NonAdmin,
]
.contains(&filter.backend_user_id_kind)
{
Some(*backend_id)
} else {
None
}
}
} {
vec![Box::new(ExampleCreds {
id: backend_id,
passphrase: Passphrase::generate(None),
})]
} else {
Vec::new()
}
}
}
impl MappingSystemUserId for ExampleUserMapping {
fn system_user_id(&self) -> Option<&SystemUserId> {
match self {
Self::Admin { .. } => None,
Self::Backup { system_user, .. }
| Self::Metrics { system_user, .. }
| Self::Signer { system_user, .. } => Some(system_user),
}
}
}
impl MappingBackendUserSecrets for ExampleUserMapping {}Provided Methods§
Sourcefn create_non_admin_backend_user_secrets(
&self,
secret_handling: NonAdministrativeSecretHandling,
) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, Error>
fn create_non_admin_backend_user_secrets( &self, secret_handling: NonAdministrativeSecretHandling, ) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, Error>
Creates on-disk secrets for non-administrative backend users of the mapping.
Returns a list of the created credentials as UserWithPassphrase implementations.
§Note
Returns Ok(None), if the mapping implementation tracks no system user.
§Errors
Returns an error if
- the system user in the user mapping does not match an existing Unix user
- the user calling this function is not root
write_passphrase_to_secrets_filefails for one of the newly generated passphrases
Sourcefn load_non_admin_backend_user_secrets(
&self,
secret_handling: NonAdministrativeSecretHandling,
filter: NonAdminBackendUserIdFilter,
) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, Error>
fn load_non_admin_backend_user_secrets( &self, secret_handling: NonAdministrativeSecretHandling, filter: NonAdminBackendUserIdFilter, ) -> Result<Option<Vec<Box<dyn UserWithPassphrase>>>, Error>
Loads secrets from on-disk files for each non-administrative backend user matching a
filter.
Returns a list of the loaded credentials as UserWithPassphrase implementations.
§Notes
Returns Ok(None), if the mapping implementation tracks no system user.
The system user of the user mapping implementation must match the effective user of the current process.
Delegates to load_passphrase_from_secrets_file for the loading of a single
Passphrase from a secrets file.
§Errors
Returns an error if
- the system user in the user mapping does not match the currently calling Unix user
load_passphrase_from_secrets_filefails for one of the secret files of the system user of the mapping