ente/cli/pkg/mapper/photo.go
2024-03-01 12:39:01 +05:30

146 lines
4.6 KiB
Go

package mapper
import (
"context"
"encoding/json"
"errors"
"github.com/ente-io/cli/internal/api"
eCrypto "github.com/ente-io/cli/internal/crypto"
"github.com/ente-io/cli/pkg/model"
"github.com/ente-io/cli/pkg/model/export"
"github.com/ente-io/cli/pkg/secrets"
"github.com/ente-io/cli/utils/encoding"
"log"
)
func MapCollectionToAlbum(ctx context.Context, collection api.Collection, holder *secrets.KeyHolder) (*model.RemoteAlbum, error) {
var album model.RemoteAlbum
userID := ctx.Value("user_id").(int64)
album.OwnerID = collection.Owner.ID
album.ID = collection.ID
album.IsShared = collection.Owner.ID != userID
album.LastUpdatedAt = collection.UpdationTime
album.IsDeleted = collection.IsDeleted
collectionKey, err := holder.GetCollectionKey(ctx, collection)
if err != nil {
return nil, err
}
album.AlbumKey = *model.MakeEncString(collectionKey, holder.DeviceKey)
var name string
if collection.EncryptedName != "" {
decrName, err := eCrypto.SecretBoxOpenBase64(collection.EncryptedName, collection.NameDecryptionNonce, collectionKey)
if err != nil {
log.Fatalf("failed to decrypt collection name: %v", err)
}
name = string(decrName)
} else {
// Early beta users (friends & family) might have collections without encrypted names
name = collection.Name
}
album.AlbumName = name
if collection.MagicMetadata != nil {
_, encodedJsonBytes, err := eCrypto.DecryptChaChaBase64(collection.MagicMetadata.Data, collectionKey, collection.MagicMetadata.Header)
if err != nil {
return nil, err
}
err = json.Unmarshal(encodedJsonBytes, &album.PrivateMeta)
if err != nil {
return nil, err
}
}
if collection.PublicMagicMetadata != nil {
_, encodedJsonBytes, err := eCrypto.DecryptChaChaBase64(collection.PublicMagicMetadata.Data, collectionKey, collection.PublicMagicMetadata.Header)
if err != nil {
return nil, err
}
err = json.Unmarshal(encodedJsonBytes, &album.PublicMeta)
if err != nil {
return nil, err
}
}
if album.IsShared && collection.SharedMagicMetadata != nil {
_, encodedJsonBytes, err := eCrypto.DecryptChaChaBase64(collection.SharedMagicMetadata.Data, collectionKey, collection.SharedMagicMetadata.Header)
if err != nil {
return nil, err
}
err = json.Unmarshal(encodedJsonBytes, &album.SharedMeta)
if err != nil {
return nil, err
}
}
return &album, nil
}
func MapApiFileToPhotoFile(ctx context.Context, album model.RemoteAlbum, file api.File, holder *secrets.KeyHolder) (*model.RemoteFile, error) {
if file.IsDeleted {
return nil, errors.New("file is deleted")
}
albumKey := album.AlbumKey.MustDecrypt(holder.DeviceKey)
fileKey, err := eCrypto.SecretBoxOpen(
encoding.DecodeBase64(file.EncryptedKey),
encoding.DecodeBase64(file.KeyDecryptionNonce),
albumKey)
if err != nil {
return nil, err
}
var photoFile model.RemoteFile
photoFile.ID = file.ID
photoFile.LastUpdateTime = file.UpdationTime
photoFile.Key = *model.MakeEncString(fileKey, holder.DeviceKey)
photoFile.FileNonce = file.File.DecryptionHeader
photoFile.ThumbnailNonce = file.Thumbnail.DecryptionHeader
photoFile.OwnerID = file.OwnerID
if file.Info != nil {
photoFile.Info = model.Info{
FileSize: file.Info.FileSize,
ThumbnailSize: file.Info.ThumbnailSize,
}
}
if file.Metadata.DecryptionHeader != "" {
_, encodedJsonBytes, err := eCrypto.DecryptChaChaBase64(file.Metadata.EncryptedData, fileKey, file.Metadata.DecryptionHeader)
if err != nil {
return nil, err
}
err = json.Unmarshal(encodedJsonBytes, &photoFile.Metadata)
if err != nil {
return nil, err
}
}
if file.MagicMetadata != nil {
_, encodedJsonBytes, err := eCrypto.DecryptChaChaBase64(file.MagicMetadata.Data, fileKey, file.MagicMetadata.Header)
if err != nil {
return nil, err
}
err = json.Unmarshal(encodedJsonBytes, &photoFile.PrivateMetadata)
if err != nil {
return nil, err
}
}
if file.PubicMagicMetadata != nil {
_, encodedJsonBytes, err := eCrypto.DecryptChaChaBase64(file.PubicMagicMetadata.Data, fileKey, file.PubicMagicMetadata.Header)
if err != nil {
return nil, err
}
err = json.Unmarshal(encodedJsonBytes, &photoFile.PublicMetadata)
if err != nil {
return nil, err
}
}
return &photoFile, nil
}
func MapRemoteFileToDiskMetadata(file model.RemoteFile) *export.DiskFileMetadata {
return &export.DiskFileMetadata{
Title: file.GetTitle(),
Description: file.GetCaption(),
CreationTime: file.GetCreationTime(),
ModificationTime: file.GetModificationTime(),
Location: file.GetLatlong(),
Info: &export.Info{
ID: file.ID,
Hash: file.GetFileHash(),
OwnerID: file.OwnerID,
},
}
}