Add access key status management to Admin UI (#8050)

* Add access key status management to Admin UI

- Add Status field to AccessKeyInfo struct
- Implement UpdateAccessKeyStatus API endpoint
- Add status dropdown in access keys modal
- Fix modal backdrop issue by using refreshAccessKeysList helper
- Status can be toggled between Active and Inactive

* Replace magic strings with constants for access key status

- Define AccessKeyStatusActive and AccessKeyStatusInactive constants in admin_data.go
- Define STATUS_ACTIVE and STATUS_INACTIVE constants in JavaScript
- Replace all hardcoded 'Active' and 'Inactive' strings with constants
- Update error messages to use constants for consistency

* Remove duplicate manageAccessKeys function definition

* Add security improvements to access key status management

- Add status validation in UpdateAccessKeyStatus to prevent invalid values
- Fix XSS vulnerability by replacing inline onchange with data attributes
- Add delegated event listener for status select changes
- Add URL encoding to API request path segments
This commit is contained in:
Chris Lu
2026-01-17 18:18:32 -08:00
committed by GitHub
parent dbde8983a7
commit 6bc5a64a98
6 changed files with 159 additions and 12 deletions

View File

@@ -12,6 +12,12 @@ import (
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
)
// Access key status constants
const (
AccessKeyStatusActive = "Active"
AccessKeyStatusInactive = "Inactive"
)
type AdminData struct {
Username string `json:"username"`
TotalVolumes int `json:"total_volumes"`
@@ -69,9 +75,14 @@ type UpdateUserPoliciesRequest struct {
type AccessKeyInfo struct {
AccessKey string `json:"access_key"`
SecretKey string `json:"secret_key"`
Status string `json:"status"`
CreatedAt time.Time `json:"created_at"`
}
type UpdateAccessKeyStatusRequest struct {
Status string `json:"status" binding:"required"`
}
type UserDetails struct {
Username string `json:"username"`
Email string `json:"email"`

View File

@@ -192,6 +192,7 @@ func (s *AdminServer) GetObjectStoreUserDetails(username string) (*UserDetails,
details.AccessKeys = append(details.AccessKeys, AccessKeyInfo{
AccessKey: cred.AccessKey,
SecretKey: cred.SecretKey,
Status: cred.Status,
CreatedAt: time.Now().AddDate(0, -1, 0), // Mock creation date
})
}
@@ -223,6 +224,7 @@ func (s *AdminServer) CreateAccessKey(username string) (*AccessKeyInfo, error) {
credential := &iam_pb.Credential{
AccessKey: accessKey,
SecretKey: secretKey,
Status: AccessKeyStatusActive,
}
// Create access key using credential manager
@@ -234,6 +236,7 @@ func (s *AdminServer) CreateAccessKey(username string) (*AccessKeyInfo, error) {
return &AccessKeyInfo{
AccessKey: accessKey,
SecretKey: secretKey,
Status: AccessKeyStatusActive,
CreatedAt: time.Now(),
}, nil
}
@@ -261,6 +264,51 @@ func (s *AdminServer) DeleteAccessKey(username, accessKeyId string) error {
return nil
}
// UpdateAccessKeyStatus updates the status of an access key for a user
func (s *AdminServer) UpdateAccessKeyStatus(username, accessKeyId, status string) error {
if s.credentialManager == nil {
return fmt.Errorf("credential manager not available")
}
// Validate status against allowed values
if status != AccessKeyStatusActive && status != AccessKeyStatusInactive {
return fmt.Errorf("invalid status '%s': must be '%s' or '%s'", status, AccessKeyStatusActive, AccessKeyStatusInactive)
}
ctx := context.Background()
// Get user using credential manager
identity, err := s.credentialManager.GetUser(ctx, username)
if err != nil {
if err == credential.ErrUserNotFound {
return fmt.Errorf("user %s not found", username)
}
return fmt.Errorf("failed to get user: %w", err)
}
// Find and update the access key status
found := false
for _, cred := range identity.Credentials {
if cred.AccessKey == accessKeyId {
cred.Status = status
found = true
break
}
}
if !found {
return fmt.Errorf("access key %s not found for user %s", accessKeyId, username)
}
// Update user using credential manager
err = s.credentialManager.UpdateUser(ctx, username, identity)
if err != nil {
return fmt.Errorf("failed to update user access key status: %w", err)
}
return nil
}
// GetUserPolicies returns the policies for a user (actions)
func (s *AdminServer) GetUserPolicies(username string) ([]string, error) {
if s.credentialManager == nil {