93 lines
2.7 KiB
Go
93 lines
2.7 KiB
Go
package files
|
|
|
|
import (
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"regexp"
|
|
|
|
"github.com/didiercrunch/filou/contract"
|
|
)
|
|
|
|
type encryptor func(reader io.Reader, writer io.Writer, acceptedContract *contract.AcceptedContract) error
|
|
|
|
type PathEncryptor struct {
|
|
EncryptFile encryptor
|
|
EncryptDirectory encryptor
|
|
}
|
|
|
|
func (this *PathEncryptor) fileExists(path string) bool {
|
|
_, err := os.Stat(path)
|
|
return !os.IsNotExist(err)
|
|
}
|
|
|
|
func (this *PathEncryptor) getDefaultPathToEncryptFile(originalFileName string) string {
|
|
isFileWithSingleExtension := regexp.MustCompile(`\.\w+$`)
|
|
isFileWithDoubleExtension := regexp.MustCompile(`\.\w+\.\w+$`)
|
|
isHiddenDirectory := regexp.MustCompile(`\/.\w+$`)
|
|
isHiddenFile := regexp.MustCompile(`\/\.\w+\.\w+$`)
|
|
|
|
if isHiddenFile.MatchString(originalFileName) {
|
|
return isFileWithSingleExtension.ReplaceAllString(originalFileName, ".filou")
|
|
}
|
|
if isHiddenDirectory.MatchString(originalFileName) {
|
|
return originalFileName + ".filou"
|
|
}
|
|
if isFileWithDoubleExtension.MatchString(originalFileName) {
|
|
return isFileWithDoubleExtension.ReplaceAllString(originalFileName, ".filou")
|
|
}
|
|
if isFileWithSingleExtension.MatchString(originalFileName) {
|
|
return isFileWithSingleExtension.ReplaceAllString(originalFileName, ".filou")
|
|
}
|
|
return originalFileName + ".filou"
|
|
}
|
|
|
|
// create a file with permission set to 600
|
|
func (this *PathEncryptor) createPrivateFile(name string) (*os.File, error) {
|
|
return os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
|
|
}
|
|
|
|
func (this *PathEncryptor) EncryptPathToDefaultFile(path string, acceptedContract *contract.AcceptedContract) error {
|
|
outputPathName := this.getDefaultPathToEncryptFile(path)
|
|
if _, err := os.Stat(outputPathName); !os.IsNotExist(err) {
|
|
return errors.New("the default path to encrypt already exists.")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *PathEncryptor) EncryptPathToOtherPath(fromPath, toPath string, acceptedContract *contract.AcceptedContract) error {
|
|
if this.fileExists(toPath) {
|
|
return errors.New("output file already exists")
|
|
}
|
|
if f, err := this.createPrivateFile(toPath); err != nil {
|
|
return err
|
|
} else {
|
|
defer f.Close()
|
|
return this.EncryptPathToWriter(fromPath, f, acceptedContract)
|
|
}
|
|
}
|
|
|
|
func (this *PathEncryptor) EncryptPathToWriter(path string, writer io.Writer, acceptedContract *contract.AcceptedContract) error {
|
|
if !this.fileExists(path) {
|
|
return errors.New("input file does not exists")
|
|
}
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
if err := f.Close(); err != nil {
|
|
panic(err)
|
|
}
|
|
}()
|
|
|
|
if fd, err := f.Stat(); err != nil {
|
|
return err
|
|
} else if fd.IsDir() {
|
|
return this.EncryptDirectory(f, writer, acceptedContract)
|
|
} else {
|
|
return this.EncryptFile(f, writer, acceptedContract)
|
|
}
|
|
}
|