diff --git a/.github/workflows/distribute.yml b/.github/workflows/distribute.yml index 7152390..01c6d3b 100644 --- a/.github/workflows/distribute.yml +++ b/.github/workflows/distribute.yml @@ -1,9 +1,9 @@ -# This file is autogenerated by maturin v0.14.17 +# This file is autogenerated by maturin v1.8.3 # To update, run # # maturin generate-ci github # -name: Package & Distribute +name: CI on: push: @@ -12,117 +12,133 @@ on: tags: - '*' -env: - UNIX_PYTHON_VERSIONS: 3.9 3.10 3.11 3.12 3.13 pypy3.10 - WINDOWS_PYTHON_VERSIONS: 3.9 3.10 3.11 3.12 3.13 - permissions: contents: read jobs: linux: - runs-on: ubuntu-latest + runs-on: ${{ matrix.platform.runner }} strategy: matrix: - target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] + platform: + - runner: ubuntu-22.04 + target: x86_64 + - runner: ubuntu-22.04 + target: x86 + - runner: ubuntu-22.04 + target: aarch64 + - runner: ubuntu-22.04 + target: armv7 + - runner: ubuntu-22.04 + target: s390x + - runner: ubuntu-22.04 + target: ppc64le steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.13' + python-version: 3.x - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.UNIX_PYTHON_VERSIONS }} - sccache: 'true' + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} manylinux: auto - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-linux-${{ matrix.target }} + name: wheels-linux-${{ matrix.platform.target }} path: dist - linux-musl: - runs-on: ubuntu-latest + musllinux: + runs-on: ${{ matrix.platform.runner }} strategy: matrix: - platform: [ - { target: "x86_64-unknown-linux-musl", image_tag: "x86_64-musl" }, - { target: "i686-unknown-linux-musl", image_tag: "i686-musl" }, - { target: "aarch64-unknown-linux-musl", image_tag: "aarch64-musl" }, - { target: "armv7-unknown-linux-musleabihf", image_tag: "armv7-musleabihf" }, - { target: "powerpc64le-unknown-linux-musl", image_tag: "powerpc64le-musl" }, - ] - container: - image: docker://messense/rust-musl-cross:${{ matrix.platform.image_tag }} - env: - CFLAGS_armv7_unknown_linux_musleabihf: '-mfpu=vfpv3-d16' + platform: + - runner: ubuntu-22.04 + target: x86_64 + - runner: ubuntu-22.04 + target: x86 + - runner: ubuntu-22.04 + target: aarch64 + - runner: ubuntu-22.04 + target: armv7 steps: - - uses: actions/checkout@v3 - - name: Build wheels - linux-musl + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Build wheels uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist --interpreter ${{ env.UNIX_PYTHON_VERSIONS }} - sccache: 'true' - manylinux: musllinux_1_1 - container: off + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + manylinux: musllinux_1_2 - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-musl-${{ matrix.platform.target }} + name: wheels-musllinux-${{ matrix.platform.target }} path: dist windows: - runs-on: windows-latest + runs-on: ${{ matrix.platform.runner }} strategy: matrix: - target: [x64, x86] + platform: + - runner: windows-latest + target: x64 + - runner: windows-latest + target: x86 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.13' - architecture: ${{ matrix.target }} + python-version: 3.x + architecture: ${{ matrix.platform.target }} - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.WINDOWS_PYTHON_VERSIONS }} - sccache: 'true' + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-windows-${{ matrix.target }} + name: wheels-windows-${{ matrix.platform.target }} path: dist macos: - runs-on: macos-latest + runs-on: ${{ matrix.platform.runner }} strategy: matrix: - target: [x86_64, aarch64] + platform: + - runner: macos-13 + target: x86_64 + - runner: macos-14 + target: aarch64 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.13' + python-version: 3.x - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.UNIX_PYTHON_VERSIONS }} - sccache: 'true' + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} - name: Upload wheels uses: actions/upload-artifact@v4 with: - name: wheels-macos-${{ matrix.target }} + name: wheels-macos-${{ matrix.platform.target }} path: dist sdist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build sdist uses: PyO3/maturin-action@v1 with: @@ -134,27 +150,29 @@ jobs: name: wheels-sdist path: dist - merge: - runs-on: ubuntu-latest - needs: [linux, linux-musl, windows, macos, sdist] - steps: - - name: Merge Artifacts - uses: actions/upload-artifact/merge@v4 - with: - name: wheels - pattern: wheels-* - release: name: Release runs-on: ubuntu-latest - if: "startsWith(github.ref, 'refs/tags/')" - needs: merge + if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} + needs: [linux, musllinux, windows, macos, sdist] + permissions: + # Use to sign the release artifacts + id-token: write + # Used to upload release artifacts + contents: write + # Used to generate artifact attestation + attestations: write steps: - uses: actions/download-artifact@v4 + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v2 + with: + subject-path: 'wheels-*/*' - name: Publish to PyPI + if: ${{ startsWith(github.ref, 'refs/tags/') }} uses: PyO3/maturin-action@v1 env: MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} with: command: upload - args: --skip-existing wheels/* + args: --non-interactive --skip-existing wheels-*/* diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 11b80e7..d6865d7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,16 +9,111 @@ on: pull_request: branches: [ "main" ] -env: - UNIX_PYTHON_VERSIONS: 3.9 3.10 3.11 3.12 3.13 pypy3.10 - WINDOWS_PYTHON_VERSIONS: 3.9 3.10 3.11 3.12 3.13 - permissions: contents: read jobs: - build: - runs-on: ubuntu-latest + linux: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-22.04 + target: x86_64 + - runner: ubuntu-22.04 + target: x86 + - runner: ubuntu-22.04 + target: aarch64 + - runner: ubuntu-22.04 + target: armv7 + - runner: ubuntu-22.04 + target: s390x + - runner: ubuntu-22.04 + target: ppc64le + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + manylinux: auto + + musllinux: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-22.04 + target: x86_64 + - runner: ubuntu-22.04 + target: x86 + - runner: ubuntu-22.04 + target: aarch64 + - runner: ubuntu-22.04 + target: armv7 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + manylinux: musllinux_1_2 + + windows: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: windows-latest + target: x64 + - runner: windows-latest + target: x86 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + architecture: ${{ matrix.platform.target }} + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + + macos: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: macos-13 + target: x86_64 + - runner: macos-14 + target: aarch64 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist --find-interpreter + sccache: ${{ !startsWith(github.ref, 'refs/tags/') }} + + test: + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 - name: Set up Python 3.13 @@ -46,84 +141,3 @@ jobs: with: requirements_file: "requirements-dev.txt" - build-linux: - runs-on: ubuntu-latest - strategy: - matrix: - target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.13' - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.UNIX_PYTHON_VERSIONS }} - sccache: 'true' - manylinux: auto - - build-windows: - runs-on: windows-latest - strategy: - matrix: - target: [x64, x86] - - steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.10 - uses: actions/setup-python@v4 - with: - python-version: "3.13" - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.WINDOWS_PYTHON_VERSIONS }} - sccache: 'true' - manylinux: auto - build-macos: - runs-on: macos-latest - strategy: - matrix: - target: [x86_64, aarch64] - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: '3.13' - - name: Build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.UNIX_PYTHON_VERSIONS }} - sccache: 'true' - build-linux-musl: - runs-on: ubuntu-latest - strategy: - matrix: - platform: [ - { target: "x86_64-unknown-linux-musl", image_tag: "x86_64-musl" }, - { target: "i686-unknown-linux-musl", image_tag: "i686-musl" }, - { target: "aarch64-unknown-linux-musl", image_tag: "aarch64-musl" }, - { target: "armv7-unknown-linux-musleabihf", image_tag: "armv7-musleabihf" }, - { target: "powerpc64le-unknown-linux-musl", image_tag: "powerpc64le-musl" }, - ] - container: - image: docker://messense/rust-musl-cross:${{ matrix.platform.image_tag }} - env: - CFLAGS_armv7_unknown_linux_musleabihf: '-mfpu=vfpv3-d16' - steps: - - uses: actions/checkout@v3 - # - uses: actions/setup-python@v4 - # with: - # python-version: '3.13' - - name: Build wheels - linux-musl - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.platform.target }} - args: --release --out dist --interpreter ${{ env.UNIX_PYTHON_VERSIONS }} - sccache: 'true' - manylinux: musllinux_1_1 - container: off diff --git a/Cargo.lock b/Cargo.lock index f77d3a5..b557bbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -705,9 +705,9 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.22.6" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884" +checksum = "17da310086b068fbdcefbba30aeb3721d5bb9af8db4987d6735b2183ca567229" dependencies = [ "cfg-if", "chrono", @@ -724,9 +724,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.22.6" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38" +checksum = "e27165889bd793000a098bb966adc4300c312497ea25cf7a690a9f0ac5aa5fc1" dependencies = [ "once_cell", "target-lexicon", @@ -734,9 +734,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.22.6" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636" +checksum = "05280526e1dbf6b420062f3ef228b78c0c54ba94e157f5cb724a609d0f2faabc" dependencies = [ "libc", "pyo3-build-config", @@ -744,9 +744,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.22.6" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453" +checksum = "5c3ce5686aa4d3f63359a5100c62a127c9f15e8398e5fdeb5deef1fed5cd5f44" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -756,9 +756,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.22.6" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe" +checksum = "f4cf6faa0cbfb0ed08e89beb8103ae9724eb4750e3a78084ba4017cbe94f3855" dependencies = [ "heck", "proc-macro2", @@ -1012,9 +1012,9 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.16" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" [[package]] name = "thiserror" diff --git a/Cargo.toml b/Cargo.toml index 5067e86..1984216 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ crate-type = ["cdylib"] [dependencies] biscuit-auth = { version = "6.0.0-beta.3", features = ["pem"] } -pyo3 = { version = "0.22.6", features = ["extension-module", "chrono"] } +pyo3 = { version = "0.24.1", features = ["extension-module", "chrono"] } hex = "0.4" base64 = "0.13.0" chrono = "0.4" diff --git a/biscuit_test.py b/biscuit_test.py index 660a4c3..8d49186 100644 --- a/biscuit_test.py +++ b/biscuit_test.py @@ -9,7 +9,7 @@ def test_fact(): fact = Fact('fact(1, true, "", "Test", hex:aabbcc, 2023-04-29T01:00:00Z)') assert fact.name == "fact" - assert fact.terms == [1, True, "", "Test", [0xaa, 0xbb, 0xcc], datetime(2023, 4, 29, 1, 0, 0, tzinfo = timezone.utc)] + assert fact.terms == [1, True, "", "Test", b'\xaa\xbb\xcc', datetime(2023, 4, 29, 1, 0, 0, tzinfo = timezone.utc)] def test_biscuit_builder(): kp = KeyPair() @@ -30,7 +30,7 @@ def test_biscuit_builder(): { 'str': "1234", 'int': 1, 'bool': True, - 'bytes': [0xaa, 0xbb], + 'bytes': b'\xaa\xbb', 'datetime': datetime(2023, 4, 3, 10, 0, 0, tzinfo = timezone.utc), 'set': {2, True, "Test", datetime(2023, 4, 29, 1, 0, 0, tzinfo = timezone.utc) }, 'array': [2, True, "Test", ["inner"]], @@ -94,7 +94,7 @@ def test_block_builder(): { 'str': "1234", 'int': 1, 'bool': True, - 'bytes': [0xaa, 0xbb], + 'bytes': b'\xaa\xbb', 'datetime': datetime(2023, 4, 3, 10, 0, 0, tzinfo = timezone.utc), }, { 'pubkey': pubkey } @@ -149,7 +149,7 @@ def test_authorizer_builder(): { 'str': "1234", 'int': 1, 'bool': True, - 'bytes': [0xaa, 0xbb], + 'bytes': b'\xaa\xbb', 'datetime': datetime(2023, 4, 3, 10, 0, 0, tzinfo = timezone.utc), }, { 'pubkey': pubkey } @@ -299,18 +299,16 @@ def test_snapshot(): assert facts[0].name == "u" assert facts[0].terms == ["1234"] - # raw_snapshot() returns a list of bytes, not a `bytes` value directly - return raw_snapshot = authorizer.raw_snapshot() parsed_from_raw = Authorizer.from_raw_snapshot(raw_snapshot) assert repr(authorizer) == repr(parsed_from_raw) - raw_policy = raw_parsed.authorize() + raw_policy = parsed_from_raw.authorize() assert raw_policy == 0 rule = Rule("u($id) <- user($id), $id == {id}", { 'id': "1234"}) - raw_facts = raw_parsed.query(rule) + raw_facts = parsed_from_raw.query(rule) assert len(raw_facts) == 1 assert raw_facts[0].name == "u" @@ -325,8 +323,6 @@ def test_builder_snapshot(): parsed = AuthorizerBuilder.from_base64_snapshot(snapshot) assert repr(authorizer) == repr(parsed) - # raw_snapshot() returns a list of bytes, not a `bytes` value directly - return raw_snapshot = authorizer.raw_snapshot() parsed_from_raw = AuthorizerBuilder.from_raw_snapshot(raw_snapshot) assert repr(authorizer) == repr(parsed_from_raw) diff --git a/docs/datalog.rst b/docs/datalog.rst index 63b2507..b4178fc 100644 --- a/docs/datalog.rst +++ b/docs/datalog.rst @@ -128,7 +128,7 @@ Terms of a fact can be extracted to python values.o >>> fact.name 'fact' >>> fact.terms -['abc', 123, [170], datetime.datetime(2023, 6, 9, 0, 0, tzinfo=datetime.timezone.utc), True] +['abc', 123, b'\xaa', datetime.datetime(2023, 6, 9, 0, 0, tzinfo=datetime.timezone.utc), True] .. warning:: Extracting sets is not supported yet. diff --git a/requirements-dev.txt b/requirements-dev.txt index 1be0498..241cb6c 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,3 @@ maturin pytest -mypy \ No newline at end of file +mypy diff --git a/src/lib.rs b/src/lib.rs index bd2be88..e11c6a9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1225,12 +1225,19 @@ pub enum NestedPyTerm { Bytes(Vec), } +// TODO follow up-to-date conversion methods from pyo3 fn inner_term_to_py(t: &builder::Term, py: Python<'_>) -> PyResult> { match t { - builder::Term::Integer(i) => Ok((*i).into_py(py)), - builder::Term::Str(s) => Ok(s.into_py(py)), - builder::Term::Date(d) => Ok(Utc.timestamp_opt(*d as i64, 0).unwrap().into_py(py)), - builder::Term::Bytes(bs) => Ok(bs.clone().into_py(py)), + builder::Term::Integer(i) => Ok((*i).into_pyobject(py).unwrap().into_any().unbind()), + builder::Term::Str(s) => Ok(s.into_pyobject(py).unwrap().into_any().unbind()), + builder::Term::Date(d) => Ok(Utc + .timestamp_opt(*d as i64, 0) + .unwrap() + .into_pyobject(py) + .unwrap() + .into_any() + .unbind()), + builder::Term::Bytes(bs) => Ok(bs.clone().into_pyobject(py).unwrap().into_any().unbind()), builder::Term::Bool(b) => Ok(b.into_py(py)), _ => Err(DataLogError::new_err("Invalid term value".to_string())), } @@ -1613,26 +1620,17 @@ pub fn biscuit_auth(py: Python, m: &Bound) -> PyResult<()> { m.add_class::()?; m.add_class::()?; - m.add("DataLogError", py.get_type_bound::())?; - m.add( - "AuthorizationError", - py.get_type_bound::(), - )?; - m.add( - "BiscuitBuildError", - py.get_type_bound::(), - )?; - m.add( - "BiscuitBlockError", - py.get_type_bound::(), - )?; + m.add("DataLogError", py.get_type::())?; + m.add("AuthorizationError", py.get_type::())?; + m.add("BiscuitBuildError", py.get_type::())?; + m.add("BiscuitBlockError", py.get_type::())?; m.add( "BiscuitValidationError", - py.get_type_bound::(), + py.get_type::(), )?; m.add( "BiscuitSerializationError", - py.get_type_bound::(), + py.get_type::(), )?; Ok(())