@@ -29,8 +29,7 @@ import (
2929type Crypt struct {
3030 model.Storage
3131 Addition
32- cipher * rcCrypt.Cipher
33- remoteStorage driver.Driver
32+ cipher * rcCrypt.Cipher
3433}
3534
3635const obfuscatedPrefix = "___Obfuscated___"
@@ -60,15 +59,7 @@ func (d *Crypt) Init(ctx context.Context) error {
6059 }
6160 d .FileNameEncoding = utils .GetNoneEmpty (d .FileNameEncoding , "base64" )
6261 d .EncryptedSuffix = utils .GetNoneEmpty (d .EncryptedSuffix , ".bin" )
63-
64- op .MustSaveDriverStorage (d )
65-
66- // need remote storage exist
67- storage , err := fs .GetStorage (d .RemotePath , & fs.GetStoragesArgs {})
68- if err != nil {
69- return fmt .Errorf ("can't find remote storage: %w" , err )
70- }
71- d .remoteStorage = storage
62+ d .RemotePath = utils .FixAndCleanPath (d .RemotePath )
7263
7364 p , _ := strings .CutPrefix (d .Password , obfuscatedPrefix )
7465 p2 , _ := strings .CutPrefix (d .Salt , obfuscatedPrefix )
@@ -108,79 +99,75 @@ func (d *Crypt) Drop(ctx context.Context) error {
10899}
109100
110101func (d * Crypt ) List (ctx context.Context , dir model.Obj , args model.ListArgs ) ([]model.Obj , error ) {
111- path := dir .GetPath ()
112- // return d.list(ctx, d.RemotePath, path)
113- // remoteFull
114-
115- objs , err := fs .List (ctx , d .getPathForRemote (path , true ), & fs.ListArgs {NoLog : true , Refresh : args .Refresh })
102+ remoteFullPath := dir .GetPath ()
103+ objs , err := fs .List (ctx , remoteFullPath , & fs.ListArgs {NoLog : true , Refresh : args .Refresh })
116104 // the obj must implement the model.SetPath interface
117105 // return objs, err
118106 if err != nil {
119107 return nil , err
120108 }
121109
122- var result []model.Obj
110+ result := make ( []model.Obj , 0 , len ( objs ))
123111 for _ , obj := range objs {
112+ rawName := model .UnwrapObj (obj ).GetName ()
124113 if obj .IsDir () {
125- name , err := d .cipher .DecryptDirName (obj . GetName () )
114+ name , err := d .cipher .DecryptDirName (rawName )
126115 if err != nil {
127116 // filter illegal files
128117 continue
129118 }
130119 if ! d .ShowHidden && strings .HasPrefix (name , "." ) {
131120 continue
132121 }
133- objRes := model.Object {
122+ result = append (result , & model.Object {
123+ Path : stdpath .Join (remoteFullPath , rawName ),
134124 Name : name ,
135125 Size : 0 ,
136126 Modified : obj .ModTime (),
137127 IsFolder : obj .IsDir (),
138128 Ctime : obj .CreateTime (),
139129 // discarding hash as it's encrypted
140- }
141- result = append (result , & objRes )
142- } else {
143- thumb , ok := model .GetThumb (obj )
144- size , err := d .cipher .DecryptedSize (obj .GetSize ())
145- if err != nil {
146- // filter illegal files
147- continue
148- }
149- name , err := d .cipher .DecryptFileName (obj .GetName ())
150- if err != nil {
151- // filter illegal files
152- continue
153- }
154- if ! d .ShowHidden && strings .HasPrefix (name , "." ) {
155- continue
156- }
157- objRes := model.Object {
158- Name : name ,
159- Size : size ,
160- Modified : obj .ModTime (),
161- IsFolder : obj .IsDir (),
162- Ctime : obj .CreateTime (),
163- // discarding hash as it's encrypted
164- }
165- if d .Thumbnail && thumb == "" {
166- thumbPath := stdpath .Join (args .ReqPath , ".thumbnails" , name + ".webp" )
167- thumb = fmt .Sprintf ("%s/d%s?sign=%s" ,
168- common .GetApiUrl (ctx ),
169- utils .EncodePath (thumbPath , true ),
170- sign .Sign (thumbPath ))
171- }
172- if ! ok && ! d .Thumbnail {
173- result = append (result , & objRes )
174- } else {
175- objWithThumb := model.ObjThumb {
176- Object : objRes ,
177- Thumbnail : model.Thumbnail {
178- Thumbnail : thumb ,
179- },
180- }
181- result = append (result , & objWithThumb )
182- }
130+ })
131+ continue
132+ }
133+
134+ size , err := d .cipher .DecryptedSize (obj .GetSize ())
135+ if err != nil {
136+ // filter illegal files
137+ continue
138+ }
139+ name , err := d .cipher .DecryptFileName (rawName )
140+ if err != nil {
141+ // filter illegal files
142+ continue
143+ }
144+ if ! d .ShowHidden && strings .HasPrefix (name , "." ) {
145+ continue
183146 }
147+ objRes := & model.Object {
148+ Path : stdpath .Join (remoteFullPath , rawName ),
149+ Name : name ,
150+ Size : size ,
151+ Modified : obj .ModTime (),
152+ IsFolder : obj .IsDir (),
153+ Ctime : obj .CreateTime (),
154+ // discarding hash as it's encrypted
155+ }
156+ if ! d .Thumbnail || ! strings .HasPrefix (args .ReqPath , "/" ) {
157+ result = append (result , objRes )
158+ continue
159+ }
160+ thumbPath := stdpath .Join (args .ReqPath , ".thumbnails" , name + ".webp" )
161+ thumb := fmt .Sprintf ("%s/d%s?sign=%s" ,
162+ common .GetApiUrl (ctx ),
163+ utils .EncodePath (thumbPath , true ),
164+ sign .Sign (thumbPath ))
165+ result = append (result , & model.ObjThumb {
166+ Object : * objRes ,
167+ Thumbnail : model.Thumbnail {
168+ Thumbnail : thumb ,
169+ },
170+ })
184171 }
185172
186173 return result , nil
@@ -191,67 +178,62 @@ func (d *Crypt) Get(ctx context.Context, path string) (model.Obj, error) {
191178 return & model.Object {
192179 Name : "Root" ,
193180 IsFolder : true ,
194- Path : "/" ,
181+ Path : d . RemotePath ,
195182 }, nil
196183 }
197- remoteFullPath := ""
198- var remoteObj model.Obj
199- var err , err2 error
184+
200185 firstTryIsFolder , secondTry := guessPath (path )
201- remoteFullPath = d . getPathForRemote (path , firstTryIsFolder )
202- remoteObj , err = fs .Get (ctx , remoteFullPath , & fs.GetArgs {NoLog : true })
186+ remoteFullPath := stdpath . Join ( d . RemotePath , d . encryptPath (path , firstTryIsFolder ) )
187+ remoteObj , err : = fs .Get (ctx , remoteFullPath , & fs.GetArgs {NoLog : true })
203188 if err != nil {
204- if errs .IsObjectNotFound (err ) && secondTry {
189+ if secondTry && errs .IsObjectNotFound (err ) {
205190 // try the opposite
206- remoteFullPath = d . getPathForRemote (path , ! firstTryIsFolder )
207- remoteObj , err2 = fs .Get (ctx , remoteFullPath , & fs.GetArgs {NoLog : true })
208- if err2 != nil {
209- return nil , err2
191+ remoteFullPath = stdpath . Join ( d . RemotePath , d . encryptPath (path , ! firstTryIsFolder ) )
192+ remoteObj , err = fs .Get (ctx , remoteFullPath , & fs.GetArgs {NoLog : true })
193+ if err != nil {
194+ return nil , err
210195 }
211196 } else {
212197 return nil , err
213198 }
214199 }
215- var size int64 = 0
216- name := ""
200+
201+ size := remoteObj .GetSize ()
202+ name := model .UnwrapObj (remoteObj ).GetName ()
217203 if ! remoteObj .IsDir () {
218- size , err = d .cipher .DecryptedSize (remoteObj . GetSize () )
204+ size , err = d .cipher .DecryptedSize (size )
219205 if err != nil {
220206 log .Warnf ("DecryptedSize failed for %s ,will use original size, err:%s" , path , err )
221- size = remoteObj .GetSize ()
222207 }
223- name , err = d .cipher .DecryptFileName (remoteObj . GetName () )
208+ name , err = d .cipher .DecryptFileName (name )
224209 if err != nil {
225210 log .Warnf ("DecryptFileName failed for %s ,will use original name, err:%s" , path , err )
226- name = remoteObj .GetName ()
227211 }
228212 } else {
229- name , err = d .cipher .DecryptDirName (remoteObj . GetName () )
213+ name , err = d .cipher .DecryptDirName (name )
230214 if err != nil {
231215 log .Warnf ("DecryptDirName failed for %s ,will use original name, err:%s" , path , err )
232- name = remoteObj .GetName ()
233216 }
234217 }
235218 obj := & model.Object {
236- Path : path ,
219+ Path : remoteFullPath ,
237220 Name : name ,
238221 Size : size ,
239222 Modified : remoteObj .ModTime (),
240223 IsFolder : remoteObj .IsDir (),
241224 }
242225 return obj , nil
243- // return nil, errs.ObjectNotFound
244226}
245227
246228// https://github.com/rclone/rclone/blob/v1.67.0/backend/crypt/cipher.go#L37
247229const fileHeaderSize = 32
248230
249- func (d * Crypt ) Link (ctx context.Context , file model.Obj , args model.LinkArgs ) (* model.Link , error ) {
250- dstDirActualPath , err := d . getActualPathForRemote (file .GetPath (), false )
231+ func (d * Crypt ) Link (ctx context.Context , file model.Obj , _ model.LinkArgs ) (* model.Link , error ) {
232+ remoteStorage , remoteActualPath , err := op . GetStorageAndActualPath (file .GetPath ())
251233 if err != nil {
252- return nil , fmt . Errorf ( "failed to convert path to remote path: %w" , err )
234+ return nil , err
253235 }
254- remoteLink , remoteFile , err := op .Link (ctx , d . remoteStorage , dstDirActualPath , args )
236+ remoteLink , remoteFile , err := op .Link (ctx , remoteStorage , remoteActualPath , model. LinkArgs {} )
255237 if err != nil {
256238 return nil , err
257239 }
@@ -323,64 +305,50 @@ func (d *Crypt) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
323305}
324306
325307func (d * Crypt ) MakeDir (ctx context.Context , parentDir model.Obj , dirName string ) error {
326- dstDirActualPath , err := d . getActualPathForRemote (parentDir .GetPath (), true )
308+ remoteStorage , remoteActualPath , err := op . GetStorageAndActualPath (parentDir .GetPath ())
327309 if err != nil {
328- return fmt . Errorf ( "failed to convert path to remote path: %w" , err )
310+ return err
329311 }
330- dir := d .cipher .EncryptDirName (dirName )
331- return op .MakeDir (ctx , d . remoteStorage , stdpath .Join (dstDirActualPath , dir ))
312+ encryptedName := d .cipher .EncryptDirName (dirName )
313+ return op .MakeDir (ctx , remoteStorage , stdpath .Join (remoteActualPath , encryptedName ))
332314}
333315
334316func (d * Crypt ) Move (ctx context.Context , srcObj , dstDir model.Obj ) error {
335- srcRemoteActualPath , err := d .getActualPathForRemote (srcObj .GetPath (), srcObj .IsDir ())
336- if err != nil {
337- return fmt .Errorf ("failed to convert path to remote path: %w" , err )
338- }
339- dstRemoteActualPath , err := d .getActualPathForRemote (dstDir .GetPath (), dstDir .IsDir ())
340- if err != nil {
341- return fmt .Errorf ("failed to convert path to remote path: %w" , err )
342- }
343- return op .Move (ctx , d .remoteStorage , srcRemoteActualPath , dstRemoteActualPath )
317+ _ , err := fs .Move (ctx , srcObj .GetPath (), dstDir .GetPath ())
318+ return err
344319}
345320
346321func (d * Crypt ) Rename (ctx context.Context , srcObj model.Obj , newName string ) error {
347- remoteActualPath , err := d . getActualPathForRemote (srcObj .GetPath (), srcObj . IsDir ())
322+ remoteStorage , remoteActualPath , err := op . GetStorageAndActualPath (srcObj .GetPath ())
348323 if err != nil {
349- return fmt . Errorf ( "failed to convert path to remote path: %w" , err )
324+ return err
350325 }
351326 var newEncryptedName string
352327 if srcObj .IsDir () {
353328 newEncryptedName = d .cipher .EncryptDirName (newName )
354329 } else {
355330 newEncryptedName = d .cipher .EncryptFileName (newName )
356331 }
357- return op .Rename (ctx , d . remoteStorage , remoteActualPath , newEncryptedName )
332+ return op .Rename (ctx , remoteStorage , remoteActualPath , newEncryptedName )
358333}
359334
360335func (d * Crypt ) Copy (ctx context.Context , srcObj , dstDir model.Obj ) error {
361- srcRemoteActualPath , err := d .getActualPathForRemote (srcObj .GetPath (), srcObj .IsDir ())
362- if err != nil {
363- return fmt .Errorf ("failed to convert path to remote path: %w" , err )
364- }
365- dstRemoteActualPath , err := d .getActualPathForRemote (dstDir .GetPath (), dstDir .IsDir ())
366- if err != nil {
367- return fmt .Errorf ("failed to convert path to remote path: %w" , err )
368- }
369- return op .Copy (ctx , d .remoteStorage , srcRemoteActualPath , dstRemoteActualPath )
336+ _ , err := fs .Copy (ctx , srcObj .GetPath (), dstDir .GetPath ())
337+ return err
370338}
371339
372340func (d * Crypt ) Remove (ctx context.Context , obj model.Obj ) error {
373- remoteActualPath , err := d . getActualPathForRemote (obj .GetPath (), obj . IsDir ())
341+ remoteStorage , remoteActualPath , err := op . GetStorageAndActualPath (obj .GetPath ())
374342 if err != nil {
375- return fmt . Errorf ( "failed to convert path to remote path: %w" , err )
343+ return err
376344 }
377- return op .Remove (ctx , d . remoteStorage , remoteActualPath )
345+ return op .Remove (ctx , remoteStorage , remoteActualPath )
378346}
379347
380348func (d * Crypt ) Put (ctx context.Context , dstDir model.Obj , streamer model.FileStreamer , up driver.UpdateProgress ) error {
381- dstDirActualPath , err := d . getActualPathForRemote (dstDir .GetPath (), true )
349+ remoteStorage , remoteActualPath , err := op . GetStorageAndActualPath (dstDir .GetPath ())
382350 if err != nil {
383- return fmt . Errorf ( "failed to convert path to remote path: %w" , err )
351+ return err
384352 }
385353
386354 // Encrypt the data into wrappedIn
@@ -404,15 +372,15 @@ func (d *Crypt) Put(ctx context.Context, dstDir model.Obj, streamer model.FileSt
404372 ForceStreamUpload : true ,
405373 Exist : streamer .GetExist (),
406374 }
407- err = op .Put (ctx , d .remoteStorage , dstDirActualPath , streamOut , up , false )
408- if err != nil {
409- return err
410- }
411- return nil
375+ return op .Put (ctx , remoteStorage , remoteActualPath , streamOut , up )
412376}
413377
414378func (d * Crypt ) GetDetails (ctx context.Context ) (* model.StorageDetails , error ) {
415- remoteDetails , err := op .GetStorageDetails (ctx , d .remoteStorage )
379+ remoteStorage , _ , err := op .GetStorageAndActualPath (d .RemotePath )
380+ if err != nil {
381+ return nil , errs .NotImplement
382+ }
383+ remoteDetails , err := op .GetStorageDetails (ctx , remoteStorage )
416384 if err != nil {
417385 return nil , err
418386 }
@@ -421,8 +389,4 @@ func (d *Crypt) GetDetails(ctx context.Context) (*model.StorageDetails, error) {
421389 }, nil
422390}
423391
424- //func (d *Safe) Other(ctx context.Context, args model.OtherArgs) (interface{}, error) {
425- // return nil, errs.NotSupport
426- //}
427-
428392var _ driver.Driver = (* Crypt )(nil )
0 commit comments