def test_http_services_session_file_save_load(self): save_session_data = self.create_and_save_session_data( 'test_http_services_session_file_save_load') load_session_data = CO.HttpServices() load_session_data.load_httpd_session() self.assertSessionDataEqual(save_session_data, 'saved', load_session_data, 'loaded')
def redirect_client_start(): """ This function implements the C{start()} portion of the Dropbox OAuth redirect flow. It passes the necessary parameters to dropbox C{start()} and returns the generated URL to the caller. """ logger.debug('starting Dropbox authorisation (redirect mode)') logger.debug( 'creating DropboxOAuth2Flow client for app "{app_name}" with key "{key}" and secret "{secret}"' .format(app_name=CO.AppData.APP_NAME, key=CO.AppData.APP_KEY, secret=CO.AppData.APP_SECRET)) httpd_services = CO.HttpServices() # EXERCISE: # - create an OAuth redirect object (the class is DropboxOAuth2Flow) # hint: get the app key and secret from CO.AppData # hint: get the finish URL from the httpd_services object # hint: the CSRF session variable is httpd_services.httpd_session # hint: the CSRF session key is httpd_services.OAUTH_CSRF_SESSION_KEY # - start the dropbox OAuth redirect workflow by calling start() # - save the returned redirect URL in authorise_url # TODO ==> INSERT CODE HERE <== logger.info( 'Dropbox authorisation start successful, authorisation URL="{url}"'. format(url=authorise_url)) logger.debug('CSRF token="{token}", HTTP session is "{session}"'.format( token=httpd_services.httpd_session[ httpd_services.OAUTH_CSRF_SESSION_KEY], session=str(httpd_services.httpd_session))) httpd_services.save_httpd_session() return DropboxStatus(301, redirect_url=authorise_url)
def do_GET(self): """Process an HTTP GET""" logger.info('do_GET: request is "%s"' % (self.path,)) http_services = CO.HttpServices() http_services.save_latest_url(self.path) try: parsed_url = urlparse(self.path) # this is a named tuple logger.debug('do_GET: parsed URL is %s' % (str(parsed_url),)) # this code turns the query into a dict of the form 'query_param' : 'query_value' query_dict = { query_param[0]: query_param[1][0] for query_param in parse_qs(parsed_url.query).items() } logger.debug('do_GET: query dict is %s' % (str(query_dict),)) if parsed_url.path.endswith(http_services.OAUTH_FINISH_PAGE): logger.debug('do_GET.finish-handler: path is "{path}", query is "{query}"'.format( path=self.path, query=query_dict)) dropbox_status = DW.httpd_handle_finish_and_save(self.path, query_dict) logger.info('do_GET.start-handler: dropbox finish() successfully handled') self.handle_dropbox_status(dropbox_status) elif parsed_url.path.endswith('favicon.ico'): logger.info('do_GET: /favicon.ico (not found)') self.send_error(404, 'Not Found') elif parsed_url.path.endswith('home'): logger.info('do_GET: /home (send home page)') self.send_http_header() self.send_html_content(self.home_page_body()) elif parsed_url.path.startswith('/doc/'): logger.info('do_GET: /doc (script documentation), path is %s') if (parsed_url.path == '/doc/'): logger.debug('do_GET: invalid documentation URL %s, redirecting', parsed_url.path) self.send_http_header('/home') else: module_path = parsed_url.path.split('/') module_file = module_path[2] file_type = module_file.split('.')[1] logger.debug('do_GET: module path is %s, module file is %s', str(module_path), module_file) self.send_http_header() # with file('{demodir}/doc/{module_file}'.format( # demodir=CO.DEMO_DIRECTORY, module_file=module_file)) as f: with file(os.path.join(CO.DOC_DIRECTORY, module_file)) as f: file_content = f.read() if file_type == 'txt': file_content = '<html><head><title>BCS SPA 2014 OAuth Demo</title><body><pre>%s</pre></body></html> ' % (file_content) self.wfile.write(file_content) else: logger.info('do_GET: unsupported request {request}'.format(request=self.path)) self.send_error(404, 'unsupported request {request}'.format(request=self.path)) except IOError: logger.info('do_GET: internal server error (request={request})'.format(request=self.path)) self.send_error(500, 'internal server error (request={request})'.format(request=self.path))
def setUp(self): """unit test fixture - setup""" CO.logger.setLevel(logging.CRITICAL) self.delete_oauth_files() TestCommonOauth.http_services = CO.HttpServices()
# @see http://docs.python.org/2/library/unittest.html # use @unittest.skip("not yet written") to skip a test import logging from mock import Mock import types import urllib import unittest from common_test import * # module under test import common_oauth as CO http_services = CO.HttpServices() class TestCommonOauth(CustomAssertions): def delete_oauth_files(self): for datafile in [ CO.AccessData.ACCESS_TOKEN_FILE, http_services.HTTPD_SESSION_FILE, http_services.HTTPD_SESSION_FILE_EXPIRED, http_services.HTTPD_LATEST_URL_FILE ]: delete_file(datafile) def create_and_save_access_data(self, test_name): save_access_data = CO.AccessData('TEST %s' % (test_name)) save_access_data.access_token = 'TOKEN %s' % (test_name)
def httpd_handle_finish_and_save(request_path, query_dict): """ This httpd handler implements the finish() portion of the Dropbox OAuth server (redirect) flow. It calls Dropbox C{finish()} to finish the Oauth workflow. It then saves the access token returned by C{finish()} and creates some sample files in the Dropbox app folder. """ httpd_services = CO.HttpServices() httpd_services.load_httpd_session() logger.debug( 'finishing Dropbox authorisation (redirect mode), URL query="%s"' % (str(query_dict), )) # EXERCISE: # - create an OAuth no-redirect object (as you did for redirect_client_start) # hint: get the app key and secret from CO.AppData # SPA14_OAUTH_START logger.debug( 'creating DropboxOAuth2Flow client for app "{app_name}" with key "{key}" and secret "{secret}"' .format(app_name=CO.AppData.APP_NAME, key=CO.AppData.APP_KEY, secret=CO.AppData.APP_SECRET)) redirect_client = dropbox.client.DropboxOAuth2Flow( CO.AppData.APP_KEY, CO.AppData.APP_SECRET, httpd_services.OAUTH_FINISH_URL, httpd_services.httpd_session, httpd_services.OAUTH_CSRF_SESSION_KEY) logger.debug( 'created DropboxOAuth2Flow client, running finish() to generate Dropbox access token' ) # SPA14_OAUTH_FINISH try: # EXERCISE: # - finish the dropbox OAuth no-redirect workflow by calling finish() # (pass it the URL query dict{} that was used in the redirect to the HTTP server) # - store the returned access token and user id in a CO.AccessData() object # - (this demo ignores the "URL state" variable) # SPA14_OAUTH_START access_data = CO.AccessData( 'created using Python dropbox.client.DropboxOAuth2Flow()') access_data.access_token, access_data.user_id, url_state = redirect_client.finish( query_dict) # SPA14_OAUTH_FINISH httpd_services.expire_httpd_session() logger.info( 'Dropbox authorisation finish successful, access token="{access_token}", user id="{user_id}"' .format(access_token=access_data.access_token, user_id=access_data.user_id)) access_data.save() db_create_sample_files() return DropboxStatus( 200, '<h1>Congratulations!</h1><p>The Dropbox access token was created successfully.<p>You may return to your client.' ) except dropbox.client.DropboxOAuth2Flow.BadRequestException as e: logger.error('do_GET.finish-handler: 400 bad request "%s"' % (request_path, )) httpd_services.expire_httpd_session() return DropboxStatus(400, 'Bad Request') except dropbox.client.DropboxOAuth2Flow.BadStateException as e: logger.error('do_GET.finish-handler: bad state, request="%s"' % (request_path, )) httpd_services.expire_httpd_session() return DropboxStatus(301, redirect_url=OAUTH_START_URL) except dropbox.client.DropboxOAuth2Flow.CsrfException as e: logger.error( 'do_GET.finish-handler: 403 missing CSRF token, request="%s"' % (request_path, )) httpd_services.expire_httpd_session() return DropboxStatus(403, 'Forbidden') except dropbox.client.DropboxOAuth2Flow.NotApprovedException as e: logger.error( 'do_GET.finish-handler: user did not approve, request="%s"' % (request_path, )) httpd_services.expire_httpd_session() return DropboxStatus(301, redirect_url=OAUTH_START_URL) except dropbox.client.DropboxOAuth2Flow.ProviderException as e: logger.error( 'do_GET.finish-handler: 403 Dropbox authorisation error %s, request="%s"' % (e, path)) httpd_services.expire_httpd_session() return DropboxStatus(403, 'Forbidden')