def clean_response_type(self): """ :rfc:`3.1.1` Lists of values are space delimited. """ response_type = self.cleaned_data.get('response_type') if not response_type: raise OAuthValidationError({ 'error': 'invalid_request', 'error_description': "No 'response_type' supplied." }) types = response_type.split(" ") for type in types: if type not in RESPONSE_TYPE_CHOICES: raise OAuthValidationError({ 'error': 'unsupported_response_type', 'error_description': u"'%s' is not a supported response " "type." % type }) return response_type
def clean(self): if self._errors: return {} backend = self.request.backend if not isinstance(backend, social_oauth.BaseOAuth2): raise OAuthValidationError({ "error": "invalid_request", "error_description": "{} is not a supported provider".format(backend.name), }) self.request.session[ pipeline.AUTH_ENTRY_KEY] = pipeline.AUTH_ENTRY_LOGIN_API client_id = self.cleaned_data["client_id"] try: client = self.oauth2_adapter.get_client(client_id=client_id) except (Client.DoesNotExist, Application.DoesNotExist): raise OAuthValidationError({ "error": "invalid_client", "error_description": "{} is not a valid client_id".format(client_id), }) if client.client_type not in [ provider.constants.PUBLIC, Application.CLIENT_PUBLIC ]: raise OAuthValidationError({ # invalid_client isn't really the right code, but this mirrors # https://github.com/edx/django-oauth2-provider/blob/edx/provider/oauth2/forms.py#L331 "error": "invalid_client", "error_description": "{} is not a public client".format(client_id), }) self.cleaned_data["client"] = client user = None access_token = self.cleaned_data.get("access_token") try: user = backend.do_auth(access_token, allow_inactive_user=True) except (HTTPError, AuthException): pass if user and isinstance(user, User): self.cleaned_data["user"] = user else: # Ensure user does not re-enter the pipeline self.request.social_strategy.clean_partial_pipeline(access_token) raise OAuthValidationError({ "error": "invalid_grant", "error_description": "access_token is not valid", }) return self.cleaned_data
def clean_code(self): code = self.cleaned_data.get('code') if not code: raise OAuthValidationError({'error': 'invalid_request'}) try: self.cleaned_data['grant'] = Grant.objects.get( code=code, client=self.client, expires__gt=datetime.now()) except Grant.DoesNotExist: raise OAuthValidationError({'error': 'invalid_grant'}) return code
def clean(self): data = super(PublicPasswordGrantForm, self).clean() try: client = Client.objects.get(client_id=data.get('client_id')) except Client.DoesNotExist: raise OAuthValidationError({'error': 'invalid_client'}) if client.client_type != 1: # public raise OAuthValidationError({'error': 'invalid_client'}) data['client'] = client return data
def clean_refresh_token(self): token = self.cleaned_data.get('refresh_token') if not token: raise OAuthValidationError({'error': 'invalid_request'}) try: token = RefreshToken.objects.get(token=token, expired=False, client=self.client) except RefreshToken.DoesNotExist: raise OAuthValidationError({'error': 'invalid_grant'}) return token
def validate(self, value): """ Validates that the input is a list or tuple. """ if self.required and not value: raise OAuthValidationError({'error': 'invalid_request'}) # Validate that each value in the value list is in self.choices. for val in value: if not self.valid_value(val): raise OAuthValidationError({ 'error': 'invalid_request', 'error_description': _("'%s' is not a valid scope.") % \ val})
def clean_username(self): username = self.cleaned_data.get('username') if not username: raise OAuthValidationError({'error': 'invalid_request'}) return username
def clean_grant_type(self): grant_type = self.cleaned_data.get('grant_type') if grant_type != 'password': raise OAuthValidationError({'error': 'invalid_grant'}) return grant_type
def clean(self): data = self.cleaned_data # pylint: disable=no-member username = data.get('username') password = data.get('password') user = authenticate(username=username, password=password) # If the username was not found try the user using username as # the email address. It is valid because the edx-platform has # a unique constraint placed on the email field. if user is None: try: user_obj = User.objects.get(email=username) user = authenticate(username=user_obj.username, password=password) except User.DoesNotExist: user = None if user is None: # TODO This is a temporary workaround while the is_active field on the # user is coupled with whether or not the user has verified ownership # of their claimed email address. Once is_active is decoupled from # verified_email, add the following condition to the 'if' statement above. # or not user.is_active error_description = "Username does not exist or invalid credentials given for username '{}'.".format( username) log.error("OAuth2: {}".format(error_description)) raise OAuthValidationError({ 'error': 'invalid_grant', 'error_description': error_description }) data['user'] = user return data
def clean(self): def get_user_from_facebook_token(signed_request, access_token): def build_url(*args, **kwargs): get = kwargs.pop('get', {}) url = reverse(*args, **kwargs) if get: url += '?' + urllib.urlencode(get) return url request = HttpRequest() request.user = AnonymousUser() request.session = SessionStore() request.GET['access_token'] = access_token request.GET['signed_request'] = signed_request request.REQUEST = {'next': '/'} oauth_callback(request, 'facebook') return request.user data = self.cleaned_data user = get_user_from_facebook_token(data['username'], data['password']) if user is None or user == AnonymousUser(): raise OAuthValidationError({'error': 'invalid_grant'}) data['user'] = user return data
def clean(self): data = self.cleaned_data # pylint: disable=no-member username = data.get('username') password = data.get('password') user = authenticate(username=username, password=password) # If the username was not found try the user using username as # the email address. It is valid because the edx-platform has # a unique constraint placed on the email field. if user is None: try: user_obj = User.objects.get(email=username) user = authenticate(username=user_obj.username, password=password) except User.DoesNotExist: user = None if (user is None # TODO This is a temporary workaround while the is_active field on the # user is coupled with whether or not the user has verified ownership # of their claimed email address. Once is_active is decoupled from # verified_email, we can uncomment the following line. # or not user.is_active ): raise OAuthValidationError({'error': 'invalid_grant'}) data['user'] = user return data
def clean_password(self): password = self.cleaned_data.get('password') if not password: raise OAuthValidationError({'error': 'invalid_request'}) return password
def clean(self): data = self.cleaned_data # pylint: disable=no-member username = data.get('username') password = data.get('password') try: user_obj = User.objects.get(username=username) user = authenticate(username=user_obj.username, password=password) except User.DoesNotExist: try: user_obj = UserProfile.objects.get(phone=username).user user = authenticate(username=user_obj.username, password=password) except ObjectDoesNotExist: user = None if user is None: error_description = "Username does not exist or invalid credentials given for phone number '{}'.".format( username) log.error("OAuth2: {}".format(error_description)) raise OAuthValidationError({ 'error': 'invalid_grant', 'error_description': error_description }) data['user'] = user try: client = Client.objects.get(client_id=data.get('client_id')) except Client.DoesNotExist: error_description = "Client ID '{}' does not exist.".format( data.get('client_id')) log.exception("OAuth2: {}".format(error_description)) raise OAuthValidationError({ 'error': 'invalid_client', 'error_description': error_description }) if client.client_type != provider.constants.PUBLIC: error_description = "'{}' is not a public client.".format( client.client_type) log.error("OAuth2: {}".format(error_description)) raise OAuthValidationError({ 'error': 'invalid_client', 'error_description': error_description }) data['client'] = client return data
def to_python(self, value): if not value: return [] if not isinstance(value, (list, tuple)): raise OAuthValidationError({'error': 'invalid_request'}) # Split values into list return u' '.join([smart_unicode(val) for val in value]).split(u' ')
def authenticate(self, username=None, password=None, **kwargs): user = super(EloueAuthBackend, self).authenticate(username, password, **kwargs) if user and not user.is_active: if user.login_count < settings.NON_ACTIVE_LOGIN_COUNT: user.login_count += 1 user.save() else: raise OAuthValidationError({'error': 'user_inactive'}) return user
def clean(self): self.clean_login_attempts() ModelClazz = self.get_user_model() assert ModelClazz, u"Cannot identify client {name}".format( name=u"None" if not self.client else self.client.name ) data = self.cleaned_data try: model = ModelClazz.objects.get(user__username=data.get("username")) except ModelClazz.DoesNotExist: raise OAuthValidationError({"error": "invalid_grant"}) if not model.user.is_active: raise OAuthValidationError({"error": "account_disabled"}) return super(ClientIdPasswordGrantForm, self).clean()
def clean(self): data = self.cleaned_data user = authenticate(username=data.get('username'), password=data.get('password')) if user is None: raise OAuthValidationError({'error': 'invalid_grant'}) data['user'] = user return data
def clean(self): """ Make sure that the scope is less or equal to the previous scope! """ data = self.cleaned_data if 'scope' in data and not scope.check( data.get('scope'), data.get('refresh_token').access_token.scope): raise OAuthValidationError({'error': 'invalid_scope'}) return data
def clean(self): """ Make sure that the scope is less or equal to the scope allowed on the grant! """ data = self.cleaned_data # Only check if we've actually got a scope in the data # (read: All fields have been cleaned) if 'scope' in data and not scope.check(data.get('scope'), data.get('grant').scope): raise OAuthValidationError({'error': 'invalid_scope'}) return data
def clean(self): data = super(PublicPasswordGrantForm, self).clean() try: client = Client.objects.get(client_id=data.get('client_id')) except Client.DoesNotExist: error_description = "Client ID '{}' does not exist.".format(data.get('client_id')) log.exception("OAuth2: {}".format(error_description)) raise OAuthValidationError({ 'error': 'invalid_client', 'error_description': error_description }) if client.client_type != provider.constants.PUBLIC: error_description = "'{}' is not a public client.".format(client.client_type) log.error("OAuth2: {}".format(error_description)) raise OAuthValidationError({ 'error': 'invalid_client', 'error_description': error_description }) data['client'] = client return data
def _require_oauth_field(self, field_name): """ Raise an appropriate OAuthValidationError error if the field is missing """ field_val = self.cleaned_data.get(field_name) if not field_val: raise OAuthValidationError( { "error": "invalid_request", "error_description": "{} is required".format(field_name), } ) return field_val
def clean_login_attempts(self): username = self.cleaned_data["username"] cooloff_time = timezone.now() - datetime.timedelta(minutes=settings.LOGIN_FAILURE_COOLOFF_TIME) attempts = AccessAttempt.objects.filter(username=username, created__gt=cooloff_time).count() if attempts >= settings.LOGIN_FAILURE_LIMIT: self.account_lockedout = True logger.info("account locked out", extra={"username": username}) raise OAuthValidationError({"error": "locked_out"})
def clean(self): """ Make sure that the scope is less or equal to the scope allowed on the grant! """ data = self.cleaned_data want_scope = data.get('scope') or None grant = data.get('grant') if want_scope and grant: has_scope = {s.name for s in grant.scope.all()} want_scope = {s.name for s in want_scope} if want_scope.issubset(has_scope): return data raise OAuthValidationError({'error': 'invalid_grant'})
def clean_redirect_uri(self): """ :rfc:`3.1.2` The redirect value has to match what was saved on the authorization server. """ redirect_uri = self.cleaned_data.get('redirect_uri') if redirect_uri: if not redirect_uri == self.client.redirect_uri: raise OAuthValidationError({ 'error': 'invalid_request', 'error_description': _("The requested redirect didn't " "match the client settings.")}) return redirect_uri
def clean(self): self.clean_login_attempts() ModelClazz = self.get_user_model() assert ModelClazz, u"Cannot identify client {name}".format( name=u'None' if not self.client else self.client.name) data = self.cleaned_data try: ModelClazz.objects.get(user__username=data.get('username')) except ModelClazz.DoesNotExist as e: raise OAuthValidationError({'error': 'invalid_grant'}) return super(ClientIdPasswordGrantForm, self).clean()
def clean_login_attempts(self): username = self.cleaned_data['username'] cooloff_time = timezone.now() - datetime.timedelta( minutes=settings.LOGIN_FAILURE_COOLOFF_TIME) attempts = AccessAttempt.objects.filter( username=username, created__gt=cooloff_time).count() if attempts >= settings.LOGIN_FAILURE_LIMIT: self.account_lockedout = True statsd.incr('account.lockout.created') logger.info('account locked out', extra={'username': username}) raise OAuthValidationError({'error': "locked_out"})
def clean(self): """ Make sure that the scope is less or equal to the scope allowed on the grant! """ data = self.cleaned_data want_scope = data.get('scope') or 0 grant = data.get('grant') has_scope = grant.scope if grant else 0 # Only check if we've actually got a scope in the data # (read: All fields have been cleaned) if want_scope is not 0 and not scope.check(want_scope, has_scope): raise OAuthValidationError({'error': 'invalid_scope'}) return data
def clean_redirect_uri(self): """ Change original behavior to accept variable redirect_uri's """ redirect_uri = self.cleaned_data.get('redirect_uri') if redirect_uri: if not self.domain_cmp(redirect_uri, self.client.redirect_uri): raise OAuthValidationError({ 'error': 'invalid_request', 'error_description': _("The requested redirect didn't " "match the client settings.") }) return redirect_uri
def clean(self): """ Make sure that the scope is less or equal to the previous scope! """ data = self.cleaned_data want_scope = data.get('scope') or None refresh_token = data.get('refresh_token') access_token = getattr(refresh_token, 'access_token', None) if \ refresh_token else \ None if refresh_token and want_scope: want_scope = {s.name for s in want_scope} has_scope = {s.name for s in access_token.scope.all()} if want_scope.issubset(has_scope): return data raise OAuthValidationError({'error': 'invalid_grant'})
def clean(self): """ Make sure that the scope is less or equal to the previous scope! """ data = self.cleaned_data want_scope = data.get('scope') or 0 refresh_token = data.get('refresh_token') access_token = getattr(refresh_token, 'access_token', None) if \ refresh_token else \ None has_scope = access_token.scope if access_token else 0 # Only check if we've actually got a scope in the data # (read: All fields have been cleaned) if want_scope is not 0 and not scope.check(want_scope, has_scope): raise OAuthValidationError({'error': 'invalid_scope'}) return data