password-as-service

Crates.iopassword-as-service
lib.rspassword-as-service
version0.1.4
sourcesrc
created_at2019-05-07 21:58:19.962016
updated_at2019-05-10 19:48:43.317633
descriptiona very poorly considered http/rest service
homepage
repositoryhttps://gitlab.com/efronlicht/passwd-as-service
max_upload_size
id132701
size9,490,587
Efron Licht (efronlicht)

documentation

https://docs.rs/password-as-service/0.1.3/lib/

README

passwd-as-service

crate source docs

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 for details on the exact challenge.

Documentation

Clone the source and run cargo doc --open, or visit the docs on docs.rs

Installation

  • Install Rust using rustup.

  • Install the nightly toolchain

    rustup install nightly
    
  • Install via crates.io

    cargo +nightly install password-as-service
    

    Alternatively, prebuilt binaries for 64-bit OSX, Windows, and Linux Ubuntu/Debianare available in [./bin].

Configuration

[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

    cd ~/rust
    git clone gitlab.com/efronlicht/passwd-as-service
    
  • Navigate to the project directory

    cd ~/rust/passwd-ass-service
    
  • Run Tests

    Cargo

    cargo test
    

Test Coverage (Ubuntu/Debian)

  • Install Tarpaulin:

    # 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

    $ 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.

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.
Commit count: 23

cargo fmt