Compare commits

...

88 Commits

Author SHA1 Message Date
DanCodes 0feac2d904
chore: use ubuntu image to reduce image size (#142)
* chore: use ubuntu image to reduce image size

* fix(lint): hadolint issues
2024-01-17 10:08:37 -08:00
ViViDboarder 5f63df3dee Make sure vaultwarden has an 'object' in the compose files 2024-01-17 09:45:38 -08:00
Ian e80dce8042
Merge pull request #129 from ViViDboarder/dependabot/cargo/serde_json-1.0.95
Bump serde_json from 1.0.91 to 1.0.95
2023-06-14 07:57:28 -07:00
Ian 0a0d9ed69f
Merge pull request #130 from ViViDboarder/dependabot/cargo/anyhow-1.0.70
Bump anyhow from 1.0.68 to 1.0.70
2023-06-14 07:56:50 -07:00
Ian 44179f886a
Merge pull request #123 from ViViDboarder/dependabot/cargo/ldap3-0.11.1
Bump ldap3 from 0.9.4 to 0.11.1
2023-06-14 07:56:06 -07:00
Ian 4b5c9f36c4
Merge pull request #131 from ViViDboarder/dependabot/cargo/thiserror-1.0.40
Bump thiserror from 1.0.38 to 1.0.40
2023-06-14 07:55:39 -07:00
Ian 8e8586bc90
Merge pull request #121 from ViViDboarder/dependabot/github_actions/docker/metadata-action-4
Bump docker/metadata-action from 3 to 4
2023-06-14 07:54:57 -07:00
Ian a96c8d91b8
Merge pull request #120 from ViViDboarder/dependabot/github_actions/docker/build-push-action-4
Bump docker/build-push-action from 3 to 4
2023-06-14 07:54:45 -07:00
Ian 3dda190c3a
Merge pull request #118 from ViViDboarder/dependabot/github_actions/hadolint/hadolint-action-3.1.0
Bump hadolint/hadolint-action from 1.6.0 to 3.1.0
2023-06-14 07:54:05 -07:00
Ian f366b20fef
Merge pull request #119 from ViViDboarder/dependabot/github_actions/pre-commit/action-3.0.0
Bump pre-commit/action from 2.0.3 to 3.0.0
2023-06-14 07:53:38 -07:00
dependabot[bot] 78fd8c4248
Bump thiserror from 1.0.38 to 1.0.40
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.38 to 1.0.40.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.38...1.0.40)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 04:58:55 +00:00
dependabot[bot] 10aeba1ce8
Bump anyhow from 1.0.68 to 1.0.70
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.68 to 1.0.70.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.68...1.0.70)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 04:58:48 +00:00
dependabot[bot] 6882de79af
Bump serde_json from 1.0.91 to 1.0.95
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.91 to 1.0.95.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.91...v1.0.95)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-01 04:58:41 +00:00
Ian 5209fb6c8d
Update README.md
Fixes #127
2023-03-30 09:33:47 -07:00
dependabot[bot] 02f6383444
Bump ldap3 from 0.9.4 to 0.11.1
Bumps [ldap3](https://github.com/inejge/ldap3) from 0.9.4 to 0.11.1.
- [Release notes](https://github.com/inejge/ldap3/releases)
- [Changelog](https://github.com/inejge/ldap3/blob/master/CHANGELOG.md)
- [Commits](https://github.com/inejge/ldap3/compare/v0.9.4...v0.11.1)

---
updated-dependencies:
- dependency-name: ldap3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 04:01:33 +00:00
dependabot[bot] 8f897713fd
Bump docker/metadata-action from 3 to 4
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 3 to 4.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md)
- [Commits](https://github.com/docker/metadata-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 04:01:10 +00:00
dependabot[bot] fcc02354ca
Bump docker/build-push-action from 3 to 4
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 3 to 4.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v3...v4)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 04:01:05 +00:00
dependabot[bot] 50cc9cf2cb
Bump pre-commit/action from 2.0.3 to 3.0.0
Bumps [pre-commit/action](https://github.com/pre-commit/action) from 2.0.3 to 3.0.0.
- [Release notes](https://github.com/pre-commit/action/releases)
- [Commits](https://github.com/pre-commit/action/compare/v2.0.3...v3.0.0)

---
updated-dependencies:
- dependency-name: pre-commit/action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-01 04:01:01 +00:00
dependabot[bot] e0005fbd38
Bump hadolint/hadolint-action from 1.6.0 to 3.1.0
Bumps [hadolint/hadolint-action](https://github.com/hadolint/hadolint-action) from 1.6.0 to 3.1.0.
- [Release notes](https://github.com/hadolint/hadolint-action/releases)
- [Changelog](https://github.com/hadolint/hadolint-action/blob/master/.releaserc)
- [Commits](https://github.com/hadolint/hadolint-action/compare/v1.6.0...v3.1.0)

---
updated-dependencies:
- dependency-name: hadolint/hadolint-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-01-26 00:47:01 +00:00
ViViDboarder 30974696be Update testing instructions and bump 1.0 2023-01-25 16:42:55 -08:00
Ian f7b7f28e77
Merge pull request #117 from ViViDboarder/bump-rust-versions
Upgrade dependencies to replace vulnerable versions
2023-01-25 16:40:54 -08:00
ViViDboarder 1111b2a3df Upgrade dependencies to replace vulnerable versions
This also requried a Rust upgrade.

Verified with `make itest`
2023-01-25 16:13:02 -08:00
Ian 9c6c339dc8
Merge pull request #116 from ViViDboarder/action-dependa-bump
Action dependa bump
2023-01-25 16:03:11 -08:00
ViViDboarder 74c5ec4e72 Remove pinned ca-certs version 2023-01-25 15:58:21 -08:00
ViViDboarder 3faf747817 Merge remote-tracking branch 'origin/dependabot/github_actions/actions/setup-python-4' into action-dependa-bump 2023-01-25 15:53:29 -08:00
ViViDboarder 98a276b644 Merge remote-tracking branch 'origin/dependabot/github_actions/docker/build-push-action-3' into action-dependa-bump 2023-01-25 15:53:01 -08:00
ViViDboarder b735760315 Merge remote-tracking branch 'origin/dependabot/github_actions/docker/login-action-2' into action-dependa-bump 2023-01-25 15:52:44 -08:00
ViViDboarder e4b9c19215 Merge remote-tracking branch 'origin/dependabot/github_actions/actions/checkout-3' into action-dependa-bump 2023-01-25 15:52:15 -08:00
Ian 66f35bff6d
Merge pull request #68 from ViViDboarder/dependabot/cargo/ldap3-0.9.4
Bump ldap3 from 0.9.3 to 0.9.4
2023-01-25 15:47:30 -08:00
dependabot[bot] 11ab2b92c2
Bump actions/setup-python from 2 to 4
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 4.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](https://github.com/actions/setup-python/compare/v2...v4)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-01 04:06:22 +00:00
dependabot[bot] 11a0c3902b
Bump ldap3 from 0.9.3 to 0.9.4
Bumps [ldap3](https://github.com/inejge/ldap3) from 0.9.3 to 0.9.4.
- [Release notes](https://github.com/inejge/ldap3/releases)
- [Changelog](https://github.com/inejge/ldap3/blob/v0.9.4/CHANGELOG.md)
- [Commits](https://github.com/inejge/ldap3/compare/v0.9.3...v0.9.4)

---
updated-dependencies:
- dependency-name: ldap3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-09 04:53:37 +00:00
Ian ce6cb783d0
Merge pull request #82 from epsilon-0/master
add security features on OpenBSD
2022-06-08 21:51:43 -07:00
dependabot[bot] b2dd2d42bc
Bump docker/build-push-action from 2 to 3
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2 to 3.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-01 06:12:22 +00:00
dependabot[bot] 274adaff9d
Bump docker/login-action from 1 to 2
Bumps [docker/login-action](https://github.com/docker/login-action) from 1 to 2.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v1...v2)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-01 06:12:17 +00:00
Aisha Tammy 97a64c7247 add security features on OpenBSD
Signed-off-by: Aisha Tammy <floss@bsd.ac>
2022-05-24 16:30:41 -04:00
dependabot[bot] eb204793d3
Bump actions/checkout from 2 to 3
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-01 04:03:39 +00:00
Ian dd92cc509a
Merge pull request #54 from ViViDboarder/dependabot/cargo/serde-1.0.132
Bump serde from 1.0.131 to 1.0.132
2022-01-20 13:02:58 -08:00
Ian 8ab22b5788
Merge pull request #56 from ViViDboarder/dependabot/cargo/serde_json-1.0.73
Bump serde_json from 1.0.72 to 1.0.73
2022-01-20 13:02:42 -08:00
Ian 4d71304f91
Merge pull request #59 from ViViDboarder/dependabot/cargo/reqwest-0.11.9
Bump reqwest from 0.11.7 to 0.11.9
2022-01-20 13:02:17 -08:00
Ian 7514928afe
Merge pull request #55 from ViViDboarder/dependabot/cargo/anyhow-1.0.52
Bump anyhow from 1.0.51 to 1.0.52
2022-01-20 13:01:55 -08:00
dependabot[bot] ef52691c63
Bump reqwest from 0.11.7 to 0.11.9
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.11.7 to 0.11.9.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.11.7...v0.11.9)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-20 20:59:16 +00:00
dependabot[bot] 8992de2e6b
Bump anyhow from 1.0.51 to 1.0.52
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.51 to 1.0.52.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.51...1.0.52)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-20 20:58:19 +00:00
ViViDboarder 5d41a1532f Update ca-certs for alpine 2022-01-20 12:52:59 -08:00
ViViDboarder 13760d7e6f Fix hadolint in github actions 2022-01-20 12:46:32 -08:00
ViViDboarder 71aa764522 Bump cargo versions in prep for release 2022-01-20 12:46:32 -08:00
ViViDboarder 653891102b Update pre-commit hooks 2022-01-20 12:32:10 -08:00
dependabot[bot] 2d5656bd22
Bump serde_json from 1.0.72 to 1.0.73
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.72 to 1.0.73.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.72...v1.0.73)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-01 04:09:35 +00:00
dependabot[bot] b134df4653
Bump serde from 1.0.131 to 1.0.132
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.131 to 1.0.132.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.131...v1.0.132)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-01-01 04:09:20 +00:00
dependabot[bot] f1b229ebc3
Merge pull request #45 from ViViDboarder/dependabot/cargo/reqwest-0.11.4 2021-12-11 01:49:36 +00:00
ViViDboarder 829ae70a9b Update reqwest usage for new version
Had to rebuild lock
2021-12-10 16:32:54 -08:00
dependabot[bot] fce9d3064c
Bump reqwest from 0.9.24 to 0.11.4
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.9.24 to 0.11.4.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.9.24...v0.11.4)

---
updated-dependencies:
- dependency-name: reqwest
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:38:37 +00:00
dependabot[bot] 741ece568a
Merge pull request #44 from ViViDboarder/dependabot/cargo/ldap3-0.9.3 2021-12-10 18:37:18 +00:00
dependabot[bot] 4c4112cd82
Merge pull request #49 from ViViDboarder/dependabot/cargo/anyhow-1.0.51 2021-12-10 18:32:48 +00:00
ViViDboarder 3a34f70385 Make ldap mutable to support new version 2021-12-10 10:25:12 -08:00
dependabot[bot] 1c69bd6936
Bump anyhow from 1.0.42 to 1.0.51
Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.42 to 1.0.51.
- [Release notes](https://github.com/dtolnay/anyhow/releases)
- [Commits](https://github.com/dtolnay/anyhow/compare/1.0.42...1.0.51)

---
updated-dependencies:
- dependency-name: anyhow
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:16:09 +00:00
Ian 9e7f4a7820
Merge pull request #48 from ViViDboarder/dependabot/cargo/serde_json-1.0.72
Bump serde_json from 1.0.64 to 1.0.72
2021-12-10 10:15:38 -08:00
Ian 3c83cde044
Merge pull request #46 from ViViDboarder/dependabot/cargo/serde-1.0.131
Bump serde from 1.0.126 to 1.0.131
2021-12-10 10:15:22 -08:00
Ian 07b05844b3
Merge pull request #47 from ViViDboarder/dependabot/cargo/thiserror-1.0.30
Bump thiserror from 1.0.26 to 1.0.30
2021-12-10 10:14:53 -08:00
dependabot[bot] 0c2c2eae0d
Bump serde_json from 1.0.64 to 1.0.72
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.64 to 1.0.72.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.64...v1.0.72)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:09:13 +00:00
Ian bc390527bd
Merge pull request #43 from ViViDboarder/dependabot/github_actions/pre-commit/action-2.0.3
Bump pre-commit/action from 2.0.2 to 2.0.3
2021-12-10 10:09:13 -08:00
dependabot[bot] d9468b0105
Bump thiserror from 1.0.26 to 1.0.30
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.26 to 1.0.30.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/1.0.26...1.0.30)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:09:09 +00:00
dependabot[bot] d29d7ffb07
Bump serde from 1.0.126 to 1.0.131
Bumps [serde](https://github.com/serde-rs/serde) from 1.0.126 to 1.0.131.
- [Release notes](https://github.com/serde-rs/serde/releases)
- [Commits](https://github.com/serde-rs/serde/compare/v1.0.126...v1.0.131)

---
updated-dependencies:
- dependency-name: serde
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:09:07 +00:00
dependabot[bot] ade0192e11
Bump ldap3 from 0.6.1 to 0.9.3
Bumps [ldap3](https://github.com/inejge/ldap3) from 0.6.1 to 0.9.3.
- [Release notes](https://github.com/inejge/ldap3/releases)
- [Changelog](https://github.com/inejge/ldap3/blob/master/CHANGELOG.md)
- [Commits](https://github.com/inejge/ldap3/compare/v0.6.1...v0.9.3)

---
updated-dependencies:
- dependency-name: ldap3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:08:56 +00:00
dependabot[bot] 40113a71d4
Bump pre-commit/action from 2.0.2 to 2.0.3
Bumps [pre-commit/action](https://github.com/pre-commit/action) from 2.0.2 to 2.0.3.
- [Release notes](https://github.com/pre-commit/action/releases)
- [Commits](https://github.com/pre-commit/action/compare/v2.0.2...v2.0.3)

---
updated-dependencies:
- dependency-name: pre-commit/action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-12-10 18:08:10 +00:00
Ian 55e3536c70
Merge pull request #42 from GoliathLabs/dependabot
Added: dependabot.yml
2021-12-10 10:07:51 -08:00
GoliathLabs d21c835411
Added: newline 2021-12-10 18:12:20 +01:00
GoliathLabs 0d49839189
Added: dependabot.yml 2021-12-10 18:10:47 +01:00
ViViDboarder 60699e6f5a Ignore consecutive run statement in hadolint 2021-11-29 10:47:33 -08:00
ViViDboarder 85511d8dc9 Update rust build to 1.56.1 and alpine rust version to 1.51.0 2021-11-29 10:22:52 -08:00
ViViDboarder db03a5299f Fix new linting error (thanks clippy!) 2021-09-20 17:01:52 -07:00
ViViDboarder 96d7483d31 More descriptive errors when failing to parse a config file 2021-09-20 17:01:27 -07:00
ViViDboarder 94d82a827f Bump version to v0.6.1 2021-07-23 15:53:23 -07:00
ViViDboarder 21a50a1ee0 Fix alpine build 2021-07-23 15:52:34 -07:00
ViViDboarder 5682eab8dc Update Readme to describe how to configure using env variables 2021-07-23 15:33:43 -07:00
ViViDboarder 556a8edbe7 Bump release v0.6.0 2021-07-23 15:29:49 -07:00
ViViDboarder 0ea5eadd71 Make running integration tests easier 2021-07-23 15:28:19 -07:00
ViViDboarder 5fd947f127 Clean up of env config PR 2021-07-23 15:27:45 -07:00
Tobias Florek f25278ea3c implement loading config from environment
This still has the bug, that envy conflicts with serde's
deny_unknown_fields option.

For the time being use e.g.
```
env -i VAULTWARDEN_URL=https://example.com vaultwarden_ldap
```
2021-07-23 15:09:30 -07:00
ViViDboarder 5238bc1b60 Slim final image
Using an intermediate image for building. Could possibly slim further by making the `RUN_TAG` a slim variant
2021-06-21 13:38:36 -07:00
ViViDboarder 08dcdd2bba Bump minor version 2021-06-13 20:22:30 -07:00
ViViDboarder a1a69617e3 Use correct image name 2021-06-13 20:00:15 -07:00
ViViDboarder 80a16664e8 Update Dockerfile.alpine to pass hadolint 2021-06-13 19:50:05 -07:00
ViViDboarder 13e0775d56 Add GitHub Actions
Using GHA for builds rather than Docker Hub
2021-06-13 19:07:02 -07:00
ViViDboarder 77919aa3d4 Improved error handling
Massive refactor of error handling to make messages easier to debug
2021-06-13 18:09:43 -07:00
Ian c090fb5a52
Merge pull request #32 from ibotty/log-uid
also log uid when email not found
2021-05-20 17:34:17 -07:00
ViViDboarder 231f9036fb Add --build flag to example compose 2021-05-20 17:33:30 -07:00
ViViDboarder adf460c05e Add some additional configs for easier testing 2021-05-20 17:29:45 -07:00
Tobias Florek 8be4057e3b also log uid when email not found 2021-05-20 09:09:50 +02:00
17 changed files with 1265 additions and 1328 deletions

22
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,22 @@
# Docs: <https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/customizing-dependency-updates>
version: 2
updates:
- package-ecosystem: github-actions
directory: /
schedule: {interval: monthly}
reviewers: [ViViDboarder]
assignees: [ViViDboarder]
- package-ecosystem: docker
directory: /
schedule: {interval: monthly}
reviewers: [ViViDboarder]
assignees: [ViViDboarder]
- package-ecosystem: cargo
directory: /
schedule: {interval: monthly}
reviewers: [ViViDboarder]
assignees: [ViViDboarder]

35
.github/workflows/cargo.yml vendored Normal file
View File

@ -0,0 +1,35 @@
---
name: Tests
"on":
push:
branches: [master]
pull_request:
branches: [master]
env:
CARGO_TERM_COLOR: always
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build
run: cargo build --verbose
- name: Run tests
run: cargo test --verbose
- uses: actions/setup-python@v4
- name: Run pre-commit hooks
uses: pre-commit/action@v3.0.0
env:
SKIP: hadolint
- name: Run hadolint
uses: hadolint/hadolint-action@v3.1.0

56
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,56 @@
---
name: Docker
"on":
push:
branches:
- master
tags:
- 'v*'
pull_request:
branches:
- master
jobs:
docker:
strategy:
matrix:
include:
- dockerfile: Dockerfile
latest: "auto"
suffix: ""
- dockerfile: Dockerfile.alpine
latest: "false"
suffix: "-alpine"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
images: vividboarder/vaultwarden_ldap
flavor: |
latest=${{ matrix.latest }}
suffix=${{ matrix.suffix }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
- name: Login to DockerHub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ${{ matrix.dockerfile }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@ -1,7 +1,7 @@
---
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.4.0
rev: v4.1.0
hooks:
- id: check-added-large-files
- id: check-yaml
@ -16,7 +16,10 @@ repos:
- id: cargo-check
- id: clippy
- repo: https://github.com/IamTheFij/docker-pre-commit
rev: v2.0.0
rev: v2.0.1
hooks:
- id: docker-compose-check
- repo: https://github.com/hadolint/hadolint
rev: v2.8.0
hooks:
- id: hadolint

1908
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,17 @@
[package]
name = "vaultwarden_ldap"
version = "0.4.0"
version = "1.0.0"
authors = ["ViViDboarder <vividboarder@gmail.com>"]
edition = "2018"
[dependencies]
ldap3 = "0.6"
ldap3 = "0.11"
serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
reqwest = "0.9"
reqwest = { version = "0.11", features = ["json", "blocking"] }
serde_json = "1.0"
thiserror = "1.0"
anyhow = "1.0"
envy = "0.4.1"
pledge = "0.4.2"
unveil = "0.3.2"

View File

@ -1,4 +1,7 @@
FROM rust:1.46
ARG BUILD_TAG=1.57.0
ARG RUN_TAG=$BUILD_TAG
FROM rust:$BUILD_TAG as builder
WORKDIR /usr/src/
RUN USER=root cargo new --bin vaultwarden_ldap
@ -9,9 +12,15 @@ COPY Cargo.toml Cargo.lock ./
RUN cargo build --locked --release
# Remove bins to make sure we rebuild
# hadolint ignore=DL3059
RUN rm ./target/release/deps/vaultwarden_ldap*
# Copy source and install
COPY src ./src
RUN cargo install --path .
RUN cargo build --release
CMD ["vaultwarden_ldap"]
FROM ubuntu:focal
WORKDIR /app
RUN apt-get update -y && apt-get install -y libssl-dev=1.1.1f-1ubuntu2.20 --no-install-recommends && rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/src/vaultwarden_ldap/target/release/vaultwarden_ldap /usr/local/bin/
CMD ["/usr/local/bin/vaultwarden_ldap"]

View File

@ -1,21 +1,21 @@
FROM ekidd/rust-musl-builder:1.46.0 AS builder
FROM ekidd/rust-musl-builder:1.57.0 AS builder
WORKDIR /home/rust/src
# Cache build deps
RUN USER=rust cargo init
COPY Cargo.toml Cargo.lock ./
RUN cargo build --locked --release
COPY --chown=rust:rust Cargo.toml Cargo.lock ./
RUN cargo build --locked --release && \
rm src/*.rs
# Remove temp src
RUN rm src/*.rs
# Remove bins to make sure we rebuild
# RUN rm ./target/release/deps/vaultwarden_ldap*
COPY --chown=rust:rust ./src ./src
RUN touch ./src/main.rs
RUN USER=rust touch ./src/main.rs
# hadolint ignore=DL3059
RUN cargo build --release
FROM alpine:3
RUN apk --no-cache add ca-certificates=20191127-r5
# hadolint ignore=DL3018
RUN apk --no-cache add ca-certificates
COPY --from=builder \
/home/rust/src/target/x86_64-unknown-linux-musl/release/vaultwarden_ldap \
/usr/local/bin/

View File

@ -14,6 +14,9 @@ target/debug/vaultwarden_ldap: src/
target/release/vaultwarden_ldap: src/
cargo build --locked --release
.PHONY: build
build: debug
.PHONY: debug
debug: target/debug/vaultwarden_ldap
@ -30,6 +33,38 @@ run-debug: target/debug/vaultwarden_ldap
test:
cargo test
# Run bootstrapped integration test
.PHONY: itest
itest:
docker-compose -f docker-compose.yml \
-f itest/docker-compose.itest.yml \
build
docker-compose -f docker-compose.yml \
-f itest/docker-compose.itest.yml \
up -d vaultwarden ldap
docker-compose -f docker-compose.yml \
-f itest/docker-compose.itest.yml \
run ldap_sync
docker-compose stop
# Run bootstrapped integration test using env for config
.PHONY: itest-env
itest-env:
docker-compose -f docker-compose.yml \
-f itest/docker-compose.itest-env.yml \
build
docker-compose -f docker-compose.yml \
-f itest/docker-compose.itest-env.yml \
up -d vaultwarden ldap
docker-compose -f docker-compose.yml \
-f itest/docker-compose.itest-env.yml \
run ldap_sync
docker-compose stop
.PHONY: clean-itest
clean-itest:
docker-compose down -v
# Installs pre-commit hooks
.PHONY: install-hooks
install-hooks:
@ -49,6 +84,9 @@ check-version:
clean:
rm -f ./target
.PHONY: docker-build-all
docker-build-all: docker-build docker-build-alpine
.PHONY: docker-build
docker-build:
docker build -f ./Dockerfile -t $(DOCKER_TAG) .

View File

@ -1,7 +1,7 @@
# vaultwarden_ldap
An LDAP connector for [vaultwarden](https://github.com/dani-garcia/vaultwarden)
LDAP user invites for [vaultwarden](https://github.com/dani-garcia/vaultwarden)
After configuring, run `vaultwarden_ldap` and it will invite any users it finds in LDAP to your `vaultwarden` instance.
After configuring, run `vaultwarden_ldap` and it will invite any users it finds in LDAP to your `vaultwarden` instance. This is NOT a sync tool like the [Bitwarden Directory Connector](https://bitwarden.com/help/directory-sync/).
## Deploying
@ -34,6 +34,8 @@ Configuration values are as follows:
|`ldap_sync_interval_seconds`|Integer|Optional|Number of seconds to wait between each LDAP request. Defaults to `60`|
|`ldap_sync_loop`|Boolean|Optional|Indicates whether or not syncing should be polled in a loop or done once. Defaults to `true`|
Alternatively, instead of using `config.toml`, all values can be provided using enviroment variables prefixed with `APP_`. For example: `APP_VAULTWARDEN_URL=https://vault.example.com`
## Development
This repo has a predefined set of [pre-commit](https://pre-commit.com) rules. You can install pre-commit via any means you'd like. Once your system has `pre-commit` installed, you can run `make install-hooks` to ensure the hooks will run with every commit. You can also force running all hooks with `make check`.
@ -42,7 +44,18 @@ For those less familiar with `cargo`, you can use the `make` targets that have b
## Testing
All testing is manual right now. First step is to set up Bitwarden and the LDAP server.
There are no unit tests, but there are integration tests that require manual verification.
### Integration tests
Running `make itest` will spin up an ldap server with a test user, a Vaultwarden server, and then run the sync. If successful the log should show an invitation sent to the test user. If you run `make itest` again, it should show no invites sent because the user already has been invited. If you'd like to reset the testing, `make clean-itest` will clear out the Vaultwarden database and start fresh.
It's also possible to test passing configs via enviornment variables by running `make itest-env`. The validation steps are the same.
### Steps for manual testing
The first step is to set up Bitwarden and the LDAP server.
```bash
docker-compose up -d vaultwarden ldap ldap_admin
@ -69,7 +82,6 @@ From there you can set up your test group and users.
docker-compose up ldap_sync
```
## Future
Alternately, you can bootstrap some of this by running:
* Any kind of proper logging
* Tests
docker-compose -f docker-compose.yml -f itest/docker-compose.itest.yml up --build

View File

@ -4,7 +4,7 @@ services:
ldap_sync:
build:
context: .
dockerfile: Dockerfile.alpine
dockerfile: Dockerfile
volumes:
- ./example.config.toml:/config.toml:ro
# ./root.cert:/usr/src/vaultwarden_ldap/root.cert:ro
@ -24,12 +24,10 @@ services:
ADMIN_TOKEN: admin
SIGNUPS_ALLOWED: 'false'
INVITATIONS_ALLOWED: 'true'
I_REALLY_WANT_VOLATILE_STORAGE: 'true'
ldap:
image: osixia/openldap
ports:
- 389:389
- 636:636
volumes:
- /var/lib/ldap
- /etc/ldap/slapd.d

53
itest/50-seed-user.ldif Normal file
View File

@ -0,0 +1,53 @@
# LDIF Export for cn=Users,dc=example,dc=org
# Server: ldap (ldap)
# Search Scope: sub
# Search Filter: (objectClass=*)
# Total Entries: 2
#
# Generated by phpLDAPadmin (http://phpldapadmin.sourceforge.net) on May 4, 2021 6:06 pm
# Version: 1.2.5
version: 1
# Entry 1: cn=Users,dc=example,dc=org
dn: cn=Users,dc=example,dc=org
cn: Users
gidnumber: 500
objectclass: posixGroup
objectclass: top
# Entry 2: cn=Someone,cn=Users,dc=example,dc=org
dn: cn=Someone,cn=Users,dc=example,dc=org
cn: Someone
gidnumber: 500
homedirectory: /home/users/someone
mail: test@example.com
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: Someone
uid: someone
uidnumber: 1000
# Entry 3: cn=SomeoneNoEmail,cn=Users,dc=example,dc=org
dn: cn=SomeoneNoEmail,cn=Users,dc=example,dc=org
cn: SomeoneNoEmail
gidnumber: 500
homedirectory: /home/users/someonenoemail
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: SomeoneNoEmail
uid: someonenoemail
uidnumber: 1001
# Entry 4: cn=SomeoneNoEmailNoUid,cn=Users,dc=example,dc=org
# dn: cn=SomeoneNoEmailNoUid,cn=Users,dc=example,dc=org
# cn: SomeoneNoEmailNoUid
# gidnumber: 500
# homedirectory: /home/users/someonenoemailnoUid
# objectclass: inetOrgPerson
# objectclass: posixAccount
# objectclass: top
# sn: SomeoneNoEmail
# uidnumber: 1002

View File

@ -0,0 +1,21 @@
---
version: '3'
services:
ldap_sync:
environment:
CONFIG_PATH: ""
APP_VAULTWARDEN_URL: "http://vaultwarden:80"
APP_VAULTWARDEN_ADMIN_TOKEN: "admin"
APP_LDAP_HOST: "ldap"
APP_LDAP_BIND_DN: "cn=admin,dc=example,dc=org"
APP_LDAP_BIND_PASSWORD: "admin"
APP_LDAP_SEARCH_BASE_DN: "dc=example,dc=org"
APP_LDAP_SEARCH_FILTER: "(&(objectClass=*)(uid=*))"
APP_LDAP_SYNC_LOOP: "false"
vaultwarden: {}
ldap:
command: ["--copy-service"]
volumes:
- ./itest/50-seed-user.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-seed-user.ldif

View File

@ -0,0 +1,13 @@
---
version: '3'
services:
ldap_sync:
volumes:
- ./itest/config.toml:/config.toml:ro
vaultwarden: {}
ldap:
command: ["--copy-service"]
volumes:
- ./itest/50-seed-user.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-seed-user.ldif

View File

@ -17,18 +17,41 @@ pub fn get_config_path() -> String {
}
}
/// Reads configuration from file and panics if it can't
// Tries to read configuration from file, failing that from the environment,
// panics if it can't
pub fn read_config() -> Config {
match read_config_from_file() {
Ok(config) => config,
Err(err) => {
println!("{}", err);
match read_config_from_env() {
Ok(config) => config,
Err(err) => panic!("{}", err),
}
}
}
}
/// Tries to read configuration from file
pub fn read_config_from_file() -> Result<Config, String> {
let config_path = get_config_path();
let contents = fs::read_to_string(&config_path).unwrap_or_else(|_| {
panic!("Failed to open config file at {}", config_path);
});
let config: Config = toml::from_str(contents.as_str()).unwrap_or_else(|_| {
panic!("Failed to parse config file at {}", config_path);
});
let contents = fs::read_to_string(&config_path)
.map_err(|err| format!("Failed to open config file at {}: {}", config_path, err))?;
let config: Config = toml::from_str(contents.as_str())
.map_err(|err| format!("Failed to parse config file at {}: {}", config_path, err))?;
config
println!("Config read from file at {}", config_path);
Ok(config)
}
// Tries to read configuration from environment
pub fn read_config_from_env() -> Result<Config, String> {
let config = envy::prefixed("APP_")
.from_env()
.map_err(|err| format!("Error parsing config from env: {}", err))?;
println!("Config read from environment");
Ok(config)
}
#[derive(Deserialize)]
@ -151,7 +174,7 @@ impl Config {
pub fn get_ldap_mail_field(&self) -> String {
match &self.ldap_mail_field {
Some(mail_field) => mail_field.clone(),
None => String::from("mail").clone(),
None => String::from("mail"),
}
}

View File

@ -1,11 +1,18 @@
extern crate anyhow;
extern crate ldap3;
extern crate pledge;
extern crate unveil;
use std::collections::HashSet;
use std::error::Error;
use std::thread::sleep;
use std::time::Duration;
use anyhow::Context as _;
use anyhow::Error as AnyError;
use anyhow::Result;
use ldap3::{DerefAliases, LdapConn, LdapConnSettings, Scope, SearchEntry, SearchOptions};
use pledge::pledge;
use unveil::unveil;
mod config;
mod vw_admin;
@ -13,34 +20,38 @@ mod vw_admin;
fn main() {
let config = config::Config::from_file();
let mut client = vw_admin::Client::new(
config.get_vaultwarden_url().clone(),
config.get_vaultwarden_admin_token().clone(),
config.get_vaultwarden_root_cert_file().clone(),
config.get_vaultwarden_url(),
config.get_vaultwarden_admin_token(),
config.get_vaultwarden_root_cert_file(),
);
if let Err(e) = invite_users(&config, &mut client, config.get_ldap_sync_loop()) {
panic!("{}", e);
}
unveil(config::get_config_path(), "r")
.or_else(unveil::Error::ignore_platform)
.expect("Could not unveil config file");
unveil("", "")
.or_else(unveil::Error::ignore_platform)
.expect("Could not disable further unveils");
pledge("dns flock inet rpath stdio tty", "")
.or_else(pledge::Error::ignore_platform)
.expect("Could not pledge permissions");
invite_users(&config, &mut client, config.get_ldap_sync_loop())
}
/// Invites new users to Bitwarden from LDAP
fn invite_users(
config: &config::Config,
client: &mut vw_admin::Client,
start_loop: bool,
) -> Result<(), Box<dyn Error>> {
fn invite_users(config: &config::Config, client: &mut vw_admin::Client, start_loop: bool) {
if start_loop {
start_sync_loop(config, client)?;
start_sync_loop(config, client).expect("Failed to start invite sync loop");
} else {
invite_from_ldap(config, client)?;
invite_from_ldap(config, client).expect("Failed to invite users");
}
Ok(())
}
/// Creates set of email addresses for users that already exist in Bitwarden
fn get_existing_users(client: &mut vw_admin::Client) -> Result<HashSet<String>, Box<dyn Error>> {
let all_users = client.users()?;
fn get_existing_users(client: &mut vw_admin::Client) -> Result<HashSet<String>, AnyError> {
let all_users = client
.users()
.context("Could not get list of existing users from server")?;
let mut user_emails = HashSet::with_capacity(all_users.len());
for user in all_users {
user_emails.insert(user.get_email().to_lowercase());
@ -67,45 +78,44 @@ fn ldap_client(
bind_pw: String,
no_tls_verify: bool,
starttls: bool,
) -> Result<LdapConn, Box<dyn Error>> {
) -> Result<LdapConn, AnyError> {
let settings = LdapConnSettings::new()
.set_starttls(starttls)
.set_no_tls_verify(no_tls_verify);
let ldap = LdapConn::with_settings(settings, ldap_url.as_str())?;
match ldap.simple_bind(bind_dn.as_str(), bind_pw.as_str()) {
_ => {}
};
let mut ldap = LdapConn::with_settings(settings, ldap_url.as_str())
.context("Failed to connect to LDAP server")?;
ldap.simple_bind(bind_dn.as_str(), bind_pw.as_str())
.context("Could not bind to LDAP server")?;
Ok(ldap)
}
/// Retrieves search results from ldap
fn search_entries(config: &config::Config) -> Result<Vec<SearchEntry>, Box<dyn Error>> {
let ldap = ldap_client(
fn search_entries(config: &config::Config) -> Result<Vec<SearchEntry>, AnyError> {
let mut ldap = ldap_client(
config.get_ldap_url(),
config.get_ldap_bind_dn(),
config.get_ldap_bind_password(),
config.get_ldap_no_tls_verify(),
config.get_ldap_starttls(),
);
if ldap.is_err() {
println!("Error: Could not bind to ldap server");
}
)
.context("LDAP client initialization failed")?;
let mail_field = config.get_ldap_mail_field();
let fields = vec!["uid", "givenname", "sn", "cn", mail_field.as_str()];
// TODO: Something something error handling
let (results, _res) = ldap?
// Something something error handling
let (results, _res) = ldap
.with_search_options(SearchOptions::new().deref(DerefAliases::Always))
.search(
&config.get_ldap_search_base_dn().as_str(),
config.get_ldap_search_base_dn().as_str(),
Scope::Subtree,
&config.get_ldap_search_filter().as_str(),
config.get_ldap_search_filter().as_str(),
fields,
)?
.success()?;
)
.context("LDAP search failure")?
.success()
.context("LDAP search usucessful")?;
// Build list of entries
let mut entries = Vec::new();
@ -120,52 +130,65 @@ fn search_entries(config: &config::Config) -> Result<Vec<SearchEntry>, Box<dyn E
fn invite_from_ldap(
config: &config::Config,
client: &mut vw_admin::Client,
) -> Result<(), Box<dyn Error>> {
match get_existing_users(client) {
Ok(existing_users) => {
let mail_field = config.get_ldap_mail_field();
let mut num_users = 0;
for ldap_user in search_entries(config)? {
// Safely get first email from list of emails in field
if let Some(user_email) = ldap_user
.attrs
.get(mail_field.as_str())
.and_then(|l| (l.first()))
{
if existing_users.contains(&user_email.to_lowercase()) {
println!("User with email already exists: {}", user_email);
} else {
println!("Try to invite user: {}", user_email);
// TODO: Validate response
let _response = client.invite(user_email);
num_users = num_users + 1;
// println!("Invite response: {:?}", response);
}
} else {
println!("Warning: Email field, {:?}, not found on user", mail_field);
}
}
) -> Result<(), AnyError> {
let existing_users =
get_existing_users(client).context("Failed to get existing users from server")?;
let mail_field = config.get_ldap_mail_field();
let mut num_users = 0;
// Maybe think about returning this value for some other use
println!("Sent invites to {} user(s).", num_users);
}
Err(e) => {
println!("Error: Failed to get existing users from Bitwarden");
return Err(e);
for ldap_user in search_entries(config)? {
//
// Safely get first email from list of emails in field
if let Some(user_email) = ldap_user
.attrs
.get(mail_field.as_str())
.and_then(|l| (l.first()))
{
if existing_users.contains(&user_email.to_lowercase()) {
println!("User with email already exists: {}", user_email);
} else {
println!("Try to invite user: {}", user_email);
client
.invite(user_email)
.context(format!("Failed to invite user {}", user_email))?;
num_users += 1;
}
} else {
match ldap_user.attrs.get("uid").and_then(|l| l.first()) {
Some(user_uid) => println!(
"Warning: Email field, {:?}, not found on user {}",
mail_field, user_uid
),
None => println!("Warning: Email field, {:?}, not found on user", mail_field),
}
}
}
// Maybe think about returning this value for some other use
println!("Sent invites to {} user(s).", num_users);
Ok(())
}
/// Begin sync loop to invite LDAP users to Bitwarden
fn start_sync_loop(
config: &config::Config,
client: &mut vw_admin::Client,
) -> Result<(), Box<dyn Error>> {
fn start_sync_loop(config: &config::Config, client: &mut vw_admin::Client) -> Result<(), AnyError> {
let interval = Duration::from_secs(config.get_ldap_sync_interval_seconds());
let mut fail_count = 0;
let fail_limit = 5;
loop {
invite_from_ldap(config, client)?;
if let Err(err) = invite_from_ldap(config, client) {
println!(
"Error inviting users from ldap. Count {}: {:?}",
fail_count, err
);
fail_count += 1;
if fail_count > fail_limit {
return Err(err);
}
} else {
fail_count = 0
}
sleep(interval);
}
}

View File

@ -1,16 +1,26 @@
extern crate reqwest;
extern crate serde;
extern crate thiserror;
use reqwest::Response;
use reqwest::blocking::Response;
use serde::Deserialize;
use std::collections::HashMap;
use std::error::Error;
use std::fs::File;
use std::io::Read;
use std::time::{Duration, Instant};
use thiserror::Error;
const COOKIE_LIFESPAN: Duration = Duration::from_secs(20 * 60);
#[derive(Error, Debug)]
pub enum ResponseError {
#[error("vaultwarden error {0}")]
ApiError(String),
#[error("http error making request {0:?}")]
HttpError(#[from] reqwest::Error),
}
#[derive(Debug, Deserialize)]
pub struct User {
#[serde(rename = "Email")]
@ -59,115 +69,109 @@ impl Client {
.read_to_end(&mut buf)
.expect("Could not read root cert file");
return reqwest::Certificate::from_der(&buf).expect("Could not load der root cert file");
reqwest::Certificate::from_der(&buf).expect("Could not load DER root cert file")
}
fn get_http_client(&self) -> reqwest::Client {
let mut client = reqwest::Client::builder().redirect(reqwest::RedirectPolicy::none());
fn get_http_client(&self) -> reqwest::blocking::Client {
let mut client =
reqwest::blocking::Client::builder().redirect(reqwest::redirect::Policy::none());
if !&self.root_cert_file.is_empty() {
let cert = self.get_root_cert();
client = client.add_root_certificate(cert);
}
return client.build().unwrap();
client.build().expect("Failed to build http client")
}
/// Authenticate client
fn auth(&mut self) -> Response {
fn auth(&mut self) -> Result<Response, ResponseError> {
let cookie_created = Instant::now();
let client = self.get_http_client();
let result = client
.post(format!("{}{}", &self.url, "/admin/").as_str())
.form(&[("token", &self.admin_token)])
.send()
.unwrap_or_else(|e| {
panic!("Could not authenticate with {}. {:?}", &self.url, e);
});
.send()?
.error_for_status()?;
// TODO: Handle error statuses
let cookie = result
.headers()
.get(reqwest::header::SET_COOKIE)
.ok_or_else(|| {
ResponseError::ApiError(String::from("Could not read authentication cookie"))
})?;
if let Some(cookie) = result.headers().get(reqwest::header::SET_COOKIE) {
self.cookie = cookie.to_str().map(|s| String::from(s)).ok();
self.cookie_created = Some(cookie_created);
} else {
panic!("Could not authenticate.")
self.cookie = cookie.to_str().map(String::from).ok();
self.cookie_created = Some(cookie_created);
Ok(result)
}
fn cookie_expired(&self) -> bool {
match &self.cookie {
Some(_) => self
.cookie_created
.map_or(true, |created| (created.elapsed() >= COOKIE_LIFESPAN)),
None => true,
}
result
}
/// Ensure that the client has a current auth cookie
fn ensure_auth(&mut self) {
match &self.cookie {
Some(_) => {
if self
.cookie_created
.map_or(true, |created| (created.elapsed() >= COOKIE_LIFESPAN))
{
self.auth();
}
}
None => {
self.auth();
}
};
// TODO: handle errors
fn ensure_auth(&mut self) -> Result<(), ResponseError> {
if self.cookie_expired() {
match self.auth() {
Ok(_) => Ok(()),
Err(err) => Err(err),
}?
}
Ok(())
}
/// Make an authenticated GET to Bitwarden Admin
fn get(&mut self, path: &str) -> Response {
self.ensure_auth();
fn get(&mut self, path: &str) -> Result<Response, ResponseError> {
self.ensure_auth()?;
match &self.cookie {
None => {
panic!("We haven't authenticated. Must be an error");
}
Some(cookie) => {
let url = format!("{}/admin{}", &self.url, path);
let client = self.get_http_client();
let request = client
.get(url.as_str())
.header(reqwest::header::COOKIE, cookie.clone());
let response = request.send().unwrap_or_else(|e| {
panic!("Could not call with {}. {:?}", url, e);
});
let url = format!("{}/admin{}", &self.url, path);
let client = self.get_http_client();
let request = client.get(url.as_str()).header(
reqwest::header::COOKIE,
self.cookie
.as_ref()
.expect("No cookie found to add to header")
.clone(),
);
// TODO: Handle error statuses
let response = request.send()?.error_for_status()?;
return response;
}
}
Ok(response)
}
/// Make authenticated POST to Bitwarden Admin with JSON data
fn post(&mut self, path: &str, json: &HashMap<String, String>) -> Response {
self.ensure_auth();
fn post(
&mut self,
path: &str,
json: &HashMap<String, String>,
) -> Result<Response, ResponseError> {
self.ensure_auth()?;
match &self.cookie {
None => {
panic!("We haven't authenticated. Must be an error");
}
Some(cookie) => {
let url = format!("{}/admin{}", &self.url, path);
let client = self.get_http_client();
let request = client
.post(url.as_str())
.header("Cookie", cookie.clone())
.json(&json);
let response = request.send().unwrap_or_else(|e| {
panic!("Could not call with {}. {:?}", url, e);
});
let url = format!("{}/admin{}", &self.url, path);
let client = self.get_http_client();
let request = client.post(url.as_str()).json(&json).header(
reqwest::header::COOKIE,
self.cookie
.as_ref()
.expect("No cookie found to add to header")
.clone(),
);
// TODO: Handle error statuses
let response = request.send()?.error_for_status()?;
return response;
}
}
Ok(response)
}
/// Invite user with provided email
pub fn invite(&mut self, email: &str) -> Response {
pub fn invite(&mut self, email: &str) -> Result<Response, ResponseError> {
let mut json = HashMap::new();
json.insert("email".to_string(), email.to_string());
@ -175,8 +179,8 @@ impl Client {
}
/// Get all existing users
pub fn users(&mut self) -> Result<Vec<User>, Box<dyn Error>> {
let all_users: Vec<User> = self.get("/users").json()?;
pub fn users(&mut self) -> Result<Vec<User>, ResponseError> {
let all_users: Vec<User> = self.get("/users")?.json()?;
Ok(all_users)
}
}