corpusops / bitwardentools

bitwarden python api client and additional tools like for migrating from vaultier to bitwarden (bitwarden_rs)
Other
35 stars 15 forks source link

Autnentication by using API key #14

Open karlism opened 2 years ago

karlism commented 2 years ago

Hello,

I've looked into documentation and couldn't really find an answer, does bitwardentools support authentication via API keys? Recent version of Vaultwarden has added support for them and I was wondering if it is possible to use API keys instead of password for authentication.

Thanks!

kiorky commented 1 year ago

from #11

BITWARDEN_TOKEN=$(curl --location -s --request POST \
  ${BITWARDEN_URL}/identity/connect/token \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "scope=api" \
  --data-urlencode 'deviceName=chrome' \
  --data-urlencode 'deviceIdentifier=DEVICE_ID' \
  --data-urlencode 'deviceType=DEVICE_TYPE' \
  --data-urlencode "username=${BITWARDEN_USER}" \
  --data-urlencode "client_id=${BITWARDEN_CLIENID}" \
  --data-urlencode "client_secret=${BITWARDEN_SECRET}" | jq -r '.access_token')
kiorky commented 1 year ago

Feel free to open PR for it, which i would be welcome to merge !

karlism commented 1 year ago

@valleedelisle, can you please create PR for your commit?

kiorky commented 1 year ago

does it cover vaultwarden api token auth too ?

Seems it's for official bitwarden server implementation, isnt it ?

mfominov commented 1 year ago

i've create a patch from this code for tests, unfortunately it doesn't handle api token auth

valleedelisle commented 1 year ago

I don't use this lib anymore because it's incomplete. I decided to wrap around the bwcli instead. Feel free to use my code if it helps, but I can't maintain this as I don't use it anymore.

commonism commented 1 year ago

possible via https://github.com/corpusops/bitwardentools/pull/18

def api_key():
    return {"client_id": "…",
            "client_secret":"…",
            "scope":"api",
            "grant_type":"client_credentials"}

client = Client(server, email, password, mfa_cb=api_key)
client.sync()
karlism commented 1 year ago

@commonism, thanks! I've tried it out with bitwardentools 1.0.56 and it works.

Unfortunately client password is still required, am I misunderstanding this feature or is it really supposed to work only when client password is provided?

kiorky commented 1 year ago

@commonism, thanks! I've tried it out with bitwardentools 1.0.56 and it works.

Unfortunately client password is still required, am I misunderstanding this feature or is it really supposed to work only when client password is provided?

Can you paste how you implemented it as there is an error on @commonism snippet, it should be

def api_key():
    return {"client_id": "…",
            "client_secret":"…",
            "scope":"api",
            "grant_type":"client_credentials"}

client = Client(server, email, password, authentication_cb=api_key)
client.sync()
kiorky commented 1 year ago

BTW, i have some bits to finish before an official release which includes this PR.

karlism commented 1 year ago

Can you paste how you implemented it as there is an error on @commonism snippet, it should be

@kiorky, I did and it works as long as username, password and API key is provided. However it doesn't work if I do not specify email or password. Am I wrong to assume that API key alone should be sufficient to authenticate user?

Python 3.10.12 (main, Jun 19 2023, 16:27:15) [Clang 13.0.0 ] on openbsd7
Type "help", "copyright", "credits" or "license" for more information.
>>> from bitwardentools import Client
>>> def api_key(loginpayload):
...     loginpayload.update(
...         {
...             "client_id": "user.eb76d2ac-528f-4189-8f5b-f200a6e6891e",
...             "client_secret": "oAI1704x6sLfxqVCsJkxtl1NrncUmz",
...             "scope": "api",
...             "grant_type": "client_credentials"
...         }
...     )
...     return loginpayload
... 
>>> Client('https://bitwarden.k8s.dev.example.com', 'username@example.com', 'password', authentication_cb=api_key)
<bitwardentools.client.Client object at 0xf43d4163fd0>
>>> Client('https://bitwarden.k8s.dev.example.com', authentication_cb=api_key)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/username/.local/lib/python3.10/site-packages/bitwardentools/client.py", line 695, in __init__
    raise RunError("no email")
bitwardentools.client.RunError: no email
>>> Client('https://bitwarden.k8s.dev.example.com', 'username@example.com', authentication_cb=api_key)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/username/.local/lib/python3.10/site-packages/bitwardentools/client.py", line 699, in __init__
    raise RunError("no password")
bitwardentools.client.RunError: no password

BTW, i have some bits to finish before an official release which includes this PR.

I'm aware of that and I've installed bitwardentools from here: https://github.com/corpusops/bitwardentools/archive/refs/tags/1.0.56.tar.gz

commonism commented 1 year ago

Email/Password is required for 2fa, pass empty strings for api key via cb. Not a beauty, but … consider this cosmetics.

kiorky commented 1 year ago

I'm aware of that and I've installed bitwardentools from here: https://github.com/corpusops/bitwardentools/archive/refs/tags/1.0.56.tar.gz

This isnt a release. Published release remain only on pypi.