Skip to content

Commit

Permalink
Fix session key extraction for Bitwarden (#359)
Browse files Browse the repository at this point in the history
  • Loading branch information
ykeremy authored May 24, 2024
1 parent 753bac3 commit b976f13
Showing 1 changed file with 38 additions and 6 deletions.
44 changes: 38 additions & 6 deletions skyvern/forge/sdk/services/bitwarden.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ def run_command(command: list[str], additional_env: dict[str, str] | None = None

return subprocess.run(command, capture_output=True, text=True, env=env)

@staticmethod
def _extract_session_key(unlock_cmd_output: str) -> str | None:
# Split the text by lines
lines = unlock_cmd_output.split("\n")

# Look for the line containing the BW_SESSION
for line in lines:
if 'BW_SESSION="' in line:
# Find the start and end positions of the session key
start = line.find('BW_SESSION="') + len('BW_SESSION="')
end = line.rfind('"', start)
return line[start:end]

return None

@staticmethod
def get_secret_value_from_url(
client_id: str,
Expand All @@ -61,25 +76,42 @@ def get_secret_value_from_url(
login_command = ["bw", "login", "--apikey"]
login_result = BitwardenService.run_command(login_command, env)

# Print both stdout and stderr for debugging
# Validate the login result
if login_result.stdout and "You are logged in!" not in login_result.stdout:
raise BitwardenLoginError(
f"Failed to log in. stdout: {login_result.stdout} stderr: {login_result.stderr}"
)

if login_result.stderr and "You are already logged in as" not in login_result.stderr:
raise BitwardenLoginError(login_result.stderr)
raise BitwardenLoginError(
f"Failed to log in. stdout: {login_result.stdout} stderr: {login_result.stderr}"
)

LOG.info("Bitwarden login successful")

# Step 2: Unlock the vault
unlock_command = ["bw", "unlock", "--passwordenv", "BW_PASSWORD"]
unlock_result = BitwardenService.run_command(unlock_command, env)

# Validate the unlock result
if unlock_result.stdout and "Your vault is now unlocked!" not in unlock_result.stdout:
raise BitwardenUnlockError(
f"Failed to unlock vault. stdout: {unlock_result.stdout} stderr: {unlock_result.stderr}"
)

# This is a part of Bitwarden's client-side telemetry
# TODO -- figure out how to disable this telemetry so we never get this error
# https://github.com/bitwarden/clients/blob/9d10825dbd891c0f41fe1b4c4dd3ca4171f63be5/libs/common/src/services/api.service.ts#L1473
if unlock_result.stderr and "Event post failed" not in unlock_result.stderr:
raise BitwardenUnlockError(unlock_result.stderr)
raise BitwardenUnlockError(
f"Failed to unlock vault. stdout: {unlock_result.stdout} stderr: {unlock_result.stderr}"
)

# Extract session key
try:
session_key = unlock_result.stdout.split('"')[1]
except IndexError:
raise BitwardenUnlockError("Unable to extract session key.")
session_key = BitwardenService._extract_session_key(unlock_result.stdout)
except Exception as e:
raise BitwardenUnlockError(f"Unable to extract session key: {str(e)}")

if not session_key:
raise BitwardenUnlockError("Session key is empty.")
Expand Down

0 comments on commit b976f13

Please sign in to comment.