use serde::{Deserialize, Serialize};
use super::permissions::{KeyStatus, Permission};
use crate::{Result, auth::crypto::parse_public_key, entry::ID};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthKey {
pubkey: String,
permissions: Permission,
status: KeyStatus,
}
impl AuthKey {
pub fn new(
pubkey: impl Into<String>,
permissions: Permission,
status: KeyStatus,
) -> Result<Self> {
let pubkey = pubkey.into();
if pubkey != "*" {
parse_public_key(&pubkey)?;
}
Ok(Self {
pubkey,
permissions,
status,
})
}
pub fn active(pubkey: impl Into<String>, permissions: Permission) -> Result<Self> {
Self::new(pubkey, permissions, KeyStatus::Active)
}
pub fn validate(&self) -> Result<()> {
parse_public_key(&self.pubkey)?;
Ok(())
}
pub fn pubkey(&self) -> &str {
&self.pubkey
}
pub fn permissions(&self) -> &Permission {
&self.permissions
}
pub fn status(&self) -> &KeyStatus {
&self.status
}
pub fn set_status(&mut self, status: KeyStatus) {
self.status = status;
}
pub fn set_permissions(&mut self, permissions: Permission) {
self.permissions = permissions;
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DelegationStep {
pub key: String,
pub tips: Option<Vec<ID>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum SigKey {
Direct(String),
DelegationPath(Vec<DelegationStep>),
}
impl Default for SigKey {
fn default() -> Self {
SigKey::Direct(String::new())
}
}
impl SigKey {
pub fn is_signed_by(&self, key_name: &str) -> bool {
match self {
SigKey::Direct(id) => id == key_name,
SigKey::DelegationPath(steps) => {
if let Some(last_step) = steps.last() {
last_step.key == key_name
} else {
false
}
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
pub struct SigInfo {
pub sig: Option<String>,
pub key: SigKey,
#[serde(skip_serializing_if = "Option::is_none")]
pub pubkey: Option<String>,
}
impl SigInfo {
pub fn is_signed_by(&self, key_name: &str) -> bool {
self.key.is_signed_by(key_name)
}
pub fn builder() -> SigInfoBuilder {
SigInfoBuilder::new()
}
}
#[derive(Debug, Clone, Default)]
pub struct SigInfoBuilder {
sig: Option<String>,
key: Option<SigKey>,
pubkey: Option<String>,
}
impl SigInfoBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn sig(mut self, sig: impl Into<String>) -> Self {
self.sig = Some(sig.into());
self
}
pub fn key(mut self, key: SigKey) -> Self {
self.key = Some(key);
self
}
pub fn pubkey(mut self, pubkey: impl Into<String>) -> Self {
self.pubkey = Some(pubkey.into());
self
}
pub fn build(self) -> SigInfo {
SigInfo {
sig: self.sig,
key: self.key.expect("key is required for SigInfo"),
pubkey: self.pubkey,
}
}
}
#[derive(Debug, Clone)]
pub struct ResolvedAuth {
pub public_key: ed25519_dalek::VerifyingKey,
pub effective_permission: Permission,
pub key_status: KeyStatus,
}