openstack_keystone_core/token/backend/fernet/
restricted.rs1use rmp::{decode::read_pfix, encode::write_pfix};
17use std::io::Write;
18
19use crate::token::{
20 backend::fernet::{FernetTokenProvider, MsgPackToken, utils},
21 error::TokenProviderError,
22 types::RestrictedPayload,
23};
24
25impl MsgPackToken for RestrictedPayload {
26 type Token = Self;
27
28 fn assemble<W: Write>(
29 &self,
30 wd: &mut W,
31 fernet_provider: &FernetTokenProvider,
32 ) -> Result<(), TokenProviderError> {
33 utils::write_uuid(wd, &self.user_id)?;
34 write_pfix(
35 wd,
36 fernet_provider.encode_auth_methods(self.methods.clone())?,
37 )
38 .map_err(|x| TokenProviderError::RmpEncode(x.to_string()))?;
39 utils::write_uuid(wd, &self.token_restriction_id)?;
40 utils::write_time(wd, self.expires_at)?;
41 utils::write_uuid(wd, &self.project_id)?;
42 utils::write_bool(wd, self.allow_renew)?;
43 utils::write_bool(wd, self.allow_rescope)?;
44 utils::write_audit_ids(wd, self.audit_ids.clone())?;
45
46 Ok(())
47 }
48
49 fn disassemble(
50 rd: &mut &[u8],
51 fernet_provider: &FernetTokenProvider,
52 ) -> Result<Self::Token, TokenProviderError> {
53 let user_id = utils::read_uuid(rd)?;
55 let methods: Vec<String> = fernet_provider
56 .decode_auth_methods(read_pfix(rd)?)?
57 .into_iter()
58 .collect();
59 let token_restriction_id = utils::read_uuid(rd)?;
60 let expires_at = utils::read_time(rd)?;
61 let project_id = utils::read_uuid(rd)?;
62 let allow_renew = utils::read_bool(rd)?;
63 let allow_rescope = utils::read_bool(rd)?;
64 let audit_ids: Vec<String> = utils::read_audit_ids(rd)?.into_iter().collect();
65 Ok(Self {
66 user_id,
67 methods,
68 expires_at,
69 audit_ids,
70 token_restriction_id,
71 project_id,
72 allow_renew,
73 allow_rescope,
74
75 ..Default::default()
76 })
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use chrono::{Local, SubsecRound};
83 use uuid::Uuid;
84
85 use super::*;
86 use crate::token::tests::setup_config;
87
88 #[test]
89 fn test_roundtrip() {
90 let token = RestrictedPayload {
91 user_id: Uuid::new_v4().simple().to_string(),
92 methods: vec!["openid".into()],
93 audit_ids: vec!["Zm9vCg".into()],
94 expires_at: Local::now().trunc_subsecs(0).into(),
95 token_restriction_id: "trid".into(),
96 project_id: "pid".into(),
97 allow_renew: true,
98 allow_rescope: true,
99 ..Default::default()
100 };
101
102 let provider = FernetTokenProvider::new(setup_config());
103
104 let mut buf = vec![];
105 token.assemble(&mut buf, &provider).unwrap();
106 let encoded_buf = buf.clone();
107 let decoded =
108 RestrictedPayload::disassemble(&mut encoded_buf.as_slice(), &provider).unwrap();
109 assert_eq!(token, decoded);
110 }
111}