|
9 | 9 | #![allow(clippy::useless_conversion)] |
10 | 10 | use ::biscuit_auth::builder::MapKey; |
11 | 11 | use ::biscuit_auth::datalog::ExternFunc; |
| 12 | +use ::biscuit_auth::error::MatchedPolicy; |
12 | 13 | use ::biscuit_auth::AuthorizerBuilder; |
13 | 14 | use ::biscuit_auth::RootKeyProvider; |
14 | 15 | use ::biscuit_auth::UnverifiedBiscuit; |
@@ -38,6 +39,27 @@ create_exception!( |
38 | 39 | AuthorizationError, |
39 | 40 | pyo3::exceptions::PyException |
40 | 41 | ); |
| 42 | + |
| 43 | +#[derive(IntoPyObject)] |
| 44 | +struct AuthorizationErrorData { |
| 45 | + policy_id: Option<MatchedPolicyData>, |
| 46 | + checks: Vec<FailedCheckData>, |
| 47 | +} |
| 48 | + |
| 49 | +#[derive(IntoPyObject)] |
| 50 | +struct MatchedPolicyData { |
| 51 | + policy_id: usize, |
| 52 | + code: String, |
| 53 | +} |
| 54 | + |
| 55 | +#[derive(IntoPyObject)] |
| 56 | +struct FailedCheckData { |
| 57 | + authorizer_check: bool, |
| 58 | + block_id: Option<u32>, |
| 59 | + check_id: u32, |
| 60 | + code: String, |
| 61 | +} |
| 62 | + |
41 | 63 | create_exception!( |
42 | 64 | biscuit_auth, |
43 | 65 | BiscuitBuildError, |
@@ -786,9 +808,37 @@ impl PyAuthorizer { |
786 | 808 | /// :return: the index of the matched allow rule |
787 | 809 | /// :rtype: int |
788 | 810 | pub fn authorize(&mut self) -> PyResult<usize> { |
789 | | - self.0 |
790 | | - .authorize() |
791 | | - .map_err(|error| AuthorizationError::new_err(error.to_string())) |
| 811 | + self.0.authorize().map_err(|error| match error { |
| 812 | + error::Token::FailedLogic(error::Logic::Unauthorized { |
| 813 | + policy: MatchedPolicy::Deny(pid), |
| 814 | + checks, |
| 815 | + }) => AuthorizationError::new_err(AuthorizationErrorData { |
| 816 | + policy_id: Some(MatchedPolicyData { |
| 817 | + policy_id: pid, |
| 818 | + code: self.0.dump().3.get(pid).unwrap().to_string(), |
| 819 | + }), |
| 820 | + checks: checks |
| 821 | + .into_iter() |
| 822 | + .map(|c| match c { |
| 823 | + error::FailedCheck::Block(failed_block_check) => FailedCheckData { |
| 824 | + authorizer_check: false, |
| 825 | + block_id: Some(failed_block_check.block_id), |
| 826 | + check_id: failed_block_check.check_id, |
| 827 | + code: failed_block_check.rule, |
| 828 | + }, |
| 829 | + error::FailedCheck::Authorizer(failed_authorizer_check) => { |
| 830 | + FailedCheckData { |
| 831 | + authorizer_check: true, |
| 832 | + block_id: None, |
| 833 | + check_id: failed_authorizer_check.check_id, |
| 834 | + code: failed_authorizer_check.rule, |
| 835 | + } |
| 836 | + } |
| 837 | + }) |
| 838 | + .collect(), |
| 839 | + }), |
| 840 | + _ => AuthorizationError::new_err(error.to_string()), |
| 841 | + }) |
792 | 842 | } |
793 | 843 |
|
794 | 844 | /// Query the authorizer by returning all the `Fact`s generated by the provided `Rule`. The generated facts won't be |
|
0 commit comments