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
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
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)
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)
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)
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)
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
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
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 ])
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
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()
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
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)
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
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
def request(self, verb): request = getattr(RequestFactory(), verb.lower())('/') request.user = self.user ACLMiddleware().process_request(request) return request