mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
Use common function for authenticating admin requests (#12915)
This commit is contained in:
parent
9ab5e0312d
commit
59bb54ed6a
@ -85,7 +85,7 @@ func (a adminAPIHandlers) GetBucketQuotaConfigHandler(w http.ResponseWriter, r *
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetBucketQuotaAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.GetBucketQuotaAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
@ -130,7 +130,7 @@ func (a adminAPIHandlers) SetRemoteTargetHandler(w http.ResponseWriter, r *http.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get current object layer instance.
|
// Get current object layer instance.
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.SetBucketTargetAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.SetBucketTargetAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
@ -258,7 +258,7 @@ func (a adminAPIHandlers) ListRemoteTargetsHandler(w http.ResponseWriter, r *htt
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Get current object layer instance.
|
// Get current object layer instance.
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetBucketTargetAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.GetBucketTargetAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
@ -298,7 +298,7 @@ func (a adminAPIHandlers) RemoveRemoteTargetHandler(w http.ResponseWriter, r *ht
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Get current object layer instance.
|
// Get current object layer instance.
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.SetBucketTargetAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.SetBucketTargetAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
|
172
cmd/admin-handler-utils.go
Normal file
172
cmd/admin-handler-utils.go
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// Copyright (c) 2015-2021 MinIO, Inc.
|
||||||
|
//
|
||||||
|
// This file is part of MinIO Object Storage stack
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU Affero General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU Affero General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/minio/kes"
|
||||||
|
"github.com/minio/madmin-go"
|
||||||
|
"github.com/minio/minio/internal/auth"
|
||||||
|
"github.com/minio/minio/internal/config"
|
||||||
|
iampolicy "github.com/minio/pkg/iam/policy"
|
||||||
|
)
|
||||||
|
|
||||||
|
func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Request, action iampolicy.AdminAction) (ObjectLayer, auth.Credentials) {
|
||||||
|
// Get current object layer instance.
|
||||||
|
objectAPI := newObjectLayerFn()
|
||||||
|
if objectAPI == nil || globalNotificationSys == nil {
|
||||||
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
|
return nil, auth.Credentials{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate request signature.
|
||||||
|
cred, adminAPIErr := checkAdminRequestAuth(ctx, r, action, "")
|
||||||
|
if adminAPIErr != ErrNone {
|
||||||
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL)
|
||||||
|
return nil, cred
|
||||||
|
}
|
||||||
|
|
||||||
|
return objectAPI, cred
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminError - is a generic error for all admin APIs.
|
||||||
|
type AdminError struct {
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
StatusCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ae AdminError) Error() string {
|
||||||
|
return ae.Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func toAdminAPIErr(ctx context.Context, err error) APIError {
|
||||||
|
if err == nil {
|
||||||
|
return noError
|
||||||
|
}
|
||||||
|
|
||||||
|
var apiErr APIError
|
||||||
|
switch e := err.(type) {
|
||||||
|
case iampolicy.Error:
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioMalformedIAMPolicy",
|
||||||
|
Description: e.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case config.Error:
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioConfigError",
|
||||||
|
Description: e.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case AdminError:
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: e.Code,
|
||||||
|
Description: e.Message,
|
||||||
|
HTTPStatusCode: e.StatusCode,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
switch {
|
||||||
|
case errors.Is(err, errConfigNotFound):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioConfigError",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusNotFound,
|
||||||
|
}
|
||||||
|
case errors.Is(err, errIAMActionNotAllowed):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioIAMActionNotAllowed",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusForbidden,
|
||||||
|
}
|
||||||
|
case errors.Is(err, errIAMNotInitialized):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioIAMNotInitialized",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusServiceUnavailable,
|
||||||
|
}
|
||||||
|
case errors.Is(err, kes.ErrKeyExists):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioKMSKeyExists",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusConflict,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tier admin API errors
|
||||||
|
case errors.Is(err, madmin.ErrTierNameEmpty):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierNameEmpty",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case errors.Is(err, madmin.ErrTierInvalidConfig):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierInvalidConfig",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case errors.Is(err, madmin.ErrTierInvalidConfigVersion):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierInvalidConfigVersion",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case errors.Is(err, madmin.ErrTierTypeUnsupported):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierTypeUnsupported",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case errors.Is(err, errTierBackendInUse):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierBackendInUse",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusConflict,
|
||||||
|
}
|
||||||
|
case errors.Is(err, errTierInsufficientCreds):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierInsufficientCreds",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
case errIsTierPermError(err):
|
||||||
|
apiErr = APIError{
|
||||||
|
Code: "XMinioAdminTierInsufficientPermissions",
|
||||||
|
Description: err.Error(),
|
||||||
|
HTTPStatusCode: http.StatusBadRequest,
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
apiErr = errorCodes.ToAPIErrWithErr(toAdminAPIErrCode(ctx, err), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return apiErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// toAdminAPIErrCode - converts errErasureWriteQuorum error to admin API
|
||||||
|
// specific error.
|
||||||
|
func toAdminAPIErrCode(ctx context.Context, err error) APIErrorCode {
|
||||||
|
switch err {
|
||||||
|
case errErasureWriteQuorum:
|
||||||
|
return ErrAdminConfigNoQuorum
|
||||||
|
default:
|
||||||
|
return toAPIErrorCode(ctx, err)
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -28,7 +27,6 @@ import (
|
|||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/minio/madmin-go"
|
"github.com/minio/madmin-go"
|
||||||
"github.com/minio/minio/internal/auth"
|
|
||||||
"github.com/minio/minio/internal/config"
|
"github.com/minio/minio/internal/config"
|
||||||
"github.com/minio/minio/internal/config/cache"
|
"github.com/minio/minio/internal/config/cache"
|
||||||
"github.com/minio/minio/internal/config/etcd"
|
"github.com/minio/minio/internal/config/etcd"
|
||||||
@ -40,31 +38,13 @@ import (
|
|||||||
iampolicy "github.com/minio/pkg/iam/policy"
|
iampolicy "github.com/minio/pkg/iam/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateAdminReqConfigKV(ctx context.Context, w http.ResponseWriter, r *http.Request) (auth.Credentials, ObjectLayer) {
|
|
||||||
// Get current object layer instance.
|
|
||||||
objectAPI := newObjectLayerFn()
|
|
||||||
if objectAPI == nil {
|
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
|
||||||
return auth.Credentials{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate request signature.
|
|
||||||
cred, adminAPIErr := checkAdminRequestAuth(ctx, r, iampolicy.ConfigUpdateAdminAction, "")
|
|
||||||
if adminAPIErr != ErrNone {
|
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL)
|
|
||||||
return cred, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return cred, objectAPI
|
|
||||||
}
|
|
||||||
|
|
||||||
// DelConfigKVHandler - DELETE /minio/admin/v3/del-config-kv
|
// DelConfigKVHandler - DELETE /minio/admin/v3/del-config-kv
|
||||||
func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Request) {
|
func (a adminAPIHandlers) DelConfigKVHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := newContext(r, w, "DeleteConfigKV")
|
ctx := newContext(r, w, "DeleteConfigKV")
|
||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -106,7 +86,7 @@ func (a adminAPIHandlers) SetConfigKVHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -173,7 +153,7 @@ func (a adminAPIHandlers) GetConfigKVHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -202,7 +182,7 @@ func (a adminAPIHandlers) ClearConfigHistoryKVHandler(w http.ResponseWriter, r *
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
_, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -239,7 +219,7 @@ func (a adminAPIHandlers) RestoreConfigHistoryKVHandler(w http.ResponseWriter, r
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
_, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -287,7 +267,7 @@ func (a adminAPIHandlers) ListConfigHistoryKVHandler(w http.ResponseWriter, r *h
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -327,7 +307,7 @@ func (a adminAPIHandlers) HelpConfigKVHandler(w http.ResponseWriter, r *http.Req
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
_, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -355,7 +335,7 @@ func (a adminAPIHandlers) SetConfigHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -407,7 +387,7 @@ func (a adminAPIHandlers) GetConfigHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
cred, objectAPI := validateAdminReqConfigKV(ctx, w, r)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ConfigUpdateAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
@ -29,40 +28,18 @@ import (
|
|||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/minio/madmin-go"
|
"github.com/minio/madmin-go"
|
||||||
"github.com/minio/minio/internal/auth"
|
|
||||||
"github.com/minio/minio/internal/config/dns"
|
"github.com/minio/minio/internal/config/dns"
|
||||||
"github.com/minio/minio/internal/logger"
|
"github.com/minio/minio/internal/logger"
|
||||||
iampolicy "github.com/minio/pkg/iam/policy"
|
iampolicy "github.com/minio/pkg/iam/policy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func validateAdminUsersReq(ctx context.Context, w http.ResponseWriter, r *http.Request, action iampolicy.AdminAction) (ObjectLayer, auth.Credentials) {
|
|
||||||
var cred auth.Credentials
|
|
||||||
var adminAPIErr APIErrorCode
|
|
||||||
|
|
||||||
// Get current object layer instance.
|
|
||||||
objectAPI := newObjectLayerFn()
|
|
||||||
if objectAPI == nil || globalNotificationSys == nil {
|
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
|
||||||
return nil, cred
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate request signature.
|
|
||||||
cred, adminAPIErr = checkAdminRequestAuth(ctx, r, action, "")
|
|
||||||
if adminAPIErr != ErrNone {
|
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL)
|
|
||||||
return nil, cred
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectAPI, cred
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveUser - DELETE /minio/admin/v3/remove-user?accessKey=<access_key>
|
// RemoveUser - DELETE /minio/admin/v3/remove-user?accessKey=<access_key>
|
||||||
func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) {
|
func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) {
|
||||||
ctx := newContext(r, w, "RemoveUser")
|
ctx := newContext(r, w, "RemoveUser")
|
||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.DeleteUserAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.DeleteUserAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -100,7 +77,7 @@ func (a adminAPIHandlers) ListBucketUsers(w http.ResponseWriter, r *http.Request
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, cred := validateAdminUsersReq(ctx, w, r, iampolicy.ListUsersAdminAction)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ListUsersAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -136,7 +113,7 @@ func (a adminAPIHandlers) ListUsers(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, cred := validateAdminUsersReq(ctx, w, r, iampolicy.ListUsersAdminAction)
|
objectAPI, cred := validateAdminReq(ctx, w, r, iampolicy.ListUsersAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -234,7 +211,7 @@ func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.AddUserToGroupAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.AddUserToGroupAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -279,7 +256,7 @@ func (a adminAPIHandlers) GetGroup(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetGroupAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.GetGroupAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -308,7 +285,7 @@ func (a adminAPIHandlers) ListGroups(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.ListGroupsAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ListGroupsAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -334,7 +311,7 @@ func (a adminAPIHandlers) SetGroupStatus(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.EnableGroupAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.EnableGroupAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -371,7 +348,7 @@ func (a adminAPIHandlers) SetUserStatus(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.EnableUserAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.EnableUserAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1144,7 +1121,7 @@ func (a adminAPIHandlers) InfoCannedPolicy(w http.ResponseWriter, r *http.Reques
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.GetPolicyAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.GetPolicyAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1169,7 +1146,7 @@ func (a adminAPIHandlers) ListBucketPolicies(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.ListUserPoliciesAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ListUserPoliciesAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1205,7 +1182,7 @@ func (a adminAPIHandlers) ListCannedPolicies(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.ListUserPoliciesAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ListUserPoliciesAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1239,7 +1216,7 @@ func (a adminAPIHandlers) RemoveCannedPolicy(w http.ResponseWriter, r *http.Requ
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.DeletePolicyAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.DeletePolicyAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1267,7 +1244,7 @@ func (a adminAPIHandlers) AddCannedPolicy(w http.ResponseWriter, r *http.Request
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.CreatePolicyAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.CreatePolicyAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1319,7 +1296,7 @@ func (a adminAPIHandlers) SetPolicyForUserOrGroup(w http.ResponseWriter, r *http
|
|||||||
|
|
||||||
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r))
|
||||||
|
|
||||||
objectAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.AttachPolicyAdminAction)
|
objectAPI, _ := validateAdminReq(ctx, w, r, iampolicy.AttachPolicyAdminAction)
|
||||||
if objectAPI == nil {
|
if objectAPI == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ import (
|
|||||||
"crypto/subtle"
|
"crypto/subtle"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"hash/crc32"
|
"hash/crc32"
|
||||||
"io"
|
"io"
|
||||||
@ -42,10 +41,7 @@ import (
|
|||||||
humanize "github.com/dustin/go-humanize"
|
humanize "github.com/dustin/go-humanize"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/klauspost/compress/zip"
|
"github.com/klauspost/compress/zip"
|
||||||
"github.com/minio/kes"
|
|
||||||
"github.com/minio/madmin-go"
|
"github.com/minio/madmin-go"
|
||||||
"github.com/minio/minio/internal/auth"
|
|
||||||
"github.com/minio/minio/internal/config"
|
|
||||||
"github.com/minio/minio/internal/dsync"
|
"github.com/minio/minio/internal/dsync"
|
||||||
"github.com/minio/minio/internal/handlers"
|
"github.com/minio/minio/internal/handlers"
|
||||||
xhttp "github.com/minio/minio/internal/http"
|
xhttp "github.com/minio/minio/internal/http"
|
||||||
@ -957,37 +953,6 @@ func (a adminAPIHandlers) SpeedtestHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
w.(http.Flusher).Flush()
|
w.(http.Flusher).Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateAdminReq(ctx context.Context, w http.ResponseWriter, r *http.Request, action iampolicy.AdminAction) (ObjectLayer, auth.Credentials) {
|
|
||||||
var cred auth.Credentials
|
|
||||||
var adminAPIErr APIErrorCode
|
|
||||||
// Get current object layer instance.
|
|
||||||
objectAPI := newObjectLayerFn()
|
|
||||||
if objectAPI == nil || globalNotificationSys == nil {
|
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
|
||||||
return nil, cred
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate request signature.
|
|
||||||
cred, adminAPIErr = checkAdminRequestAuth(ctx, r, action, "")
|
|
||||||
if adminAPIErr != ErrNone {
|
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(adminAPIErr), r.URL)
|
|
||||||
return nil, cred
|
|
||||||
}
|
|
||||||
|
|
||||||
return objectAPI, cred
|
|
||||||
}
|
|
||||||
|
|
||||||
// AdminError - is a generic error for all admin APIs.
|
|
||||||
type AdminError struct {
|
|
||||||
Code string
|
|
||||||
Message string
|
|
||||||
StatusCode int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ae AdminError) Error() string {
|
|
||||||
return ae.Message
|
|
||||||
}
|
|
||||||
|
|
||||||
// Admin API errors
|
// Admin API errors
|
||||||
const (
|
const (
|
||||||
AdminUpdateUnexpectedFailure = "XMinioAdminUpdateUnexpectedFailure"
|
AdminUpdateUnexpectedFailure = "XMinioAdminUpdateUnexpectedFailure"
|
||||||
@ -995,119 +960,6 @@ const (
|
|||||||
AdminUpdateApplyFailure = "XMinioAdminUpdateApplyFailure"
|
AdminUpdateApplyFailure = "XMinioAdminUpdateApplyFailure"
|
||||||
)
|
)
|
||||||
|
|
||||||
// toAdminAPIErrCode - converts errErasureWriteQuorum error to admin API
|
|
||||||
// specific error.
|
|
||||||
func toAdminAPIErrCode(ctx context.Context, err error) APIErrorCode {
|
|
||||||
switch err {
|
|
||||||
case errErasureWriteQuorum:
|
|
||||||
return ErrAdminConfigNoQuorum
|
|
||||||
default:
|
|
||||||
return toAPIErrorCode(ctx, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toAdminAPIErr(ctx context.Context, err error) APIError {
|
|
||||||
if err == nil {
|
|
||||||
return noError
|
|
||||||
}
|
|
||||||
|
|
||||||
var apiErr APIError
|
|
||||||
switch e := err.(type) {
|
|
||||||
case iampolicy.Error:
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioMalformedIAMPolicy",
|
|
||||||
Description: e.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case config.Error:
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioConfigError",
|
|
||||||
Description: e.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case AdminError:
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: e.Code,
|
|
||||||
Description: e.Message,
|
|
||||||
HTTPStatusCode: e.StatusCode,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
switch {
|
|
||||||
case errors.Is(err, errConfigNotFound):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioConfigError",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusNotFound,
|
|
||||||
}
|
|
||||||
case errors.Is(err, errIAMActionNotAllowed):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioIAMActionNotAllowed",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusForbidden,
|
|
||||||
}
|
|
||||||
case errors.Is(err, errIAMNotInitialized):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioIAMNotInitialized",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusServiceUnavailable,
|
|
||||||
}
|
|
||||||
case errors.Is(err, kes.ErrKeyExists):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioKMSKeyExists",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusConflict,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tier admin API errors
|
|
||||||
case errors.Is(err, madmin.ErrTierNameEmpty):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierNameEmpty",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case errors.Is(err, madmin.ErrTierInvalidConfig):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierInvalidConfig",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case errors.Is(err, madmin.ErrTierInvalidConfigVersion):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierInvalidConfigVersion",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case errors.Is(err, madmin.ErrTierTypeUnsupported):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierTypeUnsupported",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case errors.Is(err, errTierBackendInUse):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierBackendInUse",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusConflict,
|
|
||||||
}
|
|
||||||
case errors.Is(err, errTierInsufficientCreds):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierInsufficientCreds",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
case errIsTierPermError(err):
|
|
||||||
apiErr = APIError{
|
|
||||||
Code: "XMinioAdminTierInsufficientPermissions",
|
|
||||||
Description: err.Error(),
|
|
||||||
HTTPStatusCode: http.StatusBadRequest,
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
apiErr = errorCodes.ToAPIErrWithErr(toAdminAPIErrCode(ctx, err), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return apiErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the madmin.TraceInfo should be traced,
|
// Returns true if the madmin.TraceInfo should be traced,
|
||||||
// false if certain conditions are not met.
|
// false if certain conditions are not met.
|
||||||
// - input entry is not of the type *madmin.TraceInfo*
|
// - input entry is not of the type *madmin.TraceInfo*
|
||||||
|
@ -72,7 +72,7 @@ func (api adminAPIHandlers) AddTierHandler(w http.ResponseWriter, r *http.Reques
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
objAPI, cred := validateAdminUsersReq(ctx, w, r, iampolicy.SetTierAction)
|
objAPI, cred := validateAdminReq(ctx, w, r, iampolicy.SetTierAction)
|
||||||
if objAPI == nil || globalNotificationSys == nil || globalTierConfigMgr == nil {
|
if objAPI == nil || globalNotificationSys == nil || globalTierConfigMgr == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
@ -124,7 +124,7 @@ func (api adminAPIHandlers) ListTierHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
objAPI, _ := validateAdminUsersReq(ctx, w, r, iampolicy.ListTierAction)
|
objAPI, _ := validateAdminReq(ctx, w, r, iampolicy.ListTierAction)
|
||||||
if objAPI == nil || globalNotificationSys == nil || globalTierConfigMgr == nil {
|
if objAPI == nil || globalNotificationSys == nil || globalTierConfigMgr == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
@ -150,7 +150,7 @@ func (api adminAPIHandlers) EditTierHandler(w http.ResponseWriter, r *http.Reque
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
objAPI, cred := validateAdminUsersReq(ctx, w, r, iampolicy.SetTierAction)
|
objAPI, cred := validateAdminReq(ctx, w, r, iampolicy.SetTierAction)
|
||||||
if objAPI == nil || globalNotificationSys == nil || globalTierConfigMgr == nil {
|
if objAPI == nil || globalNotificationSys == nil || globalTierConfigMgr == nil {
|
||||||
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user