Skip to content

Commit

Permalink
implement logout and sync-after-write for create-org
Browse files Browse the repository at this point in the history
  • Loading branch information
maxlaverse committed Nov 14, 2024
1 parent 6eed9b1 commit 48a6f9f
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
2 changes: 1 addition & 1 deletion internal/bitwarden/crypto/keybuilder/key_pair.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
"github.com/maxlaverse/terraform-provider-bitwarden/internal/bitwarden/crypto/symmetrickey"
)

func GenerateRSAKeyPair(key symmetrickey.Key) (string, string, error) {
func GenerateEncryptedRSAKeyPair(key symmetrickey.Key) (string, string, error) {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return "", "", fmt.Errorf("error generating rsa key: %w", err)
Expand Down
11 changes: 10 additions & 1 deletion internal/bitwarden/embedded/password_manager_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,15 @@ func (v *baseVault) storeObjects(ctx context.Context, objs []models.Object) {
v.storeObject(ctx, obj)
}
}
func (v *baseVault) storeOrganizationSecrets(ctx context.Context) {
for _, orgSecret := range v.loginAccount.Secrets.OrganizationSecrets {
v.storeObject(ctx, models.Object{
ID: orgSecret.OrganizationUUID,
Object: models.ObjectTypeOrganization,
Name: orgSecret.Name,
})
}
}

func decryptAccountSecrets(account Account, password string) (*AccountSecrets, error) {
if len(account.Email) == 0 {
Expand Down Expand Up @@ -664,7 +673,7 @@ func objMatchFilter(obj models.Object, filters bitwarden.ListObjectsFilterOption
return len(filters.SearchFilter) > 0
}

func compareObjects(obj1, obj2 models.Object) error {
func compareObjects[T any](obj1, obj2 T) error {
out1, err := json.Marshal(obj1)
if err != nil {
err := fmt.Errorf("error marshalling obj1 while comparing: %w", err)
Expand Down
39 changes: 30 additions & 9 deletions internal/bitwarden/embedded/password_manager_webapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type PasswordManagerClient interface {
GetAttachment(ctx context.Context, itemId, attachmentId string) ([]byte, error)
LoginWithAPIKey(ctx context.Context, password, clientId, clientSecret string) error
LoginWithPassword(ctx context.Context, username, password string) error
Logout(ctx context.Context) error
RegisterUser(ctx context.Context, name, username, password string, kdfConfig models.KdfConfiguration) error
Sync(ctx context.Context) error
Unlock(ctx context.Context, password string) error
Expand Down Expand Up @@ -280,7 +281,7 @@ func (v *webAPIVault) CreateOrganization(ctx context.Context, organizationName,
return "", fmt.Errorf("error encryption collection label: %w", err)
}

publicKey, encryptedPrivateKey, err := keybuilder.GenerateRSAKeyPair(*sharedKey)
publicKey, encryptedPrivateKey, err := keybuilder.GenerateEncryptedRSAKeyPair(*sharedKey)
if err != nil {
return "", fmt.Errorf("error generating key pair: %w", err)
}
Expand All @@ -300,6 +301,25 @@ func (v *webAPIVault) CreateOrganization(ctx context.Context, organizationName,
if err != nil {
return "", fmt.Errorf("error creating organization: %w", err)
}

v.baseVault.loginAccount.Secrets.OrganizationSecrets[res.Id] = OrganizationSecret{
OrganizationUUID: res.Id,
Name: organizationName,
Key: *sharedKey,
}

v.storeOrganizationSecrets(ctx)

if v.syncAfterWrite {
orgSecretBeforeSync := v.baseVault.loginAccount.Secrets.OrganizationSecrets[res.Id]
err := v.sync(ctx)
if err != nil {
return "", fmt.Errorf("sync-after-write error: %w", err)
}

return res.Id, compareObjects(orgSecretBeforeSync, v.baseVault.loginAccount.Secrets.OrganizationSecrets[res.Id])
}

return res.Id, nil
}

Expand Down Expand Up @@ -567,6 +587,13 @@ func (v *webAPIVault) LoginWithPassword(ctx context.Context, username, password
return v.continueLoginWithTokens(ctx, *tokenResp, password)
}

func (v *webAPIVault) Logout(ctx context.Context) error {
v.client.ClearSession()
v.clearObjectStore(ctx)
v.loginAccount = Account{}
return nil
}

func (v *webAPIVault) RegisterUser(ctx context.Context, name, username, password string, kdfConfig models.KdfConfiguration) error {
preloginKey, err := keybuilder.BuildPreloginKey(password, username, kdfConfig)
if err != nil {
Expand All @@ -580,7 +607,7 @@ func (v *webAPIVault) RegisterUser(ctx context.Context, name, username, password
return fmt.Errorf("error generating encryption key: %w", err)
}

publicKey, encryptedPrivateKey, err := keybuilder.GenerateRSAKeyPair(*encryptionKey)
publicKey, encryptedPrivateKey, err := keybuilder.GenerateEncryptedRSAKeyPair(*encryptionKey)
if err != nil {
return fmt.Errorf("error generating key pair: %w", err)
}
Expand Down Expand Up @@ -733,13 +760,7 @@ func (v *webAPIVault) prepareAttachmentCreationRequest(ctx context.Context, item
func (v *webAPIVault) loadObjectMap(ctx context.Context, cipherMap webapi.SyncResponse) error {
v.clearObjectStore(ctx)

for _, orgSecret := range v.loginAccount.Secrets.OrganizationSecrets {
v.storeObject(ctx, models.Object{
ID: orgSecret.OrganizationUUID,
Object: models.ObjectTypeOrganization,
Name: orgSecret.Name,
})
}
v.storeOrganizationSecrets(ctx)

res, err := ciphersToObjects(v.loginAccount.Secrets, cipherMap.Ciphers)
if err != nil {
Expand Down

0 comments on commit 48a6f9f

Please sign in to comment.