Beispiel #1
0
    def test_get_admin_info_invalid_expires(self):
        controller = self.get_controller(expose_info=True,
                                         admin_key='secret-admin-key')
        utils._swift_info = {'foo': {'bar': 'baz'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = 1
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertTrue(isinstance(resp, HTTPException))
        self.assertEqual('401 Unauthorized', str(resp))

        expires = 'abc'
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertTrue(isinstance(resp, HTTPException))
        self.assertEqual('401 Unauthorized', str(resp))
Beispiel #2
0
    def test_get_admin_info_invalid_expires(self):
        controller = self.get_controller(expose_info=True,
                                         admin_key='secret-admin-key')
        utils._swift_info = {'foo': {'bar': 'baz'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = 1
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertIsInstance(resp, HTTPException)
        self.assertEqual('401 Unauthorized', str(resp))

        expires = 'abc'
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertIsInstance(resp, HTTPException)
        self.assertEqual('401 Unauthorized', str(resp))
Beispiel #3
0
    def test_head_admin_info(self):
        controller = self.get_controller(expose_info=True,
                                         admin_key='secret-admin-key')
        utils._swift_info = {'foo': {'bar': 'baz'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'HEAD'})
        resp = controller.GET(req)
        self.assertIsInstance(resp, HTTPException)
        self.assertEqual('200 OK', str(resp))

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('HEAD', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'HEAD'})
        resp = controller.GET(req)
        self.assertIsInstance(resp, HTTPException)
        self.assertEqual('200 OK', str(resp))
Beispiel #4
0
    def test_head_admin_info(self):
        controller = self.get_controller(expose_info=True,
                                         admin_key='secret-admin-key')
        utils._swift_info = {'foo': {'bar': 'baz'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'HEAD'})
        resp = controller.GET(req)
        self.assertTrue(isinstance(resp, HTTPException))
        self.assertEqual('200 OK', str(resp))

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('HEAD', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'HEAD'})
        resp = controller.GET(req)
        self.assertTrue(isinstance(resp, HTTPException))
        self.assertEqual('200 OK', str(resp))
Beispiel #5
0
    def test_admin_disallow_info(self):
        controller = self.get_controller(expose_info=True,
                                         disallowed_sections=['foo2'],
                                         admin_key='secret-admin-key')
        utils._swift_info = {'foo': {'bar': 'baz'},
                             'foo2': {'bar2': 'baz2'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertIsInstance(resp, HTTPException)
        self.assertEqual('200 OK', str(resp))
        info = json.loads(resp.body)
        self.assertNotIn('foo2', info)
        self.assertIn('admin', info)
        self.assertIn('disallowed_sections', info['admin'])
        self.assertIn('foo2', info['admin']['disallowed_sections'])
        self.assertIn('qux', info['admin'])
        self.assertIn('quux', info['admin']['qux'])
        self.assertEqual(info['admin']['qux']['quux'], 'corge')
Beispiel #6
0
    def _get_hmacs(self, env, expires, path, scoped_keys, hash_algorithm,
                   request_method=None, ip_range=None):
        """
        :param env: The WSGI environment for the request.
        :param expires: Unix timestamp as an int for when the URL
                        expires.
        :param path: The path which is used for hashing.
        :param scoped_keys: (key, scope) tuples like _get_keys() returns
        :param hash_algorithm: The hash algorithm to use.
        :param request_method: Optional override of the request in
                               the WSGI env. For example, if a HEAD
                               does not match, you may wish to
                               override with GET to still allow the
                               HEAD.
        :param ip_range: The ip range from which the resource is allowed
                         to be accessed
        :returns: a list of (hmac, scope) 2-tuples
        """
        if not request_method:
            request_method = env['REQUEST_METHOD']

        digest = functools.partial(hashlib.new, hash_algorithm)

        return [
            (get_hmac(
                request_method, path, expires, key,
                digest=digest, ip_range=ip_range
            ), scope)
            for (key, scope) in scoped_keys]
Beispiel #7
0
    def _get_hmacs(self,
                   env,
                   expires,
                   path,
                   scoped_keys,
                   hash_algorithm,
                   request_method=None):
        """
        :param env: The WSGI environment for the request.
        :param expires: Unix timestamp as an int for when the URL
                        expires.
        :param path: The path which is used for hashing.
        :param scoped_keys: (key, scope) tuples like _get_keys() returns
        :param hash_algorithm: The hash algorithm to use.
        :param request_method: Optional override of the request in
                               the WSGI env. For example, if a HEAD
                               does not match, you may wish to
                               override with GET to still allow the
                               HEAD.

        :returns: a list of (hmac, scope) 2-tuples
        """
        if not request_method:
            request_method = env['REQUEST_METHOD']

        digest = functools.partial(hashlib.new, hash_algorithm)
        return [(get_hmac(request_method, path, expires, key, digest), scope)
                for (key, scope) in scoped_keys]
Beispiel #8
0
    def test_admin_disallow_info(self):
        controller = self.get_controller(expose_info=True,
                                         disallowed_sections=['foo2'],
                                         admin_key='secret-admin-key')
        utils._swift_info = {'foo': {'bar': 'baz'},
                             'foo2': {'bar2': 'baz2'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('GET', '/info', expires, 'secret-admin-key')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertTrue(isinstance(resp, HTTPException))
        self.assertEqual('200 OK', str(resp))
        info = json.loads(resp.body)
        self.assertTrue('foo2' not in info)
        self.assertTrue('admin' in info)
        self.assertTrue('disallowed_sections' in info['admin'])
        self.assertTrue('foo2' in info['admin']['disallowed_sections'])
        self.assertTrue('qux' in info['admin'])
        self.assertTrue('quux' in info['admin']['qux'])
        self.assertEqual(info['admin']['qux']['quux'], 'corge')
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        """
        Handles requests to /info
        Should return a WSGI-style callable (such as swob.Response).

        :param req: swob.Request object
        """
        if not self.expose_info:
            return HTTPForbidden(request=req)

        admin_request = False
        sig = req.params.get('swiftinfo_sig', '')
        expires = req.params.get('swiftinfo_expires', '')

        if sig != '' or expires != '':
            admin_request = True
            if not self.admin_key:
                return HTTPForbidden(request=req)
            try:
                expires = int(expires)
            except ValueError:
                return HTTPUnauthorized(request=req)
            if expires < time():
                return HTTPUnauthorized(request=req)

            valid_sigs = []
            for method in self.allowed_hmac_methods[req.method]:
                valid_sigs.append(get_hmac(method,
                                           '/info',
                                           expires,
                                           self.admin_key))

            # While it's true that any() will short-circuit, this doesn't
            # affect the timing-attack resistance since the only way this will
            # short-circuit is when a valid signature is passed in.
            is_valid_hmac = any(streq_const_time(valid_sig, sig)
                                for valid_sig in valid_sigs)
            if not is_valid_hmac:
                return HTTPUnauthorized(request=req)

        headers = {}
        if 'Origin' in req.headers:
            headers['Access-Control-Allow-Origin'] = req.headers['Origin']
            headers['Access-Control-Expose-Headers'] = ', '.join(
                ['x-trans-id'])

        #json.dumps(dict)可以将字典形式的dict对象转换为json格式的对象
        info = json.dumps(get_swift_info(
            admin=admin_request, disallowed_sections=self.disallowed_sections))

        return HTTPOk(request=req,
                      headers=headers,
                      body=info,
                      content_type='application/json; charset=UTF-8')
Beispiel #10
0
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        """
        Handles requests to /info
        Should return a WSGI-style callable (such as swob.Response).

        :param req: swob.Request object
        """
        if not self.expose_info:
            return HTTPForbidden(request=req)

        admin_request = False
        sig = req.params.get('swiftinfo_sig', '')
        expires = req.params.get('swiftinfo_expires', '')

        if sig != '' or expires != '':
            admin_request = True
            if not self.admin_key:
                return HTTPForbidden(request=req)
            try:
                expires = int(expires)
            except ValueError:
                return HTTPUnauthorized(request=req)
            if expires < time():
                return HTTPUnauthorized(request=req)

            valid_sigs = []
            for method in self.allowed_hmac_methods[req.method]:
                valid_sigs.append(
                    get_hmac(method, '/info', expires, self.admin_key))

            # While it's true that any() will short-circuit, this doesn't
            # affect the timing-attack resistance since the only way this will
            # short-circuit is when a valid signature is passed in.
            is_valid_hmac = any(
                streq_const_time(valid_sig, sig) for valid_sig in valid_sigs)
            if not is_valid_hmac:
                return HTTPUnauthorized(request=req)

        headers = {}
        if 'Origin' in req.headers:
            headers['Access-Control-Allow-Origin'] = req.headers['Origin']
            headers['Access-Control-Expose-Headers'] = ', '.join(
                ['x-trans-id'])

        info = json.dumps(
            get_swift_info(admin=admin_request,
                           disallowed_sections=self.disallowed_sections))

        return HTTPOk(request=req,
                      headers=headers,
                      body=info,
                      content_type='application/json; charset=UTF-8')
Beispiel #11
0
 def _get_hmacs(self, env, expires, keys, request_method=None):
     """
     :param env: The WSGI environment for the request.
     :param expires: Unix timestamp as an int for when the URL
                     expires.
     :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of
                  the account.
     """
     if not request_method:
         request_method = env['REQUEST_METHOD']
     return [get_hmac(
         request_method, env['PATH_INFO'], expires, key) for key in keys]
Beispiel #12
0
    def test_disabled_admin_info(self):
        controller = self.get_controller(expose_info=True, admin_key='')
        utils._swift_info = {'foo': {'bar': 'baz'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('GET', '/info', expires, '')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertTrue(isinstance(resp, HTTPException))
        self.assertEqual('403 Forbidden', str(resp))
Beispiel #13
0
 def _get_hmacs(self, env, expires, keys, request_method=None):
     """
     :param env: The WSGI environment for the request.
     :param expires: Unix timestamp as an int for when the URL
                     expires.
     :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of
                  the account.
     """
     if not request_method:
         request_method = env['REQUEST_METHOD']
     return [
         get_hmac(request_method, env['PATH_INFO'], expires, key)
         for key in keys
     ]
Beispiel #14
0
    def test_disabled_admin_info(self):
        controller = self.get_controller(expose_info=True, admin_key='')
        utils._swift_info = {'foo': {'bar': 'baz'}}
        utils._swift_admin_info = {'qux': {'quux': 'corge'}}

        expires = int(time.time() + 86400)
        sig = utils.get_hmac('GET', '/info', expires, '')
        path = '/info?swiftinfo_sig={sig}&swiftinfo_expires={expires}'.format(
            sig=sig, expires=expires)
        req = Request.blank(
            path, environ={'REQUEST_METHOD': 'GET'})
        resp = controller.GET(req)
        self.assertIsInstance(resp, HTTPException)
        self.assertEqual('403 Forbidden', str(resp))
Beispiel #15
0
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        """
        Handles requests to /info
        Should return a WSGI-style callable (such as swob.Response).

        :param req: swob.Request object
        """
        if not self.expose_info:
            return HTTPForbidden(request=req)

        admin_request = False
        sig = req.params.get('swiftinfo_sig', '')
        expires = req.params.get('swiftinfo_expires', '')

        if sig != '' or expires != '':
            admin_request = True
            if not self.admin_key:
                return HTTPForbidden(request=req)
            try:
                expires = int(expires)
            except ValueError:
                return HTTPUnauthorized(request=req)
            if expires < time():
                return HTTPUnauthorized(request=req)

            valid_sigs = []
            for method in self.allowed_hmac_methods[req.method]:
                valid_sigs.append(
                    get_hmac(method, '/info', expires, self.admin_key))

            if sig not in valid_sigs:
                return HTTPUnauthorized(request=req)

        headers = {}
        if 'Origin' in req.headers:
            headers['Access-Control-Allow-Origin'] = req.headers['Origin']
            headers['Access-Control-Expose-Headers'] = ', '.join(
                ['x-trans-id'])

        info = json.dumps(
            get_swift_info(admin=admin_request,
                           disallowed_sections=self.disallowed_sections))

        return HTTPOk(request=req,
                      headers=headers,
                      body=info,
                      content_type='application/json; charset=UTF-8')
Beispiel #16
0
 def _get_hmacs(self, env, expires, keys, request_method=None):
     """
     :param env: The WSGI environment for the request.
     :param expires: Unix timestamp as an int for when the URL
                     expires.
     :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of
                  the account.
     :param request_method: Optional override of the request in
                            the WSGI env. For example, if a HEAD
                            does not match, you may wish to
                            override with GET to still allow the
                            HEAD.
     """
     if not request_method:
         request_method = env['REQUEST_METHOD']
     return [get_hmac(
         request_method, env['PATH_INFO'], expires, key) for key in keys]
Beispiel #17
0
 def _get_hmacs(self, env, expires, keys, request_method=None):
     """
     :param env: The WSGI environment for the request.
     :param expires: Unix timestamp as an int for when the URL
                     expires.
     :param keys: Key strings, from the X-Account-Meta-Temp-URL-Key[-2] of
                  the account.
     :param request_method: Optional override of the request in
                            the WSGI env. For example, if a HEAD
                            does not match, you may wish to
                            override with GET to still allow the
                            HEAD.
     """
     if not request_method:
         request_method = env['REQUEST_METHOD']
     return [get_hmac(
         request_method, env['PATH_INFO'], expires, key) for key in keys]
    def _get_hmacs(self, env, expires, scoped_keys, request_method=None):
        """
        :param env: The WSGI environment for the request.
        :param expires: Unix timestamp as an int for when the URL
                        expires.
        :param scoped_keys: (key, scope) tuples like _get_keys() returns
        :param request_method: Optional override of the request in
                               the WSGI env. For example, if a HEAD
                               does not match, you may wish to
                               override with GET to still allow the
                               HEAD.

        :returns: a list of (hmac, scope) 2-tuples
        """
        if not request_method:
            request_method = env["REQUEST_METHOD"]
        return [(get_hmac(request_method, env["PATH_INFO"], expires, key), scope) for (key, scope) in scoped_keys]
Beispiel #19
0
    def _get_hmacs(self, env, expires, scoped_keys, request_method=None):
        """
        :param env: The WSGI environment for the request.
        :param expires: Unix timestamp as an int for when the URL
                        expires.
        :param scoped_keys: (key, scope) tuples like _get_keys() returns
        :param request_method: Optional override of the request in
                               the WSGI env. For example, if a HEAD
                               does not match, you may wish to
                               override with GET to still allow the
                               HEAD.

        :returns: a list of (hmac, scope) 2-tuples
        """
        if not request_method:
            request_method = env['REQUEST_METHOD']
        return [(get_hmac(request_method, env['PATH_INFO'], expires,
                          key), scope) for (key, scope) in scoped_keys]
Beispiel #20
0
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        """
        Handles requests to /info
        Should return a WSGI-style callable (such as swob.Response).

        :param req: swob.Request object
        """
        if not self.expose_info:
            return HTTPForbidden(request=req)

        admin_request = False
        sig = req.params.get("swiftinfo_sig", "")
        expires = req.params.get("swiftinfo_expires", "")

        if sig != "" or expires != "":
            admin_request = True
            if not self.admin_key:
                return HTTPForbidden(request=req)
            try:
                expires = int(expires)
            except ValueError:
                return HTTPUnauthorized(request=req)
            if expires < time():
                return HTTPUnauthorized(request=req)

            valid_sigs = []
            for method in self.allowed_hmac_methods[req.method]:
                valid_sigs.append(get_hmac(method, "/info", expires, self.admin_key))

            if sig not in valid_sigs:
                return HTTPUnauthorized(request=req)

        headers = {}
        if "Origin" in req.headers:
            headers["Access-Control-Allow-Origin"] = req.headers["Origin"]
            headers["Access-Control-Expose-Headers"] = ", ".join(["x-trans-id"])

        info = json.dumps(get_swift_info(admin=admin_request, disallowed_sections=self.disallowed_sections))

        return HTTPOk(request=req, headers=headers, body=info, content_type="application/json; charset=UTF-8")