# [passwd-as-service](crates.io/crates/password-as-service) [crate](https://crates.io/crates/password-as-service) [source](https://gitlab.com/efronlicht/passwd-as-service) [docs](https://docs.rs/password-as-service/0.1.2/lib) Passwd-as-service is a webservice that provides a query API into the `/etc/passwd` and `/etc/group` files. It's not meant to be a 'real' service; it's a didactic coding sample meant for potential employers, based off a coding challenge from Brain Corp. See the file [api.pdf](./api.pdf) for details on the exact challenge. - [Documentation](#documentation) - [Installation](#installation) - [Configuration](#configuration) - [Testing](#testing) - [Design Decisions](#design-decisions) ## Documentation Clone the source and run `cargo doc --open`, or [visit the docs on docs.rs](https://docs.rs/password-as-service/0.1.2/lib/) ## Installation - ### [Install Rust](https://www.rust-lang.org/tools/install) using rustup. - ### Install the nightly toolchain ```bash rustup install nightly ``` - ### Install via crates.io ```bash cargo +nightly install password-as-service ``` Alternatively, prebuilt binaries for 64-bit [OSX](./bin/osx64), [Windows]([./bin/win64]), and Linux [Ubuntu/Debian]([./bin/lin64])are available in [./bin]. ## Configuration ```bash [ROCKET_PORT=PORT] passwd-as-service [PATH_TO_USERS] [PATH_TO_GROUPS] ``` - ROCKET_PORT is the port to serve from. This can also be set as an environment variable. - PATH_TO_USERS is the location of the users file: defaults to `"/etc/passwd"`. - PATH_TO_GROUPS is the location of the users file: defaults to `"/etc/group"` You must use both of PATH_TO_USERS and PATH_TO_GROUPS, or neither. ## Testing - Clone the repository ```bash cd ~/rust git clone gitlab.com/efronlicht/passwd-as-service ``` - Navigate to the project directory ```bash cd ~/rust/passwd-ass-service ``` - ### Run Tests Cargo ```bash cargo test ``` Test Coverage (Ubuntu/Debian) - Install [Tarpaulin](https://github.com/xd009642/tarpaulin): ```bash # install the lib-ssl development libraries apt-get install libssl-dev pkg-config cmake zlib1g-dev # set cargo to use rust's `nightly` toolchain rustup default nightly # OR: rustup override set nightly # install tarpaulin RUSTFLAGS="--cfg procmacro2_semver_exempt" cargo install cargo-tarpaulin ``` - Get Coverage ```bash $ cargo tarpaulin [INFO tarpaulin] Running Tarpaulin [INFO tarpaulin] Building project [INFO tarpaulin] Launching test [INFO tarpaulin] running /home/efron/rust/passwd-as-service/target/debug/deps/bin-f54ce995ec16a011 running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out [INFO tarpaulin] Launching test [INFO tarpaulin] running /home/efron/rust/passwd-as-service/target/debug/deps/lib-1087fab0c4512719 running 6 tests ...... test result: ok. 6 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out [INFO tarpaulin] Coverage Results: || Tested/Total Lines: || src/api/mod.rs: 14/14 || src/api/tests.rs: 84/86 || src/lib.rs: 6/20 || src/main.rs: 0/3 || src/model/group.rs: 11/18 || src/model/user.rs: 24/26 || 83.23% coverage, 139/167 lines covered ``` # Design Decisions ## Language: Rust - #### Positives + Extremely strong static typing and guarantees about concurrency. No race conditions. + No garbage collection and powerful optimizing compiler make it run blazing fast. + Easy to compile to a portable binary and deploy in containers. + Best-in-class good documentation and code quality tools + Deployment is easy, and low usage of resources makes running on rented servers cheap. + Cargo is an extremely good package and dependency manger. + My personal favorite programming language. - #### Negatives - High learning curve. - Difficult to write. - Immature ecosystem for web development comparied to competitors like JavaScript, Go, & Python. - Strictness not always necessary for 'quick and dirty' jobs. - Slow compilation times. ## Database: None, w/ a level of in-memory caching. This is a toy project, dealing with very small amounts of data. Even the largest linux system is unlikely to have more than ten thousand users or groups; we simply don't _need_ a relational database to query this kind of data. We have a single source of truth (the flat files `/etc/passwd/` and `/etc/group` themselves. - ### Positives - Removes a lot of overhead and disk usage. - Cheaper containerization: Most relational databases clock out at over 200mb and can use considerable memory that's a lot of resources for something we simply don't need. - Much simpler deployment; we can _just_ distribute a binary, with _zero_ dependencies. - ### Negatives: - Relational databasses like PostgreSQL and MYSQL are pretty much made for this kind of query. - If the project expands we'll probably need to use a database eventually. - Reinventing the wheel. ## Framework: [Rocket](https://rocket.rs/). Rocket is an _extremely_ exciting framework for writing servers in Rust. ### Positives - Very little boilerplate. - Strong typing & powerful custom macros allow you to create readable, testable APIs. - Very fast. ### Negatives - Immature. - Requires nightly rust. - Changes to Rust could leave the Rocket stranded. ## Deployment: Statically linked binaries #### Positives: - Fast - Portable - Much smaller than wrapping an entire interpreter. - Can't inject DLLs (because there _are_ no dynamic libararies) #### Negatives - Must be recompiled every time, unlike interpreted languages. - Larger than using dynamic links. ## Continuous Integration & Source Control: Git w/. Gitlab ### Upsides: - Simpler than most - Git is the most common source control tool by a country mile - Gitlab's continuous integration is much better for small or medium sized projects than the heavyweight solutions used for most github projects. ### Negatives: - Github is much more discoverable.