Skip to content
This repository has been archived by the owner on Jan 17, 2025. It is now read-only.

WIP: camelCase - Bitwarden 2024.6 / Vaultwarden 1.31+ #33

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d832534
Merge pull request #18 from commonism/2fa
kiorky Aug 8, 2023
4634b74
doc and changelog
kiorky Aug 8, 2023
d8e6dcc
Release: 1.0.56
kiorky Aug 8, 2023
f476364
Fix CI/CD
kiorky Apr 15, 2025
1eb4f0e
Add traefik front in test
kiorky Apr 16, 2025
be84e3c
Fix new vaultwarden create_orga
kiorky Apr 17, 2025
3fe4745
Fix newer vaultwarden adduser
kiorky Apr 18, 2025
e2f52b3
Fix newer vaultwarden patch
kiorky Apr 19, 2025
1ea5399
Fix newer vaultwarden set_org_access
kiorky Apr 20, 2025
2dfe31f
lint
kiorky Apr 21, 2025
b050076
doc
kiorky Apr 22, 2025
e3de73b
Merge pull request #19 from corpusops/next
kiorky Sep 30, 2023
04ed026
Release: 1.0.57
kiorky Sep 30, 2023
74077f7
Minor readme fixes
meichthys Nov 17, 2023
cd8748c
Merge pull request #22 from meichthys/patch-1
kiorky Jul 23, 2024
64435cf
2024.6 Bitwarden uses camelCase keys instead of PascalCase
OdyX Jul 17, 2024
099855c
Fix missing type/id lowercase object keys
commonism Jul 23, 2024
44b52ca
tests - using vaultwarden 1.32
commonism Aug 17, 2024
7db3b4b
cicd - on PR
commonism Aug 17, 2024
53bcc7f
tests/ci - disable dockerhub login
commonism Aug 17, 2024
41e979a
tests/ci - install docker-compose
commonism Aug 17, 2024
e25abfb
tests/ci - .tox perms
commonism Aug 17, 2024
09ea27c
tests/ci - using vaultwarden 1.32.0
commonism Aug 17, 2024
ba48367
camelCase
commonism Aug 19, 2024
da98abd
using the items dedicated key to decode the item
commonism Aug 23, 2024
fa870a4
client - key uses user_key or org_key when using item encryption keys
commonism Aug 23, 2024
8d1685d
item specific keys …
commonism Aug 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,3 @@ NO_NVM_INSTALL=1
NO_PIP_INSTALL=1
VERBOSE_NVM_INSTALL=1
COMPOSE_FILE=docker-compose.yml:docker-compose-dev.yml:docker-compose-build.yml:docker-compose-test.yml
BITWARDEN_IMAGE=vaultwarden/server:1.25.2
# BITWARDEN_IMAGE=bitwardenrs/server-postgresql:1.18.0
15 changes: 10 additions & 5 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ on:
inputs:
RUNTESTS: {description: 'Run tests', required: false}
push:
pull_request:
schedule: [{cron: '1 0 1,15 * *'}]
repository_dispatch:
env:
Expand Down Expand Up @@ -38,11 +39,11 @@ jobs:
then releasable=true;else releasable=false;fi
echo "::set-output name=releasable::$releasable"
id: v
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
# - name: Login to Docker Hub
# uses: docker/login-action@v1
# with:
# username: ${{ secrets.DOCKER_HUB_USERNAME }}
# password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Activate docker experimental
run: |-
sudo bash -exc "service docker stop;python -c \
Expand All @@ -55,6 +56,9 @@ jobs:
run: |-
for i in .env .env.local;do if [ -e $i.test ];then cp -v $i.test $i;fi;done
printf "USER_UID=$(id -u)\nUSER_GID=$(id -g)\n">>.env
- name: Install docker-compose
run: |-
sudo apt update && sudo apt install -y docker-compose
- name: Build dependant docker images if any
run: if ( docker-compose config|egrep -q build:; );then docker-compose build;fi
- name: Start stack
Expand All @@ -74,6 +78,7 @@ jobs:
for i in $http_services;do http_wait $i;done
( while true; do docker ps -a;docker-compose logs db bitwarden app;sleep 15;done )&
$bash -exc '\
sudo chmod 777 -R .tox
( while !(touch .tox/ready);do echo "app not ready ($(pwd))">&2;sleep 0.5;done \
&& touch .tox/appready )&\
/cops_helpers/dockerize -wait file://$(pwd)/.tox/appready -timeout 180s;'
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
.bash_history
src/.coverage
/dist
/.tox
10 changes: 10 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
## CHANGES

### 1.0.57
- QA & CI/CD fixes [kiorky]
- Fix newer vaultwarden patch [kiorky]
- Fix newer vaultwarden adduser [kiorky]
- Fix new vaultwarden create_orga [kiorky]
- Fix newer vaultwarden set_org_acces [kiorky]

### 1.0.56
- Customizable auth payload support (2Factor, api auth) [Markus Kötter <[email protected]>])

### 1.0.55
- ensure requests is in requirements [kiorky]

Expand Down
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# syntax=docker/dockerfile:1.3
FROM corpusops/ubuntu-bare:20.04
FROM corpusops/ubuntu-bare:22.04
WORKDIR /tmp/install
ARG DEV_DEPENDENCIES_PATTERN='^#\s*dev dependencies' \
PY_VER=3.8 \
USER_NAME=app USER_UID=1000 USER_GROUP= USER_GID= \
USER_HOME=/w
ARG PIP_SRC=$USER_HOME/lib
ENV USER_NAME=$USER_NAME USER_GROUP=${USER_GROUP:-$USER_NAME} USER_UID=$USER_UID USER_GID=${USER_GID:-${USER_UID}} USER_HOME=$USER_HOME PY_VER=${PY_VER:-} PIP_SRC=$PIP_SRC
ENV USER_NAME=$USER_NAME USER_GROUP=${USER_GROUP:-$USER_NAME} USER_UID=$USER_UID USER_GID=${USER_GID:-${USER_UID}} USER_HOME=$USER_HOME PY_VER=${PY_VER} PIP_SRC=$PIP_SRC

# system dependendencies (pkgs, users, etc)
ADD apt*.txt ./
Expand All @@ -16,6 +16,7 @@ RUN set -e \
useradd -s /bin/bash -d $USER_HOME -m -u $USER_UID -g $USER_UID $USER_NAME;fi \
&& sed -i -re "s/(python-?)[0-9]\.[0-9]+/\1$PY_VER/g" apt.txt \
&& apt update && apt install -y $(egrep -v "^#" apt.txt) \
&& git config --global --add safe.directory '*' \
&& mkdir -pv "$PIP_SRC" && chown $USER_NAME "$PIP_SRC" \
&& printf "$USER_NAME ALL=(ALL) NOPASSWD:ALL\n">/etc/sudoers.d/app \
&& : end
Expand All @@ -24,7 +25,7 @@ RUN set -e \
WORKDIR $USER_HOME
# See https://github.com/pypa/setuptools/issues/3301
# ARG PIP_REQ=>=22 SETUPTOOLS_REQ=<60 \
ARG PIP_REQ=>=22 SETUPTOOLS_REQ>=60 \
ARG PIP_REQ=>=22 SETUPTOOLS_REQ=>=60 \
REQUIREMENTS=requirements/requirements.txt requirements/requirements-dev.txt
ENV REQUIREMENTS=$REQUIREMENTS PIP_REQ=$PIP_REQ SETUPTOOLS_REQ=$SETUPTOOLS_REQ
ADD --chown=app:app lib/ lib/
Expand Down
34 changes: 17 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
# tools for working with vaultwarden/bitwarden (_rs) and vaultier
# Tools for working with vaultwarden/bitwarden (_rs) and vaultier

This package containers a python3+ client for bitwarden which uses both a native python implementation but also wraps the official the official npm `@bitwarden/cli`.
This package containers a python3+ client for bitwarden which uses both a native python implementation but also wraps the official npm `@bitwarden/cli`.

The ultimate goal is certainly only to rely on python implementation against the vaultwarden/bitwarden_rs server implementation.

- [![.github/workflows/cicd.yml](https://github.com/corpusops/bitwardentools/actions/workflows/cicd.yml/badge.svg?branch=main)](https://github.com/corpusops/bitwardentools/actions/workflows/cicd.yml)

## Features
- api controllable client
- API controllable client
- Create, Read, Update, Delete, on organizations, collection, ciphers, users (also disable/enable), and attachments
- Attach Ciphers to organization collections
- Set access at orgas, collections and users levels.
- Set access at organization, collections and users levels
- Download/Upload attachments to vault and organizations
- The client also integrate a thin wrapper to official npm CLI (see `call` mathod)
- Read [api](./src/bitwardentools/client.py) for longer details
- Integrates a thin wrapper around the official npm CLI (see `call` mathod)
- Read [api](./src/bitwardentools/client.py) for more details

## install as a python lib
## Install as a python lib
```bash
pip install bitwardentools
```
Expand All @@ -41,20 +41,20 @@ docker-compose run --rm app bash
```

```bash
sed "/COMPOSE_FILE/d" .env
echo COMPOSE_FILE=docker-compose.yml:docker-compose-dev.yml"
sed -i -e "/COMPOSE_FILE/d" .env
echo "COMPOSE_FILE=docker-compose.yml:docker-compose-dev.yml" >> .env
docker-compose up -d --force-recreate
docker-compose exec -U app bash
docker-compose exec -u app app bash
```

### run tests
### Run Tests
```bash
sed "/COMPOSE_FILE/d" .env
echo COMPOSE_FILE=docker-compose.yml:docker-compose-dev.yml:docker-compose-test.yml"
docker-compose exec -U app app tox -e linting,coverage
sed -i -e "/COMPOSE_FILE/d" .env
echo "COMPOSE_FILE=docker-compose.yml:docker-compose-dev.yml:docker-compose-test.yml" >> .env
docker-compose exec -u app app tox -e linting,coverage
```

## Credits and bibliography
## Credits and Bibliography
- [gnunux](http://gnunux.info/) excellent articles:
[1](http://gnunux.info/dotclear2/index.php?post/2020/10/11/%C3%89crire-un-client-Bitwarden-en-python-%3A-identifiant)
[2](http://gnunux.info/dotclear2/index.php?post/2020/10/11/%C3%89crire-un-client-Bitwarden-en-python-%3A-cr%C3%A9er-une-organisation-et-une-collection)
Expand All @@ -66,5 +66,5 @@ docker-compose exec -U app app tox -e linting,coverage
- https://github.com/jcs/rubywarden


## Doc
see also [USAGE](./USAGE.md) (or read below on pypi)
## Docs
See [USAGE](./USAGE.md) (or read below on pypi)
38 changes: 38 additions & 0 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,44 @@ c.remove_user_from_collection(userOrEmail, colc)
c.remove_user_from_organization(userOrEmail, orga)
```

### Manipulating the login data structure via callback (2Factor)
This allows other login mechanisms such as totp or api key:

example 1:

```python

def mfa2fa(loginpayload):
totp = pyotp.TOTP(otpseed)
loginpayload.update(
{
"twoFactorToken": str(totp.now()),
"twoFactorProvider": "0",
"twoFactorRemember": "0"
}
)
return loginpayload

client = Client(server, email, password, authentication_cb=mfa2fa)
```

example 1:

```python
def api_key(loginpayload):
loginpayload.update(
{
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"scope": "api",
"grant_type": "client_credentials"
}
)
return loginpayload

client = Client(server, email, password, authentication_cb=api_key)
```

### encode the vaultwarden/bitwarden_rs key for autovalidating user
```sh
base64 $BITWARDEN_RS_SERVER_DATA/rsa_key.der|tr -d '\n'
Expand Down
19 changes: 9 additions & 10 deletions apt.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@ openssh-client
rsync
# runtime dependencies
python3
python3.8
python3.8-distutils
python3.8-lib2to3
libpython3.8
python3.10
python3.10-distutils
python3.10-lib2to3
libpython3.10
binutils
ca-certificates
curl
gettext
git
less
libllvm10
libllvm11
libsoup2.4-1
llvm-10
llvm-11
lsb-release
sudo
tzdata
vim
wget
python3.8-venv
python3.10-venv
python3-virtualenv
python3-distlib
python3-pkg-resources
Expand All @@ -32,7 +32,6 @@ build-essential
gpg
libgcc-9-dev
libstdc++-9-dev
llvm-10-dev
python3.8-dev
python3-dev
llvm-11-dev
python3.10-dev
software-properties-common
2 changes: 1 addition & 1 deletion docker-compose-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ services:
build:
context: "."
args:
PY_VER: 3.8
PY_VER: "3.10"
REQUIREMENTS: requirements/requirements.txt requirements/requirements-dev.txt
32 changes: 24 additions & 8 deletions docker-compose-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ x-bases:
BITWARDEN_DB_IMAGE: corpusops/postgres:13
BITWARDEN_DOMAIN: bitwarden
DATABASE_URL: postgresql://db:db@db/db
BITWARDEN_IMAGE: vaultwarden/server:1.21.0
BITWARDEN_IMAGE: vaultwarden/server:1.32.0
DATA_FOLDER: /data
DISABLE_ADMIN_TOKEN: "true"
DOMAIN: http://bitwarden
Expand Down Expand Up @@ -44,7 +44,7 @@ x-bases:
SMTP_SSL: "false"
SMTP_TIMEOUT: '15'
WEBSOCKET_ENABLED: "true"
networks: {app_net: {driver: bridge, ipam: {config: [{subnet: "${BITWARDEN_NETWORK:-172.38.0}.0/24"}], driver: default}}}
networks: {bitwarden_net: {driver: bridge, ipam: {config: [{subnet: "${BITWARDEN_NETWORK:-172.38.0}.0/24"}], driver: default}}}
services:
setup:
<<: [ *base ]
Expand Down Expand Up @@ -72,13 +72,13 @@ services:
rf
while true;do printf "HTTP/1.1 200 OK\nContent-Length: 7\n\nstarted\n"|( nc -l -p 80 || /bin/true);done
image: corpusops/postgres:13
networks: {app_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.6"}}
networks: {bitwarden_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.6"}}
volumes:
- helpers:/helpers:rw
db:
<<: [ *base ]
image: corpusops/postgres:13
networks: {app_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.4"}}
networks: {bitwarden_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.4"}}
security_opt: [seccomp=unconfined]
volumes:
- db:/var/lib/postgresql/data:rw
Expand All @@ -92,29 +92,29 @@ services:
-p -c MailHog'
hostname: mailcatcher
image: corpusops/mailhog
networks: {app_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.12"}}
networks: {bitwarden_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.12"}}
user: root
volumes:
- mails:/mails:rw
bitwarden:
<<: [ *base ]
image: $BITWARDEN_IMAGE
image: ${BITWARDEN_IMAGE:-vaultwarden/server:1.32.0}
hostname: bitwarden
depends_on: [db, setup, mailcatcher]
entrypoint:
- bash
- -exc
- 'while !(curl -s setup);do echo "not ready">&2;sleep 0.5;done
&& exec /start.sh "$$@"'
networks: {app_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.14"}}
networks: {bitwarden_net: {ipv4_address: "${BITWARDEN_NETWORK:-172.38.0}.14"}}
volumes:
- bitwarden:/data:rw
- ./bitwarden:/conf:rw
- helpers:/helpers:rw
- logs:/logs:rw
app:
<<: [ *base ]
networks: {app_net: {}}
networks: {bitwarden_net: {}}
depends_on: [bitwarden]
entrypoint:
- bash
Expand All @@ -136,6 +136,22 @@ services:
volumes:
- "bitwarden:/bitwarden"
- helpers:/helpers:rw
traefik:
image: "traefik:v2.10"
networks: {bitwarden_net: {}}
entrypoint:
- "sh"
- "-xec"
- |-
/entrypoint.sh --configFile=/app/traefik.toml
ports:
- "${BITWARDEN_PORT:-3010}:80"
- "${BITWARDEN_PORT:-3013}:8080"
- "${BITWARDEN_PORT:-3011}:443"
volumes:
- "./:/app:ro"
- "./traefik.toml:/traefik.toml"
- "./traefik.r.toml:/traefik.r.toml"
volumes:
bitwarden: {}
mails: {}
Expand Down
11 changes: 11 additions & 0 deletions gencert.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env sh
set -ex
cd $(dirname $(readlink -f $0))
apk update && apk add openssl
openssl req -nodes -x509 -sha256 -newkey rsa:4096 \
-keyout local/cert.key \
-out local/cert.crt \
-days 356 \
-subj "/C=NL/ST=Zuid Holland/L=Rotterdam/O=ACME Corp/OU=IT Dept/CN=example.org" \
-addext "subjectAltName = DNS:localhost,DNS:wkbox2,DNS:localhost:3012,DNS:wkbox2:3012,DNS:vaultwarden:3011,DNS:vaultwarden:3012"
# vim:set et sts=4 ts=4 tw=80:
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
-e .
-e git+https://github.com/corpusops/vaultier-cli.git#egg=vaultcli
-e git+https://github.com/corpusops/vaultier-cli.git##egg=vaultcli
click

hkdf
Expand Down
8 changes: 5 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ def read(*rnames):
long_description = "\n\n".join([read(a) for a in READMES])
classifiers = ["Programming Language :: Python", "Topic :: Software Development"]
name = "bitwardentools"
version = "1.0.55"
version = "1.0.57"
src_dir = "src"
req = re.compile("^(?!(-e|#))", flags=re.I | re.M)
install_requires = [
a.strip() for a in open("requirements/requirements.txt").read().splitlines() if req.search(a) and a.strip()
a.strip()
for a in open("requirements/requirements.txt").read().splitlines()
if req.search(a) and a.strip()
]
extra_requires = {}
candidates = {}
Expand All @@ -51,7 +53,7 @@ def read(*rnames):
author="kiorky",
author_email="[email protected]",
url="https://github.com/corpusops/bitwardentools",
long_description_content_type='text/markdown',
long_description_content_type="text/markdown",
license="GPL",
packages=find_packages(src_dir),
package_dir={"": src_dir},
Expand Down
Loading