1extern crate biscuit_auth as biscuit;
2
3use crate::verify::{biscuit_key_from_string, ServiceNode};
4
5use biscuit::macros::{biscuit, check, rule};
6use biscuit::{Biscuit, BiscuitBuilder, KeyPair};
7use chrono::Utc;
8use std::error::Error;
9use tracing::info;
10
11#[derive(Debug, Clone, Copy)]
16pub struct TokenTimeConfig {
17 pub start_time: Option<i64>,
19 pub duration: i64,
21}
22
23impl Default for TokenTimeConfig {
24 fn default() -> Self {
25 Self {
26 start_time: None,
27 duration: 300, }
29 }
30}
31
32fn _create_base_biscuit_builder(
48 subject: String,
49 resource: String,
50 operation: String,
51) -> Result<BiscuitBuilder, Box<dyn Error>> {
52 create_base_biscuit_builder_with_time(subject, resource, operation, TokenTimeConfig::default())
53}
54
55fn create_base_biscuit_builder_with_time(
72 subject: String,
73 resource: String,
74 operation: String,
75 time_config: TokenTimeConfig,
76) -> Result<BiscuitBuilder, Box<dyn Error>> {
77 let start_time = time_config
78 .start_time
79 .unwrap_or_else(|| Utc::now().timestamp());
80 let expiration = start_time + time_config.duration;
81
82 let biscuit_builder = biscuit!(
83 r#"
84 right({subject}, {resource}, {operation});
85 check if time($time), $time < {expiration};
86 "#
87 );
88
89 Ok(biscuit_builder)
90}
91
92pub fn create_raw_biscuit(
112 subject: String,
113 resource: String,
114 operation: String,
115 key: KeyPair,
116 time_config: TokenTimeConfig,
117) -> Result<Biscuit, Box<dyn Error>> {
118 let biscuit = create_base_biscuit_builder_with_time(subject, resource, operation, time_config)?
119 .build(&key)?;
120
121 info!("biscuit (authority): {}", biscuit);
122
123 Ok(biscuit)
124}
125
126pub fn create_biscuit(
144 subject: String,
145 resource: String,
146 operation: String,
147 key: KeyPair,
148 time_config: TokenTimeConfig,
149) -> Result<Vec<u8>, Box<dyn Error>> {
150 let biscuit = create_raw_biscuit(subject, resource, operation, key, time_config)?;
151 let token = biscuit.to_vec()?;
152 Ok(token)
153}
154
155fn create_base64_biscuit(
173 subject: String,
174 resource: String,
175 operation: String,
176 key: KeyPair,
177 time_config: TokenTimeConfig,
178) -> Result<String, Box<dyn Error>> {
179 let biscuit = create_raw_biscuit(subject, resource, operation, key, time_config)?;
180 let token = biscuit.to_base64()?;
181 Ok(token)
182}
183
184pub fn create_token(
202 subject: String,
203 resource: String,
204 operation: String,
205 key: KeyPair,
206) -> Result<String, Box<dyn Error>> {
207 create_base64_biscuit(
208 subject,
209 resource,
210 operation,
211 key,
212 TokenTimeConfig::default(),
213 )
214}
215
216pub fn create_token_with_time(
234 subject: String,
235 resource: String,
236 operation: String,
237 key: KeyPair,
238 time_config: TokenTimeConfig,
239) -> Result<String, Box<dyn Error>> {
240 create_base64_biscuit(subject, resource, operation, key, time_config)
241}
242
243pub fn create_service_chain_biscuit(
262 subject: String,
263 resource: String,
264 operation: String,
265 key: KeyPair,
266 nodes: &Vec<ServiceNode>,
267 time_config: TokenTimeConfig,
268) -> Result<Vec<u8>, Box<dyn Error>> {
269 let biscuit =
270 create_raw_service_chain_biscuit(subject, resource, operation, key, nodes, time_config)?;
271 let token = biscuit.to_vec()?;
272 Ok(token)
273}
274
275fn create_base64_service_chain_biscuit(
294 subject: String,
295 resource: String,
296 operation: String,
297 key: KeyPair,
298 nodes: &Vec<ServiceNode>,
299 time_config: TokenTimeConfig,
300) -> Result<String, Box<dyn Error>> {
301 let biscuit =
302 create_raw_service_chain_biscuit(subject, resource, operation, key, nodes, time_config)?;
303 let token = biscuit.to_base64()?;
304 Ok(token)
305}
306
307pub fn create_raw_service_chain_biscuit(
327 subject: String,
328 resource: String,
329 operation: String,
330 key: KeyPair,
331 nodes: &Vec<ServiceNode>,
332 time_config: TokenTimeConfig,
333) -> Result<Biscuit, Box<dyn Error>> {
334 create_service_chain_biscuit_with_time(subject, resource, operation, key, nodes, time_config)
335}
336
337pub fn create_service_chain_token(
357 subject: String,
358 resource: String,
359 operation: String,
360 key: KeyPair,
361 nodes: &Vec<ServiceNode>,
362) -> Result<String, Box<dyn Error>> {
363 create_base64_service_chain_biscuit(
364 subject,
365 resource,
366 operation,
367 key,
368 nodes,
369 TokenTimeConfig::default(),
370 )
371}
372
373pub fn create_service_chain_biscuit_with_time(
392 subject: String,
393 resource: String,
394 operation: String,
395 key: KeyPair,
396 nodes: &Vec<ServiceNode>,
397 time_config: TokenTimeConfig,
398) -> Result<Biscuit, Box<dyn Error>> {
399 let service = resource.clone();
400 let mut biscuit_builder =
401 create_base_biscuit_builder_with_time(subject, service, operation, time_config)?;
402
403 for node in nodes {
405 let component = node.component.clone();
406 let public_key = biscuit_key_from_string(node.public_key.clone())?;
407 biscuit_builder = biscuit_builder.rule(rule!(
408 r#"
409 node($s, {component}) <- service($s) trusting {public_key};
410 "#
411 ))?;
412 }
413
414 let biscuit = biscuit_builder.build(&key)?;
415
416 info!("biscuit (authority): {}", biscuit);
417
418 Ok(biscuit)
419}
420
421pub fn create_service_chain_token_with_time(
441 subject: String,
442 resource: String,
443 operation: String,
444 key: KeyPair,
445 nodes: &Vec<ServiceNode>,
446 time_config: TokenTimeConfig,
447) -> Result<String, Box<dyn Error>> {
448 let biscuit = create_service_chain_biscuit_with_time(
449 subject,
450 resource,
451 operation,
452 key,
453 nodes,
454 time_config,
455 )?;
456 let token = biscuit.to_base64()?;
457 Ok(token)
458}
459
460pub fn create_raw_multi_party_biscuit(
476 subject: String,
477 resource: String,
478 operation: String,
479 key: KeyPair,
480 multi_party_nodes: &Vec<ServiceNode>,
481) -> Result<Biscuit, Box<dyn Error>> {
482 create_multi_party_biscuit_with_time(
483 subject,
484 resource,
485 operation,
486 key,
487 multi_party_nodes,
488 TokenTimeConfig::default(),
489 )
490}
491
492pub fn create_multi_party_biscuit(
513 subject: String,
514 resource: String,
515 operation: String,
516 key: KeyPair,
517 multi_party_nodes: &Vec<ServiceNode>,
518) -> Result<Vec<u8>, Box<dyn Error>> {
519 let biscuit =
520 create_raw_multi_party_biscuit(subject, resource, operation, key, multi_party_nodes)?;
521 let token = biscuit.to_vec()?;
522 Ok(token)
523}
524
525fn create_base64_multi_party_biscuit(
546 subject: String,
547 resource: String,
548 operation: String,
549 key: KeyPair,
550 multi_party_nodes: &Vec<ServiceNode>,
551 time_config: TokenTimeConfig,
552) -> Result<String, Box<dyn Error>> {
553 let biscuit = create_multi_party_biscuit_with_time(
554 subject,
555 resource,
556 operation,
557 key,
558 multi_party_nodes,
559 time_config,
560 )?;
561 let token = biscuit.to_base64()?;
562 Ok(token)
563}
564
565pub fn create_multi_party_token(
586 subject: String,
587 resource: String,
588 operation: String,
589 key: KeyPair,
590 multi_party_nodes: &Vec<ServiceNode>,
591) -> Result<String, Box<dyn Error>> {
592 create_base64_multi_party_biscuit(
593 subject,
594 resource,
595 operation,
596 key,
597 multi_party_nodes,
598 TokenTimeConfig::default(),
599 )
600}
601
602pub fn create_multi_party_biscuit_with_time(
624 subject: String,
625 resource: String,
626 operation: String,
627 key: KeyPair,
628 multi_party_nodes: &Vec<ServiceNode>,
629 time_config: TokenTimeConfig,
630) -> Result<Biscuit, Box<dyn Error>> {
631 let mut biscuit_builder =
632 create_base_biscuit_builder_with_time(subject, resource, operation, time_config)?;
633
634 for node in multi_party_nodes {
635 let component = node.component.clone();
636 let public_key = biscuit_key_from_string(node.public_key.clone())?;
637 biscuit_builder = biscuit_builder.check(check!(
638 r#"
639 check if namespace({component}) trusting {public_key};
640 "#
641 ))?;
642 }
643
644 let biscuit = biscuit_builder.build(&key)?;
645
646 info!("biscuit (authority): {}", biscuit);
647
648 Ok(biscuit)
649}
650
651pub fn create_multi_party_token_with_time(
652 subject: String,
653 resource: String,
654 operation: String,
655 key: KeyPair,
656 multi_party_nodes: &Vec<ServiceNode>,
657 time_config: TokenTimeConfig,
658) -> Result<String, Box<dyn Error>> {
659 let biscuit = create_multi_party_biscuit_with_time(
660 subject,
661 resource,
662 operation,
663 key,
664 multi_party_nodes,
665 time_config,
666 )?;
667 let token = biscuit.to_base64()?;
668 Ok(token)
669}
670
671#[cfg(test)]
672mod tests {
673 use super::*;
674 use crate::verify::{verify_biscuit_local, verify_service_chain_biscuit_local};
675 use biscuit::macros::block;
676 use biscuit::Biscuit;
677 #[test]
678 fn test_create_biscuit() {
679 let subject = "test@test.com".to_owned();
680 let resource: String = "res1".to_string();
681 let operation = "read".to_string();
682 let root = KeyPair::new();
683 let public_key = root.public();
684 let token = create_biscuit(
685 subject.clone(),
686 resource.clone(),
687 operation.clone(),
688 root,
689 TokenTimeConfig::default(),
690 )
691 .unwrap();
692
693 let res = verify_biscuit_local(token, public_key, subject, resource, operation);
694 assert!(res.is_ok());
695 }
696
697 #[test]
698 fn test_biscuit_operations() {
699 let subject = "test@test.com".to_owned();
700 let resource = "res1".to_string();
701 let operation = "read".to_string();
702 let root = KeyPair::new();
703 let public_key = root.public();
704
705 let read_token = create_biscuit(
707 subject.clone(),
708 resource.clone(),
709 operation.clone(),
710 root,
711 TokenTimeConfig::default(),
712 )
713 .unwrap();
714
715 let res = verify_biscuit_local(
716 read_token.clone(),
717 public_key,
718 subject.clone(),
719 resource.clone(),
720 operation.clone(),
721 );
722 assert!(res.is_ok());
723
724 let root = KeyPair::new();
725 let public_key = root.public();
726
727 let write_token = create_biscuit(
729 subject.clone(),
730 resource.clone(),
731 "write".to_string(),
732 root,
733 TokenTimeConfig::default(),
734 )
735 .unwrap();
736
737 let res = verify_biscuit_local(
738 write_token.clone(),
739 public_key,
740 subject.clone(),
741 resource.clone(),
742 "write".to_string(),
743 );
744 assert!(res.is_ok());
745
746 let res = verify_biscuit_local(
748 read_token,
749 public_key,
750 subject.clone(),
751 resource.clone(),
752 "write".to_string(),
753 );
754 assert!(res.is_err());
755
756 let res = verify_biscuit_local(
758 write_token,
759 public_key,
760 subject.clone(),
761 resource.clone(),
762 "read".to_string(),
763 );
764 assert!(res.is_err());
765 }
766
767 #[test]
768 fn test_biscuit_expiration() {
769 let subject = "test@test.com".to_owned();
770 let resource = "res1".to_string();
771 let operation = "read".to_string();
772 let root = KeyPair::new();
773 let public_key = root.public();
774 let token = create_biscuit(
776 subject.clone(),
777 resource.clone(),
778 operation.clone(),
779 root,
780 TokenTimeConfig::default(),
781 )
782 .unwrap();
783
784 let res = verify_biscuit_local(
785 token.clone(),
786 public_key,
787 subject.clone(),
788 resource.clone(),
789 operation.clone(),
790 );
791 assert!(res.is_ok());
792
793 let root = KeyPair::new();
795 let token = create_biscuit(
796 subject.clone(),
797 resource.clone(),
798 operation.clone(),
799 root,
800 TokenTimeConfig {
801 start_time: Some(Utc::now().timestamp() - 301),
802 duration: 300,
803 },
804 )
805 .unwrap();
806 let res = verify_biscuit_local(token, public_key, subject, resource, operation);
807 assert!(res.is_err());
808 }
809
810 #[test]
811 fn test_custom_token_time_config() {
812 let subject = "test@test.com".to_owned();
813 let resource = "res1".to_string();
814 let operation = "read".to_string();
815 let root = KeyPair::new();
816 let public_key = root.public();
817
818 let past_time = Utc::now().timestamp() - 3600;
820 let time_config = TokenTimeConfig {
821 start_time: Some(past_time),
822 duration: 7200, };
824
825 let token = create_biscuit(
826 subject.clone(),
827 resource.clone(),
828 operation.clone(),
829 root,
830 time_config,
831 )
832 .unwrap();
833
834 let res = verify_biscuit_local(
836 token.clone(),
837 public_key,
838 subject.clone(),
839 resource.clone(),
840 operation.clone(),
841 );
842 assert!(res.is_ok());
843 }
844
845 #[test]
846 fn test_service_chain_biscuit() {
847 let subject = "test@test.com".to_owned();
848 let resource = "res1".to_string();
849 let operation = "read".to_string();
850 let root = KeyPair::new();
851 let public_key = root.public();
852 let chain_key = KeyPair::new();
853 let chain_public_key = hex::encode(chain_key.public().to_bytes());
854 let chain_public_key = format!("ed25519/{}", chain_public_key);
855 let chain_node = ServiceNode {
856 component: "edge_function".to_string(),
857 public_key: chain_public_key.clone(),
858 };
859 let nodes = vec![chain_node];
860 let token = create_service_chain_biscuit(
861 subject.clone(),
862 resource.clone(),
863 operation.clone(),
864 root,
865 &nodes,
866 TokenTimeConfig::default(),
867 );
868 if let Err(e) = &token {
869 println!("Error: {}", e);
870 }
871 assert!(token.is_ok());
872 let token = token.unwrap();
873 let res = verify_biscuit_local(
874 token.clone(),
875 public_key,
876 subject.clone(),
877 resource.clone(),
878 operation.clone(),
879 );
880 assert!(res.is_ok());
881 let biscuit = Biscuit::from(&token, public_key).unwrap();
882 let third_party_request = biscuit.third_party_request().unwrap();
883 let third_party_block = block!(
884 r#"
885 service("res1");
886 "#
887 );
888 let third_party_block = third_party_request
889 .create_block(&chain_key.private(), third_party_block)
890 .unwrap();
891 let attested_biscuit = biscuit
892 .append_third_party(chain_key.public(), third_party_block)
893 .unwrap();
894 let attested_token = attested_biscuit.to_vec().unwrap();
895 let res = verify_service_chain_biscuit_local(
896 attested_token,
897 public_key,
898 subject.clone(),
899 resource.clone(),
900 operation.clone(),
901 nodes,
902 None,
903 );
904 assert!(res.is_ok());
905 }
906
907 #[test]
908 fn test_service_chain_biscuit_with_component_name() {
909 let subject = "test@test.com".to_owned();
910 let resource = "res1".to_string();
911 let root = KeyPair::new();
912 let public_key = root.public();
913
914 let chain_key1 = KeyPair::new();
916 let chain_public_key1 = hex::encode(chain_key1.public().to_bytes());
917 let chain_public_key1 = format!("ed25519/{}", chain_public_key1);
918 let chain_node1 = ServiceNode {
919 component: "edge_function".to_string(),
920 public_key: chain_public_key1.clone(),
921 };
922
923 let chain_key2 = KeyPair::new();
924 let chain_public_key2 = hex::encode(chain_key2.public().to_bytes());
925 let chain_public_key2 = format!("ed25519/{}", chain_public_key2);
926 let chain_node2 = ServiceNode {
927 component: "middleware".to_string(),
928 public_key: chain_public_key2.clone(),
929 };
930
931 let nodes = vec![chain_node1.clone(), chain_node2.clone()];
932
933 let token = create_service_chain_biscuit(
935 subject.clone(),
936 resource.clone(),
937 "read".to_string(),
938 root,
939 &nodes,
940 TokenTimeConfig::default(),
941 );
942 assert!(token.is_ok());
943 let token = token.unwrap();
944
945 let biscuit = Biscuit::from(&token, public_key).unwrap();
947 let third_party_request = biscuit.third_party_request().unwrap();
948 let third_party_block = block!(
949 r#"
950 service("res1");
951 "#
952 );
953 let third_party_block = third_party_request
954 .create_block(&chain_key1.private(), third_party_block)
955 .unwrap();
956 let attested_biscuit = biscuit
957 .append_third_party(chain_key1.public(), third_party_block)
958 .unwrap();
959 let attested_token = attested_biscuit.to_vec().unwrap();
960
961 let res = verify_service_chain_biscuit_local(
965 attested_token.clone(),
966 public_key,
967 subject.clone(),
968 resource.clone(),
969 "read".to_string(),
970 nodes.clone(),
971 Some("edge_function".to_string()),
972 );
973 assert!(res.is_ok());
975
976 let nodes = vec![chain_node1.clone(), chain_node2.clone()];
978
979 let res = verify_service_chain_biscuit_local(
981 attested_token.clone(),
982 public_key,
983 subject.clone(),
984 resource.clone(),
985 "read".to_string(),
986 nodes.clone(),
987 Some("middleware".to_string()),
988 );
989 assert!(res.is_ok());
990 }
991
992 #[test]
993 fn test_service_chain_biscuit_with_nonexistent_component() {
994 let subject = "test@test.com".to_owned();
995 let resource = "res1".to_string();
996 let root = KeyPair::new();
997 let public_key = root.public();
998 let chain_key = KeyPair::new();
999 let chain_public_key = hex::encode(chain_key.public().to_bytes());
1000 let chain_public_key = format!("ed25519/{}", chain_public_key);
1001 let chain_node = ServiceNode {
1002 component: "edge_function".to_string(),
1003 public_key: chain_public_key.clone(),
1004 };
1005 let nodes = vec![chain_node];
1006 let token = create_service_chain_biscuit(
1007 subject.clone(),
1008 resource.clone(),
1009 "read".to_string(),
1010 root,
1011 &nodes,
1012 TokenTimeConfig::default(),
1013 );
1014 assert!(token.is_ok());
1015 let token = token.unwrap();
1016
1017 let biscuit = Biscuit::from(&token, public_key).unwrap();
1018 let third_party_request = biscuit.third_party_request().unwrap();
1019 let third_party_block = block!(
1020 r#"
1021 service("res1");
1022 "#
1023 );
1024 let third_party_block = third_party_request
1025 .create_block(&chain_key.private(), third_party_block)
1026 .unwrap();
1027 let attested_biscuit = biscuit
1028 .append_third_party(chain_key.public(), third_party_block)
1029 .unwrap();
1030 let attested_token = attested_biscuit.to_vec().unwrap();
1031
1032 let res = verify_service_chain_biscuit_local(
1034 attested_token,
1035 public_key,
1036 subject.clone(),
1037 resource.clone(),
1038 "read".to_string(),
1039 nodes.clone(),
1040 Some("nonexistent_component".to_string()),
1041 );
1042 assert!(res.is_err());
1043
1044 let err = res.unwrap_err().to_string();
1046 assert!(err.contains("nonexistent_component"));
1047 }
1048
1049 #[test]
1050 fn test_service_chain_biscuit_with_multiple_nodes() {
1051 let subject = "test@test.com".to_owned();
1052 let resource = "res1".to_string();
1053 let root = KeyPair::new();
1054 let public_key = root.public();
1055
1056 let chain_key1 = KeyPair::new();
1058 let chain_public_key1 = hex::encode(chain_key1.public().to_bytes());
1059 let chain_public_key1 = format!("ed25519/{}", chain_public_key1);
1060 let chain_node1 = ServiceNode {
1061 component: "edge_function".to_string(),
1062 public_key: chain_public_key1.clone(),
1063 };
1064
1065 let chain_key2 = KeyPair::new();
1066 let chain_public_key2 = hex::encode(chain_key2.public().to_bytes());
1067 let chain_public_key2 = format!("ed25519/{}", chain_public_key2);
1068 let chain_node2 = ServiceNode {
1069 component: "middleware".to_string(),
1070 public_key: chain_public_key2.clone(),
1071 };
1072
1073 let chain_key3 = KeyPair::new();
1074 let chain_public_key3 = hex::encode(chain_key3.public().to_bytes());
1075 let chain_public_key3 = format!("ed25519/{}", chain_public_key3);
1076 let chain_node3 = ServiceNode {
1077 component: "backend".to_string(),
1078 public_key: chain_public_key3.clone(),
1079 };
1080
1081 let nodes = vec![
1083 chain_node1.clone(),
1084 chain_node2.clone(),
1085 chain_node3.clone(),
1086 ];
1087 let token = create_service_chain_biscuit(
1088 subject.clone(),
1089 resource.clone(),
1090 "read".to_string(),
1091 root,
1092 &nodes,
1093 TokenTimeConfig::default(),
1094 );
1095 assert!(token.is_ok());
1096 let token = token.unwrap();
1097
1098 println!("Created initial token");
1099
1100 let biscuit = Biscuit::from(&token, public_key).unwrap();
1102 let third_party_request1 = biscuit.third_party_request().unwrap();
1103 let third_party_block1 = block!(
1104 r#"
1105 service("res1");
1106 "#
1107 );
1108 let third_party_block1 = third_party_request1
1109 .create_block(&chain_key1.private(), third_party_block1)
1110 .unwrap();
1111 let attested_biscuit1 = biscuit
1112 .append_third_party(chain_key1.public(), third_party_block1)
1113 .unwrap();
1114
1115 let all_nodes = vec![
1117 chain_node1.clone(),
1118 chain_node2.clone(),
1119 chain_node3.clone(),
1120 ];
1121 let attested_token1 = attested_biscuit1.to_vec().unwrap();
1122
1123 let res = verify_service_chain_biscuit_local(
1126 attested_token1.clone(),
1127 public_key,
1128 subject.clone(),
1129 resource.clone(),
1130 "read".to_string(),
1131 all_nodes.clone(),
1132 Some("middleware".to_string()),
1133 );
1134 assert!(res.is_ok());
1135
1136 let res = verify_service_chain_biscuit_local(
1140 attested_token1.clone(),
1141 public_key,
1142 subject.clone(),
1143 resource.clone(),
1144 "read".to_string(),
1145 all_nodes.clone(),
1146 Some("backend".to_string()),
1147 );
1148 assert!(res.is_err());
1149 }
1150
1151 #[test]
1152 fn test_service_chain_biscuit_with_custom_time() {
1153 let subject = "test@test.com".to_owned();
1154 let resource = "res1".to_string();
1155 let root = KeyPair::new();
1156 let public_key = root.public();
1157 let chain_key = KeyPair::new();
1158 let chain_public_key = hex::encode(chain_key.public().to_bytes());
1159 let chain_public_key = format!("ed25519/{}", chain_public_key);
1160 let chain_node = ServiceNode {
1161 component: "edge_function".to_string(),
1162 public_key: chain_public_key.clone(),
1163 };
1164 let nodes = vec![chain_node];
1165
1166 let valid_token = create_service_chain_biscuit_with_time(
1168 subject.clone(),
1169 resource.clone(),
1170 "read".to_string(),
1171 root,
1172 &nodes,
1173 TokenTimeConfig::default(),
1174 );
1175 assert!(valid_token.is_ok());
1176 let valid_token = valid_token.unwrap().to_vec().unwrap();
1177
1178 let res = verify_biscuit_local(
1180 valid_token.clone(),
1181 public_key,
1182 subject.clone(),
1183 resource.clone(),
1184 "read".to_string(),
1185 );
1186 assert!(res.is_ok());
1187
1188 let expired_time_config = TokenTimeConfig {
1190 start_time: Some(Utc::now().timestamp() - 360), duration: 300, };
1193
1194 let root2 = KeyPair::new();
1196 let public_key2 = root2.public();
1197
1198 let expired_token = create_service_chain_biscuit_with_time(
1199 subject.clone(),
1200 resource.clone(),
1201 "read".to_string(),
1202 root2,
1203 &nodes,
1204 expired_time_config,
1205 );
1206 assert!(expired_token.is_ok());
1207 let expired_token = expired_token.unwrap().to_vec().unwrap();
1208
1209 let res = verify_biscuit_local(
1211 expired_token,
1212 public_key2,
1213 subject,
1214 resource,
1215 "read".to_string(),
1216 );
1217 assert!(res.is_err());
1218 }
1219
1220 #[test]
1221 fn test_multi_party_biscuit_helper_functions() {
1222 let subject = "test@test.com".to_owned();
1223 let resource = "res1".to_string();
1224 let operation = "read".to_string();
1225 let root = KeyPair::new();
1226
1227 let multi_party_key = KeyPair::new();
1229 let multi_party_public_key = hex::encode(multi_party_key.public().to_bytes());
1230 let multi_party_public_key = format!("ed25519/{}", multi_party_public_key);
1231 let multi_party_node = ServiceNode {
1232 component: "approval_service".to_string(),
1233 public_key: multi_party_public_key.clone(),
1234 };
1235 let nodes = vec![multi_party_node];
1236
1237 let token_string = create_multi_party_token(
1239 subject.clone(),
1240 resource.clone(),
1241 operation.clone(),
1242 root,
1243 &nodes,
1244 );
1245 assert!(token_string.is_ok());
1246
1247 let root2 = KeyPair::new();
1249 let binary_token = create_multi_party_biscuit(
1250 subject.clone(),
1251 resource.clone(),
1252 operation.clone(),
1253 root2,
1254 &nodes,
1255 );
1256 assert!(binary_token.is_ok());
1257
1258 let root3 = KeyPair::new();
1260 let raw_biscuit = create_raw_multi_party_biscuit(
1261 subject.clone(),
1262 resource.clone(),
1263 operation.clone(),
1264 root3,
1265 &nodes,
1266 );
1267 assert!(raw_biscuit.is_ok());
1268
1269 let custom_time_config = TokenTimeConfig {
1271 start_time: Some(Utc::now().timestamp()),
1272 duration: 600, };
1274 let root4 = KeyPair::new();
1275 let custom_time_token = create_multi_party_token_with_time(
1276 subject.clone(),
1277 resource.clone(),
1278 operation.clone(),
1279 root4,
1280 &nodes,
1281 custom_time_config,
1282 );
1283 assert!(custom_time_token.is_ok());
1284
1285 let root5 = KeyPair::new();
1287 let custom_time_biscuit = create_multi_party_biscuit_with_time(
1288 subject.clone(),
1289 resource.clone(),
1290 operation.clone(),
1291 root5,
1292 &nodes,
1293 custom_time_config,
1294 );
1295 assert!(custom_time_biscuit.is_ok());
1296 }
1297}