mirror of
https://github.com/passbolt/go-passbolt.git
synced 2025-05-14 11:28:21 +00:00
Implement v5 Resource Creation
This commit is contained in:
parent
5369030d50
commit
e90a19a41d
1 changed files with 140 additions and 1 deletions
|
@ -5,11 +5,144 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/ProtonMail/gopenpgp/v3/crypto"
|
||||
"github.com/passbolt/go-passbolt/api"
|
||||
)
|
||||
|
||||
// CreateResource Creates a Resource where the Password and Description are Encrypted and Returns the Resources ID
|
||||
// CreateResource Creates a Resource, Creates a v4 or v5 Resources based on the server Preference
|
||||
func CreateResource(ctx context.Context, c *api.Client, folderParentID, name, username, uri, password, description string) (string, error) {
|
||||
// Create a v5 Password if that is the Server Default
|
||||
if c.MetadataTypeSettings().DefaultResourceType == api.PassboltAPIVersionTypeV5 {
|
||||
return CreateResourceV5(ctx, c, folderParentID, name, username, uri, password, description)
|
||||
} else {
|
||||
return CreateResourceV4(ctx, c, folderParentID, name, username, uri, password, description)
|
||||
}
|
||||
}
|
||||
|
||||
func CreateResourceV5(ctx context.Context, c *api.Client, folderParentID, name, username, uri, password, description string) (string, error) {
|
||||
if c.MetadataTypeSettings().AllowCreationOfV5Resources == false {
|
||||
return "", fmt.Errorf("Creation of V5 Passwords is disabled on this Server")
|
||||
}
|
||||
|
||||
types, err := c.GetResourceTypes(ctx, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Getting ResourceTypes: %w", err)
|
||||
}
|
||||
var rType *api.ResourceType
|
||||
for _, tmp := range types {
|
||||
if tmp.Slug == "v5-default" {
|
||||
rType = &tmp
|
||||
break
|
||||
}
|
||||
}
|
||||
if rType == nil {
|
||||
return "", fmt.Errorf("Cannot find Resource type password-and-description")
|
||||
}
|
||||
|
||||
// Base Resource
|
||||
resource := api.Resource{
|
||||
ResourceTypeID: rType.ID,
|
||||
FolderParentID: folderParentID,
|
||||
}
|
||||
|
||||
// Resource Metadata
|
||||
meta := api.ResourceMetadataTypeV5Default{
|
||||
ObjectType: api.PASSBOLT_OBJECT_TYPE_RESOURCE_METADATA,
|
||||
Name: name,
|
||||
Username: username,
|
||||
URIs: []string{uri},
|
||||
}
|
||||
|
||||
metaData, err := json.Marshal(&meta)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Marshalling metadata: %w", err)
|
||||
}
|
||||
|
||||
err = validateMetadata(rType, string(metaData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Validating metadata: %w", err)
|
||||
}
|
||||
|
||||
var publicMetadataKey *crypto.Key
|
||||
// Since we are not sharing, use the Personal Key if allowed
|
||||
if c.MetadataKeySettings().AllowUsageOfPersonalKeys {
|
||||
publicMetadataKey, err = c.GetUserPrivateKeyCopy()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Get User Private Key: %w", err)
|
||||
}
|
||||
|
||||
me, err := c.GetMe(ctx)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Get User Me: %w", err)
|
||||
}
|
||||
|
||||
if me.GPGKey == nil {
|
||||
return "", fmt.Errorf("User Me GPG Key nil")
|
||||
}
|
||||
|
||||
resource.MetadataKeyID = me.GPGKey.ID
|
||||
resource.MetadataKeyType = api.MetadataKeyTypeUserKey
|
||||
} else {
|
||||
keys, err := c.GetMetadataKeys(ctx, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Get Metadata Key: %w", err)
|
||||
}
|
||||
|
||||
// TODO Get Key by id?
|
||||
if len(keys) != 1 {
|
||||
return "", fmt.Errorf("Not Exactly One Metadatakey Available")
|
||||
}
|
||||
|
||||
publicMetadataKey, err = crypto.NewKeyFromArmored(keys[0].ArmoredKey)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Get Metadata Public Key: %w", err)
|
||||
}
|
||||
|
||||
resource.MetadataKeyID = keys[0].ID
|
||||
resource.MetadataKeyType = api.MetadataKeyTypeSharedKey
|
||||
}
|
||||
|
||||
encMetadata, err := c.EncryptMessageWithKey(publicMetadataKey, string(metaData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Encrypt Metadata: %w", err)
|
||||
}
|
||||
resource.Metadata = encMetadata
|
||||
|
||||
// Resource Secret
|
||||
secret := api.SecretDataTypeV5Default{
|
||||
ObjectType: api.PASSBOLT_OBJECT_TYPE_SECRET_DATA,
|
||||
Password: password,
|
||||
Description: description,
|
||||
}
|
||||
|
||||
secretData, err := json.Marshal(&secret)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Marshalling Secret Data: %w", err)
|
||||
}
|
||||
|
||||
err = validateSecretData(rType, string(secretData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Validating Secret Data: %w", err)
|
||||
}
|
||||
|
||||
encSecretData, err := c.EncryptMessage(string(secretData))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Encrypting Secret Data for User me: %w", err)
|
||||
}
|
||||
resource.Secrets = []api.Secret{{Data: encSecretData}}
|
||||
|
||||
newresource, err := c.CreateResource(ctx, resource)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Creating Resource: %w", err)
|
||||
}
|
||||
return newresource.ID, nil
|
||||
}
|
||||
|
||||
func CreateResourceV4(ctx context.Context, c *api.Client, folderParentID, name, username, uri, password, description string) (string, error) {
|
||||
if c.MetadataTypeSettings().AllowCreationOfV4Resources == false {
|
||||
return "", fmt.Errorf("Creation of V4 Passwords is disabled on this Server")
|
||||
}
|
||||
|
||||
types, err := c.GetResourceTypes(ctx, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Getting ResourceTypes: %w", err)
|
||||
|
@ -62,6 +195,12 @@ func CreateResource(ctx context.Context, c *api.Client, folderParentID, name, us
|
|||
|
||||
// CreateResourceSimple Creates a Legacy Resource where only the Password is Encrypted and Returns the Resources ID
|
||||
func CreateResourceSimple(ctx context.Context, c *api.Client, folderParentID, name, username, uri, password, description string) (string, error) {
|
||||
if c.MetadataTypeSettings().AllowCreationOfV4Resources == false {
|
||||
return "", fmt.Errorf("Creation of V4 Passwords is disabled on this Server")
|
||||
}
|
||||
|
||||
// TODO Create a v5-password-string if v5 is enabled
|
||||
|
||||
enc, err := c.EncryptMessage(password)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Encrypting Password: %w", err)
|
||||
|
|
Loading…
Add table
Reference in a new issue