Login
4 branches 0 tags
Ben (Desktop/Arch) Remote CI 3cb47c1 14 days ago 247 Commits
rubhub / crates / auth_store / src / runner_token.rs
use std::sync::mpsc::SendError;

use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use time::OffsetDateTime;

use crate::{event::StoreEvent, AuthStore};

/// A token that allows a CI runner to connect to this instance
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RunnerToken {
    /// SHA-256 hash of the actual token (we never store plaintext)
    pub token_hash: String,
    /// Human-readable label for this token
    pub label: String,
    #[serde(with = "time::serde::rfc3339")]
    pub created_at: OffsetDateTime,
}

impl RunnerToken {
    /// Create a new runner token from a plaintext token
    pub fn new(token: &str, label: String) -> Self {
        Self {
            token_hash: Self::hash_token(token),
            label,
            created_at: OffsetDateTime::now_utc(),
        }
    }

    /// Hash a token using SHA-256
    pub fn hash_token(token: &str) -> String {
        let mut hasher = Sha256::new();
        hasher.update(token.as_bytes());
        let result = hasher.finalize();
        hex::encode(result)
    }

    pub fn save(self, store: &AuthStore) -> Result<(), SendError<StoreEvent>> {
        store.store_event(StoreEvent::RunnerToken(self))
    }

    pub fn delete(store: &AuthStore, token_hash: String) -> Result<(), SendError<StoreEvent>> {
        store.store_event(StoreEvent::RunnerTokenDelete { token_hash })
    }
}