Deprecate updating admin credentials using API calls (#7570)

Root credentials are not allowed to change in all of our
distributed setup deployments, this PR simply removes
that behavior.
This commit is contained in:
Harshavardhana
2019-04-24 12:54:44 -07:00
committed by kannappanr
parent a3ec71bc28
commit ae002aa724
7 changed files with 492 additions and 882 deletions
-68
View File
@@ -35,7 +35,6 @@ import (
"github.com/tidwall/sjson"
"github.com/minio/minio/cmd/logger"
"github.com/minio/minio/pkg/auth"
"github.com/minio/minio/pkg/cpu"
"github.com/minio/minio/pkg/disk"
"github.com/minio/minio/pkg/handlers"
@@ -1416,70 +1415,3 @@ func (a adminAPIHandlers) SetConfigKeysHandler(w http.ResponseWriter, r *http.Re
// Send success response
writeSuccessResponseHeadersOnly(w)
}
// UpdateAdminCredsHandler - POST /minio/admin/v1/config/credential
// ----------
// Update admin credentials in a minio server
func (a adminAPIHandlers) UpdateAdminCredentialsHandler(w http.ResponseWriter,
r *http.Request) {
ctx := newContext(r, w, "UpdateCredentialsHandler")
objectAPI := validateAdminReq(ctx, w, r)
if objectAPI == nil {
return
}
// Avoid setting new credentials when they are already passed
// by the environment. Deny if WORM is enabled.
if globalIsEnvCreds || globalWORMEnabled {
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrMethodNotAllowed), r.URL)
return
}
if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 {
// More than maxConfigSize bytes were available
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL)
return
}
password := globalServerConfig.GetCredential().SecretKey
configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength))
if err != nil {
logger.LogIf(ctx, err)
writeCustomErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), err.Error(), r.URL)
return
}
// Decode request body
var req madmin.SetCredsReq
if err = json.Unmarshal(configBytes, &req); err != nil {
logger.LogIf(ctx, err)
writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrRequestBodyParse), r.URL)
return
}
creds, err := auth.CreateCredentials(req.AccessKey, req.SecretKey)
if err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
// Acquire lock before updating global configuration.
globalServerConfigMu.Lock()
defer globalServerConfigMu.Unlock()
// Update local credentials in memory.
globalServerConfig.SetCredential(creds)
// Set active creds.
globalActiveCred = creds
if err = saveServerConfig(ctx, objectAPI, globalServerConfig); err != nil {
writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
return
}
// Reply to the client before restarting minio server.
writeSuccessResponseHeadersOnly(w)
}
-80
View File
@@ -599,86 +599,6 @@ func TestServiceRestartHandler(t *testing.T) {
testServicesCmdHandler(restartCmd, t)
}
// Test for service set creds management REST API.
func TestServiceSetCreds(t *testing.T) {
adminTestBed, err := prepareAdminXLTestBed()
if err != nil {
t.Fatal("Failed to initialize a single node XL backend for admin handler tests.")
}
defer adminTestBed.TearDown()
// Initialize admin peers to make admin RPC calls. Note: In a
// single node setup, this degenerates to a simple function
// call under the hood.
globalMinioAddr = "127.0.0.1:9000"
credentials := globalServerConfig.GetCredential()
testCases := []struct {
AccessKey string
SecretKey string
EnvKeysSet bool
ExpectedStatusCode int
}{
// Bad secret key
{"minio", "minio", false, http.StatusBadRequest},
// Bad secret key set from the env
{"minio", "minio", true, http.StatusMethodNotAllowed},
// Good keys set from the env
{"minio", "minio123", true, http.StatusMethodNotAllowed},
// Successful operation should be the last one to
// not change server credentials during tests.
{"minio", "minio123", false, http.StatusOK},
}
for i, testCase := range testCases {
// Set or unset environement keys
globalIsEnvCreds = testCase.EnvKeysSet
// Construct setCreds request body
body, err := json.Marshal(madmin.SetCredsReq{
AccessKey: testCase.AccessKey,
SecretKey: testCase.SecretKey})
if err != nil {
t.Fatalf("JSONify err: %v", err)
}
ebody, err := madmin.EncryptData(credentials.SecretKey, body)
if err != nil {
t.Fatal(err)
}
// Construct setCreds request
req, err := getServiceCmdRequest(setCreds, credentials, ebody)
if err != nil {
t.Fatalf("Failed to build service status request %v", err)
}
rec := httptest.NewRecorder()
// Execute request
adminTestBed.router.ServeHTTP(rec, req)
// Check if the http code response is expected
if rec.Code != testCase.ExpectedStatusCode {
t.Errorf("Test %d: Wrong status code, expected = %d, found = %d", i+1, testCase.ExpectedStatusCode, rec.Code)
resp, _ := ioutil.ReadAll(rec.Body)
t.Errorf("Expected to receive %d status code but received %d. Body (%s)",
http.StatusOK, rec.Code, string(resp))
}
// If we got 200 OK, check if new credentials are really set
if rec.Code == http.StatusOK {
cred := globalServerConfig.GetCredential()
if cred.AccessKey != testCase.AccessKey {
t.Errorf("Test %d: Wrong access key, expected = %s, found = %s", i+1, testCase.AccessKey, cred.AccessKey)
}
if cred.SecretKey != testCase.SecretKey {
t.Errorf("Test %d: Wrong secret key, expected = %s, found = %s", i+1, testCase.SecretKey, cred.SecretKey)
}
}
}
}
// buildAdminRequest - helper function to build an admin API request.
func buildAdminRequest(queryVal url.Values, method, path string,
contentLength int64, bodySeeker io.ReadSeeker) (*http.Request, error) {
-2
View File
@@ -74,8 +74,6 @@ func registerAdminRouter(router *mux.Router, enableConfigOps, enableIAMOps bool)
/// Config operations
if enableConfigOps {
// Update credentials
adminV1Router.Methods(http.MethodPut).Path("/config/credential").HandlerFunc(httpTraceHdrs(adminAPI.UpdateAdminCredentialsHandler))
// Get config
adminV1Router.Methods(http.MethodGet).Path("/config").HandlerFunc(httpTraceHdrs(adminAPI.GetConfigHandler))
// Set config