From be43c3cf880adb4567bc2d65547015fcf613e2ce Mon Sep 17 00:00:00 2001 From: Tamar Ben-Shachar Date: Mon, 22 Feb 2016 17:29:11 -0800 Subject: [PATCH] error based on user command auth not auth to get CLUSTER_ID We try to get the CLUSTER_ID before we run the user specified command. If the user if authenticated, but not authorized (to get the CLUSTER_ID), let them continue and error based on access to the command they ran. --- cli/dcoscli/main.py | 9 +++++---- dcos/cosmospackage.py | 6 ++---- dcos/errors.py | 26 ++++++++++++++++++++++++++ dcos/http.py | 8 +++++--- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/cli/dcoscli/main.py b/cli/dcoscli/main.py index 91e7b6e49..b68d58cae 100644 --- a/cli/dcoscli/main.py +++ b/cli/dcoscli/main.py @@ -9,7 +9,7 @@ import pkg_resources from dcos import (auth, constants, emitting, errors, http, mesos, subcommand, util) -from dcos.errors import DCOSException +from dcos.errors import DCOSAuthenticationException, DCOSException from dcoscli import analytics logger = util.get_logger(__name__) @@ -57,11 +57,12 @@ def _main(): executable = subcommand.command_executables(command) cluster_id = None - if dcoscli.version != 'SNAPSHOT' and command and command != "config": + if dcoscli.version != 'SNAPSHOT' and command and \ + command not in ["config", "help"]: try: cluster_id = mesos.DCOSClient().metadata().get('CLUSTER_ID') - except DCOSException: - raise + except DCOSAuthenticationException: + raise except: msg = 'Unable to get the cluster_id of the cluster.' logger.exception(msg) diff --git a/dcos/cosmospackage.py b/dcos/cosmospackage.py index c3bfde9a3..929251184 100644 --- a/dcos/cosmospackage.py +++ b/dcos/cosmospackage.py @@ -1,5 +1,5 @@ from dcos import emitting, http, util -from dcos.errors import DCOSException, DCOSHTTPException +from dcos.errors import DCOSAuthenticationException from six.moves import urllib @@ -26,9 +26,7 @@ def enabled(self): headers=_get_cosmos_header("capabilities")) # return `Authentication failed` error messages, but all other errors # are treated as endpoint not available - except DCOSHTTPException: - return False - except DCOSException: + except DCOSAuthenticationException: raise except Exception as e: logger.exception(e) diff --git a/dcos/errors.py b/dcos/errors.py index 6ba2714ae..fb9821f8f 100644 --- a/dcos/errors.py +++ b/dcos/errors.py @@ -21,6 +21,32 @@ def __str__(self): self.response.reason) +class DCOSAuthenticationException(DCOSHTTPException): + """A wrapper around Response objects for HTTP Authentication errors (401). + + :param response: requests Response object + :type response: Response + """ + def __init__(self, response): + self.response = response + + def __str__(self): + return "Authentication failed" + + +class DCOSAuthorizationException(DCOSHTTPException): + """A wrapper around Response objects for HTTP Authorization errors (403). + + :param response: requests Response object + :type response: Response + """ + def __init__(self, response): + self.response = response + + def __str__(self): + return "You are not authorized to perform this operation" + + class Error(object): """Abstract class for describing errors.""" diff --git a/dcos/http.py b/dcos/http.py index 80c21654a..bce2fb850 100644 --- a/dcos/http.py +++ b/dcos/http.py @@ -5,7 +5,9 @@ import requests from dcos import config, constants, util -from dcos.errors import DCOSException, DCOSHTTPException +from dcos.errors import (DCOSAuthenticationException, + DCOSAuthorizationException, DCOSException, + DCOSHTTPException) from requests.auth import AuthBase, HTTPBasicAuth from six.moves import urllib @@ -147,7 +149,7 @@ def _request_with_auth(response, i += 1 if response.status_code == 401: - raise DCOSException("Authentication failed") + raise DCOSAuthenticationException(response) return response @@ -201,7 +203,7 @@ def request(method, if is_success(response.status_code): return response elif response.status_code == 403: - raise DCOSException("You are not authorized to perform this operation") + raise DCOSAuthorizationException(response) else: raise DCOSHTTPException(response)