@@ -11,6 +11,8 @@ use ::biscuit_auth::builder::MapKey;
1111use :: biscuit_auth:: datalog:: ExternFunc ;
1212use :: biscuit_auth:: AuthorizerBuilder ;
1313use :: biscuit_auth:: RootKeyProvider ;
14+ use :: biscuit_auth:: ThirdPartyBlock ;
15+ use :: biscuit_auth:: ThirdPartyRequest ;
1416use :: biscuit_auth:: UnverifiedBiscuit ;
1517use chrono:: DateTime ;
1618use chrono:: Duration ;
@@ -397,6 +399,36 @@ impl PyBiscuit {
397399 . map ( PyBiscuit )
398400 }
399401
402+ /// Create a new `Biscuit` by appending a third-party attenuation block
403+ ///
404+ /// :param external_key: the public key of the third-party that signed the block.
405+ /// :type external_key: PublicKey
406+ /// :param block: the third party block to append
407+ /// :type block: ThirdPartyBlock
408+ /// :return: the attenuated biscuit
409+ /// :rtype: Biscuit
410+ pub fn append_third_party (
411+ & self ,
412+ external_key : & PyPublicKey ,
413+ block : & PyThirdPartyBlock ,
414+ ) -> PyResult < PyBiscuit > {
415+ self . 0
416+ . append_third_party ( external_key. 0 , block. 0 . clone ( ) )
417+ . map_err ( |e| BiscuitBuildError :: new_err ( e. to_string ( ) ) )
418+ . map ( PyBiscuit )
419+ }
420+
421+ /// Create a third-party request for generating third-party blocks.
422+ ///
423+ /// :return: the third-party request
424+ /// :rtype: ThirdPartyRequest
425+ pub fn third_party_request ( & self ) -> PyResult < PyThirdPartyRequest > {
426+ self . 0
427+ . third_party_request ( )
428+ . map_err ( |e| BiscuitBuildError :: new_err ( e. to_string ( ) ) )
429+ . map ( |request| PyThirdPartyRequest ( Some ( request) ) )
430+ }
431+
400432 /// The revocation ids of the token, encoded as hexadecimal strings
401433 #[ getter]
402434 pub fn revocation_ids ( & self ) -> Vec < String > {
@@ -407,6 +439,21 @@ impl PyBiscuit {
407439 . collect ( )
408440 }
409441
442+ /// Get the external key of a block if it exists
443+ ///
444+ /// :param index: the block index
445+ /// :type index: int
446+ /// :return: the public key if it exists
447+ /// :rtype: str | None
448+ pub fn block_external_key ( & self , index : usize ) -> PyResult < Option < PyPublicKey > > {
449+ let opt_key = self
450+ . 0
451+ . block_external_key ( index)
452+ . map_err ( |e| BiscuitBlockError :: new_err ( e. to_string ( ) ) ) ?;
453+
454+ Ok ( opt_key. map ( PyPublicKey ) )
455+ }
456+
410457 fn __repr__ ( & self ) -> String {
411458 self . 0 . print ( )
412459 }
@@ -1018,6 +1065,41 @@ impl PyBlockBuilder {
10181065 }
10191066}
10201067
1068+ #[ pyclass( name = "ThirdPartyRequest" ) ]
1069+ pub struct PyThirdPartyRequest ( Option < ThirdPartyRequest > ) ;
1070+
1071+ #[ pymethods]
1072+ impl PyThirdPartyRequest {
1073+ /// Create a third-party block
1074+ ///
1075+ /// :param private_key: the third-party's private key used to sign the block
1076+ /// :type external_key: PrivateKey
1077+ /// :param block: the block builder to be signed
1078+ /// :type block: BlockBuilder
1079+ /// :return: a signed block that can be appended to a Biscuit
1080+ /// :rtype: ThirdPartyBlock
1081+ ///
1082+ /// :note: this method consumes the `ThirdPartyRequest` object.
1083+ pub fn create_block (
1084+ & mut self ,
1085+ private_key : & PyPrivateKey ,
1086+ block : & PyBlockBuilder ,
1087+ ) -> PyResult < PyThirdPartyBlock > {
1088+ self . 0
1089+ . take ( )
1090+ . expect ( "third party request already consumed" )
1091+ . create_block (
1092+ & private_key. 0 ,
1093+ block. 0 . clone ( ) . expect ( "builder already consumed" ) ,
1094+ )
1095+ . map_err ( |e| BiscuitBuildError :: new_err ( e. to_string ( ) ) )
1096+ . map ( PyThirdPartyBlock )
1097+ }
1098+ }
1099+
1100+ #[ pyclass( name = "ThirdPartyBlock" ) ]
1101+ pub struct PyThirdPartyBlock ( ThirdPartyBlock ) ;
1102+
10211103/// ed25519 keypair
10221104#[ pyclass( name = "KeyPair" ) ]
10231105pub struct PyKeyPair ( KeyPair ) ;
0 commit comments