├── self_signed_certs
└── .gitkeep
├── tests
├── fixtures
│ ├── test_data
│ │ ├── test_repo_source
│ │ │ ├── my_file.txt
│ │ │ ├── my_file.html
│ │ │ └── my_folder
│ │ │ │ ├── my_file.txt
│ │ │ │ └── my_file.html
│ │ ├── rustic.toml
│ │ ├── server_acl_minimal.toml
│ │ ├── .htpasswd
│ │ ├── acl.toml
│ │ ├── rustic_server.toml
│ │ ├── README.md
│ │ └── certs
│ │ │ ├── test.crt
│ │ │ └── test.key
│ └── hurl
│ │ └── endpoints.hurl
├── integration
│ ├── main.rs
│ ├── _impl.rs
│ ├── config.rs
│ └── acceptance.rs
└── generated
│ └── test_storage
│ └── test_repo
│ ├── config
│ └── keys
│ └── 3f918b737a2b9f72f044d06d6009eb34e0e8d06668209be3ce86e5c18dac0295
├── .github
├── renovate.json
├── install-arm-linkers.yml
└── workflows
│ ├── triage.yml
│ ├── lint-docs.yml
│ ├── release-image.yml
│ ├── release-plz.yml
│ ├── audit.yml
│ ├── ci.yml
│ ├── cross-ci.yml
│ ├── prebuilt-pr.yml
│ └── nightly.yml
├── src
├── snapshots
│ ├── rustic_server__acl__tests__acl_default_impl.snap
│ ├── rustic_server__htpasswd__test__htpasswd_passes.snap
│ ├── rustic_server__config__test__default_config_passes.snap
│ ├── rustic_server__config__test__config_parsing_from_file_passes.snap
│ ├── rustic_server__acl__tests__repo_acl_passes.snap
│ ├── rustic_server__config__test__optional_implicit_parse_config_passes.snap
│ ├── rustic_server__config__test__issue_60_parse_config_passes.snap
│ ├── rustic_server__config__test__optional_explicit_parse_config_passes.snap
│ ├── rustic_server__config__test__file_read.snap
│ └── rustic_server__config__test__parse_config_passes.snap
├── handlers.rs
├── bin
│ └── rustic-server.rs
├── prelude.rs
├── lib.rs
├── handlers
│ ├── access_check.rs
│ ├── health.rs
│ ├── file_helpers.rs
│ ├── file_length.rs
│ ├── repository.rs
│ └── files_list.rs
├── log.rs
├── commands
│ ├── serve.rs
│ └── auth.rs
├── typed_path.rs
├── application.rs
├── commands.rs
├── testing.rs
├── context.rs
├── htpasswd.rs
├── storage.rs
├── auth.rs
├── error.rs
└── web.rs
├── Cross.toml
├── config
├── acl.example.toml
├── rustic_profile.toml
├── rustic_server.toml
└── README.md
├── CONTRIBUTING.md
├── .gitignore
├── release-plz.toml
├── committed.toml
├── dprint.json
├── .cargo
└── config.toml
├── containers
├── Dockerfile
└── docker-compose.yml
├── dist-workspace.toml
├── .justfile
├── cliff.toml
├── README.md
├── USAGE.md
├── CHANGELOG.md
├── Cargo.toml
└── maskfile.md
/self_signed_certs/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/test_repo_source/my_file.txt:
--------------------------------------------------------------------------------
1 | hello world
2 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/test_repo_source/my_file.html:
--------------------------------------------------------------------------------
1 |
hello wold
2 |
--------------------------------------------------------------------------------
/tests/integration/main.rs:
--------------------------------------------------------------------------------
1 | mod _impl;
2 | mod acceptance;
3 | pub(crate) mod config;
4 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/test_repo_source/my_folder/my_file.txt:
--------------------------------------------------------------------------------
1 | hello world in folder
2 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/test_repo_source/my_folder/my_file.html:
--------------------------------------------------------------------------------
1 |
hello wold in folder
2 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/rustic.toml:
--------------------------------------------------------------------------------
1 | [repository]
2 | repository = "rest:http://rustic:rustic@localhost:8000/ci_repo"
3 | password = "rustic"
4 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/server_acl_minimal.toml:
--------------------------------------------------------------------------------
1 | [acl]
2 | disable-acl = true
3 | acl-path = "/test_data/test_repo/acl.toml"
4 | append-only = false
5 |
--------------------------------------------------------------------------------
/tests/generated/test_storage/test_repo/config:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rustic-rs/rustic_server/HEAD/tests/generated/test_storage/test_repo/config
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": ["local>rustic-rs/.github:renovate-config"]
4 | }
5 |
--------------------------------------------------------------------------------
/.github/install-arm-linkers.yml:
--------------------------------------------------------------------------------
1 | - name: Install armv7 and aarch64 Linkers
2 | if: runner.os == 'Linux'
3 | run: |
4 | sudo apt install gcc-aarch64-linux-gnu
5 | sudo apt install gcc-arm-none-eabi
6 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__acl__tests__acl_default_impl.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/acl.rs
3 | expression: acl
4 | ---
5 | Acl {
6 | private_repo: true,
7 | append_only: true,
8 | repos: {},
9 | }
10 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/.htpasswd:
--------------------------------------------------------------------------------
1 | rustic:$2y$05$48brsXSjDCo83AKq.52w1.A9NgpQth3emdWZZXbPStHtqv7hxIleW
2 | restic:$2y$05$iKXd4X4AKOpBPufMhlSfwOQqrl/nu1A9yAFbKYG742cJz325qeB/a
3 | hurl:$2y$05$63hF2CpYPDYuM3Jlm04hH.TYIxGo6nk1eFjVBHd06X7LLRcTFyMz2
4 |
--------------------------------------------------------------------------------
/Cross.toml:
--------------------------------------------------------------------------------
1 | [target.i686-unknown-linux-gnu]
2 | image = "ghcr.io/cross-rs/i686-unknown-linux-gnu:edge"
3 | pre-build = [
4 | "dpkg --add-architecture $CROSS_DEB_ARCH",
5 | "apt-get update && apt-get --assume-yes install gcc-multilib-i686-linux-gnu gcc-i686-linux-gnu",
6 | ]
7 |
--------------------------------------------------------------------------------
/config/acl.example.toml:
--------------------------------------------------------------------------------
1 | [default] # Default repository
2 | alex = "Read" # Alex can read
3 | admin = "Modify" # admin can modify, so has full access, even delete
4 |
5 | [alex] # a repository named 'alex'
6 | alex = "Modify" # Alex can modify his own repository
7 | bob = "Append" # Bob can append to Alex's repository
8 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__htpasswd__test__htpasswd_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/htpasswd.rs
3 | expression: htpasswd
4 | ---
5 | path = ''
6 | [credentials.Administrator]
7 | name = 'Administrator'
8 | hash = '[hash]'
9 |
10 | [credentials.backup-user]
11 | name = 'backup-user'
12 | hash = '[hash]'
13 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to `rustic_server`
2 |
3 | Thank you for your interest in contributing to `rustic_server`!
4 |
5 | We appreciate your help in making this project better.
6 |
7 | Please read the
8 | [contribution guide](https://rustic.cli.rs/docs/contributing-to-rustic.html) to
9 | get started.
10 |
--------------------------------------------------------------------------------
/src/handlers.rs:
--------------------------------------------------------------------------------
1 | // web server response handler modules
2 | pub(crate) mod file_config;
3 | pub(crate) mod file_exchange;
4 | pub(crate) mod file_length;
5 | pub(crate) mod files_list;
6 | pub(crate) mod health;
7 | pub(crate) mod repository;
8 |
9 | // Support modules
10 | mod access_check;
11 | pub(crate) mod file_helpers;
12 |
--------------------------------------------------------------------------------
/src/bin/rustic-server.rs:
--------------------------------------------------------------------------------
1 | //! Main entry point for RusticServer
2 |
3 | #![deny(warnings, missing_docs, trivial_casts, unused_qualifications)]
4 | #![forbid(unsafe_code)]
5 |
6 | use rustic_server::application::RUSTIC_SERVER_APP;
7 |
8 | /// Boot RusticServer
9 | fn main() {
10 | abscissa_core::boot(&RUSTIC_SERVER_APP);
11 | }
12 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/acl.toml:
--------------------------------------------------------------------------------
1 | [test_repo]
2 | rustic = "Append"
3 | restic = "Append"
4 | hurl = "Append"
5 |
6 | [repo_remove_me]
7 | rustic = "Modify"
8 | restic = "Modify"
9 |
10 | [repo_remove_me_2]
11 | rustic = "Modify"
12 | restic = "Modify"
13 |
14 | [ci_repo]
15 | rustic = "Modify"
16 | restic = "Modify"
17 | hurl = "Modify"
18 |
--------------------------------------------------------------------------------
/src/prelude.rs:
--------------------------------------------------------------------------------
1 | //! Application-local prelude: conveniently import types/functions/macros
2 | //! which are generally useful and should be available in every module with
3 | //! `use crate::prelude::*;`
4 |
5 | /// Abscissa core prelude
6 | pub use abscissa_core::prelude::*;
7 |
8 | /// Application state
9 | pub use crate::application::RUSTIC_SERVER_APP;
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .venv
2 | # Generated by Cargo
3 | # will have compiled files and executables
4 | /target/
5 |
6 | # These are backup files generated by rustfmt
7 | **/*.rs.bk
8 |
9 | # IDE files
10 | .idea
11 | .vscode
12 |
13 | # Test data created may accidentally be included
14 | tests/fixtures/rest_server
15 | repo_remove_me*
16 | __*
17 | ci_repo
18 | repo_not_*
19 | containers/volumes
--------------------------------------------------------------------------------
/release-plz.toml:
--------------------------------------------------------------------------------
1 | # configuration spec can be found here https://release-plz.ieni.dev/docs/config
2 |
3 | [workspace]
4 | pr_draft = true
5 | dependencies_update = true
6 | git_release_enable = false # disable GitHub/Gitea releases
7 | # changelog_config = "cliff.toml" # Don't use this for now, as it will override the default changelog config
8 |
9 | [changelog]
10 | protect_breaking_commits = true
11 |
--------------------------------------------------------------------------------
/committed.toml:
--------------------------------------------------------------------------------
1 | subject_length = 50
2 | subject_capitalized = false
3 | subject_not_punctuated = true
4 | imperative_subject = true
5 | no_fixup = true
6 | no_wip = true
7 | hard_line_length = 0
8 | line_length = 80
9 | style = "none"
10 | allowed_types = [
11 | "fix",
12 | "feat",
13 | "chore",
14 | "docs",
15 | "style",
16 | "refactor",
17 | "perf",
18 | "test",
19 | ]
20 | merge_commit = true
21 |
--------------------------------------------------------------------------------
/config/rustic_profile.toml:
--------------------------------------------------------------------------------
1 | # Adapt to your own configuration, a full list of options can be found at:
2 | # https://github.com/rustic-rs/rustic/tree/main/config
3 | [global]
4 | log-level = "info"
5 | log-file = "~/rustic.log"
6 |
7 | [repository]
8 | repository = "rest:http://rustic:rustic@127.0.0.1:8000/ci_repo"
9 | password = "rustic"
10 |
11 | [backup]
12 |
13 | [[backup.snapshots]]
14 | sources = ["src"]
15 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__default_config_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | [server]
6 | listen = '127.0.0.1:8000'
7 |
8 | [storage]
9 | data-dir = 'C:\Users\dailyuse\AppData\Local\Temp\rustic'
10 |
11 | [auth]
12 | disable-auth = false
13 |
14 | [acl]
15 | disable-acl = false
16 | append-only = true
17 |
18 | [tls]
19 | disable-tls = true
20 |
21 | [log]
22 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__config_parsing_from_file_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | [server]
6 | listen = '127.0.0.1:8080'
7 |
8 | [storage]
9 | data-dir = 'tests/generated/test_storage/'
10 |
11 | [auth]
12 | disable-auth = false
13 | htpasswd-file = 'tests/fixtures/test_data/.htpasswd'
14 |
15 | [acl]
16 | disable-acl = false
17 | append-only = false
18 | acl-path = 'tests/fixtures/test_data/acl.toml'
19 |
20 | [tls]
21 | disable-tls = true
22 |
23 | [log]
24 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/rustic_server.toml:
--------------------------------------------------------------------------------
1 | [server]
2 | listen = "127.0.0.1:8080"
3 |
4 | [storage]
5 | data-dir = "tests/generated/test_storage/"
6 |
7 | [auth]
8 | disable-auth = false
9 | htpasswd-file = "tests/fixtures/test_data/.htpasswd"
10 |
11 | [acl]
12 | disable-acl = false
13 | append-only = false
14 | acl-path = "tests/fixtures/test_data/acl.toml"
15 |
16 | [tls]
17 | disable-tls = true
18 | # tls-cert = "tests/fixtures/test_data/certs/test.crt"
19 | # tls-key = "tests/fixtures/test_data/certs/test.key"
20 |
--------------------------------------------------------------------------------
/tests/generated/test_storage/test_repo/keys/3f918b737a2b9f72f044d06d6009eb34e0e8d06668209be3ce86e5c18dac0295:
--------------------------------------------------------------------------------
1 | {"created":"2024-11-13T09:36:49.8626939+01:00","username":"TOWERPC\\dailyuse","hostname":"TowerPC","kdf":"scrypt","N":32768,"r":8,"p":7,"salt":"eOkZJZ+hvbGoe3ebzcNcEUXA/VP/e9WK2FUa0yDr96ZrjSoFc9qTbpgt4A3Z7m0NxqkF72D/aAgslDLw8Oe4cQ==","data":"ciGXdAUQBygykL/F+FE+/YnwNdcvdUenJ4ndRVIyOZ7BDs/VJxxEVul0YEykxtNJ0tJc2fruOzcMsSyjZkrATod4Zi3c2D0CJEE9kKeggwNDSJou9TOFjXF8eoZTQrzzeEkDXXPy26wlxhtLSlj4RqR3UgZzLOuT9rp9oUalxuCq7k0CAPz65rqOvUbmE0+krmuefJwhDWXK97E+gDp5iQ=="}
--------------------------------------------------------------------------------
/config/rustic_server.toml:
--------------------------------------------------------------------------------
1 | [server]
2 | listen = "127.0.0.1:8000"
3 |
4 | [storage]
5 | data-dir = "./test_data/test_repos/"
6 | quota = 0
7 |
8 | [auth]
9 | disable-auth = false
10 | htpasswd-file = "/test_data/test_repo/.htpasswd"
11 |
12 | [acl]
13 | disable-acl = true
14 | acl-path = "/test_data/test_repo/acl.toml"
15 | append-only = false
16 |
17 | [tls]
18 | disable-tls = false
19 | tls-cert = "/test_data/test_repo/cert.pem"
20 | tls-key = "/test_data/test_repo/key.pem"
21 |
22 | [log]
23 | log-level = "info"
24 | log-file = "/test_data/test_repo/rustic.log"
25 |
--------------------------------------------------------------------------------
/.github/workflows/triage.yml:
--------------------------------------------------------------------------------
1 | on:
2 | issues:
3 | types:
4 | - opened
5 |
6 | jobs:
7 | label_issue:
8 | if: ${{ github.repository_owner == 'rustic-rs' }}
9 | name: Label issue
10 | runs-on: ubuntu-latest
11 | steps:
12 | - env:
13 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14 | ISSUE_URL: ${{ github.event.issue.html_url }}
15 | run: |
16 | # check if issue doesn't have any labels
17 | if [[ $(gh issue view $ISSUE_URL --json labels -q '.labels | length') -eq 0 ]]; then
18 | # add S-triage label
19 | gh issue edit $ISSUE_URL --add-label "S-triage"
20 | fi
21 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__acl__tests__repo_acl_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/acl.rs
3 | expression: acl
4 | ---
5 | Acl {
6 | private_repo: true,
7 | append_only: true,
8 | repos: {
9 | "all": RepoAcl(
10 | {
11 | "bob": Modify,
12 | "paul": Read,
13 | "sam": Append,
14 | },
15 | ),
16 | "bob": RepoAcl(
17 | {
18 | "bob": Modify,
19 | },
20 | ),
21 | "sam": RepoAcl(
22 | {
23 | "bob": Read,
24 | "sam": Append,
25 | },
26 | ),
27 | },
28 | }
29 |
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! `RusticServer`
2 | //!
3 | //! Application based on the [Abscissa] framework.
4 | //!
5 | //! [Abscissa]: https://github.com/iqlusioninc/abscissa
6 |
7 | #![allow(non_local_definitions)]
8 |
9 | pub mod acl;
10 | pub mod application;
11 | pub mod auth;
12 | pub mod commands;
13 | pub mod config;
14 | pub mod context;
15 | pub mod error;
16 | pub mod handlers;
17 | pub mod htpasswd;
18 | pub mod log;
19 | pub mod prelude;
20 | pub mod storage;
21 | pub mod typed_path;
22 | /// Web module
23 | ///
24 | /// implements a REST server as specified by
25 | ///
26 | pub mod web;
27 |
28 | #[cfg(test)]
29 | pub mod testing;
30 |
--------------------------------------------------------------------------------
/dprint.json:
--------------------------------------------------------------------------------
1 | {
2 | "lineWidth": 80,
3 | "markdown": {
4 | "lineWidth": 80,
5 | "emphasisKind": "asterisks",
6 | "strongKind": "asterisks",
7 | "textWrap": "always"
8 | },
9 | "toml": {
10 | "lineWidth": 80
11 | },
12 | "json": {
13 | "lineWidth": 80,
14 | "indentWidth": 4
15 | },
16 | "includes": [
17 | "**/*.{md}",
18 | "**/*.{toml}",
19 | "**/*.{json}"
20 | ],
21 | "excludes": [
22 | "target/**/*",
23 | "CHANGELOG.md",
24 | "dist-workspace.toml"
25 | ],
26 | "plugins": [
27 | "https://plugins.dprint.dev/markdown-0.17.8.wasm",
28 | "https://plugins.dprint.dev/toml-0.6.3.wasm",
29 | "https://plugins.dprint.dev/json-0.19.4.wasm"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | rustdocflags = ["--document-private-items"]
3 | # rustflags = "-C target-cpu=native -D warnings"
4 | # incremental = true
5 |
6 | [target.armv7-unknown-linux-gnueabihf]
7 | linker = "arm-linux-gnueabihf-gcc"
8 |
9 | [target.armv7-unknown-linux-musleabihf]
10 | linker = "arm-linux-gnueabihf-gcc"
11 |
12 | [target.aarch64-unknown-linux-gnu]
13 | linker = "aarch64-linux-gnu-gcc"
14 |
15 | [target.aarch64-unknown-linux-musl]
16 | linker = "aarch64-linux-gnu-gcc"
17 |
18 | [target.i686-unknown-linux-gnu]
19 | linker = "i686-linux-gnu-gcc"
20 |
21 | [env]
22 | CC_i686-unknown-linux-gnu = "i686-linux-gnu-gcc"
23 | CC_aarch64_unknown_linux_musl = "aarch64-linux-gnu-gcc"
24 | CC_armv7_unknown_linux_gnueabihf = "arm-linux-gnueabihf-gcc"
25 | CC_armv7_unknown_linux_musleabihf = "arm-linux-gnueabihf-gcc"
26 |
--------------------------------------------------------------------------------
/.github/workflows/lint-docs.yml:
--------------------------------------------------------------------------------
1 | name: Lint Markdown / Toml
2 |
3 | on:
4 | pull_request:
5 | push:
6 | branches: [main]
7 | merge_group:
8 | types: [checks_requested]
9 |
10 | concurrency:
11 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
12 | cancel-in-progress: true
13 |
14 | jobs:
15 | style:
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
19 |
20 | - uses: dprint/check@2f1cf31537886c3bfb05591c031f7744e48ba8a1 # v2.2
21 |
22 | result:
23 | name: Result (Style)
24 | runs-on: ubuntu-latest
25 | needs:
26 | - style
27 | steps:
28 | - name: Mark the job as successful
29 | run: exit 0
30 | if: success()
31 | - name: Mark the job as unsuccessful
32 | run: exit 1
33 | if: "!success()"
34 |
--------------------------------------------------------------------------------
/containers/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM alpine AS builder
2 | ARG RUSTIC_SERVER_VERSION
3 | ARG TARGETARCH
4 | RUN if [ "$TARGETARCH" = "amd64" ]; then \
5 | ASSET="rustic_server-x86_64-unknown-linux-musl.tar.xz";\
6 | elif [ "$TARGETARCH" = "arm64" ]; then \
7 | ASSET="rustic_server-aarch64-unknown-linux-musl.tar.xz"; \
8 | fi; \
9 | wget https://github.com/rustic-rs/rustic_server/releases/download/${RUSTIC_SERVER_VERSION}/${ASSET} && \
10 | tar -xf ${ASSET} --strip-components=1 && \
11 | mkdir /etc_files && \
12 | touch /etc_files/passwd && \
13 | touch /etc_files/group
14 |
15 | FROM scratch
16 | COPY --from=builder /rustic-server /rustic-server
17 | COPY --from=builder /etc_files/ /etc/
18 | EXPOSE 8000
19 | ENTRYPOINT ["/rustic-server", "serve"]
20 | HEALTHCHECK --interval=90s --timeout=10s --retries=3 \
21 | CMD curl --fail -s http://localhost:8000/health/live || exit 1
22 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__optional_implicit_parse_config_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | RusticServerConfig {
6 | server: ConnectionSettings {
7 | listen: Some(
8 | 127.0.0.1:8000,
9 | ),
10 | },
11 | storage: StorageSettings {
12 | data_dir: Some(
13 | "./test_data/test_repos/",
14 | ),
15 | quota: None,
16 | },
17 | auth: HtpasswdSettings {
18 | disable_auth: false,
19 | htpasswd_file: None,
20 | },
21 | acl: AclSettings {
22 | disable_acl: false,
23 | private_repos: true,
24 | append_only: true,
25 | acl_path: None,
26 | },
27 | tls: TlsSettings {
28 | disable_tls: true,
29 | tls_key: None,
30 | tls_cert: None,
31 | },
32 | log: LogSettings {
33 | log_level: None,
34 | log_file: None,
35 | },
36 | }
37 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__issue_60_parse_config_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | RusticServerConfig {
6 | server: ConnectionSettings {
7 | listen: Some(
8 | 127.0.0.1:8000,
9 | ),
10 | },
11 | storage: StorageSettings {
12 | data_dir: Some(
13 | "C:\\Users\\dailyuse\\AppData\\Local\\Temp\\rustic",
14 | ),
15 | quota: None,
16 | },
17 | auth: HtpasswdSettings {
18 | disable_auth: false,
19 | htpasswd_file: None,
20 | },
21 | acl: AclSettings {
22 | disable_acl: true,
23 | private_repos: true,
24 | append_only: false,
25 | acl_path: None,
26 | },
27 | tls: TlsSettings {
28 | disable_tls: true,
29 | tls_key: None,
30 | tls_cert: None,
31 | },
32 | log: LogSettings {
33 | log_level: None,
34 | log_file: None,
35 | },
36 | }
37 |
--------------------------------------------------------------------------------
/.github/workflows/release-image.yml:
--------------------------------------------------------------------------------
1 | name: Release Docker Image
2 |
3 | on: [release]
4 |
5 | jobs:
6 | docker:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Set up Docker Buildx
10 | uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3
11 |
12 | - name: Login to Docker Hub
13 | uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
14 | with:
15 | registry: ghcr.io
16 | username: ${{ github.actor }}
17 | password: ${{ secrets.GITHUB_TOKEN }}
18 |
19 | - name: Build and push
20 | uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6
21 | with:
22 | context: "{{defaultContext}}:containers"
23 | push: true
24 | platforms: linux/amd64,linux/arm64
25 | tags: ghcr.io/rustic-rs/rustic_server:latest,ghcr.io/rustic-rs/rustic_server:${{ github.ref_name }}
26 | build-args: RUSTIC_SERVER_VERSION=${{ github.ref_name }}
27 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__optional_explicit_parse_config_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | RusticServerConfig {
6 | server: ConnectionSettings {
7 | listen: Some(
8 | 127.0.0.1:8000,
9 | ),
10 | },
11 | storage: StorageSettings {
12 | data_dir: Some(
13 | "./test_data/test_repos/",
14 | ),
15 | quota: None,
16 | },
17 | auth: HtpasswdSettings {
18 | disable_auth: true,
19 | htpasswd_file: None,
20 | },
21 | acl: AclSettings {
22 | disable_acl: true,
23 | private_repos: true,
24 | append_only: true,
25 | acl_path: None,
26 | },
27 | tls: TlsSettings {
28 | disable_tls: true,
29 | tls_key: None,
30 | tls_cert: None,
31 | },
32 | log: LogSettings {
33 | log_level: Some(
34 | "info",
35 | ),
36 | log_file: None,
37 | },
38 | }
39 |
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__file_read.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | RusticServerConfig {
6 | server: ConnectionSettings {
7 | listen: 127.0.0.1:8080,
8 | },
9 | storage: StorageSettings {
10 | data_dir: Some(
11 | "tests/generated/test_storage/",
12 | ),
13 | quota: None,
14 | },
15 | auth: HtpasswdSettings {
16 | disable_auth: false,
17 | htpasswd_file: Some(
18 | "tests/fixtures/test_data/.htpasswd",
19 | ),
20 | },
21 | acl: AclSettings {
22 | disable_acl: false,
23 | private_repos: true,
24 | append_only: false,
25 | acl_path: Some(
26 | "tests/fixtures/test_data/acl.toml",
27 | ),
28 | },
29 | tls: TlsSettings {
30 | disable_tls: false,
31 | tls_key: Some(
32 | "tests/fixtures/test_data/certs/test.key",
33 | ),
34 | tls_cert: Some(
35 | "tests/fixtures/test_data/certs/test.crt",
36 | ),
37 | },
38 | log: LogSettings {
39 | log_level: None,
40 | log_file: None,
41 | },
42 | }
43 |
--------------------------------------------------------------------------------
/tests/integration/_impl.rs:
--------------------------------------------------------------------------------
1 | use std::time::Duration;
2 |
3 | use crate::config::ConfigFile;
4 | use assert_cmd::Command;
5 | use serde::Serialize;
6 |
7 | pub trait AssertCmdExt {
8 | /// Add the given configuration file
9 | fn config(&mut self, config: &impl Serialize) -> &mut Self;
10 |
11 | /// Enable test mode
12 | fn test_mode_args(&mut self) -> &mut Self;
13 | }
14 |
15 | impl AssertCmdExt for Command {
16 | fn config(&mut self, config: &impl Serialize) -> &mut Self {
17 | let target_bin = self.get_program().to_owned();
18 | let config_file = ConfigFile::create(&target_bin, config);
19 |
20 | // Leak the config file to keep it alive for the duration of the test
21 | let static_config: &'static mut ConfigFile = Box::leak(Box::new(config_file));
22 |
23 | self.args(["-c", &static_config.path().display().to_string()]);
24 | self
25 | }
26 |
27 | fn test_mode_args(&mut self) -> &mut Self {
28 | self.timeout(Duration::from_secs(10)) // Set a timeout of 10 seconds
29 | .args(["-v"]) // Enable verbose logging
30 | .env("CI", "1"); // Enable CI test mode
31 |
32 | self
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.github/workflows/release-plz.yml:
--------------------------------------------------------------------------------
1 | name: Release-plz
2 |
3 | permissions:
4 | pull-requests: write
5 | contents: write
6 |
7 | on:
8 | push:
9 | branches:
10 | - main
11 |
12 | jobs:
13 | release-plz:
14 | name: Release-plz
15 | if: ${{ github.repository_owner == 'rustic-rs' }}
16 | runs-on: ubuntu-latest
17 | steps:
18 | - name: Generate GitHub token
19 | uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1
20 | id: generate-token
21 | with:
22 | app-id: ${{ secrets.RELEASE_PLZ_APP_ID }}
23 | private-key: ${{ secrets.RELEASE_PLZ_APP_PRIVATE_KEY }}
24 | - name: Checkout repository
25 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
26 | with:
27 | fetch-depth: 0
28 | token: ${{ steps.generate-token.outputs.token }}
29 | - name: Install Rust toolchain
30 | uses: dtolnay/rust-toolchain@stable
31 |
32 | - name: Run release-plz
33 | uses: MarcoIeni/release-plz-action@301fd6d8c641b97f25b5ade37651a478a5faa7da # v0.5
34 | env:
35 | GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
36 | CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
--------------------------------------------------------------------------------
/src/snapshots/rustic_server__config__test__parse_config_passes.snap:
--------------------------------------------------------------------------------
1 | ---
2 | source: src/config.rs
3 | expression: config
4 | ---
5 | RusticServerConfig {
6 | server: ConnectionSettings {
7 | listen: "127.0.0.1:8000",
8 | },
9 | storage: StorageSettings {
10 | data_dir: Some(
11 | "./test_data/test_repos/",
12 | ),
13 | quota: Some(
14 | 0,
15 | ),
16 | },
17 | auth: HtpasswdSettings {
18 | disable_auth: false,
19 | htpasswd_file: Some(
20 | "/test_data/test_repo/.htpasswd",
21 | ),
22 | },
23 | acl: AclSettings {
24 | disable_acl: true,
25 | append_only: false,
26 | acl_path: Some(
27 | "/test_data/test_repo/acl.toml",
28 | ),
29 | },
30 | tls: TlsSettings {
31 | disable_tls: false,
32 | tls_key: Some(
33 | "/test_data/test_repo/key.pem",
34 | ),
35 | tls_cert: Some(
36 | "/test_data/test_repo/cert.pem",
37 | ),
38 | },
39 | log: LogSettings {
40 | log_level: Some(
41 | "info",
42 | ),
43 | log_file: Some(
44 | "/test_data/test_repo/rustic.log",
45 | ),
46 | },
47 | }
48 |
--------------------------------------------------------------------------------
/tests/fixtures/test_data/README.md:
--------------------------------------------------------------------------------
1 | # Test data folder
2 |
3 | The test data folder contains data required for testing the server.
4 |
5 | ## Basic files for test access to a repository
6 |
7 | ### `.htpasswd`
8 |
9 | File governing the access to the server. Without access all is rejected.
10 |
11 | The `.htpasswd` file has three entries:
12 |
13 | - rustic:rustic
14 | - restic:restic
15 | - hurl:hurl
16 |
17 | ### `acl.toml`
18 |
19 | Definition which user from the HTACCESS file has what privileges on which
20 | repository.
21 |
22 | Check [here](config/README.md) for more information.
23 |
24 | ### `rustic_server.toml`
25 |
26 | Server configuration file.
27 |
28 | ### `rustic.toml`
29 |
30 | Configuration file for the `rustic` commands. Start as:
31 |
32 | ```console
33 | rustic -P /test.toml
34 | ```
35 |
36 | In the configuration folder there is an example given. Adapt to your
37 | configuration. To make use of the `test_repo`, the file has to contain the
38 | following credentials:
39 |
40 | ```toml
41 | [repository]
42 | repository = "rest:http://rustic:rustic@localhost:8000/ci_repo"
43 | password = "rustic"
44 | ```
45 |
46 | ### `certs` directory
47 |
48 | Contains the test certificates for the server.
49 |
50 | ## Source folder for Testing
51 |
52 | There is a source folder with test data.
53 |
54 | ## Storage folder for Testing
55 |
56 | There is a storage folder with test data. It is used to store the data for the
57 | server. The data is stored in the `tests/generated/test_storage` directory.
58 |
--------------------------------------------------------------------------------
/src/handlers/access_check.rs:
--------------------------------------------------------------------------------
1 | use std::path::Path;
2 |
3 | use axum::{http::StatusCode, response::IntoResponse};
4 | use tracing::debug;
5 |
6 | // used for using auto-generated TpeKind variant names
7 | use strum::VariantNames;
8 |
9 | use crate::{
10 | acl::{AccessType, AclChecker, ACL},
11 | error::{ApiErrorKind, ApiResult},
12 | typed_path::TpeKind,
13 | };
14 |
15 | pub fn check_auth_and_acl(
16 | user: String,
17 | tpe: impl Into