def validate(self, attrs): user = self.context.get('request').user try: current_method = user.mfa_methods.get( is_primary=True, is_active=True, ) except ObjectDoesNotExist: self.fail('not_enabled') try: new_primary_method = user.mfa_methods.get( name=attrs.get('method'), is_active=True, ) except ObjectDoesNotExist: self.fail('missing_method') code = attrs.get('code') validated_backup_code = validate_backup_code( code, current_method.backup_codes, ) if validate_code(code, current_method): attrs.update(new_method=new_primary_method) attrs.update(old_method=current_method) return attrs elif validated_backup_code: attrs.update(new_method=new_primary_method) attrs.update(old_method=current_method) current_method.remove_backup_code(validated_backup_code) return attrs else: self.fail('invalid_code')
def validate(self, attrs): token = attrs.get('token') code = attrs.get('code') self.user = user_token_generator.check_token(token) if not self.user: self.fail('invalid_token') for auth_method in self.user.mfa_methods.filter(is_active=True): if validate_code(code, auth_method): return attrs if code in auth_method.backup_codes.split(','): auth_method.remove_backup_code(code) return attrs self.fail('invalid_code')
def _validate_code(self, value): if not value: self.fail('otp_code_missing') obj = self.context['obj'] validity_period = (self.context['conf'].get('VALIDITY_PERIOD') or api_settings.DEFAULT_VALIDITY_PERIOD) if validate_code(value, obj, validity_period): return value if value in obj.backup_codes.split(','): obj.remove_backup_code(value) return value self.fail('code_invalid_or_expired')
def validate_code(self, value): if not self.requires_mfa_code: return value # pragma: no cover obj = self.context['obj'] validity_period = (self.context['conf'].get('VALIDITY_PERIOD') or api_settings.DEFAULT_VALIDITY_PERIOD) if validate_code(value, obj, validity_period): return value if value in obj.backup_codes.split(','): obj.remove_backup_code(value) return value self.fail('code_invalid_or_expired')
def validate(self, attrs): ephemeral_token = attrs.get('ephemeral_token') code = attrs.get('code') self.user = user_token_generator.check_token(ephemeral_token) if not self.user: self.fail('invalid_token') for auth_method in self.user.mfa_methods.filter(is_active=True): validated_backup_code = validate_backup_code( code, auth_method.backup_codes, ) if validate_code(code, auth_method): return attrs if validated_backup_code: auth_method.remove_backup_code(validated_backup_code) return attrs self.fail('invalid_code')
def test_validate_code_yubikey(active_user_with_many_otp_methods): active_user, _ = active_user_with_many_otp_methods yubi_method = active_user.mfa_methods.get(name='yubi') assert validate_code("t" * 44, yubi_method) is False
def test_validate_code(active_user_with_email_otp): email_method = active_user_with_email_otp.mfa_methods.get() valid_code = create_otp_code(email_method.secret) assert validate_code("123456", email_method) is False assert validate_code(valid_code, email_method) is True