Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion crates/bitwarden-json/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bitwarden::ClientSettings;
use bitwarden::{ClientSettings, OrganizationId};
#[cfg(feature = "secrets")]
use bitwarden::{
generators::GeneratorClientsExt,
Expand All @@ -20,6 +20,11 @@ impl Client {
Self(bitwarden::Client::new(settings))
}

pub fn get_access_token_organization(&self) -> Option<OrganizationId> {
let client = &self.0;
client.internal.get_access_token_organization()
}

pub async fn run_command(&self, input_str: &str) -> String {
const SUBCOMMANDS_TO_CLEAN: &[&str] = &["Secrets"];
let mut cmd_value: serde_json::Value = match serde_json::from_str(input_str) {
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden-py/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ name = "bitwarden_py"
crate-type = ["cdylib"]

[dependencies]
bitwarden = { workspace = true }
bitwarden-json = { path = "../bitwarden-json", features = ["secrets"] }
pyo3 = { version = "0.27.0", features = ["extension-module", "abi3"] }
pyo3-log = "0.13.2"
Expand Down
9 changes: 9 additions & 0 deletions crates/bitwarden-py/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,13 @@ impl BitwardenClient {
fn run_command(&self, command_input: String) -> String {
self.0.block_on(self.1.run_command(&command_input))
}

#[pyo3(text_signature = "($self")]
fn get_access_token_organization(&self) -> String {
if let Some(organization_id) = self.1.get_access_token_organization() {
organization_id.to_string()
} else {
"".to_string()
}
}
}
37 changes: 30 additions & 7 deletions languages/python/bitwarden_sdk/bitwarden_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,15 @@ def get_by_ids(self, ids: List[UUID]) -> ResponseForSecretsResponse:

def create(
self,
organization_id: UUID,
organization_id: Optional[UUID],
key: str,
value: str,
note: Optional[str],
project_ids: Optional[List[UUID]] = None,
) -> ResponseForSecretResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

if note is None:
# secrets api does not accept empty notes
note = ""
Expand All @@ -120,7 +123,12 @@ def create(
)
return ResponseForSecretResponse.from_dict(result)

def list(self, organization_id: str) -> ResponseForSecretIdentifiersResponse:
def list(
self, organization_id: Optional[UUID]
) -> ResponseForSecretIdentifiersResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

result = self.client._run_command(
Command(
secrets=SecretsCommand(list=SecretIdentifiersRequest(organization_id))
Expand All @@ -130,13 +138,16 @@ def list(self, organization_id: str) -> ResponseForSecretIdentifiersResponse:

def update(
self,
organization_id: str,
organization_id: Optional[UUID],
id: str,
key: str,
value: str,
note: Optional[str],
project_ids: Optional[List[UUID]] = None,
) -> ResponseForSecretResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

if note is None:
# secrets api does not accept empty notes
note = ""
Expand All @@ -158,8 +169,11 @@ def delete(self, ids: List[str]) -> ResponseForSecretsDeleteResponse:
return ResponseForSecretsDeleteResponse.from_dict(result)

def sync(
self, organization_id: str, last_synced_date: Optional[str]
self, organization_id: Optional[UUID], last_synced_date: Optional[str]
) -> ResponseForSecretsSyncResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

result = self.client._run_command(
Command(
secrets=SecretsCommand(
Expand All @@ -182,9 +196,12 @@ def get(self, id: str) -> ResponseForProjectResponse:

def create(
self,
organization_id: str,
organization_id: Optional[UUID],
name: str,
) -> ResponseForProjectResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

result = self.client._run_command(
Command(
projects=ProjectsCommand(
Expand All @@ -194,18 +211,24 @@ def create(
)
return ResponseForProjectResponse.from_dict(result)

def list(self, organization_id: str) -> ResponseForProjectsResponse:
def list(self, organization_id: Optional[UUID]) -> ResponseForProjectsResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

result = self.client._run_command(
Command(projects=ProjectsCommand(list=ProjectsListRequest(organization_id)))
)
return ResponseForProjectsResponse.from_dict(result)

def update(
self,
organization_id: str,
organization_id: Optional[UUID],
id: str,
name: str,
) -> ResponseForProjectResponse:
if organization_id is None:
organization_id = self.client.inner.get_access_token_organization()

result = self.client._run_command(
Command(
projects=ProjectsCommand(
Expand Down
19 changes: 9 additions & 10 deletions languages/python/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

# Add some logging & set the org id
logging.basicConfig(level=logging.DEBUG)
organization_id = os.getenv("ORGANIZATION_ID")

# -- Example Generator Commands --
# Note: using the generator does not require authentication with a server
Expand Down Expand Up @@ -49,44 +48,44 @@

# -- Example Project Commands --

project = client.projects().create(organization_id, "ProjectName")
project2 = client.projects().create(organization_id, "AnotherProject")
project = client.projects().create(None, "ProjectName")
project2 = client.projects().create(None, "AnotherProject")
updated_project = client.projects().update(
organization_id, project.data.id, "Cool New Project Name"
None, project.data.id, "Cool New Project Name"
)
get_that_project = client.projects().get(project.data.id)

input("Press Enter to delete the project...")
client.projects().delete([project.data.id])

print(client.projects().list(organization_id))
print(client.projects().list(None))

# -- Example Secret Commands --

if client.secrets().sync(organization_id, None).data.has_changes is True:
if client.secrets().sync(None, None).data.has_changes is True:
print("There are changes to sync")
else:
print("No changes to sync")

last_synced_date = datetime.now(tz=timezone.utc)
print(client.secrets().sync(organization_id, last_synced_date))
print(client.secrets().sync(None, last_synced_date))

secret = client.secrets().create(
organization_id,
None,
"TEST_SECRET",
"This is a test secret",
"Secret1234!",
[project2.data.id],
)
secret2 = client.secrets().create(
organization_id,
None,
"ANOTHER_SECRET",
"Secret1234!",
None,
[project2.data.id],
)
secret_updated = client.secrets().update(
organization_id,
None,
secret.data.id,
"TEST_SECRET_UPDATED",
"This as an updated test secret",
Expand Down
Loading