154 lines
3.3 KiB
Go
154 lines
3.3 KiB
Go
package queries
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"fiskerinc.com/modules/common"
|
|
"fiskerinc.com/modules/security"
|
|
"fiskerinc.com/modules/validator"
|
|
|
|
"github.com/go-pg/pg/v10"
|
|
"github.com/go-pg/pg/v10/orm"
|
|
"github.com/pkg/errors"
|
|
berrors "errors"
|
|
)
|
|
|
|
type FileKeysInterface interface {
|
|
Delete(fileID string) (orm.Result, error)
|
|
Insert(filekey common.FileKey) (orm.Result, error)
|
|
Get(fileID string) (*common.FileKey, error)
|
|
GetMulti(fileIDs []string) ([]common.FileKey, error)
|
|
}
|
|
|
|
type FileKeys struct {
|
|
QueryBase
|
|
encryptor security.IEncryptor
|
|
once sync.Once
|
|
}
|
|
|
|
func (fk *FileKeys) getEncryptor() (security.IEncryptor, error) {
|
|
var err error
|
|
fk.once.Do(func() {
|
|
encrypt := security.Encrypt{}
|
|
fk.encryptor, err = encrypt.GetEncryptor()
|
|
})
|
|
|
|
return fk.encryptor, err
|
|
}
|
|
|
|
// Delete deletes fileID of FileKey from database
|
|
func (fk *FileKeys) Delete(fileID string) (orm.Result, error) {
|
|
if fileID == "" {
|
|
return nil, errors.WithStack(&validator.FieldError{
|
|
ErrorMsg: "FileID required",
|
|
})
|
|
}
|
|
|
|
conn := fk.GetDBConn()
|
|
return fk.resultWithStack(conn.Model(&common.FileKey{
|
|
FileID: fileID,
|
|
}).WherePK().Delete())
|
|
}
|
|
|
|
// Insert makes a copy of FileKey, encrypts encryption parameters, and inserts into database
|
|
func (fk *FileKeys) Insert(filekey common.FileKey) (orm.Result, error) {
|
|
err := validator.ValidateStruct(filekey)
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
err = fk.encrypt(&filekey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return fk.resultWithStack(fk.GetDBConn().Model(&filekey).Insert())
|
|
}
|
|
|
|
func (fk *FileKeys) Get(fileID string) (*common.FileKey, error) {
|
|
if fileID == "" {
|
|
return nil, errors.WithStack(&validator.FieldError{
|
|
ErrorMsg: "FileID required",
|
|
})
|
|
}
|
|
|
|
filekey := []common.FileKey{}
|
|
err := fk.GetDBConn().Model(&filekey).Where("file_id = ?", fileID).Select()
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
if len(filekey) == 0 {
|
|
return &common.FileKey{}, nil
|
|
}
|
|
|
|
err = fk.decrypt(&filekey[0])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &filekey[0], nil
|
|
}
|
|
|
|
func (fk *FileKeys) GetMulti(fileIDs []string) ([]common.FileKey, error) {
|
|
filekeys := []common.FileKey{}
|
|
if len(fileIDs) == 0 {
|
|
return filekeys, nil
|
|
}
|
|
err := fk.GetDBConn().Model(&filekeys).Where("file_id in (?)", pg.In(fileIDs)).Select()
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
var masterError error
|
|
for i := range filekeys {
|
|
err = fk.decrypt(&filekeys[i])
|
|
if err != nil {
|
|
masterError = berrors.Join(masterError, err)
|
|
filekeys[i].Error = err.Error()
|
|
}
|
|
}
|
|
|
|
return filekeys, masterError
|
|
}
|
|
|
|
func (fk *FileKeys) encrypt(filekey *common.FileKey) error {
|
|
encryptor, err := fk.getEncryptor()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filekey.Key = encryptor.EncryptChunk([]byte(filekey.Key))
|
|
filekey.Auth = encryptor.EncryptChunk([]byte(filekey.Auth))
|
|
filekey.Nonce = encryptor.EncryptChunk([]byte(filekey.Nonce))
|
|
|
|
return nil
|
|
}
|
|
|
|
func (fk *FileKeys) decrypt(filekey *common.FileKey) error {
|
|
|
|
encryptor, err := fk.getEncryptor()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
value, err := encryptor.DecryptChunk([]byte(filekey.Key))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filekey.Key = value
|
|
value, err = encryptor.DecryptChunk([]byte(filekey.Auth))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filekey.Auth = value
|
|
value, err = encryptor.DecryptChunk([]byte(filekey.Nonce))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
filekey.Nonce = value
|
|
return nil
|
|
}
|