Add RBAC support with roles, permissions, and session management. Implement middleware for authentication and CSRF protection. Enhance audit logging with additional fields. Update HTTP handlers and routes for new features.

This commit is contained in:
2025-12-13 17:44:09 +00:00
parent d69e01bbaf
commit 8100f87686
44 changed files with 3262 additions and 76 deletions

View File

@@ -0,0 +1,122 @@
package minio
import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/example/storage-appliance/internal/infra/osexec"
)
type Adapter struct {
Runner osexec.Runner
EnvPath string
}
func NewAdapter(runner osexec.Runner, envPath string) *Adapter {
if envPath == "" {
envPath = "/etc/minio/minio.env"
}
return &Adapter{Runner: runner, EnvPath: envPath}
}
type Settings struct {
AccessKey string `json:"access_key"`
SecretKey string `json:"secret_key"`
DataPath string `json:"data_path"`
Port int `json:"port"`
TLS bool `json:"tls"`
}
// WriteEnv writes environment file used by MinIO service
func (a *Adapter) WriteEnv(ctx context.Context, s Settings) error {
dir := filepath.Dir(a.EnvPath)
if err := os.MkdirAll(dir, 0755); err != nil {
return err
}
// env lines
lines := []string{
fmt.Sprintf("MINIO_ROOT_USER=%s", s.AccessKey),
fmt.Sprintf("MINIO_ROOT_PASSWORD=%s", s.SecretKey),
fmt.Sprintf("MINIO_VOLUMES=%s", s.DataPath),
}
if s.Port != 0 {
lines = append(lines, fmt.Sprintf("MINIO_OPTS=--address :%d", s.Port))
}
content := strings.Join(lines, "\n") + "\n"
tmp := filepath.Join(dir, ".minio.env.tmp")
if err := os.WriteFile(tmp, []byte(content), 0600); err != nil {
return err
}
if err := os.Rename(tmp, a.EnvPath); err != nil {
return err
}
return nil
}
// Reload reloads minio service to pick up new env; prefer systemctl reload
func (a *Adapter) Reload(ctx context.Context) error {
_, stderr, _, err := osexec.ExecWithRunner(a.Runner, ctx, "systemctl", "reload", "minio")
if err == nil {
return nil
}
// fallback to restart
_, stderr, _, err = osexec.ExecWithRunner(a.Runner, ctx, "systemctl", "restart", "minio")
if err != nil {
return fmt.Errorf("minio reload/restart failed: %s", stderr)
}
return nil
}
// ConfigureMC configures mc alias to point to the MinIO service using given settings
func (a *Adapter) ConfigureMC(ctx context.Context, alias string, settings Settings) error {
secure := "--insecure"
if settings.TLS {
secure = ""
}
// mc alias set <alias> <endpoint> <access> <secret> [--api S3v4]
endpoint := fmt.Sprintf("http://127.0.0.1:%d", settings.Port)
if settings.TLS {
endpoint = fmt.Sprintf("https://127.0.0.1:%d", settings.Port)
}
_, stderr, _, err := osexec.ExecWithRunner(a.Runner, ctx, "mc", "alias", "set", alias, endpoint, settings.AccessKey, settings.SecretKey, secure)
if err != nil {
return fmt.Errorf("mc alias set failed: %s", stderr)
}
return nil
}
// ListBuckets uses mc to list buckets via alias
func (a *Adapter) ListBuckets(ctx context.Context, alias string) ([]string, error) {
out, stderr, _, err := osexec.ExecWithRunner(a.Runner, ctx, "mc", "ls", "--json", alias)
if err != nil {
return nil, fmt.Errorf("mc ls failed: %s", stderr)
}
// parse JSON lines, each contains a 'key' or 'name' - in mc, `ls --json` returns 'key'
var buckets []string
lines := strings.Split(strings.TrimSpace(out), "\n")
for _, l := range lines {
var obj map[string]any
if err := json.Unmarshal([]byte(l), &obj); err != nil {
continue
}
if otype, ok := obj["type"].(string); ok && otype == "bucket" {
if name, ok := obj["key"].(string); ok {
buckets = append(buckets, name)
}
}
}
return buckets, nil
}
// CreateBucket uses mc to create a new bucket alias/<name>
func (a *Adapter) CreateBucket(ctx context.Context, alias, name string) error {
_, stderr, _, err := osexec.ExecWithRunner(a.Runner, ctx, "mc", "mb", alias+"/"+name)
if err != nil {
return fmt.Errorf("mc mb failed: %s", stderr)
}
return nil
}