1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
package proton_api_bridge
import (
"context"
"time"
"github.com/henrybear327/go-proton-api"
"github.com/relvacode/iso8601"
)
type FileSystemAttrs struct {
ModificationTime time.Time
Size int64
BlockSizes []int64
Digests string // sha1 string
}
func (protonDrive *ProtonDrive) GetRevisions(ctx context.Context, link *proton.Link, revisionType proton.RevisionState) ([]*proton.RevisionMetadata, error) {
revisions, err := protonDrive.c.ListRevisions(ctx, protonDrive.MainShare.ShareID, link.LinkID)
if err != nil {
return nil, err
}
ret := make([]*proton.RevisionMetadata, 0)
// Revisions are only for files, they represent “versions” of files.
// Each file can have 1 active/draft revision and n obsolete revisions.
for i := range revisions {
if revisions[i].State == revisionType {
ret = append(ret, &revisions[i])
}
}
return ret, nil
}
func (protonDrive *ProtonDrive) GetActiveRevisionAttrsByID(ctx context.Context, linkID string) (*FileSystemAttrs, error) {
link, err := protonDrive.getLink(ctx, linkID)
if err != nil {
return nil, err
}
return protonDrive.GetActiveRevisionAttrs(ctx, link)
}
// Might return nil when xattr is missing
func (protonDrive *ProtonDrive) GetActiveRevisionAttrs(ctx context.Context, link *proton.Link) (*FileSystemAttrs, error) {
if link == nil {
return nil, ErrLinkMustNotBeNil
}
revisionsMetadata, err := protonDrive.GetRevisions(ctx, link, proton.RevisionStateActive)
if err != nil {
return nil, err
}
if len(revisionsMetadata) != 1 {
return nil, ErrCantFindActiveRevision
}
nodeKR, err := protonDrive.getLinkKR(ctx, link)
if err != nil {
return nil, err
}
signatureVerificationKR, err := protonDrive.getSignatureVerificationKeyring([]string{link.FileProperties.ActiveRevision.SignatureEmail})
if err != nil {
return nil, err
}
revisionXAttrCommon, err := revisionsMetadata[0].GetDecXAttrString(signatureVerificationKR, nodeKR)
if err != nil {
return nil, err
}
if revisionXAttrCommon == nil {
return nil, nil
}
modificationTime, err := iso8601.ParseString(revisionXAttrCommon.ModificationTime)
if err != nil {
return nil, err
}
var sha1Hash string
if val, ok := revisionXAttrCommon.Digests["SHA1"]; ok {
sha1Hash = val
} else {
sha1Hash = ""
}
return &FileSystemAttrs{
ModificationTime: modificationTime,
Size: revisionXAttrCommon.Size,
BlockSizes: revisionXAttrCommon.BlockSizes,
Digests: sha1Hash,
}, nil
}
func (protonDrive *ProtonDrive) GetActiveRevisionWithAttrs(ctx context.Context, link *proton.Link) (*proton.Revision, *FileSystemAttrs, error) {
if link == nil {
return nil, nil, ErrLinkMustNotBeNil
}
revisionsMetadata, err := protonDrive.GetRevisions(ctx, link, proton.RevisionStateActive)
if err != nil {
return nil, nil, err
}
if len(revisionsMetadata) != 1 {
return nil, nil, ErrCantFindActiveRevision
}
revision, err := protonDrive.c.GetRevisionAllBlocks(ctx, protonDrive.MainShare.ShareID, link.LinkID, revisionsMetadata[0].ID)
if err != nil {
return nil, nil, err
}
nodeKR, err := protonDrive.getLinkKR(ctx, link)
if err != nil {
return nil, nil, err
}
signatureVerificationKR, err := protonDrive.getSignatureVerificationKeyring([]string{link.FileProperties.ActiveRevision.SignatureEmail})
if err != nil {
return nil, nil, err
}
revisionXAttrCommon, err := revision.GetDecXAttrString(signatureVerificationKR, nodeKR)
if err != nil {
return nil, nil, err
}
modificationTime, err := iso8601.ParseString(revisionXAttrCommon.ModificationTime)
if err != nil {
return nil, nil, err
}
var sha1Hash string
if val, ok := revisionXAttrCommon.Digests["SHA1"]; ok {
sha1Hash = val
} else {
sha1Hash = ""
}
return &revision, &FileSystemAttrs{
ModificationTime: modificationTime,
Size: revisionXAttrCommon.Size,
BlockSizes: revisionXAttrCommon.BlockSizes,
Digests: sha1Hash,
}, nil
}
|