def assert_access_token_response(self, r, expected): self.assertEqual(r.status_code, 200) try: data = json.loads(r.content) except: self.fail("Unexpected response content") self.assertTrue('access_token' in data) access_token = data['access_token'] self.assertTrue('token_type' in data) token_type = data['token_type'] self.assertTrue('expires_in' in data) expires_in = data['expires_in'] try: token = Token.objects.get(code=access_token) self.assertEqual( token.expires_at, token.created_at + datetime.timedelta(seconds=expires_in)) self.assertEqual(token.token_type, token_type) self.assertEqual(token.grant_type, 'authorization_code') #self.assertEqual(token.user, expected.get('user')) self.assertEqual(normalize(uenc(token.redirect_uri)), normalize(uenc(expected.get('redirect_uri')))) self.assertEqual(normalize(uenc(token.scope)), normalize(uenc(expected.get('scope')))) self.assertEqual(token.state, expected.get('state')) except Token.DoesNotExist: self.fail("Invalid access_token")
def _build_response(self, oa2response): response = http.HttpResponse() response.status_code = oa2response.status response.content = oa2response.body for key, value in oa2response.headers.iteritems(): response[uenc(key)] = uenc(value) return response
def assert_access_token_response(self, r, expected): self.assertEqual(r.status_code, 200) try: data = json.loads(r.content) except: self.fail("Unexpected response content") self.assertTrue('access_token' in data) access_token = data['access_token'] self.assertTrue('token_type' in data) token_type = data['token_type'] self.assertTrue('expires_in' in data) expires_in = data['expires_in'] try: token = Token.objects.get(code=access_token) self.assertEqual(token.expires_at, token.created_at + datetime.timedelta(seconds=expires_in)) self.assertEqual(token.token_type, token_type) self.assertEqual(token.grant_type, 'authorization_code') #self.assertEqual(token.user, expected.get('user')) self.assertEqual(normalize(uenc(token.redirect_uri)), normalize(uenc(expected.get('redirect_uri')))) self.assertEqual(normalize(uenc(token.scope)), normalize(uenc(expected.get('scope')))) self.assertEqual(token.state, expected.get('state')) except Token.DoesNotExist: self.fail("Invalid access_token")
def grapher(request, graph_type, hostname): hostname = decrypt(uenc(hostname)) fname = uenc(os.path.join(settings.RRD_PREFIX, hostname)) if not os.path.isdir(fname): raise faults.ItemNotFound("No such instance") outfname = uenc(os.path.join(settings.GRAPH_PREFIX, hostname)) draw_func = available_graph_types[graph_type] response = HttpResponse(draw_func(fname, outfname), status=200, content_type="image/png") response.override_serialization = True return response
def _create_image_response(image): response = HttpResponse() for key in DETAIL_FIELDS: if key == 'properties': for k, v in image.get('properties', {}).items(): name = 'x-image-meta-property-' + k.replace('_', '-') response[name] = uenc(v) else: name = 'x-image-meta-' + key.replace('_', '-') response[name] = uenc(image.get(key, '')) return response
def grapher(request, graph_type, hostname): hostname = decrypt(uenc(hostname)) fname = uenc(os.path.join(settings.RRD_PREFIX, hostname)) if not os.path.isdir(fname): raise faults.ItemNotFound('No such instance') outfname = uenc(os.path.join(settings.GRAPH_PREFIX, hostname)) draw_func = available_graph_types[graph_type] response = HttpResponse(draw_func(fname, outfname), status=200, content_type="image/png") response.override_serialization = True return response
def grapher(request, graph_type, hostname): try: hostname = decrypt(uenc(hostname)) except (ValueError, TypeError): raise faults.BadRequest("Invalid encrypted virtual server name") fname = uenc(os.path.join(settings.RRD_PREFIX, hostname)) if not os.path.isdir(fname): raise faults.ItemNotFound('No such instance') outfname = uenc(os.path.join(settings.GRAPH_PREFIX, hostname)) draw_func = available_graph_types[graph_type] response = HttpResponse(draw_func(fname, outfname), status=200, content_type="image/png") response.override_serialization = True return response
def register(self, name, image_url, metadata): # Validate that metadata are allowed if "id" in metadata: raise ValueError("Passing an ID is not supported") store = metadata.pop("store", "pithos") if store != "pithos": raise ValueError("Invalid store '%s'. Only 'pithos' store is" "supported" % store) disk_format = metadata.setdefault("disk_format", settings.DEFAULT_DISK_FORMAT) if disk_format not in settings.ALLOWED_DISK_FORMATS: raise ValueError("Invalid disk format '%s'" % disk_format) container_format =\ metadata.setdefault("container_format", settings.DEFAULT_CONTAINER_FORMAT) if container_format not in settings.ALLOWED_CONTAINER_FORMATS: raise ValueError("Invalid container format '%s'" % container_format) # Validate that 'size' and 'checksum' are valid account, container, object = split_url(image_url) meta = self._get_meta(image_url) size = int(metadata.pop('size', meta['bytes'])) if size != meta['bytes']: raise ValueError("Invalid size") checksum = metadata.pop('checksum', meta['hash']) if checksum != meta['hash']: raise ValueError("Invalid checksum") # Fix permissions is_public = metadata.pop('is_public', False) if is_public: permissions = {'read': ['*']} else: permissions = {'read': [self.user]} # Extract the properties dictionary from metadata, and store each # property as a separeted, prefixed metadata properties = metadata.pop("properties", {}) meta = dict([(PROPERTY_PREFIX + k, v) for k, v in properties.items()]) # Add creation(register) timestamp as a metadata, to avoid extra # queries when retrieving the list of images. meta['created_at'] = time() # Update rest metadata meta.update(name=name, status='available', **metadata) # Do the actualy update in the Pithos backend self._update_meta(image_url, meta) self._update_permissions(image_url, permissions) logger.debug("User '%s' created image '%s'('%s')", self.user, image_url, uenc(name)) return self._get_image(image_url)
def _update_meta(self, image_url, meta, replace=False): """Update object's metadata.""" account, container, name = split_url(image_url) prefixed = [(PLANKTON_PREFIX + uenc(k), uenc(v)) for k, v in meta.items() if k in PLANKTON_META or k.startswith(PROPERTY_PREFIX)] prefixed = dict(prefixed) for k, v in prefixed.items(): if len(k) > 128: raise InvalidMetadata('Metadata keys should be less than %s ' 'characters' % MAX_META_KEY_LENGTH) if len(v) > 256: raise InvalidMetadata('Metadata values should be less than %s ' 'characters.' % MAX_META_VALUE_LENGTH) self.backend.update_object_meta(self.user, account, container, name, PLANKTON_DOMAIN, prefixed, replace) logger.debug("User '%s' updated image '%s', meta: '%s'", self.user, image_url, prefixed)
def add_image(request): """Add a new virtual machine image Described in: 3.6. Adding a New Virtual Machine Image Implementation notes: * The implementation is very inefficient as it loads the whole image in memory. Limitations: * x-image-meta-id is not supported. Will always return 409 Conflict. Extensions: * An x-image-meta-location header can be passed with a link to file, instead of uploading the data. """ params = _get_image_headers(request) log.debug('add_image %s', params) if not set(params.keys()).issubset(set(ADD_FIELDS)): raise faults.BadRequest("Invalid parameters") name = params.pop('name') if name is None: raise faults.BadRequest("Image 'name' parameter is required") elif len(uenc(name)) == 0: raise faults.BadRequest("Invalid image name") location = params.pop('location', None) if location is None: raise faults.BadRequest("'location' parameter is required") try: split_url(location) except InvalidLocation: raise faults.BadRequest("Invalid location '%s'" % location) validate_fields(params) if location: with image_backend(request.user_uniq) as backend: image = backend.register(name, location, params) else: #f = StringIO(request.body) #image = backend.put(name, f, params) return HttpResponse(status=501) # Not Implemented if not image: return HttpResponse('Registration failed', status=500) return _create_image_response(image)
def add_image(request): """Add a new virtual machine image Described in: 3.6. Adding a New Virtual Machine Image Implementation notes: * The implementation is very inefficient as it loads the whole image in memory. Limitations: * x-image-meta-id is not supported. Will always return 409 Conflict. Extensions: * An x-image-meta-location header can be passed with a link to file, instead of uploading the data. """ params = _get_image_headers(request) log.debug('add_image %s', params) if not set(params.keys()).issubset(set(ADD_FIELDS)): raise faults.BadRequest("Invalid parameters") name = params.pop('name', None) if name is None: raise faults.BadRequest("Image 'name' parameter is required") elif len(uenc(name)) == 0: raise faults.BadRequest("Invalid image name") location = params.pop('location', None) if location is None: raise faults.BadRequest("'location' parameter is required") try: split_url(location) except InvalidLocation: raise faults.BadRequest("Invalid location '%s'" % location) validate_fields(params) if location: with image_backend(request.user_uniq) as backend: image = backend.register(name, location, params) else: #f = StringIO(request.body) #image = backend.put(name, f, params) return HttpResponse(status=501) # Not Implemented if not image: return HttpResponse('Registration failed', status=500) return _create_image_response(image)
def astakos_user(user): """ Context manager to mock astakos response. usage: with astakos_user("*****@*****.**"): .... make api calls .... """ with patch("snf_django.lib.api.get_token") as get_token: get_token.return_value = "DummyToken" with patch('astakosclient.AstakosClient.get_user_info') as m: m.return_value = {"uuid": text.uenc(user, 'utf8')} with patch('astakosclient.AstakosClient.get_quotas') as m2: m2.return_value = { "system": { "pithos.diskspace": { "usage": 0, "limit": 1073741824, # 1GB "pending": 0 } } } issue_fun = "astakosclient.AstakosClient.issue_one_commission" with patch(issue_fun) as m3: serials = [] append = serials.append def get_serial(*args, **kwargs): global serial serial += 1 append(serial) return serial m3.side_effect = get_serial resolv_fun = \ 'astakosclient.AstakosClient.resolve_commissions' with patch(resolv_fun) as m4: m4.return_value = {'accepted': serials, 'rejected': [], 'failed': []} users_fun = 'astakosclient.AstakosClient.get_usernames' with patch(users_fun) as m5: def get_usernames(*args, **kwargs): uuids = args[-1] return dict((uuid, uuid) for uuid in uuids) m5.side_effect = get_usernames yield
def check_name_length(name, max_length, message): """Check if a string is within acceptable value length""" if len(uenc(name)) > max_length: raise faults.BadRequest(message)
def wrapper(request, *args, **kwargs): if request.method not in ["GET", "HEAD"]: return HttpResponseNotAllowed(["GET", "HEAD"]) try: access_token = request.GET.get("access_token") requested_resource = text.uenc(request.path.split(VIEW_PREFIX, 2)[-1]) astakos = AstakosClient(SERVICE_TOKEN, ASTAKOS_AUTH_URL, retry=2, use_pool=True, logger=logger) if access_token is not None: # authenticate using the short-term access token try: request.user = astakos.validate_token(access_token, requested_resource) except AstakosClientException: return HttpResponseRedirect(request.path) request.user_uniq = request.user["access"]["user"]["id"] _func = api_method(token_required=False, user_required=False)(func) response = _func(request, *args, **kwargs) if response.status_code == 404: raise Http404 elif response.status_code == 403: raise PermissionDenied return response client_id, client_secret = OAUTH2_CLIENT_CREDENTIALS # TODO: check if client credentials are not set authorization_code = request.GET.get("code") redirect_uri = unquote(request.build_absolute_uri(request.get_full_path())) if authorization_code is None: # request authorization code params = { "response_type": "code", "client_id": client_id, "redirect_uri": redirect_uri, "state": "", # TODO include state for security "scope": requested_resource, } return HttpResponseRedirect("%s?%s" % (join_urls(astakos.oauth2_url, "auth"), urlencode(params))) else: # request short-term access token parts = list(urlsplit(redirect_uri)) params = dict(parse_qsl(parts[3], keep_blank_values=True)) if "code" in params: # always True del params["code"] if "state" in params: del params["state"] parts[3] = urlencode(params) redirect_uri = urlunsplit(parts) data = astakos.get_token( "authorization_code", *OAUTH2_CLIENT_CREDENTIALS, redirect_uri=redirect_uri, scope=requested_resource, code=authorization_code ) params["access_token"] = data.get("access_token", "") parts[3] = urlencode(params) redirect_uri = urlunsplit(parts) return HttpResponseRedirect(redirect_uri) except AstakosClientException, err: logger.exception(err) raise PermissionDenied
def normalize(url): return urltools.normalize(uenc(url))
def urlencode(params): if hasattr(params, 'urlencode') and callable(getattr(params, 'urlencode')): return params.urlencode() for k in params: params[uenc(k)] = uenc(params.pop(k)) return urllib.urlencode(params)
def test_code_authorization(self): # missing response_type r = self.client.get(self.client.get_url(self.client.auth_url)) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # invalid response_type r = self.client.get(self.client.get_url(self.client.auth_url, response_type='invalid')) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # unsupported response_type r = self.client.get(self.client.get_url(self.client.auth_url, response_type='token')) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # missing client_id r = self.client.get(self.client.get_url(self.client.auth_url, response_type='code')) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # fake client r = self.client.authorize_code('client-fake') self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # mixed up credentials/client_id's self.client.set_credentials('client1', 'secret') r = self.client.authorize_code('client3') self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # invalid credentials self.client.set_credentials('client2', '') r = self.client.authorize_code('client2') self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # invalid redirect_uri: not absolute URI self.client.set_credentials() params = {'redirect_uri': urlparse.urlparse(self.client1_redirect_uri).path} r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # mismatching redirect uri self.client.set_credentials() params = {'redirect_uri': self.client1_redirect_uri[1:]} r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # valid request: untrusted client params = {'redirect_uri': self.client1_redirect_uri, 'scope': self.client1_redirect_uri, 'extra_param': 'γιουνικοντ'} self.client.set_credentials('client1', 'secret') r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 302) self.assertTrue('Location' in r) self.assertHost(r['Location'], "testserver:80") self.assertPath(r['Location'], reverse('login')) self.client.set_credentials('client1', 'secret') self.client.login(username="******", password="******") r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 200) r = self.client.authorize_code('client1', urlparams=params, extraparams={'reject': 0}) self.assertCount(AuthorizationCode, 1) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server.com") self.assertPath(redirect, "/handle_code") code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) #self.assertEqual(code.state, '') self.assertEqual(code.state, None) self.assertEqual(code.redirect_uri, self.client1_redirect_uri) params['state'] = 'csrfstate' params['scope'] = 'resource1' r = self.client.authorize_code('client1', urlparams=params) redirect = self.get_redirect_url(r) self.assertParamEqual(redirect, "state", 'csrfstate') self.assertCount(AuthorizationCode, 2) code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(code.redirect_uri, self.client1_redirect_uri) # valid request: trusted client params = {'redirect_uri': self.client3_redirect_uri, 'scope': self.client3_redirect_uri, 'extra_param': 'γιουνικοντ'} self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 3) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertNoParam(redirect, "state") self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, "/handle_code") code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, None) self.assertEqual(code.redirect_uri, self.client3_redirect_uri) # valid request: trusted client params['state'] = 'csrfstate' self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 4) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertParamEqual(redirect, "state", 'csrfstate') self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, "/handle_code") code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(code.redirect_uri, self.client3_redirect_uri) # redirect uri startswith the client's registered redirect url params['redirect_uri'] = '%sφωτογραφία.JPG' % self.client3_redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 400) # redirect uri descendant redirect_uri = '%s/' % self.client3_redirect_uri rest = settings.MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH - len(redirect_uri) redirect_uri = '%s%s' % (redirect_uri, 'a'*rest) params['redirect_uri'] = redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 5) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertParamEqual(redirect, "state", 'csrfstate') self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, urlparse.urlparse(redirect_uri).path) code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(code.redirect_uri, redirect_uri) # too long redirect uri params['redirect_uri'] = '%sa' % redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 400) # redirect uri descendant redirect_uri = '%s/φωτογραφία.JPG?α=γιουνικοντ' % self.client3_redirect_uri params['redirect_uri'] = redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 6) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertParamEqual(redirect, "state", 'csrfstate') self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, urlparse.urlparse(redirect_uri).path) code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(normalize(uenc(code.redirect_uri)), normalize(uenc(redirect_uri)))
def test_code_authorization(self): # missing response_type r = self.client.get(self.client.get_url(self.client.auth_url)) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # invalid response_type r = self.client.get( self.client.get_url(self.client.auth_url, response_type='invalid')) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # unsupported response_type r = self.client.get( self.client.get_url(self.client.auth_url, response_type='token')) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # missing client_id r = self.client.get( self.client.get_url(self.client.auth_url, response_type='code')) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # fake client r = self.client.authorize_code('client-fake') self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # mixed up credentials/client_id's self.client.set_credentials('client1', 'secret') r = self.client.authorize_code('client3') self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # invalid credentials self.client.set_credentials('client2', '') r = self.client.authorize_code('client2') self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # invalid redirect_uri: not absolute URI self.client.set_credentials() params = { 'redirect_uri': urlparse.urlparse(self.client1_redirect_uri).path } r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # mismatching redirect uri self.client.set_credentials() params = {'redirect_uri': self.client1_redirect_uri[1:]} r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 400) self.assertCount(AuthorizationCode, 0) # valid request: untrusted client params = { 'redirect_uri': self.client1_redirect_uri, 'scope': self.client1_redirect_uri, 'extra_param': 'γιουνικοντ' } self.client.set_credentials('client1', 'secret') r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 302) self.assertTrue('Location' in r) self.assertHost(r['Location'], "testserver:80") self.assertPath(r['Location'], reverse('login')) self.client.set_credentials('client1', 'secret') self.client.login(username="******", password="******") r = self.client.authorize_code('client1', urlparams=params) self.assertEqual(r.status_code, 200) r = self.client.authorize_code('client1', urlparams=params, extraparams={'reject': 0}) self.assertCount(AuthorizationCode, 1) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server.com") self.assertPath(redirect, "/handle_code") code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) #self.assertEqual(code.state, '') self.assertEqual(code.state, None) self.assertEqual(code.redirect_uri, self.client1_redirect_uri) params['state'] = 'csrfstate' params['scope'] = 'resource1' r = self.client.authorize_code('client1', urlparams=params) redirect = self.get_redirect_url(r) self.assertParamEqual(redirect, "state", 'csrfstate') self.assertCount(AuthorizationCode, 2) code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(code.redirect_uri, self.client1_redirect_uri) # valid request: trusted client params = { 'redirect_uri': self.client3_redirect_uri, 'scope': self.client3_redirect_uri, 'extra_param': 'γιουνικοντ' } self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 3) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertNoParam(redirect, "state") self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, "/handle_code") code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, None) self.assertEqual(code.redirect_uri, self.client3_redirect_uri) # valid request: trusted client params['state'] = 'csrfstate' self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 4) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertParamEqual(redirect, "state", 'csrfstate') self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, "/handle_code") code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(code.redirect_uri, self.client3_redirect_uri) # redirect uri startswith the client's registered redirect url params['redirect_uri'] = '%sφωτογραφία.JPG' % self.client3_redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 400) # redirect uri descendant redirect_uri = '%s/' % self.client3_redirect_uri rest = settings.MAXIMUM_ALLOWED_REDIRECT_URI_LENGTH - len(redirect_uri) redirect_uri = '%s%s' % (redirect_uri, 'a' * rest) params['redirect_uri'] = redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 5) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertParamEqual(redirect, "state", 'csrfstate') self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, urlparse.urlparse(redirect_uri).path) code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(code.redirect_uri, redirect_uri) # too long redirect uri params['redirect_uri'] = '%sa' % redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 400) # redirect uri descendant redirect_uri = '%s/φωτογραφία.JPG?α=γιουνικοντ' % self.client3_redirect_uri params['redirect_uri'] = redirect_uri self.client.set_credentials('client3', 'secret') r = self.client.authorize_code('client3', urlparams=params) self.assertEqual(r.status_code, 302) self.assertCount(AuthorizationCode, 6) # redirect is valid redirect = self.get_redirect_url(r) self.assertParam(redirect, "code") self.assertParamEqual(redirect, "state", 'csrfstate') self.assertNoParam(redirect, "extra_param") self.assertHost(redirect, "server3.com") self.assertPath(redirect, urlparse.urlparse(redirect_uri).path) code = AuthorizationCode.objects.get(code=redirect.params['code'][0]) self.assertEqual(code.state, 'csrfstate') self.assertEqual(normalize(uenc(code.redirect_uri)), normalize(uenc(redirect_uri)))
def wrapper(request, *args, **kwargs): if request.method not in ['GET', 'HEAD']: return HttpResponseNotAllowed(['GET', 'HEAD']) try: access_token = request.GET.get('access_token') requested_resource = text.uenc(request.path.split(VIEW_PREFIX, 2)[-1]) astakos = AstakosClient(SERVICE_TOKEN, ASTAKOS_AUTH_URL, retry=2, use_pool=True, logger=logger) if access_token is not None: # authenticate using the short-term access token try: request.user = astakos.validate_token( access_token, requested_resource) except AstakosClientException: return HttpResponseRedirect(request.path) request.user_uniq = request.user["access"]["user"]["id"] _func = api_method(token_required=False, user_required=False)(func) response = _func(request, *args, **kwargs) if response.status_code == 404: raise Http404 elif response.status_code == 403: raise PermissionDenied return response client_id, client_secret = OAUTH2_CLIENT_CREDENTIALS # TODO: check if client credentials are not set authorization_code = request.GET.get('code') redirect_uri = unquote(request.build_absolute_uri( request.get_full_path())) if authorization_code is None: # request authorization code params = {'response_type': 'code', 'client_id': client_id, 'redirect_uri': redirect_uri, 'state': '', # TODO include state for security 'scope': requested_resource} return HttpResponseRedirect('%s?%s' % (join_urls(astakos.oauth2_url, 'auth'), urlencode(params))) else: # request short-term access token parts = list(urlsplit(redirect_uri)) params = dict(parse_qsl(parts[3], keep_blank_values=True)) if 'code' in params: # always True del params['code'] if 'state' in params: del params['state'] parts[3] = urlencode(params) redirect_uri = urlunsplit(parts) data = astakos.get_token('authorization_code', *OAUTH2_CLIENT_CREDENTIALS, redirect_uri=redirect_uri, scope=requested_resource, code=authorization_code) params['access_token'] = data.get('access_token', '') parts[3] = urlencode(params) redirect_uri = urlunsplit(parts) return HttpResponseRedirect(redirect_uri) except AstakosClientException, err: logger.exception(err) raise PermissionDenied
def pprint_table(out, table, headers=None, output_format='pretty', separator=None, vertical=False, title=None): """Print a pretty, aligned string representation of table. Works by finding out the max width of each column and padding to data to this value. """ assert(isinstance(table, (list, tuple))), "Invalid table type" if headers: assert(isinstance(headers, (list, tuple))), "Invalid headers type" sep = separator if separator else " " def stringnify(obj): if isinstance(obj, (unicode, str)): return udec(obj) else: return str(obj) if headers: headers = map(stringnify, headers) table = [map(stringnify, row) for row in table] if output_format == "json": assert(headers is not None), "json output format requires headers" table = [dict(zip(headers, row)) for row in table] out.write(json.dumps(table, indent=4)) out.write("\n") elif output_format == "csv": cw = csv.writer(out) if headers: table.insert(0, headers) table = map(functools.partial(map, uenc), table) cw.writerows(table) elif output_format == "pretty": if vertical: assert(len(table) == 1) row = table[0] max_key = max(map(len, headers)) for row in table: for (k, v) in zip(headers, row): k = uenc(k.ljust(max_key)) v = uenc(v) out.write("%s: %s\n" % (k, v)) else: # Find out the max width of each column columns = [headers] + table if headers else table widths = [max(map(len, col)) for col in zip(*(columns))] t_length = sum(widths) + len(sep) * (len(widths) - 1) if title is not None: out.write(title.center(t_length) + "\n") if headers: # pretty print the headers line = sep.join(uenc(v.rjust(w))\ for v, w in zip(headers, widths)) out.write(line + "\n") out.write("-" * t_length + "\n") # print the rest table for row in table: line = sep.join(uenc(v.rjust(w)) for v, w in zip(row, widths)) out.write(line + "\n") else: raise ValueError("Unknown output format '%s'" % output_format)
def pprint_table(out, table, headers=None, output_format='pretty', separator=None, vertical=False, title=None): """Print a pretty, aligned string representation of table. Works by finding out the max width of each column and padding to data to this value. """ assert (isinstance(table, (list, tuple))), "Invalid table type" if headers: assert (isinstance(headers, (list, tuple))), "Invalid headers type" sep = separator if separator else " " def stringnify(obj): if isinstance(obj, (unicode, str)): return udec(obj) else: return str(obj) if headers: headers = map(stringnify, headers) table = [map(stringnify, row) for row in table] if output_format == "json": assert (headers is not None), "json output format requires headers" table = [dict(zip(headers, row)) for row in table] out.write(json.dumps(table, indent=4)) out.write("\n") elif output_format == "csv": cw = csv.writer(out) if headers: table.insert(0, headers) table = map(functools.partial(map, uenc), table) cw.writerows(table) elif output_format == "pretty": if vertical: assert (len(table) == 1) row = table[0] max_key = max(map(len, headers)) for row in table: for (k, v) in zip(headers, row): k = uenc(k.ljust(max_key)) v = uenc(v) out.write("%s: %s\n" % (k, v)) else: # Find out the max width of each column columns = [headers] + table if headers else table widths = [max(map(len, col)) for col in zip(*(columns))] t_length = sum(widths) + len(sep) * (len(widths) - 1) if title is not None: t_length = max(t_length, len(title)) out.write("-" * t_length + "\n") out.write(title.center(t_length) + "\n") out.write("-" * t_length + "\n") if headers: # pretty print the headers line = sep.join( uenc(v.rjust(w)) for v, w in zip(headers, widths)) out.write(line + "\n") out.write("-" * t_length + "\n") # print the rest table for row in table: line = sep.join(uenc(v.rjust(w)) for v, w in zip(row, widths)) out.write(line + "\n") else: raise ValueError("Unknown output format '%s'" % output_format)