diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..342d941 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,21 @@ +kind: pipeline +name: deploy + +steps: + - name: deploy + image: appleboy/drone-ssh + settings: + host: 89.104.69.222 + username: root + password: + from_secret: ssh_password + script: + - rm -fr /home/tailly_messages + - mkdir /home/tailly_messages + - cd /home/tailly_messages + - git clone https://admin:103e837d56b8d0bb029e9b5e03a20f568611c610@git.altomta.ru/admin/tailly_messages . || true + - git pull + - docker stop tailly_messages || true + - docker rm tailly_messages || true + - DOCKER_BUILDKIT=1 docker build -t tailly_messages . + - docker run -d --name tailly_messages --network tailly_net -p 50051:50051 -p 9092:9092 tailly_messages diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..022e7ab --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# ===== Билдер ===== +FROM golang:1.25rc2-alpine AS builder + +# Устанавливаем зависимости для сборки +RUN apk add --no-cache git make gcc musl-dev + +# Рабочая директория +WORKDIR /build + +# Копируем файлы модулей +COPY go.mod go.sum ./ + +# Скачиваем зависимости +RUN go mod download + +# Копируем весь проект +COPY . . + +# Собираем бинарник (статически линкованный) +RUN CGO_ENABLED=0 GOOS=linux go build \ + -ldflags="-w -s -extldflags '-static'" \ + -o /app/server \ + ./server.go + +# ===== Финальный образ ===== +FROM alpine:3.19 + +# Устанавливаем tzdata для работы с временными зонами +RUN apk add --no-cache tzdata ca-certificates && \ + update-ca-certificates + +# Копируем бинарник +COPY --from=builder /app/server /usr/local/bin/server + +# Копируем .env если нужен +# COPY --from=builder /build/.env /app/.env + +# Настройки среды +ENV GIN_MODE=release \ + PORT=50051 + +# Открываем порт +EXPOSE $PORT + +# Запускаем сервер +CMD ["/usr/local/bin/server"] \ No newline at end of file diff --git a/server.go b/server.go index 8df770d..5107a1a 100644 --- a/server.go +++ b/server.go @@ -96,10 +96,25 @@ func (s *server) CreateChat(ctx context.Context, req *proto.CreateChatRequest) ( } func (s *server) SendMessage(ctx context.Context, req *proto.SendMessageRequest) (*proto.MessageResponse, error) { + + // Проверяем, что отправитель является участником чата + var isParticipant bool + err := s.db.QueryRow(ctx, ` + SELECT EXISTS( + SELECT 1 FROM chats + WHERE id = $1 AND (user1_id = $2 OR user2_id = $2) + )`, req.ChatId, req.SenderId).Scan(&isParticipant) + if err != nil { + return nil, fmt.Errorf("failed to check chat participation: %v", err) + } + if !isParticipant { + return nil, fmt.Errorf("user %d is not a participant of chat %d", req.SenderId, req.ChatId) + } + var message proto.Message var createdAt time.Time - err := s.db.QueryRow(ctx, ` + err = s.db.QueryRow(ctx, ` INSERT INTO messages (chat_id, sender_id, content) VALUES ($1, $2, $3) RETURNING id, chat_id, sender_id, content, status, created_at