Beispiel #1
0
    def is_authenticated(self, request, **kwargs):
        oauth_server, oauth_request = initialize_oauth_server_request(request)

        try:
            auth_header_value = request.META.get('HTTP_AUTHORIZATION')
            key = get_oauth_consumer_key_from_header(auth_header_value)

            if not key:
                return None

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

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

        # Check that consumer is valid.
        if consumer.status != 'accepted':
            log.info(u'Consumer not accepted: %s' % consumer)
            return False

        ACLMiddleware().process_request(request)
        # Do not allow any user with any roles to use the API.
        # Just in case.
        if request.amo_user.groups.all():
            log.info(u'Attempt to use API with roles, user: %s' %
                     request.amo_user.pk)
            return False

        return True
Beispiel #2
0
    def is_authenticated(self, request, **kwargs):
        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.user = User.objects.get(email=email)
                except User.DoesNotExist:
                    log.info('Auth token matches absent user (%s)' % email)
                    return False

                ACLMiddleware().process_request(request)
            else:
                log.info('Shared-secret auth token does not match')

            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
Beispiel #3
0
 def test_throttled_user_setting_disabled(self):
     with self.settings(API_THROTTLE=False):
         ACLMiddleware().process_request(self.request)
         with self.mocked_sbt as sbt:
             sbt.return_value = True
             self.no_throttle_expected()
             eq_(self.throttle.should_be_throttled.call_count, 0)
Beispiel #4
0
 def test_unthrottled_user(self):
     self.grant_permission(self.user.get_profile(), 'Apps:APIUnthrottled')
     ACLMiddleware().process_request(self.request)
     with self.mocked_sbt as sbt:
         sbt.return_value = True
         self.no_throttle_expected()
         eq_(self.throttle.should_be_throttled.call_count, 0)
Beispiel #5
0
def _login(request, template=None, data=None, dont_redirect=False):
    data = data or {}
    data['webapp'] = True
    # In case we need it later.  See below.
    get_copy = request.GET.copy()

    if 'to' in request.GET:
        request = _clean_next_url(request)

    if request.user.is_authenticated():
        return http.HttpResponseRedirect(
            request.GET.get('to', settings.LOGIN_REDIRECT_URL))

    user = None
    login_status = None
    r = auth_login(request, template_name=template, redirect_field_name='to',
                   extra_context=data)

    if isinstance(r, http.HttpResponseRedirect):
        # Django's auth.views.login has security checks to prevent someone from
        # redirecting to another domain.  Since we want to allow this in
        # certain cases, we have to make a new response object here to replace
        # the above.

        if 'domain' in request.GET:
            request.GET = get_copy
            request = _clean_next_url(request)
            r = http.HttpResponseRedirect(request.GET['to'])

        # Succsesful log in according to django.  Now we do our checks.  I do
        # the checks here instead of the form's clean() because I want to use
        # the messages framework and it's not available in the request there.
        if user.deleted:
            logout(request)
            log.warning(u'Attempt to log in with deleted account (%s)' % user)
            messages.error(request, _('Wrong email address or password!'))
            user.log_login_attempt(False)
            log_cef('Authentication Failure', 5, request,
                    username=request.user, signature='AUTHFAIL',
                    msg='Account is deactivated')
            return render(request, template, data)

        login_status = True

        if dont_redirect:
            # We're recalling the middleware to re-initialize amo_user
            ACLMiddleware().process_request(request)
            r = render(request, template, data)

    if login_status is not None:
        user.log_login_attempt(login_status)
        log_cef('Authentication Failure', 5, request,
                username=request.POST['username'],
                signature='AUTHFAIL',
                msg='The password was incorrect')

    return r
 def request(self, verb, qs=None, **data):
     if not qs:
         qs = ''
     request = getattr(RequestFactory(), verb.lower())
     request = request('/?' + qs, content_type='application/json',
                       data=json.dumps(data) if data else '')
     request.user = self.user
     ACLMiddleware().process_request(request)
     return Request(request)
Beispiel #7
0
 def region_for(self, region):
     req = self.factory.get('/', ({} if region is None else
                                  {'region': region}))
     req.API = True
     req.LANG = ''
     req.user = self.user
     req.amo_user = self.profile
     RegionMiddleware().process_request(req)
     ACLMiddleware().process_request(req)
     return self.resource.get_region_from_request(req)
Beispiel #8
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
Beispiel #9
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]
        elif waffle.switch_is_active('shared-secret-in-url'):
            auth = request.GET.get('_user')
        else:
            auth = ''
        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)
            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
Beispiel #10
0
    def is_authenticated(self, request):
        if request.user and request.user.is_authenticated():
            return True

        # To avoid patching django-piston, use a partial to cope with
        # piston not sending in request when called later.
        self.challenge = partial(self._challenge, request=request)

        # Authenticate the user using Piston, rv will be True or False
        # depending upon how it went.
        rv = super(AMOOAuthAuthentication, self).is_authenticated(request)

        if rv and request.user:
            # The user is there, but we need to alter the user to be
            # a user specified in the request. Specifically chose this
            # term to avoid conflict with user, which could be used elsewhere.
            if self.two_legged and 'authenticate_as' in request.REQUEST:
                pk = request.REQUEST.get('authenticate_as')
                try:
                    profile = UserProfile.objects.get(pk=pk)
                except UserProfile.DoesNotExist:
                    log.warning('Cannot find user: %s' % pk)
                    return False

                if profile.deleted or profile.confirmationcode:
                    log.warning(
                        'Tried to use deleted or unconfirmed user: %s' % pk)
                    return False

                log.info('Authenticating as: %s' % pk)
                request.user = profile.user

            # If that worked and request.user got set, setup AMO specific bits.
            ACLMiddleware().process_request(request)
        else:
            # The piston middleware could find a consumer, but no
            # user on that consumer. If it does it returns True, but
            # request.user is None, which then blows up other things.
            request.user = AnonymousUser()
            return False

        return rv
 def request(self,
             verb,
             qs=None,
             content_type='application/json',
             encoder=json.dumps,
             **data):
     if not qs:
         qs = ''
     request = getattr(RequestFactory(), verb.lower())
     request = request('/?' + qs,
                       content_type=content_type,
                       data=encoder(data) if data else '')
     request.user = self.user
     ACLMiddleware().process_request(request)
     return Request(
         request,
         parsers=[
             parser_cls()
             for parser_cls in api_settings.DEFAULT_PARSER_CLASSES
         ])
Beispiel #12
0
    def is_authenticated(self, request, **kwargs):
        oauth_server, oauth_request = initialize_oauth_server_request(request)

        try:
            auth_header_value = request.META.get('HTTP_AUTHORIZATION')
            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)

        # 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')

        # Do not allow any user with any roles to use the API.
        # Just in case.
        if request.amo_user.groups.all():
            log.info(u'Attempt to use API with roles, user: %s'
                     % request.amo_user.pk)
            return self._error('roles')

        return True
Beispiel #13
0
 def test_throttled_user_setting_enabled(self):
     with self.settings(API_THROTTLE=True):
         ACLMiddleware().process_request(self.request)
         with self.mocked_sbt as sbt:
             sbt.return_value = True
             self.throttle_expected()
Beispiel #14
0
 def request(self, verb, anon=False):
     request = getattr(RequestFactory(), verb.lower())('/')
     request.user = AnonymousUser() if anon else self.user
     ACLMiddleware().process_request(request)
     return request
Beispiel #15
0
 def setup_request(self, request, grant_permission=False):
     request.user = self.user
     if grant_permission:
         self.grant_permission(self.user.get_profile(), 'Apps:Publisher')
     ACLMiddleware().process_request(request)
Beispiel #16
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
Beispiel #17
0
def _login(request, template=None, data=None, dont_redirect=False):
    data = data or {}
    # In case we need it later.  See below.
    get_copy = request.GET.copy()

    if 'to' in request.GET:
        request = _clean_next_url(request)

    if request.user.is_authenticated():
        return http.HttpResponseRedirect(
            request.GET.get('to', settings.LOGIN_REDIRECT_URL))

    limited = getattr(request, 'limited', 'recaptcha_shown' in request.POST)
    user = None
    login_status = None
    if 'username' in request.POST:
        try:
            # We are doing all this before we try and validate the form.
            user = UserProfile.objects.get(email=request.POST['username'])
            limited = (
                (user.failed_login_attempts >= settings.LOGIN_RATELIMIT_USER)
                or limited)
            login_status = False
        except UserProfile.DoesNotExist:
            log_cef('Authentication Failure',
                    5,
                    request,
                    username=request.POST['username'],
                    signature='AUTHFAIL',
                    msg='The username was invalid')
            pass
    partial_form = partial(forms.AuthenticationForm, use_recaptcha=limited)
    r = auth.views.login(request,
                         template_name=template,
                         redirect_field_name='to',
                         authentication_form=partial_form,
                         extra_context=data)

    if isinstance(r, http.HttpResponseRedirect):
        # Django's auth.views.login has security checks to prevent someone from
        # redirecting to another domain.  Since we want to allow this in
        # certain cases, we have to make a new response object here to replace
        # the above.

        if 'domain' in request.GET:
            request.GET = get_copy
            request = _clean_next_url(request)
            r = http.HttpResponseRedirect(request.GET['to'])

        # Succsesful log in according to django.  Now we do our checks.  I do
        # the checks here instead of the form's clean() because I want to use
        # the messages framework and it's not available in the request there.
        if user.deleted:
            logout(request)
            log.warning(u'Attempt to log in with deleted account (%s)' % user)
            messages.error(request, _('Wrong email address or password!'))
            data.update({'form': partial_form()})
            user.log_login_attempt(False)
            log_cef('Authentication Failure',
                    5,
                    request,
                    username=request.user,
                    signature='AUTHFAIL',
                    msg='Account is deactivated')
            return render(request, template, data)

        if user.confirmationcode:
            logout(request)
            log.info(u'Attempt to log in with unconfirmed account (%s)' % user)
            msg1 = _(u'A link to activate your user account was sent by email '
                     u'to your address {0}. You have to click it before you '
                     u'can log in.').format(user.email)
            url = "%s%s" % (settings.SITE_URL,
                            reverse('users.confirm.resend', args=[user.id]))
            msg2 = _('If you did not receive the confirmation email, make '
                     'sure your email service did not mark it as "junk '
                     'mail" or "spam". If you need to, you can have us '
                     '<a href="%s">resend the confirmation message</a> '
                     'to your email address mentioned above.') % url
            messages.error(request, _('Activation Email Sent'), msg1)
            messages.info(request,
                          _('Having Trouble?'),
                          msg2,
                          title_safe=True,
                          message_safe=True)
            data.update({'form': partial_form()})
            user.log_login_attempt(False)
            return render(request, template, data)

        rememberme = request.POST.get('rememberme', None)
        if rememberme:
            request.session.set_expiry(settings.SESSION_COOKIE_AGE)
            log.debug(
                u'User (%s) logged in successfully with "remember me" set' %
                user)

        login_status = True

        if dont_redirect:
            # We're recalling the middleware to re-initialize amo_user
            ACLMiddleware().process_request(request)
            r = render(request, template, data)

    if login_status is not None:
        user.log_login_attempt(login_status)
        log_cef('Authentication Failure',
                5,
                request,
                username=request.POST['username'],
                signature='AUTHFAIL',
                msg='The password was incorrect')

    return r
Beispiel #18
0
 def request(self, verb):
     request = getattr(RequestFactory(), verb.lower())('/')
     request.user = self.user
     ACLMiddleware().process_request(request)
     return request