Example #1
0
class TestPinningMiddleware(amo.tests.TestCase):
    def setUp(self):
        self.pin = APIPinningMiddleware()
        self.req = RequestFactory().get('/')
        self.req.API = True
        self.req.amo_user = mock.Mock()

    def test_pinned(self):
        self.req.amo_user.is_anonymous.return_value = False
        self.pin.process_request(self.req)
        ok_(this_thread_is_pinned())

    def test_not_pinned(self):
        self.req.amo_user.is_anonymous.return_value = True
        self.pin.process_request(self.req)
        ok_(not this_thread_is_pinned())
Example #2
0
class TestPinningMiddleware(amo.tests.TestCase):
    def setUp(self):
        self.pin = APIPinningMiddleware()
        self.req = RequestFactory().get("/")
        self.req.API = True
        self.req.amo_user = mock.Mock()

    def test_pinned(self):
        self.req.amo_user.is_anonymous.return_value = False
        self.pin.process_request(self.req)
        ok_(this_thread_is_pinned())

    def test_not_pinned(self):
        self.req.amo_user.is_anonymous.return_value = True
        self.pin.process_request(self.req)
        ok_(not this_thread_is_pinned())
Example #3
0
    def is_authenticated(self, request, **kwargs):
        if not settings.SITE_URL:
            raise ValueError('SITE_URL is not specified')

        auth_header_value = request.META.get('HTTP_AUTHORIZATION')
        if not auth_header_value:
            return self._error('headers')

        oauth_server, oauth_request = initialize_oauth_server_request(request)
        try:
            key = get_oauth_consumer_key_from_header(auth_header_value)
            if not key:
                return None

            consumer = Access.objects.get(key=key)
            oauth_server.verify_request(oauth_request, consumer, None)
            # Set the current user to be the consumer owner.
            request.user = consumer.user

        except Access.DoesNotExist:
            log.error(u'Cannot find APIAccess token with that key: %s' % key)
            request.user = AnonymousUser()
            return self._error('headers')

        except:
            log.error(u'Error getting OAuth headers', exc_info=True)
            request.user = AnonymousUser()
            return self._error('headers')

        ACLMiddleware().process_request(request)
        # We've just become authenticated, time to run the pinning middleware
        # again.
        #
        # TODO: I'd like to see the OAuth authentication move to middleware.
        request.API = True  # We can be pretty sure we are in the API.
        APIPinningMiddleware().process_request(request)

        # Do not allow access without agreeing to the dev agreement.
        if not request.amo_user.read_dev_agreement:
            log.info(u'Attempt to use API without dev agreement: %s' %
                     request.amo_user.pk)
            return self._error('terms')

        # But you cannot have one of these roles.
        denied_groups = set(['Admins'])
        roles = set(request.amo_user.groups.values_list('name', flat=True))
        if roles and roles.intersection(denied_groups):
            log.info(u'Attempt to use API with denied role, user: %s' %
                     request.amo_user.pk)
            return self._error('roles')

        return True
Example #4
0
    def is_authenticated(self, request, **kwargs):
        header = request.META.get('HTTP_AUTHORIZATION', '').split(None, 1)
        if header and header[0].lower() == 'mkt-shared-secret':
            auth = header[1]
        else:
            auth = request.GET.get('_user')
        if not auth:
            log.info('API request made without shared-secret auth token')
            return False
        try:
            email, hm, unique_id = str(auth).split(',')
            consumer_id = hashlib.sha1(email + settings.SECRET_KEY).hexdigest()
            matches = hmac.new(unique_id + settings.SECRET_KEY, consumer_id,
                               hashlib.sha512).hexdigest() == hm
            if matches:
                try:
                    request.amo_user = UserProfile.objects.select_related(
                        'user').get(email=email)
                    request.user = request.amo_user.user
                except UserProfile.DoesNotExist:
                    log.info('Auth token matches absent user (%s)' % email)
                    return False

                # Persist the user's language.
                if (getattr(request, 'amo_user', None)
                        and getattr(request, 'LANG', None)
                        and request.amo_user.lang != request.LANG):
                    request.amo_user.lang = request.LANG
                    request.amo_user.save()

                ACLMiddleware().process_request(request)
                request.API = True  # We can be pretty sure we are in the API.
                APIPinningMiddleware().process_request(request)
            else:
                log.info('Shared-secret auth token does not match')
                return False

            log.info('Successful SharedSecret with user: %s' % request.user.pk)
            return matches
        except Exception, e:
            log.info('Bad shared-secret auth data: %s (%s)', auth, e)
            return False
Example #5
0
 def setUp(self):
     self.pin = APIPinningMiddleware()
     self.req = RequestFactory().get('/')
     self.req.API = True
     self.key = 'api-pinning:42'
Example #6
0
class TestPinningMiddleware(amo.tests.TestCase):
    def setUp(self):
        self.pin = APIPinningMiddleware()
        self.req = RequestFactory().get('/')
        self.req.API = True
        self.key = 'api-pinning:42'

    def attach_user(self, anon=True):
        self.req.amo_user = mock.Mock(id=42, is_anonymous=lambda: anon)

    def test_pinned_request_method(self):
        self.attach_user(anon=False)

        for method in ['DELETE', 'PATCH', 'POST', 'PUT']:
            self.req.method = method
            self.pin.process_request(self.req)
            ok_(this_thread_is_pinned())

        for method in ['GET', 'HEAD', 'OPTIONS', 'POOP']:
            self.req.method = method
            self.pin.process_request(self.req)
            ok_(not this_thread_is_pinned())

    def test_pinned_cached(self):
        cache.set(self.key, 1, 5)
        self.attach_user(anon=False)
        self.pin.process_request(self.req)
        ok_(this_thread_is_pinned())
        cache.delete(self.key)

    def test_not_pinned(self):
        self.attach_user(anon=True)
        self.pin.process_request(self.req)
        ok_(not this_thread_is_pinned())

    def test_process_response_anon(self):
        self.attach_user(anon=True)
        self.req.method = 'POST'
        self.pin.process_response(self.req, HttpResponse())
        ok_(not cache.get(self.key))

    def test_process_response(self):
        self.attach_user(anon=False)
        for method in ['DELETE', 'PATCH', 'POST', 'PUT']:
            self.req.method = method
            self.pin.process_response(self.req, HttpResponse())
            ok_(cache.get(self.key))
            cache.delete(self.key)

        for method in ['GET', 'HEAD', 'OPTIONS', 'POOP']:
            self.req.method = method
            self.pin.process_response(self.req, HttpResponse())
            ok_(not cache.get(self.key))

    def pinned_header(self):
        self.attach_user(anon=True)
        return self.pin.process_response(self.req,
                                         HttpResponse())['API-Pinned']

    @mock.patch('mkt.api.middleware.this_thread_is_pinned')
    def test_pinned_header_true(self, mock_pinned):
        mock_pinned.return_value = True
        eq_(self.pinned_header(), 'True')

    @mock.patch('mkt.api.middleware.this_thread_is_pinned')
    def test_pinned_header_false(self, mock_pinned):
        mock_pinned.return_value = False
        eq_(self.pinned_header(), 'False')
Example #7
0
    def is_authenticated(self, request, **kwargs):
        if not settings.SITE_URL:
            raise ValueError('SITE_URL is not specified')

        auth_header_value = request.META.get('HTTP_AUTHORIZATION')
        if (not auth_header_value
                and 'oauth_token' not in request.META['QUERY_STRING']):
            self.user = AnonymousUser()
            log.error('No header')
            return self._error('headers')

        auth_header = {'Authorization': auth_header_value}
        method = getattr(request, 'signed_method', request.method)
        oauth = OAuthServer()
        if ('oauth_token' in request.META['QUERY_STRING']
                or 'oauth_token' in auth_header_value):
            # This is 3-legged OAuth.
            log.info('Trying 3 legged OAuth')
            try:
                valid, oauth_request = oauth.verify_request(
                    request.build_absolute_uri(),
                    method,
                    headers=auth_header,
                    require_resource_owner=True)
            except ValueError:
                log.error('ValueError on verifying_request', exc_info=True)
                return False
            if not valid:
                log.error(u'Cannot find APIAccess token with that key: %s' %
                          oauth.attempted_key)
                return self._error('headers')
            uid = Token.objects.filter(
                token_type=ACCESS_TOKEN,
                key=oauth_request.resource_owner_key).values_list('user_id',
                                                                  flat=True)[0]
            request.amo_user = UserProfile.objects.select_related('user').get(
                pk=uid)
            request.user = request.amo_user.user
        else:
            # This is 2-legged OAuth.
            log.info('Trying 2 legged OAuth')
            try:
                valid, oauth_request = oauth.verify_request(
                    request.build_absolute_uri(),
                    method,
                    headers=auth_header,
                    require_resource_owner=False)
            except ValueError:
                log.error('ValueError on verifying_request', exc_info=True)
                return False
            if not valid:
                log.error(u'Cannot find APIAccess token with that key: %s' %
                          oauth.attempted_key)
                return self._error('headers')
            uid = Access.objects.filter(
                key=oauth_request.client_key).values_list('user_id',
                                                          flat=True)[0]
            request.amo_user = UserProfile.objects.select_related('user').get(
                pk=uid)
            request.user = request.amo_user.user
        ACLMiddleware().process_request(request)
        # We've just become authenticated, time to run the pinning middleware
        # again.
        #
        # TODO: I'd like to see the OAuth authentication move to middleware.
        request.API = True  # We can be pretty sure we are in the API.
        APIPinningMiddleware().process_request(request)

        # Persist the user's language.
        if (getattr(request, 'amo_user', None)
                and getattr(request, 'LANG', None)
                and request.amo_user.lang != request.LANG):
            request.amo_user.lang = request.LANG
            request.amo_user.save()

        # But you cannot have one of these roles.
        denied_groups = set(['Admins'])
        roles = set(request.amo_user.groups.values_list('name', flat=True))
        if roles and roles.intersection(denied_groups):
            log.info(u'Attempt to use API with denied role, user: %s' %
                     request.amo_user.pk)
            return self._error('roles')

        log.info('Successful OAuth with user: %s' % request.user)
        return True
Example #8
0
 def setUp(self):
     self.pin = APIPinningMiddleware()
     self.req = RequestFactory().get('/')
     self.req.API = True
     self.req.amo_user = mock.Mock()
Example #9
0
 def setUp(self):
     self.pin = APIPinningMiddleware()
     self.req = RequestFactory().get('/')
     self.req.API = True
     self.req.amo_user = mock.Mock()
Example #10
0
 def setUp(self):
     self.pin = APIPinningMiddleware()
     self.req = RequestFactory().get("/")
     self.req.API = True
     self.key = "api-pinning:42"
Example #11
0
class TestPinningMiddleware(amo.tests.TestCase):
    def setUp(self):
        self.pin = APIPinningMiddleware()
        self.req = RequestFactory().get("/")
        self.req.API = True
        self.key = "api-pinning:42"

    def attach_user(self, anon=True):
        self.req.amo_user = mock.Mock(id=42, is_anonymous=lambda: anon)

    def test_pinned_request_method(self):
        self.attach_user(anon=False)

        for method in ["DELETE", "PATCH", "POST", "PUT"]:
            self.req.method = method
            self.pin.process_request(self.req)
            ok_(this_thread_is_pinned())

        for method in ["GET", "HEAD", "OPTIONS", "POOP"]:
            self.req.method = method
            self.pin.process_request(self.req)
            ok_(not this_thread_is_pinned())

    def test_pinned_cached(self):
        cache.set(self.key, 1, 5)
        self.attach_user(anon=False)
        self.pin.process_request(self.req)
        ok_(this_thread_is_pinned())
        cache.delete(self.key)

    def test_not_pinned(self):
        self.attach_user(anon=True)
        self.pin.process_request(self.req)
        ok_(not this_thread_is_pinned())

    def test_process_response_anon(self):
        self.attach_user(anon=True)
        self.req.method = "POST"
        self.pin.process_response(self.req, HttpResponse())
        ok_(not cache.get(self.key))

    def test_process_response(self):
        self.attach_user(anon=False)
        for method in ["DELETE", "PATCH", "POST", "PUT"]:
            self.req.method = method
            self.pin.process_response(self.req, HttpResponse())
            ok_(cache.get(self.key))
            cache.delete(self.key)

        for method in ["GET", "HEAD", "OPTIONS", "POOP"]:
            self.req.method = method
            self.pin.process_response(self.req, HttpResponse())
            ok_(not cache.get(self.key))

    def pinned_header(self):
        self.attach_user(anon=True)
        return self.pin.process_response(self.req, HttpResponse())["API-Pinned"]

    @mock.patch("mkt.api.middleware.this_thread_is_pinned")
    def test_pinned_header_true(self, mock_pinned):
        mock_pinned.return_value = True
        eq_(self.pinned_header(), "True")

    @mock.patch("mkt.api.middleware.this_thread_is_pinned")
    def test_pinned_header_false(self, mock_pinned):
        mock_pinned.return_value = False
        eq_(self.pinned_header(), "False")
Example #12
0
class TestPinningMiddleware(amo.tests.TestCase):

    def setUp(self):
        self.pin = APIPinningMiddleware()
        self.req = RequestFactory().get('/')
        self.req.API = True
        self.key = 'api-pinning:42'

    def attach_user(self, anon=True):
        self.req.user = mock.Mock(id=42, is_anonymous=lambda: anon)

    def test_pinned_request_method(self):
        self.attach_user(anon=False)

        for method in ['DELETE', 'PATCH', 'POST', 'PUT']:
            self.req.method = method
            self.pin.process_request(self.req)
            ok_(this_thread_is_pinned())

        for method in ['GET', 'HEAD', 'OPTIONS', 'POOP']:
            self.req.method = method
            self.pin.process_request(self.req)
            ok_(not this_thread_is_pinned())

    def test_pinned_cached(self):
        cache.set(self.key, 1, 5)
        self.attach_user(anon=False)
        self.pin.process_request(self.req)
        ok_(this_thread_is_pinned())
        cache.delete(self.key)

    def test_not_pinned(self):
        self.attach_user(anon=True)
        self.pin.process_request(self.req)
        ok_(not this_thread_is_pinned())

    def test_process_response_anon(self):
        self.attach_user(anon=True)
        self.req.method = 'POST'
        self.pin.process_response(self.req, HttpResponse())
        ok_(not cache.get(self.key))

    def test_process_response(self):
        self.attach_user(anon=False)
        for method in ['DELETE', 'PATCH', 'POST', 'PUT']:
            self.req.method = method
            self.pin.process_response(self.req, HttpResponse())
            ok_(cache.get(self.key))
            cache.delete(self.key)

        for method in ['GET', 'HEAD', 'OPTIONS', 'POOP']:
            self.req.method = method
            self.pin.process_response(self.req, HttpResponse())
            ok_(not cache.get(self.key))

    def pinned_header(self):
        self.attach_user(anon=True)
        return self.pin.process_response(self.req, HttpResponse())['API-Pinned']

    @mock.patch('mkt.api.middleware.this_thread_is_pinned')
    def test_pinned_header_true(self, mock_pinned):
        mock_pinned.return_value = True
        eq_(self.pinned_header(), 'True')

    @mock.patch('mkt.api.middleware.this_thread_is_pinned')
    def test_pinned_header_false(self, mock_pinned):
        mock_pinned.return_value = False
        eq_(self.pinned_header(), 'False')