mirror of
https://github.com/ente-io/ente.git
synced 2025-07-12 09:58:48 +00:00
110 lines
2.9 KiB
Go
110 lines
2.9 KiB
Go
package pkg
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"github.com/ente-io/cli/internal/api/models"
|
|
"github.com/ente-io/cli/pkg/mapper"
|
|
"github.com/ente-io/cli/pkg/model"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
)
|
|
|
|
func (c *ClICtrl) SyncAuthAccount(account model.Account, filters model.Filter) error {
|
|
secretInfo, err := c.KeyHolder.LoadSecrets(account)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ctx := c.buildRequestContext(context.Background(), account, filters)
|
|
err = createDataBuckets(c.DB, account)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.Client.AddToken(account.AccountKey(), base64.URLEncoding.EncodeToString(secretInfo.Token))
|
|
data, err := c.fetchRemoteAuthenticatorData(ctx)
|
|
if err != nil {
|
|
log.Printf("Error fetching entities: %s", err)
|
|
return err
|
|
}
|
|
return c.writeAuthExport(ctx, account, data)
|
|
}
|
|
|
|
func (c *ClICtrl) writeAuthExport(ctx context.Context, account model.Account, data []string) error {
|
|
exportDir := account.ExportDir
|
|
if exportDir == "" {
|
|
return fmt.Errorf("export directory not set")
|
|
}
|
|
outputFile := fmt.Sprintf("%s/ente_auth.txt", exportDir)
|
|
// if outout file exists, create a backup with current datetime
|
|
if _, err := os.Stat(outputFile); err == nil {
|
|
backupFile := fmt.Sprintf("%s/ente_auth_%s.txt", exportDir, time.Now().Format("2006-01-02_15-04-05"))
|
|
if err := os.Rename(outputFile, backupFile); err != nil {
|
|
return fmt.Errorf("error creating backup file: %v", err)
|
|
}
|
|
}
|
|
// write the data to the output file, one line per entity
|
|
file, err := os.Create(outputFile)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating output file: %v", err)
|
|
}
|
|
defer file.Close()
|
|
for _, line := range data {
|
|
if _, err := file.WriteString(line + "\n"); err != nil {
|
|
return fmt.Errorf("error writing to output file: %v", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c *ClICtrl) fetchRemoteAuthenticatorData(ctx context.Context) ([]string, error) {
|
|
var entities []models.AuthEntity
|
|
hasMore := true
|
|
sinceTime := int64(0)
|
|
|
|
for hasMore {
|
|
fetched, err := c.Client.GetAuthDiff(ctx, sinceTime, 500)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get entities: %s", err)
|
|
}
|
|
entities = append(entities, fetched...)
|
|
if len(fetched) < 500 {
|
|
hasMore = false
|
|
} else {
|
|
for _, entity := range fetched {
|
|
if entity.UpdatedAt > sinceTime {
|
|
sinceTime = entity.UpdatedAt
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if len(entities) == 0 {
|
|
log.Println("No data to export")
|
|
return nil, nil
|
|
}
|
|
var key []byte
|
|
var err error
|
|
authKey, authKeyErr := c.Client.GetAuthKey(ctx)
|
|
if authKeyErr != nil {
|
|
return nil, fmt.Errorf("failed to get auth key: %s", authKeyErr)
|
|
} else {
|
|
key, err = c.KeyHolder.GetAuthenticatorKey(ctx, *authKey)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to decrypt auth key: %s", err)
|
|
}
|
|
}
|
|
var codes []string
|
|
for _, authEntity := range entities {
|
|
if authEntity.IsDeleted {
|
|
continue
|
|
}
|
|
code, mapErr := mapper.MapRemoteAuthEntityToString(ctx, authEntity, key)
|
|
if mapErr != nil {
|
|
return nil, mapErr
|
|
}
|
|
codes = append(codes, *code)
|
|
}
|
|
return codes, nil
|
|
}
|