diff --git a/README.md b/README.md index 46c07cc..df5b40f 100644 --- a/README.md +++ b/README.md @@ -176,17 +176,19 @@ $keyPair = KeyPair::fromPrivateKey($privateKey); ### Algorithm Support ```php +use Biscuit\Auth\Algorithm; + // Ed25519 is the default algorithm (recommended) $keypair1 = new KeyPair(); // Uses Ed25519 $keypair2 = KeyPair::newWithAlgorithm(); // Uses Ed25519 by default // Explicitly use Secp256r1 -$keypair3 = KeyPair::newWithAlgorithm(1); // ALGORITHM_SECP256R1 +$keypair3 = KeyPair::newWithAlgorithm(Algorithm::Secp256r1); // Key import defaults to Ed25519 $publicKey = PublicKey::fromBytes($bytes); // Defaults to Ed25519 -$publicKey = PublicKey::fromBytes($bytes, 0); // Explicit Ed25519 -$publicKey = PublicKey::fromBytes($bytes, 1); // Explicit Secp256r1 +$publicKey = PublicKey::fromBytes($bytes, Algorithm::Ed25519); // Explicit Ed25519 +$publicKey = PublicKey::fromBytes($bytes, Algorithm::Secp256r1); // Explicit Secp256r1 ``` ## Testing diff --git a/mago.toml b/mago.toml index 40a9644..dc83af9 100644 --- a/mago.toml +++ b/mago.toml @@ -1,9 +1,10 @@ # Welcome to Mago! # For full documentation, see https://mago.carthage.software/tools/overview -php-version = "8.4.0" +php-version = "8.5.0" [source] -paths = ["tests/"] +workspace = "." +paths = ["stubs/Biscuit/", "tests/"] includes = ["vendor"] excludes = [] @@ -19,12 +20,18 @@ integrations = ["phpunit"] ambiguous-function-call = { enabled = false } literal-named-argument = { enabled = false } halstead = { effort-threshold = 7000 } +strict-types = { enabled = false } too-many-methods = { enabled = false } [analyzer] find-unused-definitions = true find-unused-expressions = false analyze-dead-code = false -check-throws = true +memoize-properties = true allow-possibly-undefined-array-keys = true +check-throws = false perform-heuristic-checks = true +strict-list-index-checks = false +no-boolean-literal-comparison = false +check-missing-type-hints = false +register-super-globals = true diff --git a/src/lib.rs b/src/lib.rs index 254fb20..1ef2445 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,20 +4,25 @@ use std::str::FromStr; use biscuit_auth::builder::Algorithm as BiscuitAlgorithm; use biscuit_auth::{KeyPair as BiscuitKeyPair, ThirdPartyBlock as BiscuitThirdPartyBlock}; use ext_php_rs::binary_slice::BinarySlice; -use ext_php_rs::zend::{ce, ModuleEntry}; +use ext_php_rs::zend::{ModuleEntry, ce}; use ext_php_rs::{info_table_end, info_table_row, info_table_start, prelude::*}; -// TODO: refactor this to use enum when ext-php-rs supports it -#[php_const] -pub const ALGORITHM_ED25519: i64 = 0; -#[php_const] -pub const ALGORITHM_SECP256R1: i64 = 1; +/// Algorithm enum for cryptographic key operations +#[php_enum] +#[php(name = "Biscuit\\Auth\\Algorithm")] +pub enum Algorithm { + #[php(value = 0)] + Ed25519, + #[php(name = "Secp256r1", value = 1)] + Secp256r1, +} -fn algorithm_from_int(value: i64) -> PhpResult { - match value { - 0 => Ok(BiscuitAlgorithm::Ed25519), - 1 => Ok(BiscuitAlgorithm::Secp256r1), - _ => Err(PhpException::default("Invalid algorithm".to_string())), +impl From for BiscuitAlgorithm { + fn from(alg: Algorithm) -> Self { + match alg { + Algorithm::Ed25519 => BiscuitAlgorithm::Ed25519, + Algorithm::Secp256r1 => BiscuitAlgorithm::Secp256r1, + } } } @@ -761,9 +766,9 @@ impl KeyPair { } #[php(name = "newWithAlgorithm")] - pub fn new_with_algorithm(alg: Option) -> PhpResult { - let algorithm = algorithm_from_int(alg.unwrap_or(0))?; - Ok(Self(BiscuitKeyPair::new_with_algorithm(algorithm))) + pub fn new_with_algorithm(alg: Option) -> Self { + let algorithm = alg.unwrap_or(Algorithm::Ed25519).into(); + Self(BiscuitKeyPair::new_with_algorithm(algorithm)) } #[php(name = "fromPrivateKey")] @@ -794,8 +799,8 @@ impl PublicKey { } #[php(name = "fromBytes")] - pub fn from_bytes(data: BinarySlice, alg: Option) -> PhpResult { - let algorithm = algorithm_from_int(alg.unwrap_or(0))?; + pub fn from_bytes(data: BinarySlice, alg: Option) -> PhpResult { + let algorithm = alg.unwrap_or(Algorithm::Ed25519).into(); biscuit_auth::PublicKey::from_bytes(data.as_ref(), algorithm) .map(Self) .map_err(|e| PhpException::from_class::(e.to_string())) @@ -842,8 +847,8 @@ impl PrivateKey { } #[php(name = "fromBytes")] - pub fn from_bytes(data: BinarySlice, alg: Option) -> PhpResult { - let algorithm = algorithm_from_int(alg.unwrap_or(0))?; + pub fn from_bytes(data: BinarySlice, alg: Option) -> PhpResult { + let algorithm = alg.unwrap_or(Algorithm::Ed25519).into(); biscuit_auth::PrivateKey::from_bytes(data.as_ref(), algorithm) .map(Self) .map_err(|e| PhpException::from_class::(e.to_string())) @@ -965,6 +970,7 @@ pub extern "C" fn php_module_info(_module: *mut ModuleEntry) { pub fn get_module(module: ModuleBuilder) -> ModuleBuilder { module .info_function(php_module_info) + .enumeration::() .class::() .class::() .class::() diff --git a/stubs/Biscuit/Auth/Algorithm.php b/stubs/Biscuit/Auth/Algorithm.php new file mode 100644 index 0000000..8cfbda6 --- /dev/null +++ b/stubs/Biscuit/Auth/Algorithm.php @@ -0,0 +1,14 @@ +public()->toHex()); @@ -39,7 +40,7 @@ public function testNewWithAlgorithmEd25519(): void public function testNewWithAlgorithmSecp256r1(): void { - $keyPair = KeyPair::newWithAlgorithm(1); + $keyPair = KeyPair::newWithAlgorithm(Algorithm::Secp256r1); static::assertInstanceOf(KeyPair::class, $keyPair); static::assertStringStartsWith('secp256r1/', $keyPair->public()->toHex()); @@ -112,7 +113,7 @@ public function testPrivateKeyFromBytesWithExplicitAlgorithm(): void $privateKey = new PrivateKey($privateKeyHex); $bytes = $privateKey->toBytes(); - $reconstructed = PrivateKey::fromBytes(pack('C*', ...$bytes), 0); + $reconstructed = PrivateKey::fromBytes(pack('C*', ...$bytes), Algorithm::Ed25519); static::assertSame($privateKeyHex, $reconstructed->toHex()); } @@ -187,7 +188,7 @@ public function testPublicKeyFromBytesWithExplicitAlgorithm(): void $publicKey = new PublicKey($publicKeyHex); $bytes = $publicKey->toBytes(); - $reconstructed = PublicKey::fromBytes(pack('C*', ...$bytes), 0); + $reconstructed = PublicKey::fromBytes(pack('C*', ...$bytes), Algorithm::Ed25519); static::assertSame($publicKeyHex, $reconstructed->toHex()); }