Author: dlee Date: Fri Jun 28 00:39:34 2013 New Revision: 3876 URL: http://svnview.digium.com/svn/testsuite?view=rev&rev=3876 Log: Authentication test; fixed continue test for authentication.
Added: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf (with props) asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf (with props) asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test (with props) asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml (with props) Modified: asterisk/team/dlee/ari-authn/lib/python/asterisk/ari.py asterisk/team/dlee/ari-authn/tests/rest_api/continue/configs/ast1/stasis_http.conf asterisk/team/dlee/ari-authn/tests/rest_api/tests.yaml Modified: asterisk/team/dlee/ari-authn/lib/python/asterisk/ari.py URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/lib/python/asterisk/ari.py?view=diff&rev=3876&r1=3875&r2=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/lib/python/asterisk/ari.py (original) +++ asterisk/team/dlee/ari-authn/lib/python/asterisk/ari.py Fri Jun 28 00:39:34 2013 @@ -38,18 +38,22 @@ self.host = '127.0.0.1' self.port = DEFAULT_PORT self.test_object = test_object + username = module_config.get('username') or 'testsuite' + password = module_config.get('password') or 'testsuite' + userpass = (username, password) #: ARI interface object - self.ari = ARI(self.host, self.port) + self.ari = ARI(self.host, port=self.port, userpass=userpass) #: Matchers for incoming events self.event_matchers = [ EventMatcher(self.ari, e, test_object) for e in module_config['events']] - apps = module_config['apps'] + apps = module_config.get('apps') or 'testsuite' if isinstance(apps, list): apps = ','.join(apps) #: Twisted protocol factory for ARI WebSockets self.factory = AriClientFactory(host=self.host, port=self.port, - apps=apps, on_event=self.on_event) + apps=apps, on_event=self.on_event, + userpass=userpass) def on_event(self, event): '''Handle incoming events from the WebSocket. @@ -63,7 +67,7 @@ class AriClientFactory(WebSocketClientFactory): '''Twisted protocol factory for building ARI WebSocket clients. ''' - def __init__(self, host, apps, on_event, port=DEFAULT_PORT, + def __init__(self, host, apps, on_event, userpass, port=DEFAULT_PORT, timeout_secs=60): '''Constructor @@ -74,7 +78,8 @@ :param timeout_secs: Maximum time to try to connect to Asterisk. ''' url = "ws://%s:%d/ws?%s" % \ - (host, port, urllib.urlencode({'app': apps})) + (host, port, + urllib.urlencode({'app': apps, 'api_key': '%s:%s' % userpass})) WebSocketClientFactory.__init__(self, url, protocols=["stasis"]) self.on_event = on_event self.timeout_secs = timeout_secs @@ -148,14 +153,14 @@ '''Bare bones object for an ARI interface. ''' - def __init__(self, host, port=DEFAULT_PORT): + def __init__(self, host, userpass, port=DEFAULT_PORT): '''Constructor. :param host: Hostname of Asterisk. :param port: Port of the Asterisk webserver. ''' self.base_url = "http://%s:%d/stasis" % (host, port) - + self.userpass = userpass def build_url(self, *args): '''Build a URL from the given path. @@ -177,9 +182,9 @@ :returns: requests.models.Response :throws: requests.exceptions.HTTPError ''' - url = self.build_url(*args, **kwargs) + url = self.build_url(*args) logger.info("GET %s %r" % (url, kwargs)) - return raise_on_err(requests.get(url, params=kwargs)) + return raise_on_err(requests.get(url, params=kwargs, auth=self.userpass)) def post(self, *args, **kwargs): '''Send a POST request to ARI. @@ -191,7 +196,7 @@ ''' url = self.build_url(*args, **kwargs) logger.info("POST %s %r" % (url, kwargs)) - return raise_on_err(requests.post(url, params=kwargs)) + return raise_on_err(requests.post(url, params=kwargs, auth=self.userpass)) def delete(self, *args, **kwargs): '''Send a DELETE request to ARI. @@ -203,7 +208,7 @@ ''' url = self.build_url(*args, **kwargs) logger.info("DELETE %s %r" % (url, kwargs)) - return raise_on_err(requests.delete(url, params=kwargs)) + return raise_on_err(requests.delete(url, params=kwargs, auth=self.userpass)) def raise_on_err(resp): Added: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf?view=auto&rev=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf (added) +++ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf Fri Jun 28 00:39:34 2013 @@ -1,0 +1,3 @@ +[general] +enabled=yes +bindaddr=127.0.0.1 Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/http.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf?view=auto&rev=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf (added) +++ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf Fri Jun 28 00:39:34 2013 @@ -1,0 +1,15 @@ +[general] +enabled = yes + +[user-ro] +read_only = yes +password = ro-pass + +[user-rw] +password = rw-pass + +[user-crypt] +; password = q +password_format = crypt +password = $6$Wwpq0WjHUpbzGlWH$Yl0iVJDUzMsG25g5b3gTftVvhMerlO7clXAJidxgmx26cLOOyjcdiSk8PkDJKFGA2Oj0ZN9J.5u3/wkbEwYCd/ + Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/configs/ast1/stasis_http.conf ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test?view=auto&rev=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test (added) +++ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test Fri Jun 28 00:39:34 2013 @@ -1,0 +1,117 @@ +#!/usr/bin/env python +''' +Copyright (C) 2013, Digium, Inc. +David M. Lee, II <d...@digium.com> + +This program is free software, distributed under the terms of +the GNU General Public License Version 2. +''' + +import logging +import requests +import sys + +from requests import codes +from twisted.internet import reactor + +sys.path.append("lib/python") +from asterisk.asterisk import Asterisk +from asterisk.TestCase import TestCase + +LOGGER = logging.getLogger(__name__) + +HOST='localhost' +PORT=8088 + +def build_url(*args): + return "http://%s:%d/%s" %\ + (HOST, PORT, '/'.join([str(arg) for arg in args])) + +class Scenario(object): + def __init__(self, userpass, method, expected_response): + self.userpass = userpass + self.method = method + self.expected_response = expected_response + + def __repr__(self): + return '{ userpass=%s, method=%s, expected=%d }' % ( + self.userpass, self.method.__name__, self.expected_response) + + def eval(self, str, test, resp): + if self.expected_response != resp.status_code: + LOGGER.error("Expected %d, got %d (%s). %s - %s" % ( + self.expected_response, resp.status_code, resp.text, self, str)) + test.passed = False + + def run(self, test): + LOGGER.debug("Running %s" % self) + if self.userpass is None: + # Test no authentication + resp = self.method(build_url('stasis', 'channels')) + self.eval('Unauthenticated', test, resp) + return + + # Test basic auth + resp = self.method(build_url('stasis', 'channels'), + auth=self.userpass) + self.eval('Basic', test, resp) + + # Test api_key auth + resp = self.method(build_url('stasis', 'channels'), + params={'api_key': "%s:%s" % self.userpass}) + self.eval('api_key', test, resp) + + +SCENARIOS=[ + # Unauthenticated requests + Scenario(None, requests.get, codes.unauthorized), + Scenario(None, requests.post, codes.unauthorized), + Scenario(('ro', 'not-a-password'), requests.get, codes.unauthorized), + Scenario(('notauser', 'password'), requests.get, codes.unauthorized), + + # Read only requests + Scenario(('ro', 'ro-pass'), requests.options, codes.no_content), + Scenario(('ro', 'ro-pass'), requests.get, codes.okay), + Scenario(('ro', 'ro-pass'), requests.post, codes.forbidden), + Scenario(('ro', 'ro-pass'), requests.put, codes.forbidden), + Scenario(('ro', 'ro-pass'), requests.patch, codes.forbidden), + Scenario(('ro', 'ro-pass'), requests.delete, codes.forbidden), + + # Read-write requests + Scenario(('rw', 'rw-pass'), requests.options, codes.no_content), + Scenario(('rw', 'rw-pass'), requests.get, codes.okay), + Scenario(('rw', 'rw-pass'), requests.post, codes.bad_request), + Scenario(('rw', 'rw-pass'), requests.put, codes.method_not_allowed), + Scenario(('rw', 'rw-pass'), requests.patch, codes.method_not_allowed), + Scenario(('rw', 'rw-pass'), requests.delete, codes.method_not_allowed), + + # crypted password + Scenario(('crypt', 'q'), requests.get, codes.okay), + Scenario(('crypt', 'Q'), requests.get, codes.unauthorized), +] + +class ARIAuthenticationTest(TestCase): + def __init__(self): + TestCase.__init__(self) + self.passed = True + self.create_asterisk() + + def run(self): + try: + for scenario in SCENARIOS: + scenario.run(self) + except: + logging.exception("Exception caught during test") + self.passed = False + finally: + self.stop_reactor() + +def main(): + test = ARIAuthenticationTest() + reactor.run() + if test.passed: + return 0 + return 1 + +if __name__ == "__main__": + sys.exit(main() or 0) Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test ------------------------------------------------------------------------------ svn:executable = * Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/run-test ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml?view=auto&rev=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml (added) +++ asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml Fri Jun 28 00:39:34 2013 @@ -1,0 +1,16 @@ +testinfo: + summary: Test authentication for the RESTful API + description: | + This test attempts several accesses to the RESTful API via all of its + authentication mechanisms, making sure we don't accidentally leave the + door open for everyone. + +properties: + minversion: '12.0.0' + dependencies: + - python : twisted + - python : starpy + - python : requests + - asterisk : res_stasis_http_channels + tags: + - ARI Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml ------------------------------------------------------------------------------ svn:keywords = Author Date Id Revision Propchange: asterisk/team/dlee/ari-authn/tests/rest_api/authentication/test-config.yaml ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: asterisk/team/dlee/ari-authn/tests/rest_api/continue/configs/ast1/stasis_http.conf URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/tests/rest_api/continue/configs/ast1/stasis_http.conf?view=diff&rev=3876&r1=3875&r2=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/tests/rest_api/continue/configs/ast1/stasis_http.conf (original) +++ asterisk/team/dlee/ari-authn/tests/rest_api/continue/configs/ast1/stasis_http.conf Fri Jun 28 00:39:34 2013 @@ -1,2 +1,5 @@ [general] enabled = yes + +[user-testsuite] +password = testsuite Modified: asterisk/team/dlee/ari-authn/tests/rest_api/tests.yaml URL: http://svnview.digium.com/svn/testsuite/asterisk/team/dlee/ari-authn/tests/rest_api/tests.yaml?view=diff&rev=3876&r1=3875&r2=3876 ============================================================================== --- asterisk/team/dlee/ari-authn/tests/rest_api/tests.yaml (original) +++ asterisk/team/dlee/ari-authn/tests/rest_api/tests.yaml Fri Jun 28 00:39:34 2013 @@ -1,3 +1,4 @@ # Enter tests here in the order they should be considered for execution: tests: - test: 'continue' + - test: 'authentication' -- _____________________________________________________________________ -- Bandwidth and Colocation Provided by http://www.api-digital.com -- svn-commits mailing list To UNSUBSCRIBE or update options visit: http://lists.digium.com/mailman/listinfo/svn-commits