From 745e0e7d882a00f45d10e3d7080355ff6d2e83fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D1=80=D0=B8=D0=B3=D0=BE=D1=80=D0=B8=D0=B9=20=D0=A1?= =?UTF-8?q?=D0=B0=D1=84=D1=80=D0=BE=D0=BD=D0=BE=D0=B2?= Date: Sun, 17 May 2026 14:30:19 +0000 Subject: [PATCH] Delete internal/api/webui_credentials.go --- internal/api/webui_credentials.go | 272 ------------------------------ 1 file changed, 272 deletions(-) delete mode 100644 internal/api/webui_credentials.go diff --git a/internal/api/webui_credentials.go b/internal/api/webui_credentials.go deleted file mode 100644 index 8b2685d..0000000 --- a/internal/api/webui_credentials.go +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2026 Safronov Grigorii - * - * Licensed under the CDDL, Version 1.0 (the "License"); - * you may not use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * https://opensource.org/licenses/CDDL-1.0 - */ - -// Файл: internal/api/webui_credentials.go -// Назначение: Управление учётными данными для веб-интерфейса -// Хранит логин/пароль в скрытом файле .credentials в директории futriis - -package api - -import ( - "crypto/sha256" - "encoding/base64" - "encoding/json" - "fmt" - "os" - "path/filepath" - "sync" -) - -// CredentialManager управляет учётными данными веб-интерфейса -type CredentialManager struct { - mu sync.RWMutex - credentials *Credentials - credFile string - currentUser string -} - -// Credentials структура для хранения учётных данных -type Credentials struct { - Username string `json:"username"` - Password string `json:"password"` // хранится в виде хеша - Avatar map[string]string `json:"avatar,omitempty"` // username -> base64 avatar -} - -// NewCredentialManager создаёт новый менеджер учётных данных -func NewCredentialManager() *CredentialManager { - // Определяем путь к директории futriis - execPath, err := os.Executable() - if err != nil { - execPath = "." - } - futriisDir := filepath.Dir(execPath) - - // Ищем директорию futriis (поднимаемся вверх, если нужно) - for { - if _, err := os.Stat(filepath.Join(futriisDir, "futriis")); err == nil { - futriisDir = filepath.Join(futriisDir, "futriis") - break - } - parent := filepath.Dir(futriisDir) - if parent == futriisDir { - // Не нашли директорию futriis, создаём в текущей - futriisDir = filepath.Join(execPath, "futriis") - os.MkdirAll(futriisDir, 0700) - break - } - futriisDir = parent - } - - credFile := filepath.Join(futriisDir, ".credentials") - - return &CredentialManager{ - credentials: &Credentials{ - Username: "admin", - Password: "", - Avatar: make(map[string]string), - }, - credFile: credFile, - } -} - -// hashPassword создаёт хеш пароля -func (cm *CredentialManager) hashPassword(password string) string { - hash := sha256.Sum256([]byte(password)) - return base64.StdEncoding.EncodeToString(hash[:]) -} - -// Load загружает учётные данные из файла -func (cm *CredentialManager) Load() error { - cm.mu.Lock() - defer cm.mu.Unlock() - - data, err := os.ReadFile(cm.credFile) - if err != nil { - if os.IsNotExist(err) { - return cm.createDefaultFile() - } - return err - } - - var creds Credentials - if err := json.Unmarshal(data, &creds); err != nil { - return err - } - - cm.credentials = &creds - if cm.credentials.Avatar == nil { - cm.credentials.Avatar = make(map[string]string) - } - - return nil -} - -// createDefaultFile создаёт файл с учётными данными по умолчанию -func (cm *CredentialManager) createDefaultFile() error { - cm.credentials.Username = "admin" - cm.credentials.Password = cm.hashPassword("admin") - cm.credentials.Avatar = make(map[string]string) - - return cm.save() -} - -// CreateDefault создаёт учётные данные по умолчанию (если файл не существует) -func (cm *CredentialManager) CreateDefault() error { - cm.mu.Lock() - defer cm.mu.Unlock() - - // Проверяем, существует ли файл - if _, err := os.Stat(cm.credFile); err == nil { - return nil // файл уже существует - } - - cm.credentials.Username = "admin" - cm.credentials.Password = cm.hashPassword("admin") - cm.credentials.Avatar = make(map[string]string) - - return cm.save() -} - -// save сохраняет учётные данные в файл -func (cm *CredentialManager) save() error { - data, err := json.MarshalIndent(cm.credentials, "", " ") - if err != nil { - return err - } - - // Устанавливаем права доступа 0600 (только владелец может читать/писать) - return os.WriteFile(cm.credFile, data, 0600) -} - -// Validate проверяет учётные данные -func (cm *CredentialManager) Validate(username, password string) bool { - cm.mu.RLock() - defer cm.mu.RUnlock() - - if cm.credentials == nil { - return false - } - - if cm.credentials.Username != username { - return false - } - - return cm.credentials.Password == cm.hashPassword(password) -} - -// ChangePassword изменяет пароль пользователя -func (cm *CredentialManager) ChangePassword(username, currentPassword, newPassword string) error { - cm.mu.Lock() - defer cm.mu.Unlock() - - if cm.credentials == nil { - return fmt.Errorf("credentials not loaded") - } - - if cm.credentials.Username != username { - return fmt.Errorf("user not found") - } - - if cm.credentials.Password != cm.hashPassword(currentPassword) { - return fmt.Errorf("current password is incorrect") - } - - if len(newPassword) < 4 { - return fmt.Errorf("new password must be at least 4 characters") - } - - cm.credentials.Password = cm.hashPassword(newPassword) - - return cm.save() -} - -// SetAvatar устанавливает аватар для пользователя -func (cm *CredentialManager) SetAvatar(username, avatarBase64 string) error { - cm.mu.Lock() - defer cm.mu.Unlock() - - if cm.credentials == nil { - return fmt.Errorf("credentials not loaded") - } - - if cm.credentials.Username != username { - return fmt.Errorf("user not found") - } - - if cm.credentials.Avatar == nil { - cm.credentials.Avatar = make(map[string]string) - } - - cm.credentials.Avatar[username] = avatarBase64 - - return cm.save() -} - -// GetAvatar возвращает аватар пользователя -func (cm *CredentialManager) GetAvatar(username string) (string, error) { - cm.mu.RLock() - defer cm.mu.RUnlock() - - if cm.credentials == nil { - return "", fmt.Errorf("credentials not loaded") - } - - if cm.credentials.Username != username { - return "", fmt.Errorf("user not found") - } - - if cm.credentials.Avatar == nil { - return "", nil - } - - avatar, ok := cm.credentials.Avatar[username] - if !ok { - return "", nil - } - - return avatar, nil -} - -// DeleteAvatar удаляет аватар пользователя -func (cm *CredentialManager) DeleteAvatar(username string) error { - cm.mu.Lock() - defer cm.mu.Unlock() - - if cm.credentials == nil { - return fmt.Errorf("credentials not loaded") - } - - if cm.credentials.Username != username { - return fmt.Errorf("user not found") - } - - if cm.credentials.Avatar != nil { - delete(cm.credentials.Avatar, username) - } - - return cm.save() -} - -// GetCurrentUsername возвращает имя текущего пользователя -func (cm *CredentialManager) GetCurrentUsername() string { - cm.mu.RLock() - defer cm.mu.RUnlock() - - if cm.credentials == nil { - return "" - } - - return cm.credentials.Username -} - -// GetCredentialsFile возвращает путь к файлу с учётными данными -func (cm *CredentialManager) GetCredentialsFile() string { - return cm.credFile -}