Fixes on the authorization mechanism

This commit fixes some errors introduced with the support for the
authorization in Synergy. The files involved are: service.py and
shell.py and related unit tests.

Change-Id: I84587e48927307d85b9a3f96ea49154805da7bcd
Sem-Ver: bugfix
This commit is contained in:
Lisa Zangrando 2017-07-17 12:16:14 +02:00
parent 3b568b70a0
commit 51e6dde4e5
4 changed files with 83 additions and 64 deletions

View File

@ -128,55 +128,65 @@ def main():
command_name = args.command_name command_name = args.command_name
token = None token = None
if not os_username:
raise ValueError("'os-username' not defined!")
if not os_password:
raise ValueError("'os-password' not defined!")
if not os_project_name:
raise ValueError("'os-project-name' not defined!")
if not os_auth_url:
raise ValueError("'os-auth-url' not defined!")
if not os_user_domain_name:
os_user_domain_name = "default"
if not os_project_domain_name:
os_project_domain_name = "default"
client = keystone_v3.KeystoneClient(
auth_url=os_auth_url,
username=os_username,
password=os_password,
ca_cert=os_cacert,
user_domain_id=os_user_domain_id,
user_domain_name=os_user_domain_name,
project_name=os_project_name,
project_domain_id=os_project_domain_id,
project_domain_name=os_project_domain_name)
token = client.authenticate()
if bypass_url: if bypass_url:
synergy_url = bypass_url synergy_url = bypass_url
else: else:
if not os_username:
raise ValueError("'os-username' not defined!")
if not os_password:
raise ValueError("'os-password' not defined!")
if not os_project_name:
raise ValueError("'os-project-name' not defined!")
if not os_auth_url:
raise ValueError("'os-auth-url' not defined!")
if not os_user_domain_name:
os_user_domain_name = "default"
if not os_project_domain_name:
os_project_domain_name = "default"
client = keystone_v3.KeystoneClient(
auth_url=os_auth_url,
username=os_username,
password=os_password,
ca_cert=os_cacert,
user_domain_id=os_user_domain_id,
user_domain_name=os_user_domain_name,
project_name=os_project_name,
project_domain_id=os_project_domain_id,
project_domain_name=os_project_domain_name)
token = client.authenticate()
synergy_endpoint = client.getEndpoint("synergy") synergy_endpoint = client.getEndpoint("synergy")
synergy_url = synergy_endpoint["url"] synergy_url = synergy_endpoint["url"]
if command_name not in commands: if command_name not in commands:
print("command %r not found!" % command_name) print("Command %r not found!" % command_name)
commands[command_name].setToken(token) commands[command_name].setToken(token)
commands[command_name].execute(synergy_url, args) commands[command_name].execute(synergy_url, args)
except KeyboardInterrupt: except KeyboardInterrupt:
print("Shutting down synergyclient") print("Shutting down synergyclient")
sys.exit(1) sys.exit(1)
except (RequestException, ConnectionError, HTTPError) as ex: except ConnectionError as ex:
print("connection to %s failed!" % synergy_url) print("Failed to establish a new connection to %s" % synergy_url)
sys.exit(1)
except HTTPError as ex:
if ex.response._content:
print("%s" % ex.response._content)
else:
print("%s" % ex.message)
sys.exit(1)
except RequestException as ex:
print("%s" % ex.response._content)
sys.exit(1) sys.exit(1)
except Exception as ex: except Exception as ex:
print(ex.message) print(ex)
sys.exit(1) sys.exit(1)

View File

@ -155,6 +155,9 @@ class Synergy(Service):
def parseParameters(f): def parseParameters(f):
def wrapper(self, *args, **kw): def wrapper(self, *args, **kw):
if not args:
return f(self, *args, **kw)
context = args[0] context = args[0]
query = context.get("QUERY_STRING", None) query = context.get("QUERY_STRING", None)
@ -177,24 +180,24 @@ class Synergy(Service):
return wrapper return wrapper
def checkParameters(paremeters): def checkParameters(parameters):
def check(f): def check(f):
def wrapper(self, *args, **kw): def wrapper(self, *args, **kw):
context = args[0] context = args[0]
start_response = args[1] start_response = args[1]
for parameter in paremeters: for parameter in parameters:
value = context.get(parameter, None) value = context.get(parameter, None)
if not value: if not value:
start_response("400 BAD REQUEST", start_response("400 BAD REQUEST",
[("Content-Type", "text/plain")]) [("Content-Type", "text/plain")])
return "parameter %s not found!" % parameter return ["parameter %s not found!" % parameter]
if parameter == "manager" and value not in self.managers: if parameter == "manager" and value not in self.managers:
start_response("404 NOT FOUND", start_response("404 NOT FOUND",
[("Content-Type", "text/plain")]) [("Content-Type", "text/plain")])
return "manager %s not found!" % value return ["manager %s not found!" % value]
return f(self, *args, **kw) return f(self, *args, **kw)
return wrapper return wrapper
@ -211,7 +214,7 @@ class Synergy(Service):
except AuthorizationError as ex: except AuthorizationError as ex:
args[1]("401 Unauthorized", args[1]("401 Unauthorized",
[("Content-Type", "text/plain")]) [("Content-Type", "text/plain")])
return [ex.message] return ["%s" % ex.message]
return f(self, *args, **kw) return f(self, *args, **kw)
@ -265,7 +268,7 @@ class Synergy(Service):
return [json.dumps(result, cls=SynergyEncoder)] return [json.dumps(result, cls=SynergyEncoder)]
@parseParameters @parseParameters
@checkParameters(["manager", "command", "args"]) @checkParameters(["manager", "command"])
@authorize @authorize
def executeCommand(self, environ, start_response): def executeCommand(self, environ, start_response):
manager_name = environ["manager"] manager_name = environ["manager"]
@ -284,14 +287,14 @@ class Synergy(Service):
LOG.error(message) LOG.error(message)
start_response("500 INTERNAL SERVER ERROR", start_response("500 INTERNAL SERVER ERROR",
[("Content-Type", "text/plain")]) [("Content-Type", "text/plain")])
return message return [message]
except SynergyError as ex: except SynergyError as ex:
LOG.debug("execute command: error=%s" % ex) LOG.debug("execute command: error=%s" % ex)
start_response("500 INTERNAL SERVER ERROR", start_response("422 Unprocessable Entity",
[("Content-Type", "text/plain")]) [("Content-Type", "text/plain")])
return "%s" % ex return ["%s" % ex.message]
@parseParameters @parseParameters
@checkParameters(["manager"]) @checkParameters(["manager"])
@ -320,7 +323,7 @@ class Synergy(Service):
result.set("message", "wrong state") result.set("message", "wrong state")
start_response("200 OK", [("Content-Type", "text/html")]) start_response("200 OK", [("Content-Type", "text/html")])
return json.dumps(result, cls=SynergyEncoder) return [json.dumps(result, cls=SynergyEncoder)]
@parseParameters @parseParameters
@checkParameters(["manager"]) @checkParameters(["manager"])
@ -348,7 +351,7 @@ class Synergy(Service):
result.set("message", "wrong state") result.set("message", "wrong state")
start_response("200 OK", [("Content-Type", "text/html")]) start_response("200 OK", [("Content-Type", "text/html")])
return json.dumps(result, cls=SynergyEncoder) return [json.dumps(result, cls=SynergyEncoder)]
def start(self): def start(self):
self.model_disconnected = False self.model_disconnected = False
@ -438,16 +441,13 @@ def main():
", /etc/) and the '--config-file' option!") ", /etc/) and the '--config-file' option!")
setLogger(name="synergy") setLogger(name="synergy")
setLogger(name="oslo.messaging._drivers")
global LOG global LOG
# LOG = logging.getLogger(None)
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
LOG.info("Starting Synergy...") LOG.info("Starting Synergy...")
# set session ID to this process so we can kill group in sigterm
# os.setsid()
server = Synergy() server = Synergy()
server.start() server.start()

View File

@ -99,12 +99,12 @@ class SynergyTests(unittest.TestCase):
result = self.synergy.startManager(environ, start_response) result = self.synergy.startManager(environ, start_response)
self.assertEqual(result, "manager NONE not found!") self.assertEqual(result[0], "manager NONE not found!")
environ = {'QUERY_STRING': 'manager=TimerManager'} environ = {'QUERY_STRING': 'manager=TimerManager'}
result = self.synergy.startManager(environ, start_response) result = self.synergy.startManager(environ, start_response)
result = json.loads(result, object_hook=objectHookHandler) result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(result.getStatus(), 'RUNNING') self.assertEqual(result.getStatus(), 'RUNNING')
self.assertEqual(result.get("message"), 'started successfully') self.assertEqual(result.get("message"), 'started successfully')
@ -112,7 +112,7 @@ class SynergyTests(unittest.TestCase):
time.sleep(0.5) time.sleep(0.5)
result = self.synergy.startManager(environ, start_response) result = self.synergy.startManager(environ, start_response)
result = json.loads(result, object_hook=objectHookHandler) result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(result.getStatus(), 'RUNNING') self.assertEqual(result.getStatus(), 'RUNNING')
self.assertEqual(result.get("message"), 'WARN: already started') self.assertEqual(result.get("message"), 'WARN: already started')
@ -124,17 +124,17 @@ class SynergyTests(unittest.TestCase):
result = self.synergy.startManager(environ, stop_response) result = self.synergy.startManager(environ, stop_response)
self.assertEqual(result, "manager NONE not found!") self.assertEqual(result[0], "manager NONE not found!")
environ = {'QUERY_STRING': 'manager=TimerManager'} environ = {'QUERY_STRING': 'manager=TimerManager'}
result = self.synergy.startManager(environ, stop_response) result = self.synergy.startManager(environ, stop_response)
result = json.loads(result, object_hook=objectHookHandler) result = json.loads(result[0], object_hook=objectHookHandler)
time.sleep(0.5) time.sleep(0.5)
result = self.synergy.stopManager(environ, stop_response) result = self.synergy.stopManager(environ, stop_response)
result = json.loads(result, object_hook=objectHookHandler) result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(result.getStatus(), 'ACTIVE') self.assertEqual(result.getStatus(), 'ACTIVE')

View File

@ -162,6 +162,15 @@ class TestHTTPCommand(base.TestCase):
def test_bypass_url(self, mock_argv, mock_httpcmd): def test_bypass_url(self, mock_argv, mock_httpcmd):
"""Filling bypass-url should set other params as defaults.""" """Filling bypass-url should set other params as defaults."""
args = [ args = [
'--os-username', 'username',
'--os-password', 'password',
'--os-user-domain-id', 'user_domain_id',
'--os-user-domain-name', 'user_domain_name',
'--os-project-name', 'project_name',
'--os-project-domain-id', 'project_domain_id',
'--os-project-domain-name', 'project_domain_name',
'--os-cacert', 'cacert',
'--os-auth-url', 'auth_url',
'--bypass-url', 'bypass_url', '--bypass-url', 'bypass_url',
'manager', 'list'] 'manager', 'list']
mock_argv.__getitem__.return_value = args mock_argv.__getitem__.return_value = args
@ -174,14 +183,14 @@ class TestHTTPCommand(base.TestCase):
command='list', command='list',
command_name='manager', command_name='manager',
debug=False, debug=False,
os_auth_url=None, os_auth_url='auth_url',
os_cacert=None, os_cacert='cacert',
os_password=None, os_password='password',
os_project_domain_id=None, os_project_domain_id='project_domain_id',
os_project_domain_name=None, os_project_domain_name='project_domain_name',
os_project_id=None, os_project_id=None,
os_project_name=None, os_project_name='project_name',
os_user_domain_id=None, os_user_domain_id='user_domain_id',
os_user_domain_name=None, os_user_domain_name='user_domain_name',
os_username=None) os_username='username')
mock_httpcmd.assert_called_once_with("bypass_url", ns) mock_httpcmd.assert_called_once_with("bypass_url", ns)