Feat: Erstellt die Crate
This commit is contained in:
Generated
+1
@@ -3,6 +3,7 @@
|
|||||||
<component name="NewModuleRootManager">
|
<component name="NewModuleRootManager">
|
||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
# AGENTS.md
|
# AGENTS.md
|
||||||
|
|
||||||
Dieses Dokument definiert Richtlinien, Konventionen und Arbeitsanweisungen für KI-Agenten und LLM-Tools, die an diesem Repository oder daraus erstellten Rust-Crates arbeiten.
|
Dieses Dokument definiert Richtlinien, Konventionen und Arbeitsanweisungen für KI-Agenten und LLM-Tools, die an diesem Repository (`sudo-ctdra`) arbeiten.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Projektübersicht & Kontext
|
## 1. Projektübersicht & Kontext
|
||||||
|
|
||||||
- **Typ:** Rust Library Crate Template
|
- **Projektname:** `sudo-ctdra`
|
||||||
|
- **Typ:** Rust Library
|
||||||
|
- **Zweck:** Bereitstellung von Hilfsfunktionen zur Überprüfung (`is_run_as_root`) und Anforderung von Root-Rechten via `sudo` (`run_as_root`).
|
||||||
- **Rust Edition:** `2024`
|
- **Rust Edition:** `2024`
|
||||||
- **Einstiegspunkt:** `src/lib.rs`
|
- **Einstiegspunkt:** `src/lib.rs`
|
||||||
- **CI/CD Plattform:** Gitea Actions (`.gitea/workflows/`)
|
- **CI/CD Plattform:** Gitea Actions (`.gitea/workflows/`)
|
||||||
@@ -20,18 +22,19 @@ Dieses Dokument definiert Richtlinien, Konventionen und Arbeitsanweisungen für
|
|||||||
### 2.1 Sprache & Idiomatik
|
### 2.1 Sprache & Idiomatik
|
||||||
- Verwende modernes, idiomatisches Rust (Edition 2024).
|
- Verwende modernes, idiomatisches Rust (Edition 2024).
|
||||||
- Bevorzuge explizite Typen und klare Signaturen in öffentlichen Schnittstellen (`pub`).
|
- Bevorzuge explizite Typen und klare Signaturen in öffentlichen Schnittstellen (`pub`).
|
||||||
- Halte die API ergonomisch und benutzerfreundlich.
|
- Halte die API ergonomisch, leichtgewichtig und benutzerfreundlich.
|
||||||
|
|
||||||
### 2.2 Fehlerbehandlung
|
### 2.2 Fehlerbehandlung
|
||||||
- Nutze `Result<T, E>` und `Option<T>` für alle potenziell fehlschlagenden Operationen.
|
- Nutze `Result<T, E>`, `Option<T>` oder explizite Fehlerrückgaben (`std::io::Error`) für alle potenziell fehlschlagenden Operationen.
|
||||||
- Definiere aussagekräftige, domänenspezifische Fehlertypen (z. B. via `thiserror` oder standardmäßig `std::error::Error`).
|
|
||||||
- **Verboten im produktiven Bibliothekscode (`src/`):**
|
- **Verboten im produktiven Bibliothekscode (`src/`):**
|
||||||
- Unbegründete `unwrap()`, `expect()` oder `panic!()` Aufrufe.
|
- Unbegründete `unwrap()`, `expect()` oder `panic!()` Aufrufe.
|
||||||
|
- Abrupter Programmabbruch via `std::process::exit` innerhalb von Bibliotheksfunktionen (Fehler müssen stattdessen an den Aufrufer zurückgegeben werden).
|
||||||
|
- Direktes oder ungefragtes Logging via Hilfsfunktionen oder Makros im Bibliothekscode; Fehlermeldungen / Fehlerstrukturen sind als Rückgabewerte zu liefern.
|
||||||
- Ignorieren von Fehlern via `let _ = ...`, es sei denn, es ist explizit begründet und dokumentiert.
|
- Ignorieren von Fehlern via `let _ = ...`, es sei denn, es ist explizit begründet und dokumentiert.
|
||||||
|
|
||||||
### 2.3 Dokumentation
|
### 2.3 Dokumentation
|
||||||
- Dokumentiere alle öffentlichen Module, Structs, Enums, Traits und Funktionen mit Rustdoc-Kommentaren (`///` bzw. Modul-Ebene `//!`).
|
- Dokumentiere alle öffentlichen Module, Structs, Enums, Traits und Funktionen mit Rustdoc-Kommentaren (`///` bzw. Modul-Ebene `//!`).
|
||||||
- Füge für öffentliche Schnittstellen nach Möglichkeit Code-Beispiele ein, die über `cargo test --doc` automatisch validiert werden.
|
- Füge für öffentliche Schnittstellen Code-Beispiele ein, die über `cargo test --doc` automatisch validiert werden.
|
||||||
|
|
||||||
### 2.4 Code-Qualität & Formatierung
|
### 2.4 Code-Qualität & Formatierung
|
||||||
- Halte den Code stets formatiert gemäß `rustfmt` (`cargo fmt`).
|
- Halte den Code stets formatiert gemäß `rustfmt` (`cargo fmt`).
|
||||||
@@ -92,10 +95,11 @@ Die CI/CD-Pipelines werden über Gitea Actions gesteuert:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Arbeitsanweisungen für Agenten bei Projekt-Initialisierung
|
## 5. Arbeitsanweisungen für Agenten
|
||||||
|
|
||||||
Wenn dieser Template-Stand verwendet wird, um eine neue Crate zu erstellen:
|
Bei Änderungen an diesem Repository:
|
||||||
1. Aktualisiere die `Cargo.toml`-Metadaten (`name`, `version`, `authors`, `repository`, `description`).
|
1. Pflege die Metadaten in `Cargo.toml` (`version`, `description`, etc.).
|
||||||
2. Passe die `README.md` an die konkrete Funktionalität der neuen Crate an.
|
2. Halte `README.md` und `AGENTS.md` aktuell bezüglich Funktionsumfang und Konventionen.
|
||||||
3. Behalte die Gitea-Workflows bei oder passe sie an das Ziel-Repository an.
|
3. Behalte die Gitea-Workflows bei bzw. passe sie bei Änderungen an.
|
||||||
4. Stelle sicher, dass keine Secrets, temporären Build-Dateien (`target/`) oder IDE-spezifischen Caches (außer `.idea` Konfigurationen) committed werden.
|
4. Stelle sicher, dass keine Secrets, temporären Build-Dateien (`target/`) oder IDE-spezifischen Caches (außer `.idea` Konfigurationen) committed werden.
|
||||||
|
5. Führe stets alle Prüfungen gemäß Abschnitt 3.2 vor Abschluss der Arbeiten durch.
|
||||||
|
|||||||
Generated
+10
-1
@@ -3,5 +3,14 @@
|
|||||||
version = 4
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-creat-template"
|
name = "libc"
|
||||||
|
version = "1.0.0-alpha.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d0f24f33af482526a4e3f9b47f0abb2c6377a1713c8aa4a8106994689a4cfa5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sudo-ctdra"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|||||||
+6
-14
@@ -1,23 +1,15 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rust-creat-template" # TODO Setzen
|
name = "sudo-ctdra"
|
||||||
version = "1.0.0" # TODO Setzen
|
version = "1.0.0"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
authors = ['DragonSlayer_14'] # TODO Setzen
|
authors = ['DragonSlayer_14']
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
repository = "https://gitea.creative-dragonslayer.de/Templates/rust-crate-template" # TODO Setzen
|
repository = "https://gitea.creative-dragonslayer.de/Rust-Crates/sudo"
|
||||||
description = "Ein Template-Projekt, das fürs erstellen von Rust-Crates verwendet werden kann." # TODO Setzen
|
description = "Eine Rust-Bibliothek zur Überprüfung und Anforderung von Root-Rechten über sudo unter Linux."
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
libc = "1.0.0-alpha.4"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = "none"
|
debug = "none"
|
||||||
|
|
||||||
[registry]
|
|
||||||
default = "gitea"
|
|
||||||
|
|
||||||
[registries.gitea]
|
|
||||||
index = "sparse+https://gitea.creative-dragonslayer.de/api/packages/Rust-Crates/cargo/"
|
|
||||||
|
|
||||||
[net]
|
|
||||||
git-fetch-with-cli = true
|
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ If you develop a new program, and you want it to be of the greatest possible use
|
|||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
|
To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
rust-crate-template
|
sudo
|
||||||
Copyright (C) 2026 Rust-Crates
|
Copyright (C) 2026 Rust-Crates
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||||
@@ -221,7 +221,7 @@ Also add information on how to contact you by electronic and paper mail.
|
|||||||
|
|
||||||
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
|
If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
rust-crate-template Copyright (C) 2026 Rust-Crates
|
sudo Copyright (C) 2026 Rust-Crates
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
|
This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,54 @@
|
|||||||
# Rust Crate Template
|
# sudo-ctdra
|
||||||
|
|
||||||
Ein vorkonfiguriertes Template-Projekt für die schnelle und standardisierte Entwicklung von Rust-Crates (Libraries) mit automatisierter CI/CD-Pipeline für Gitea.
|
Eine kompakte, leichtgewichtige Rust-Bibliothek zur Überprüfung und Anforderung von Root-/Administrator-Rechten über `sudo` unter Linux und Unix-Systemen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🚀 Übersicht & Features
|
## 🚀 Übersicht & Features
|
||||||
|
|
||||||
- **Rust Edition 2024**: Moderner Rust-Standard mit optimierten Profil-Einstellungen (`profile.release.debug = "none"`).
|
- **Root-Prüfung (`is_run_as_root`)**: Schnelle und zuverlässige Überprüfung der effektiven Benutzer-ID (`libc::geteuid() == 0`).
|
||||||
- **Automatisierte CI/CD-Workflows (Gitea Actions)**:
|
- **Prozess-Eskalation (`run_as_root`)**: Startet das aktuelle Programm über `sudo` neu, übergibt alle Befehlszeilenargumente (`std::env::args`) und ersetzt den aktuellen Prozess ([`CommandExt::exec`](https://doc.rust-lang.org/std/os/unix/process/trait.CommandExt.html#tymethod.exec)).
|
||||||
- **Testing-Pipeline (`testing`-Branch)**: Führt Tests und Compiler-Checks aus und erstellt automatisch ein Gitea Pre-Release (`v<VERSION>-preview`) inklusive `.crate`-Paket als Release-Asset.
|
- **Saubere Fehlerbehandlung**: Gibt bei Fehlschlägen einen [`std::io::Error`] zurück, anstatt das Programm unkontrolliert zu beenden oder ungefragt zu loggen.
|
||||||
- **Main-Release-Pipeline (`main`-Branch)**: Führt Tests und Compiler-Checks aus, paketiert die Crate, veröffentlicht sie in der Gitea Cargo Package Registry und erstellt ein offizielles Gitea Release (`v<VERSION>`) mit Asset.
|
- **Rust Edition 2024**: Moderner Rust-Standard mit optimierten Profileinstellungen.
|
||||||
- **Integrierte Gitea Package Registry**: Vorkonfigurierte sparse index Registry-Anbindung.
|
- **Automatisierte CI/CD-Workflows**: Vorkonfigurierte Gitea Actions für Tests, Compiler-Checks, Paketierung und Releases.
|
||||||
- **GPL-3.0-or-later Lizenz**: Vorkonfiguriert mit Lizenzdatei und Metadaten.
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📦 Einbindung
|
||||||
|
|
||||||
|
Füge die Crate zu deiner `Cargo.toml` hinzu:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
sudo-ctdra = { version = "1.0.0", registry = "gitea" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Falls die Gitea Package Registry genutzt wird, trage diese in deiner `.cargo/config.toml` ein:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[registries.gitea]
|
||||||
|
index = "sparse+https://gitea.creative-dragonslayer.de/api/packages/Rust-Crates/cargo/"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 💡 Anwendungsbeispiel
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use sudo_ctdra::{is_run_as_root, run_as_root};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if is_run_as_root() {
|
||||||
|
println!("Programm läuft mit Root-Rechten.");
|
||||||
|
// Privilegierte Aktionen durchführen...
|
||||||
|
} else {
|
||||||
|
println!("Normale Benutzerrechte erkannt. Starte neu als Root über sudo...");
|
||||||
|
let err = run_as_root();
|
||||||
|
eprintln!("Fehler beim Ausführen von 'sudo': {err}");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -25,7 +62,9 @@ Ein vorkonfiguriertes Template-Projekt für die schnelle und standardisierte Ent
|
|||||||
│ └── testing.yaml # CI/CD: Test, Check & Pre-Release für 'testing'
|
│ └── testing.yaml # CI/CD: Test, Check & Pre-Release für 'testing'
|
||||||
├── .idea/ # Vorkonfigurierte JetBrains IDE Einstellungen
|
├── .idea/ # Vorkonfigurierte JetBrains IDE Einstellungen
|
||||||
├── src/
|
├── src/
|
||||||
│ └── lib.rs # Einstiegspunkt der Crate / Library
|
│ └── lib.rs # Einstiegspunkt der Crate / Bibliotheksfunktionen
|
||||||
|
├── tests/
|
||||||
|
│ └── integration_tests.rs # Integrations- und Subprozess-Tests
|
||||||
├── Cargo.lock
|
├── Cargo.lock
|
||||||
├── Cargo.toml # Crate-Manifest & Metadaten
|
├── Cargo.toml # Crate-Manifest & Metadaten
|
||||||
├── LICENSE # GNU General Public License v3.0
|
├── LICENSE # GNU General Public License v3.0
|
||||||
@@ -35,39 +74,16 @@ Ein vorkonfiguriertes Template-Projekt für die schnelle und standardisierte Ent
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 🛠️ Verwendung als Template
|
|
||||||
|
|
||||||
### 1. Template initialisieren & Metadaten anpassen
|
|
||||||
Passe nach dem Klonen bzw. Erstellen des neuen Repositories die Platzhalter in `Cargo.toml` an:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[package]
|
|
||||||
name = "mein-crate-name"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
authors = ['DeinName <deine.email@example.com>']
|
|
||||||
readme = "README.md"
|
|
||||||
license = "GPL-3.0-or-later"
|
|
||||||
repository = "https://gitea.example.com/Organisation/mein-crate-name"
|
|
||||||
description = "Beschreibung der Crate."
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Gitea Repository Secrets einrichten
|
|
||||||
Für die Veröffentlichung und Release-Erstellung in Gitea Actions muss mindestens ein Access-Token als Repository-Secret hinterlegt werden (z. B. unter `Einstellungen -> Secrets -> Actions`):
|
|
||||||
- `PACKAGE_TOKEN` (oder alternativ `RELEASE_TOKEN`, `GITEA_TOKEN`): Ein Personal Access Token mit Berechtigungen für Packages (`write:package`) und Repositories/Releases (`write:repository`).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 💻 Lokale Entwicklung & Befehle
|
## 💻 Lokale Entwicklung & Befehle
|
||||||
|
|
||||||
Die gängigen Cargo-Befehle zur Entwicklung:
|
Die gängigen Cargo-Befehle zur Entwicklung und Validierung:
|
||||||
|
|
||||||
- **Kompilierung prüfen:**
|
- **Kompilierung prüfen:**
|
||||||
```bash
|
```bash
|
||||||
cargo check --all-targets
|
cargo check --all-targets
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Tests ausführen:**
|
- **Tests ausführen (Unit-, Integrations- und Doc-Tests):**
|
||||||
```bash
|
```bash
|
||||||
cargo test
|
cargo test
|
||||||
```
|
```
|
||||||
@@ -97,25 +113,7 @@ Die gängigen Cargo-Befehle zur Entwicklung:
|
|||||||
| `testing` | Push auf `testing` | • `cargo test`<br>• `cargo check --all-targets`<br>• `cargo package`<br>• Erstellt/Aktualisiert Pre-Release `v<VERSION>-preview` mit `.crate`-Asset |
|
| `testing` | Push auf `testing` | • `cargo test`<br>• `cargo check --all-targets`<br>• `cargo package`<br>• Erstellt/Aktualisiert Pre-Release `v<VERSION>-preview` mit `.crate`-Asset |
|
||||||
| `main` | Push auf `main` | • `cargo test`<br>• `cargo check --all-targets`<br>• `cargo package`<br>• Veröffentlicht Crate in Gitea Package Registry<br>• Erstellt/Aktualisiert Release `v<VERSION>` mit `.crate`-Asset |
|
| `main` | Push auf `main` | • `cargo test`<br>• `cargo check --all-targets`<br>• `cargo package`<br>• Veröffentlicht Crate in Gitea Package Registry<br>• Erstellt/Aktualisiert Release `v<VERSION>` mit `.crate`-Asset |
|
||||||
|
|
||||||
> **Hinweis zur Versionierung:** Die Versionsnummer wird automatisch aus `Cargo.toml` (`version = "..."`) ausgelesen. Passe vor einem Merge auf `main` oder `testing` die Version in `Cargo.toml` entsprechend SemVer an.
|
> **Hinweis zur Versionierung:** Die Versionsnummer wird automatisch aus `Cargo.toml` (`version = "..."`) ausgelesen. Passe vor einem Release / Merge die Version in `Cargo.toml` entsprechend **SemVer** an.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📦 Verwenden der Crate in anderen Projekten
|
|
||||||
|
|
||||||
Um die in der Gitea Package Registry veröffentlichte Crate in einem anderen Cargo-Projekt zu verwenden:
|
|
||||||
|
|
||||||
1. Trage die Registry in deiner lokalen `~/.cargo/config.toml` oder projektweiten `.cargo/config.toml` ein:
|
|
||||||
```toml
|
|
||||||
[registries.gitea]
|
|
||||||
index = "sparse+https://gitea.creative-dragonslayer.de/api/packages/Rust-Crates/cargo/"
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Binde die Crate in deiner `Cargo.toml` ein:
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
mein-crate-name = { version = "1.0.0", registry = "gitea" }
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
+86
@@ -0,0 +1,86 @@
|
|||||||
|
//! Eine leichtgewichtige Rust-Bibliothek zur Überprüfung und Anforderung von Root-Rechten über `sudo`.
|
||||||
|
//!
|
||||||
|
//! # Beispiele
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use sudo_ctdra::is_run_as_root;
|
||||||
|
//!
|
||||||
|
//! if is_run_as_root() {
|
||||||
|
//! println!("Das Programm läuft mit Root-Rechten.");
|
||||||
|
//! } else {
|
||||||
|
//! println!("Das Programm läuft mit normalen Benutzerrechten.");
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::io;
|
||||||
|
use std::os::unix::process::CommandExt;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
/// Prüft, ob das Programm mit Root-/Administrator-Rechten ausgeführt wird.
|
||||||
|
///
|
||||||
|
/// Ermittelt anhand der effektiven Benutzer-ID (`geteuid() == 0`), ob der aktuelle
|
||||||
|
/// Prozess über Root-Rechte verfügt.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// * `true` - Das Programm läuft mit erhöhten Rechten (EUID == 0)
|
||||||
|
/// * `false` - Das Programm läuft mit normalen Benutzerrechten
|
||||||
|
///
|
||||||
|
/// # Beispiele
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// use sudo_ctdra::is_run_as_root;
|
||||||
|
///
|
||||||
|
/// let is_root = is_run_as_root();
|
||||||
|
/// println!("Läuft als Root: {}", is_root);
|
||||||
|
/// ```
|
||||||
|
#[must_use]
|
||||||
|
pub fn is_run_as_root() -> bool {
|
||||||
|
unsafe { libc::geteuid() == 0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Startet das Programm mit Root-Rechten über `sudo` neu.
|
||||||
|
///
|
||||||
|
/// Diese Funktion versucht das Programm mit erhöhten Rechten via `sudo` neu zu starten
|
||||||
|
/// und übergibt dabei alle bisherigen Befehlszeilenargumente (`std::env::args`).
|
||||||
|
///
|
||||||
|
/// Da bei erfolgreicher Ausführung der bestehende Prozess durch den `sudo`-Aufruf
|
||||||
|
/// ersetzt wird ([`CommandExt::exec`]), kehrt diese Funktion im Erfolgsfall nicht zurück.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
///
|
||||||
|
/// Gibt einen [`std::io::Error`] zurück, falls die Ausführung von `sudo` fehlschlägt.
|
||||||
|
///
|
||||||
|
/// # Beispiele
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use sudo_ctdra::{is_run_as_root, run_as_root};
|
||||||
|
///
|
||||||
|
/// if !is_run_as_root() {
|
||||||
|
/// let err = run_as_root();
|
||||||
|
/// eprintln!("Fehler beim Neustart mit Root-Rechten: {err}");
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn run_as_root() -> io::Error {
|
||||||
|
let commandline_args: Vec<String> = env::args().collect();
|
||||||
|
Command::new("sudo").args(&commandline_args).exec()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_run_as_root_matches_libc_geteuid() {
|
||||||
|
let expected = unsafe { libc::geteuid() == 0 };
|
||||||
|
assert_eq!(is_run_as_root(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_is_run_as_root_consistency() {
|
||||||
|
let first = is_run_as_root();
|
||||||
|
let second = is_run_as_root();
|
||||||
|
assert_eq!(first, second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
use std::process::Command;
|
||||||
|
use sudo_ctdra::{is_run_as_root, run_as_root};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_public_api_is_run_as_root() {
|
||||||
|
let is_root = is_run_as_root();
|
||||||
|
let expected = unsafe { libc::geteuid() == 0 };
|
||||||
|
assert_eq!(is_root, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_run_as_root_returns_io_error_when_command_fails() {
|
||||||
|
if std::env::var("TEST_RUN_AS_ROOT_SUBPROCESS").is_ok() {
|
||||||
|
let err = run_as_root();
|
||||||
|
if err.kind() == std::io::ErrorKind::NotFound {
|
||||||
|
std::process::exit(42);
|
||||||
|
} else {
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let current_exe =
|
||||||
|
std::env::current_exe().expect("Pfad zur Test-Executable konnte nicht ermittelt werden");
|
||||||
|
let output = Command::new(current_exe)
|
||||||
|
.arg("test_run_as_root_returns_io_error_when_command_fails")
|
||||||
|
.arg("--exact")
|
||||||
|
.arg("--nocapture")
|
||||||
|
.env("TEST_RUN_AS_ROOT_SUBPROCESS", "1")
|
||||||
|
.env("PATH", "")
|
||||||
|
.output()
|
||||||
|
.expect("Subprozess konnte nicht ausgeführt werden");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
output.status.code(),
|
||||||
|
Some(42),
|
||||||
|
"Subprozess sollte mit Exit-Code 42 beendet worden sein (ErrorKind::NotFound). Stderr: {}",
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user