Skip to content

Commit

Permalink
Merge pull request #12 from egorgasay/auth
Browse files Browse the repository at this point in the history
🐛 fixes
  • Loading branch information
egorgasay authored May 22, 2024
2 parents cca192a + 318b916 commit c505333
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 70 deletions.
4 changes: 3 additions & 1 deletion config/config-servers.toml
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Servers = ["127.0.0.1:8889"]
Servers = [
# "127.0.0.1:8889"
]
6 changes: 0 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ type BalancerConfig struct {

type SecurityConfig struct {
MandatoryAuthorization bool `toml:"MandatoryAuthorization"`
MandatoryEncryption bool `toml:"MandatoryEncryption"`
}

type LoggingConfig struct {
Expand All @@ -58,11 +57,6 @@ type LoggingConfig struct {
var _configFlag = flag.String("config", "", "Specify the path to the config file")
var _configServersFlag = flag.String("config-servers", "", "Specify the path to the config file")

var _noSecurity = SecurityConfig{
MandatoryAuthorization: false,
MandatoryEncryption: false,
}

const _defaultPathToConfig = "config/config.toml"
const _defaultPathToServers = "config/config-servers.toml"

Expand Down
14 changes: 6 additions & 8 deletions config/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ BackupDirectory = "transaction-logger"
# Buffer size.
BufferSize = "1s"

# Encryption parameters.
# Параметры шифрования.
[Encryption]
# Key that is used to encrypt data.
# Example: "jdvbe3j1hve11jhv2js1vdvuvs1yud"
Key = "CHANGE ME"
# Key used for data encryption.
# Must be an AES key, 16, 24, or 32 bytes long to select AES-128, AES-192, or AES-256.
# Example: "PLEASE CHANGE ME" = 16 bytes -> AES-128.
# DO NOT CHANGE THE NUMBER OF BYTES AFTER THE FIRST PRODUCTION RUN.
Key = "PLEASE CHANGE ME"

# Web application settings.
[WebApp]
Expand All @@ -52,9 +54,5 @@ On = true
# If false, authentication is not required for keys and objects that has Default level.
MandatoryAuthorization = true

# Mandatory encryption.
# If false, encryption is not mandatory for keys and objects that has Secret level.
MandatoryEncryption = true

[Logging]
Level = "debug"
8 changes: 8 additions & 0 deletions doc/src/other.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ SERVERS
<- no available servers
```

### ADD SERVER - Add server to the list of active servers.

Example:
```go
ADD SERVER 127.0.0.1:8080
<- OK
```

### EXIT - Exit from the acount.
```go
EXIT
Expand Down
1 change: 1 addition & 0 deletions internal/domains/transaction-logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Restorer interface {
CreateObject(name string, opts models.ObjectOptions) gost.ResultN
AttachToObject(dst, src string) gost.ResultN
NewUser(user models.User) (r gost.ResultN)
DeleteUser(login string) (r gost.Result[bool])
AddObjectInfo(name string, info models.ObjectInfo)
DeleteObjectInfo(name string)
DeleteAttr(object, key string) gost.ResultN
Expand Down
121 changes: 67 additions & 54 deletions internal/service/security/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ import (
)

type SecurityService struct {
cfg config.SecurityConfig
cfg config.SecurityConfig
encryptionConfig config.EncryptionConfig
}

func NewSecurityService(cfg config.SecurityConfig, encryptionConfig config.EncryptionConfig) *SecurityService {
return &SecurityService{
cfg: cfg,
cfg: cfg,
encryptionConfig: encryptionConfig,
}
}
Expand All @@ -46,60 +46,73 @@ func (l *SecurityService) HasPermission(claimsOpt gost.Option[models.UserClaims]
}

func (l *SecurityService) Encrypt(val string) (string, error) {
// Преобразуем ключ из конфигурации шифрования в байты
key := []byte(l.encryptionConfig.Key)
// Создаем шифр на основе ключа
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}

// Преобразуем строку для шифрования в байты
plaintext := []byte(val)
// Создаем массив для шифротекста с дополнительным местом для IV
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
// Используем первый блок массива в качестве IV
iv := ciphertext[:aes.BlockSize]
// Заполняем IV случайными данными
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}

// Создаем потоковый шифр для шифрования
stream := cipher.NewCFBEncrypter(block, iv)
// Применяем XOR между ключом и текстом, начиная с позиции после IV
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

// Возвращаем зашифрованное значение
return val, nil
// Преобразуем ключ из конфигурации шифрования в байты
key := []byte(l.encryptionConfig.Key)
// Создаем шифр на основе ключа
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}

// Преобразуем строку для шифрования в байты
plaintext := []byte(val)
// Создаем массив для шифротекста с дополнительным местом для IV
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
// Используем первый блок массива в качестве IV
iv := ciphertext[:aes.BlockSize]
// Заполняем IV случайными данными
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return "", err
}

// Создаем потоковый шифр для шифрования
stream := cipher.NewCFBEncrypter(block, iv)
// Применяем XOR между ключом и текстом, начиная с позиции после IV
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)

// Возвращаем зашифрованное значение
return string(ciphertext), nil
}

func (l *SecurityService) Decrypt(val string) (string, error) {
// Преобразуем ключ из конфигурации шифрования в байты
key := []byte(l.encryptionConfig.Key)

// Создаем шифр на основе ключа
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}

// Проверяем, достаточно ли длинный шифротекст
if len(val) < aes.BlockSize {
return "", errors.New("ciphertext too short")
}

// Используем первый блок шифротекста в качестве IV
iv := val[:aes.BlockSize]
val = val[aes.BlockSize:]

// Создаем потоковый шифр для дешифрования
stream := cipher.NewCFBDecrypter(block, []byte(iv))
// Применяем XOR между ключом и текстом
stream.XORKeyStream([]byte(val), []byte(val))

// Возвращаем дешифрованное значение
return string(val), nil
}
// Преобразуем ключ из конфигурации шифрования в байты
key := []byte(l.encryptionConfig.Key)

// Создаем шифр на основе ключа
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}

// Проверяем, достаточно ли длинный шифротекст
if len(val) < aes.BlockSize {
return "", errors.New("ciphertext too short")
}

// Используем первый блок шифротекста в качестве IV
iv := []byte(val[:aes.BlockSize])
ciphertext := []byte(val[aes.BlockSize:])

// Создаем потоковый шифр для дешифрования
stream := cipher.NewCFBDecrypter(block, iv)
// Применяем XOR между ключом и текстом
stream.XORKeyStream(ciphertext, ciphertext)

// Возвращаем дешифрованное значение
return string(ciphertext), nil
}

// func pad(src []byte, blockSize int) []byte {
// padding := blockSize - len(src)%blockSize
// padtext := bytes.Repeat([]byte{byte(padding)}, padding)
// return append(src, padtext...)
// }

// func unpad(src []byte) ([]byte, error) {
// length := len(src)
// unpadding := int(src[length-1])
// if unpadding > length {
// return nil, errors.New("unpad error. This can happen when incorrect encryption key is used")
// }
// return src[:(length - unpadding)], nil
// }
4 changes: 3 additions & 1 deletion internal/service/servers/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ func (s *Servers) AddServer(ctx context.Context, address string, force bool) (in
s.logger.Error("can't add server", zap.Int32("server", server), zap.Error(err))
if !force {
return 0, err
}
}

stClient.tries.Add(constants.MaxServerTries)
}

var addresses = make([]string, 0, len(s.servers))
Expand Down
5 changes: 5 additions & 0 deletions internal/service/transaction-logger/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ func (t *TransactionLogger) handleEvents(r domains.Restorer, events <-chan Event
if rUser.IsErr() {
return fmt.Errorf("can't create user %s, v: %s: %w", e.Name, e.Value, rUser.Error())
}
case DeleteUser:
rDelUser := r.DeleteUser(e.Name)
if rDelUser.IsErr() {
return fmt.Errorf("can't delete user %s: %w", e.Name, rDelUser.Error())
}
case CreateObject:
split := strings.Split(e.Value, constants.MetadataSeparator)
if len(split) < 2 {
Expand Down

0 comments on commit c505333

Please sign in to comment.