Skip to content

Commit

Permalink
Merge pull request #5 from quambene/eric-sdk
Browse files Browse the repository at this point in the history
Validate and send xml
  • Loading branch information
quambene authored Aug 4, 2024
2 parents 3936a9d + d9b63e1 commit 7eb87a6
Show file tree
Hide file tree
Showing 22 changed files with 2,992 additions and 23 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: cargo check
run: cargo check --all-targets --all-features -p eric-sdk
run: cargo check --all-targets -p eric-sdk --features eric-bindings-no-build
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: cargo clippy
run: cargo clippy --all-features --all-targets -p eric-sdk -- -D warnings
- name: cargo clippy -- -D warnings
run: cargo clippy --all-targets -p eric-sdk --features eric-bindings-no-build -- -D warnings
doc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: cargo doc
run: cargo doc --no-deps --all-features -p eric-sdk
run: cargo doc --no-deps -p eric-sdk --features eric-bindings-no-build
fmt:
runs-on: ubuntu-latest
steps:
Expand All @@ -49,11 +49,11 @@ jobs:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: cargo test --lib
run: cargo test --lib -p eric-sdk
run: cargo test --lib -p eric-sdk --features eric-bindings-no-build
doc-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: cargo test --doc
run: cargo test --locked --doc -p eric-sdk
run: cargo test --locked --doc -p eric-sdk --features eric-bindings-no-build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

# Eric
**/eric.log
**/*.pdf

# Environment
**/.env
Expand Down
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ resolver = "2"
[workspace.package]
authors = ["quambene <[email protected]>"]
edition = "2021"
version = "0.1.0"
readme = "README.md"
license = "Apache-2.0"
homepage = "https://github.com/quambene/eric-rs"
Expand Down
55 changes: 49 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Eric

[![latest version](https://img.shields.io/crates/v/eric-bindings.svg)](https://crates.io/crates/eric-bindings)
[![documentation](https://docs.rs/eric-bindings/badge.svg)](https://docs.rs/eric-bindings)
[![latest version](https://img.shields.io/crates/v/eric-bindings.svg?label=eric-bindings)](https://crates.io/crates/eric-bindings)
[![documentation](https://img.shields.io/docsrs/eric-bindings?label=eric-bindings)](https://docs.rs/eric-bindings)
[![latest version](https://img.shields.io/crates/v/eric-sdk.svg?label=eric-sdk)](https://crates.io/crates/eric-sdk)
[![documentation](https://img.shields.io/docsrs/eric-sdk?label=eric-sdk)](https://docs.rs/eric-sdk)
[![build status](https://github.com/quambene/eric-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/quambene/eric-rs/actions/workflows/ci.yml)

Rust bindings and SDK for the ELSTER Rich Client (ERiC)
Expand All @@ -12,14 +14,19 @@ Rust bindings and SDK for the ELSTER Rich Client (ERiC)
- [Rust bindings](#rust-bindings)
- [Generate bindings](#generate-bindings)
- [Test bindings](#test-bindings)
- [Eric SDK](#eric-sdk)
- [Usage](#usage)
- [Supported Eric versions](#supported-eric-versions)
- [Test SDK](#test-sdk)
- [Changelog](#changelog)

## What is ELSTER?

Elster (short for _Elektronische Steuererklärung_) is a project by the German tax administrations to process tax returns and declarations.

## What is ERiC?

ERiC is a C library that is integrated into a tax application. ERiC checks the data supplied by the tax application for plausibility, and transmits the data encrypted to the computing center of the respective tax administration.
ERiC is a shared C library that is integrated into a tax application. ERiC checks the data supplied by the tax application for plausibility, and transmits the data encrypted to the computing center of the respective tax administration.

## Requirements

Expand All @@ -35,8 +42,8 @@ apt install llvm-dev libclang-dev clang

### Generate bindings

The environment variables `LIBRARY_NAME`, `LIBRARY_PATH`, `HEADER_FILE`, and
`PLUGIN_PATH` are expected. For example:
To generate the bindings, `eric-bindings` expects the environment variables `LIBRARY_NAME`, `LIBRARY_PATH`, `HEADER_FILE`, and
`PLUGIN_PATH`. For example:

``` bash
LIBRARY_NAME=ericapi
Expand All @@ -48,7 +55,7 @@ PLUGIN_PATH=ERiC-38.1.6.0-Linux-x86_64/ERiC-38.1.6.0/Linux-x86_64/lib/plugins2
The bindings have to be generated on-the-fly for your specific platform and architecture:

``` bash
cargo build -p eric-bindings # Build bindings in debug mode
cargo build -p eric-bindings
```

The bindings are generated in `target/debug/build/eric-bindings-<random-id>/out/bindings.rs`.
Expand All @@ -62,3 +69,39 @@ cargo test -p eric-bindings --lib
```

Logs are written to `eric.log` in the current directory.

## Eric SDK

`eric-sdk` supports single-threaded Eric instances.

### Usage

To use `eric-sdk`, add the path of the shared C library (e.g. to `LD_LIBRARY_PATH` on Linux).

To send the xml file, the path and password of the Elster certificate has to be provided via environment variables `CERTIFICATE_PATH` and `CERTIFICATE_PASSWORD`.

### Supported Eric versions

| Rust SDK | Eric |
| -------- | -------- |
| 0.1.0 | 38.1.6.0 |

### Test SDK

``` bash
# Run unit tests
cargo test -p eric-sdk -- --test-threads=1

# Run integration tests
cargo test -p eric-sdk --test '*' -- --test-threads=1

# Run external tests
cargo test -p eric-sdk --test '*' --features external-test -- --test-threads=1
```

## Changelog

The `eric-rs` repository contains multiple crates with separate changelogs:

- `eric-bindings`: [view changelog](https://github.com/quambene/eric-rs/blob/main/eric-bindings/CHANGELOG.md)
- `eric-sdk`: [view changelog](https://github.com/quambene/eric-rs/blob/main/eric-sdk/CHANGELOG.md)
1 change: 1 addition & 0 deletions CHANGELOG.md → eric-bindings/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- added
- changed
- Rename feature from `docs-rs` to `no-build`
- removed

## v0.1.2 (2024-08-03)
Expand Down
8 changes: 4 additions & 4 deletions eric-bindings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ license.workspace = true
homepage.workspace = true
repository.workspace = true
description = "Rust bindings for the ELSTER Rich Client (ERiC)"
documentation = "https://docs.rs/eric_bindings"
documentation = "https://docs.rs/eric-bindings"
keywords = ["eric", "bindings", "taxes", "accounting"]
categories = ["external-ffi-bindings"]
build = "build.rs"

exclude = ["src/bindings/bindings_eric_38_1_6_0_linux_x86_64.rs"]
exclude = ["src/bindings/bindings_eric_39_6_4_0_linux_x86_64.rs"]

[package.metadata.docs.rs]
features = ["docs-rs"]
features = ["no-build"]

[features]
# This feature is used to publish the documentation for `eric-bindings`.
docs-rs = []
no-build = []

[lib]
path = "src/lib.rs"
Expand Down
2 changes: 1 addition & 1 deletion eric-bindings/build.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io;

fn main() -> io::Result<()> {
#[cfg(not(feature = "docs-rs"))]
#[cfg(not(feature = "no-build"))]
{
use std::{
env,
Expand Down
2 changes: 1 addition & 1 deletion eric-bindings/src/bindings/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod bindings_eric_39_6_4_0_linux_x86_64;
pub mod bindings_eric_38_1_6_0_linux_x86_64;
8 changes: 4 additions & 4 deletions eric-bindings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
// TODO: extern block uses type u128, which is not FFI-safe
#![allow(improper_ctypes)]

#[cfg(feature = "docs-rs")]
#[cfg(feature = "no-build")]
mod bindings;
#[cfg(feature = "docs-rs")]
pub use bindings::bindings_eric_39_6_4_0_linux_x86_64::*;
#[cfg(feature = "no-build")]
pub use bindings::bindings_eric_38_1_6_0_linux_x86_64::*;

#[cfg(not(feature = "docs-rs"))]
#[cfg(not(feature = "no-build"))]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

#[cfg(test)]
Expand Down
13 changes: 13 additions & 0 deletions eric-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- markdownlint-disable MD041 -->

## Unreleased

- added
- changed
- removed

## v0.1.0 (2024-08-04)

- added
- Validate and send xml
- Support Eric v38.1.6.0
18 changes: 18 additions & 0 deletions eric-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,29 @@ name = "eric-sdk"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
readme.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
description = "Rust SDK for the ELSTER Rich Client (ERiC)"
documentation = "https://docs.rs/eric-sdk"
keywords = ["eric", "sdk", "taxes", "accounting"]
categories = ["finance"]

[lib]
path = "src/lib.rs"
name = "eric_sdk"

[package.metadata.docs.rs]
features = ["eric-bindings-no-build"]

[features]
eric-bindings-no-build = ["eric-bindings/no-build"]
external-test = []

[dependencies]
eric-bindings = { version = "0.1.2", path = "../eric-bindings" }
anyhow = { workspace = true }

[dev-dependencies]
roxmltree = "0.20.0"
42 changes: 42 additions & 0 deletions eric-sdk/src/certificate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use crate::error_code::ErrorCode;
use anyhow::anyhow;
use eric_bindings::{EricCloseHandleToCertificate, EricGetHandleToCertificate};
use std::{ffi::CStr, ptr};

pub struct Certificate {
pub handle: u32,
}

impl Certificate {
pub fn new(path: &CStr) -> Result<Self, anyhow::Error> {
println!("Preparing certificate '{}'", path.to_str()?);

let mut handle = 0;
let pin_support = ptr::null::<u32>() as *mut u32;

// SAFETY: path.as_ptr() is not dangling as path is allocated in struct CertificateConfig and path is not moved as a reference to the CString is given
let error_code =
unsafe { EricGetHandleToCertificate(&mut handle, pin_support, path.as_ptr()) };

match error_code {
x if x == ErrorCode::ERIC_OK as i32 => Ok(Certificate { handle }),
error_code => Err(anyhow!("Can't create certificate: {}", error_code)),
}
}

// TODO: check validity of certificate
// unsafe { EricHoleZertifikatseigenschaften() }
}

impl Drop for Certificate {
fn drop(&mut self) {
println!("Cleaning up certificate");

let error_code = unsafe { EricCloseHandleToCertificate(self.handle) };

match error_code {
x if x == ErrorCode::ERIC_OK as i32 => (),
error_code => panic!("Can't drop certificate handle: {}", error_code),
}
}
}
Loading

0 comments on commit 7eb87a6

Please sign in to comment.