mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-08-17 16:47:51 +00:00
feat: add functionality to create and reveal secret access keys for users
Signed-off-by: Noste <83548733+Noooste@users.noreply.github.com>
This commit is contained in:
@@ -111,25 +111,12 @@ func (h *BucketHandler) CreateBucket(c fiber.Ctx) error {
|
||||
)
|
||||
}
|
||||
|
||||
// Check if bucket already exists
|
||||
bucketInfo, err := h.adminService.GetBucketInfoByAlias(ctx, req.Name)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(
|
||||
models.ErrorResponse(models.ErrCodeInternalError, "Failed to check bucket existence: "+err.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
if bucketInfo != nil {
|
||||
return c.Status(fiber.StatusConflict).JSON(
|
||||
models.ErrorResponse(models.ErrCodeBucketExists, "Bucket already exists"),
|
||||
)
|
||||
}
|
||||
|
||||
// Create the bucket
|
||||
createBucketReq := models.CreateBucketAdminRequest{
|
||||
GlobalAlias: &req.Name,
|
||||
}
|
||||
if bucketInfo, err = h.adminService.CreateBucket(ctx, createBucketReq); err != nil {
|
||||
|
||||
if _, err := h.adminService.CreateBucket(ctx, createBucketReq); err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(
|
||||
models.ErrorResponse(models.ErrCodeInternalError, "Failed to create bucket: "+err.Error()),
|
||||
)
|
||||
|
||||
@@ -251,6 +251,41 @@ func (h *UserHandler) GetUser(c fiber.Ctx) error {
|
||||
return c.JSON(models.SuccessResponse(userInfo))
|
||||
}
|
||||
|
||||
// GetUserSecretKey retrieves the secret key for a specific user/access key
|
||||
//
|
||||
// @Summary Get user secret key
|
||||
// @Description Retrieves the secret access key for a specific user/access key
|
||||
// @Tags Users
|
||||
// @Produce json
|
||||
// @Param access_key path string true "Access key of the user to retrieve secret for"
|
||||
// @Success 200 {object} models.APIResponse{data=map[string]string} "Secret key retrieved successfully"
|
||||
// @Failure 400 {object} models.APIResponse{error=models.APIError} "Access key is required"
|
||||
// @Failure 500 {object} models.APIResponse{error=models.APIError} "Failed to get secret key"
|
||||
// @Router /api/v1/users/{access_key}/secret [get]
|
||||
func (h *UserHandler) GetUserSecretKey(c fiber.Ctx) error {
|
||||
ctx := c.Context()
|
||||
accessKey := c.Params("access_key")
|
||||
|
||||
if accessKey == "" {
|
||||
return c.Status(fiber.StatusBadRequest).JSON(
|
||||
models.ErrorResponse(models.ErrCodeBadRequest, "Access key is required"),
|
||||
)
|
||||
}
|
||||
|
||||
// Get key information WITH secret key
|
||||
keyInfo, err := h.adminService.GetKeyInfo(ctx, accessKey, true)
|
||||
if err != nil {
|
||||
return c.Status(fiber.StatusInternalServerError).JSON(
|
||||
models.ErrorResponse(models.ErrCodeInternalError, "Failed to get secret key: "+err.Error()),
|
||||
)
|
||||
}
|
||||
|
||||
// Return only the secret key
|
||||
return c.JSON(models.SuccessResponse(map[string]string{
|
||||
"secretKey": *keyInfo.SecretAccessKey,
|
||||
}))
|
||||
}
|
||||
|
||||
// UpdateUserPermissions updates user permissions
|
||||
//
|
||||
// @Summary Update user permissions
|
||||
|
||||
@@ -194,7 +194,7 @@ type ClusterHealth struct {
|
||||
KnownNodes int `json:"knownNodes"`
|
||||
ConnectedNodes int `json:"connectedNodes"`
|
||||
StorageNodes int `json:"storageNodes"`
|
||||
StorageNodesUp int `json:"storageNodesUp"`
|
||||
StorageNodesUp int `json:"storageNodesOk"`
|
||||
Partitions int `json:"partitions"`
|
||||
PartitionsQuorum int `json:"partitionsQuorum"`
|
||||
PartitionsAllOk int `json:"partitionsAllOk"`
|
||||
|
||||
@@ -74,6 +74,7 @@ func SetupRoutes(
|
||||
users.Get("/", userHandler.ListUsers) // List all users/keys
|
||||
users.Post("/", userHandler.CreateUser) // Create new user/key
|
||||
users.Get("/:access_key", userHandler.GetUser) // Get user info
|
||||
users.Get("/:access_key/secret", userHandler.GetUserSecretKey) // Get user secret key
|
||||
users.Delete("/:access_key", userHandler.DeleteUser) // Delete user/key
|
||||
users.Patch("/:access_key", userHandler.UpdateUserPermissions) // Update user permissions
|
||||
}
|
||||
@@ -217,10 +218,10 @@ func SetupRoutes(
|
||||
}
|
||||
}
|
||||
|
||||
cfg.Server.FrontendPath = "./frontend/dist"
|
||||
|
||||
// Check if frontend path exists
|
||||
if _, err := os.Stat(cfg.Server.FrontendPath); err == nil {
|
||||
fmt.Println("Serving frontend from:", cfg.Server.FrontendPath)
|
||||
|
||||
// SPA fallback - serve index.html for all non-API routes
|
||||
app.Use(func(c fiber.Ctx) error {
|
||||
path := c.Path()
|
||||
|
||||
@@ -210,7 +210,7 @@ func (s *GarageAdminService) GetBucketInfoByAlias(ctx context.Context, globalAli
|
||||
}
|
||||
|
||||
var result models.GarageBucketInfo
|
||||
if err := decodeResponse(resp, &result); err != nil {
|
||||
if err = decodeResponse(resp, &result); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode response: %w", err)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user