aboutsummaryrefslogtreecommitdiff
path: root/import/asset_token/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'import/asset_token/src/lib.rs')
-rw-r--r--import/asset_token/src/lib.rs111
1 files changed, 0 insertions, 111 deletions
diff --git a/import/asset_token/src/lib.rs b/import/asset_token/src/lib.rs
deleted file mode 100644
index ef1850e..0000000
--- a/import/asset_token/src/lib.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- This file is part of jellything (https://codeberg.org/metamuffin/jellything)
- which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
- Copyright (C) 2025 metamuffin <metamuffin.org>
-*/
-use aes_gcm_siv::{aead::Aead, Aes256GcmSiv, KeyInit};
-use anyhow::{anyhow, bail, Context};
-use base64::Engine;
-use jellycache::CachePath;
-pub use jellycommon as common;
-use jellycommon::{Asset, LocalTrack};
-use log::warn;
-use serde::{Deserialize, Serialize};
-use sha2::digest::generic_array::GenericArray;
-use std::sync::Mutex;
-use std::{path::PathBuf, sync::LazyLock};
-
-#[rustfmt::skip]
-#[derive(Debug, Deserialize, Serialize, Default)]
-pub struct Config {
- asset_key: Option<String>,
-}
-
-pub static CONF_PRELOAD: Mutex<Option<Config>> = Mutex::new(None);
-static CONF: LazyLock<Config> = LazyLock::new(|| {
- CONF_PRELOAD
- .lock()
- .unwrap()
- .take()
- .expect("cache config not preloaded. logic error")
-});
-
-const VERSION: u32 = 3;
-
-static ASSET_KEY: LazyLock<Aes256GcmSiv> = LazyLock::new(|| {
- if let Some(sk) = &CONF.asset_key {
- let r = base64::engine::general_purpose::STANDARD
- .decode(sk)
- .expect("key invalid; should be valid base64");
- aes_gcm_siv::Aes256GcmSiv::new_from_slice(&r)
- .expect("key has the wrong length; should be 32 bytes")
- } else {
- warn!("session_key not configured; generating a random one.");
- aes_gcm_siv::Aes256GcmSiv::new_from_slice(&[(); 32].map(|_| rand::random())).unwrap()
- }
-});
-
-#[derive(Debug, Serialize, PartialEq, Eq)]
-pub enum AssetInner {
- Federated { host: String, asset: Vec<u8> },
- Cache(CachePath),
- Assets(PathBuf),
- Media(PathBuf),
- LocalTrack(LocalTrack),
-}
-
-impl AssetInner {
- pub fn ser(&self) -> Asset {
- let mut plaintext = Vec::new();
- plaintext.extend(u32::to_le_bytes(VERSION));
- plaintext.extend(bincode::encode_to_vec(self, bincode::config::standard()).unwrap());
-
- while plaintext.len() % 16 == 0 {
- plaintext.push(0);
- }
-
- let nonce = [(); 12].map(|_| rand::random());
- let mut ciphertext = ASSET_KEY
- .encrypt(&GenericArray::from(nonce), plaintext.as_slice())
- .unwrap();
- ciphertext.extend(nonce);
-
- Asset(base64::engine::general_purpose::URL_SAFE.encode(&ciphertext))
- }
- pub fn deser(s: &str) -> anyhow::Result<Self> {
- let ciphertext = base64::engine::general_purpose::URL_SAFE.decode(s)?;
- let (ciphertext, nonce) = ciphertext.split_at(ciphertext.len() - 12);
- let plaintext = ASSET_KEY
- .decrypt(nonce.into(), ciphertext)
- .map_err(|_| anyhow!("asset token decrypt failed"))?;
-
- let version = u32::from_le_bytes(plaintext[0..4].try_into().unwrap());
- if version != VERSION {
- bail!("asset token version mismatch");
- }
-
- let (data, _): (AssetInner, _) =
- bincode::decode_from_slice(&plaintext[4..], bincode::config::standard())
- .context("asset token has invalid format")?;
- Ok(data)
- }
-
- /// Returns `true` if the asset inner is [`Federated`].
- ///
- /// [`Federated`]: AssetInner::Federated
- #[must_use]
- pub fn is_federated(&self) -> bool {
- matches!(self, Self::Federated { .. })
- }
-}
-
-#[test]
-fn test_identities() {
- *CONF_PRELOAD.lock().unwrap() = Some(Config { asset_key: None });
-
- let a = AssetInner::Assets(PathBuf::new());
- let b = a.ser();
- let c = AssetInner::deser(&b.0).unwrap();
-
- assert_eq!(a, c)
-}