/
t3
/
gateway-server
Обзор
Документация
Войти
/
t3
/
gateway-server
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
internal/api/buckets_handler.go
110 строк
4 KB
Ivan
end-to-end logging
25 июл 2026, 00:10
25 июл 2026, 00:10
663e207
Код
Авторство
О чём код?
package api import ( "encoding/json" "log/slog" "net/http" "gitverse.ru/t3/gateway-server/internal/auth" "gitverse.ru/t3/gateway-server/internal/client" ) type BucketsHandler struct { s3Client *client.S3Client iamClient *client.IAMClient logger *slog.Logger } func NewBucketsHandler(s3Client *client.S3Client, iamClient *client.IAMClient, logger *slog.Logger) *BucketsHandler { return &BucketsHandler{s3Client: s3Client, iamClient: iamClient, logger: logger} } func (h *BucketsHandler) ListBuckets(w http.ResponseWriter, r *http.Request) { claims := auth.ClaimsFromContext(r.Context()) if claims == nil { writeError(w, http.StatusUnauthorized, "unauthorized", "no session") return } // Fetch all buckets from S3. allBuckets, err := h.s3Client.ListBuckets(r.Context(), claims.AccessKey, claims.AccessSecret) if err != nil { h.logger.Error("list buckets failed", "error", err) writeError(w, http.StatusBadGateway, "bad_gateway", "S3 service error") return } // Filter: show own buckets + those with IAM permission. var result []BucketResponse for _, b := range allBuckets { resource := "arn:t3:s3:::" + b.Name if b.Owner == claims.UserID { result = append(result, BucketResponse{Name: b.Name, Owner: b.Owner, CreationDate: b.CreationDate}) continue } // Check IAM for s3:ListBucket on this bucket. check, err := h.iamClient.AuthCheck(r.Context(), claims.AccessKey, claims.AccessSecret, "s3:ListBucket", resource) if err == nil && check.Allowed { result = append(result, BucketResponse{Name: b.Name, Owner: b.Owner, CreationDate: b.CreationDate}) } } writeJSON(w, http.StatusOK, result) } func (h *BucketsHandler) CreateBucket(w http.ResponseWriter, r *http.Request) { claims := auth.ClaimsFromContext(r.Context()) if claims == nil { writeError(w, http.StatusUnauthorized, "unauthorized", "no session") return } var req CreateBucketRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { writeError(w, http.StatusBadRequest, "bad_request", "invalid JSON body") return } if req.Name == "" { writeError(w, http.StatusBadRequest, "bad_request", "bucket name required") return } resource := "arn:t3:s3:::" + req.Name check, err := h.iamClient.AuthCheck(r.Context(), claims.AccessKey, claims.AccessSecret, "s3:CreateBucket", resource) if err != nil || !check.Allowed { writeError(w, http.StatusForbidden, "forbidden", "no permission to create bucket") return } if err := h.s3Client.CreateBucket(r.Context(), req.Name, claims.UserID, claims.AccessKey, claims.AccessSecret); err != nil { h.logger.Error("create bucket failed", "error", err, "bucket", req.Name) writeError(w, http.StatusBadGateway, "bad_gateway", err.Error()) return } writeJSON(w, http.StatusCreated, BucketResponse{Name: req.Name, Owner: claims.UserID, CreationDate: ""}) } func (h *BucketsHandler) DeleteBucket(w http.ResponseWriter, r *http.Request) { claims := auth.ClaimsFromContext(r.Context()) if claims == nil { writeError(w, http.StatusUnauthorized, "unauthorized", "no session") return } bucket := r.PathValue("bucket") resource := "arn:t3:s3:::" + bucket check, err := h.iamClient.AuthCheck(r.Context(), claims.AccessKey, claims.AccessSecret, "s3:DeleteBucket", resource) if err != nil || !check.Allowed { writeError(w, http.StatusForbidden, "forbidden", "no permission to delete bucket") return } if err := h.s3Client.DeleteBucket(r.Context(), bucket, claims.AccessKey, claims.AccessSecret); err != nil { h.logger.Error("delete bucket failed", "error", err, "bucket", bucket) writeError(w, http.StatusBadGateway, "bad_gateway", err.Error()) return } w.WriteHeader(http.StatusNoContent) }