mirror of
https://github.com/passbolt/go-passbolt.git
synced 2025-05-14 19:38:22 +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"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/gopenpgp/v3/crypto"
|
||||||
"github.com/passbolt/go-passbolt/api"
|
"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) {
|
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)
|
types, err := c.GetResourceTypes(ctx, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Getting ResourceTypes: %w", err)
|
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
|
// 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) {
|
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)
|
enc, err := c.EncryptMessage(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("Encrypting Password: %w", err)
|
return "", fmt.Errorf("Encrypting Password: %w", err)
|
||||||
|
|
Loading…
Add table
Reference in a new issue