small fixes

This commit is contained in:
2025-06-18 09:01:14 +03:00
parent 42f2b68848
commit 5e609017f0
15 changed files with 55 additions and 108 deletions

View File

@@ -8,12 +8,12 @@ import (
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/hex" // Для преобразования хеша в строку
"encoding/hex"
"encoding/json"
"encoding/pem"
"errors"
"fmt"
"image/png" // Для валидации PNG
"image/png"
"io"
"mime/multipart"
"os"
@@ -45,7 +45,6 @@ func NewProfileService(repo *database.UserRepository, keyPath, domain string) (*
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
// Попробуем PKCS#8, если PKCS#1 не удался
key, errPkcs8 := x509.ParsePKCS8PrivateKey(block.Bytes)
if errPkcs8 != nil {
return nil, fmt.Errorf("failed to parse private key: %v / %v", err, errPkcs8)
@@ -71,7 +70,6 @@ func (s *ProfileService) GetSignedProfile(ctx context.Context, playerUUID uuid.U
return nil, err
}
// 1. Формируем структуру со свойствами текстур
textures := models.Textures{}
if profile.SkinHash != "" {
textures.SKIN = &models.TextureInfo{URL: fmt.Sprintf("http://%s/files/textures/%s", s.domain, profile.SkinHash)}
@@ -88,14 +86,12 @@ func (s *ProfileService) GetSignedProfile(ctx context.Context, playerUUID uuid.U
Textures: textures,
}
// 2. Маршализация в JSON и кодирование в Base64
valueJSON, err := json.Marshal(propValue)
if err != nil {
return nil, err
}
valueBase64 := base64.StdEncoding.EncodeToString(valueJSON)
// 3. Подпись
hasher := sha1.New()
hasher.Write([]byte(valueBase64))
hashed := hasher.Sum(nil)
@@ -106,7 +102,6 @@ func (s *ProfileService) GetSignedProfile(ctx context.Context, playerUUID uuid.U
}
signatureBase64 := base64.StdEncoding.EncodeToString(signature)
// 4. Формирование итогового ответа
response := &models.SessionProfileResponse{
ID: profileID,
Name: user.Username,
@@ -124,15 +119,12 @@ func (s *ProfileService) GetSignedProfile(ctx context.Context, playerUUID uuid.U
// UpdateUserSkin обрабатывает загрузку, валидацию и сохранение файла скина.
func (s *ProfileService) UpdateUserSkin(ctx context.Context, userID int, file multipart.File, header *multipart.FileHeader) error {
// 1. Читаем файл в память
fileBytes, err := io.ReadAll(file)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}
// Возвращаем указатель файла в начало, чтобы его можно было прочитать снова
file.Seek(0, 0)
// 2. Валидация PNG 64x64
config, err := png.DecodeConfig(file)
if err != nil {
return errors.New("invalid PNG file")
@@ -141,20 +133,16 @@ func (s *ProfileService) UpdateUserSkin(ctx context.Context, userID int, file mu
return errors.New("skin must be 64x64 pixels")
}
// 3. Вычисляем SHA1 хеш
hasher := sha1.New()
hasher.Write(fileBytes)
hash := hex.EncodeToString(hasher.Sum(nil))
// 4. Сохраняем файл на диск
// Путь к хранилищу текстур должен быть конфигурируемым
storagePath := os.Getenv("TEXTURES_STORAGE_PATH")
if storagePath == "" {
return errors.New("textures storage path not configured")
}
filePath := fmt.Sprintf("%s/%s", storagePath, hash)
// Создаем файл только если его еще нет
if _, err := os.Stat(filePath); os.IsNotExist(err) {
outFile, err := os.Create(filePath)
if err != nil {
@@ -168,6 +156,5 @@ func (s *ProfileService) UpdateUserSkin(ctx context.Context, userID int, file mu
}
}
// 5. Сохраняем хеш в БД
return s.UserRepo.UpdateSkinHash(ctx, userID, hash)
}