324 lines
12 KiB
Python
324 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
Security and Validation Tests for Survey Custom Certificate Template
|
|
|
|
This test module verifies the security features and validation logic
|
|
implemented in Task 15.
|
|
"""
|
|
|
|
import json
|
|
import unittest
|
|
from odoo.tests.common import TransactionCase
|
|
from odoo.exceptions import ValidationError, UserError
|
|
|
|
|
|
class TestSecurityValidation(TransactionCase):
|
|
"""Test security and validation features."""
|
|
|
|
def setUp(self):
|
|
super(TestSecurityValidation, self).setUp()
|
|
|
|
# Create a test survey
|
|
self.survey = self.env['survey.survey'].create({
|
|
'title': 'Test Security Survey',
|
|
'access_mode': 'public',
|
|
})
|
|
|
|
def test_placeholder_key_validation(self):
|
|
"""Test that invalid placeholder keys are rejected."""
|
|
wizard = self.env['survey.custom.certificate.wizard'].create({
|
|
'survey_id': self.survey.id,
|
|
})
|
|
|
|
# Test valid placeholder key
|
|
valid_placeholder = self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.valid_field}',
|
|
'value_type': 'custom_text',
|
|
})
|
|
self.assertTrue(valid_placeholder.id, "Valid placeholder should be created")
|
|
|
|
# Test invalid placeholder key - missing braces
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': 'key.invalid',
|
|
'value_type': 'custom_text',
|
|
})
|
|
|
|
# Test invalid placeholder key - special characters
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.invalid-field}',
|
|
'value_type': 'custom_text',
|
|
})
|
|
|
|
# Test invalid placeholder key - SQL injection attempt
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': "{key.field'; DROP TABLE users--}",
|
|
'value_type': 'custom_text',
|
|
})
|
|
|
|
def test_value_field_validation(self):
|
|
"""Test that invalid value_field names are rejected."""
|
|
wizard = self.env['survey.custom.certificate.wizard'].create({
|
|
'survey_id': self.survey.id,
|
|
})
|
|
|
|
# Test valid value_field
|
|
valid_placeholder = self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test}',
|
|
'value_type': 'survey_field',
|
|
'value_field': 'survey_title',
|
|
})
|
|
self.assertTrue(valid_placeholder.id, "Valid value_field should be accepted")
|
|
|
|
# Test valid value_field with dots
|
|
valid_placeholder2 = self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test2}',
|
|
'value_type': 'user_field',
|
|
'value_field': 'partner_id.name',
|
|
})
|
|
self.assertTrue(valid_placeholder2.id, "Valid value_field with dots should be accepted")
|
|
|
|
# Test invalid value_field - special characters
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test3}',
|
|
'value_type': 'survey_field',
|
|
'value_field': 'field-name',
|
|
})
|
|
|
|
# Test invalid value_field - SQL injection attempt
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test4}',
|
|
'value_type': 'survey_field',
|
|
'value_field': "field'; DROP TABLE--",
|
|
})
|
|
|
|
def test_custom_text_length_validation(self):
|
|
"""Test that excessively long custom text is rejected."""
|
|
wizard = self.env['survey.custom.certificate.wizard'].create({
|
|
'survey_id': self.survey.id,
|
|
})
|
|
|
|
# Test valid custom text
|
|
valid_placeholder = self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test}',
|
|
'value_type': 'custom_text',
|
|
'custom_text': 'Valid text',
|
|
})
|
|
self.assertTrue(valid_placeholder.id, "Valid custom text should be accepted")
|
|
|
|
# Test custom text at limit (1000 characters)
|
|
long_text = 'x' * 1000
|
|
valid_long = self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test2}',
|
|
'value_type': 'custom_text',
|
|
'custom_text': long_text,
|
|
})
|
|
self.assertTrue(valid_long.id, "Custom text at limit should be accepted")
|
|
|
|
# Test custom text exceeding limit
|
|
too_long_text = 'x' * 1001
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.certificate.placeholder'].create({
|
|
'wizard_id': wizard.id,
|
|
'source_key': '{key.test3}',
|
|
'value_type': 'custom_text',
|
|
'custom_text': too_long_text,
|
|
})
|
|
|
|
def test_json_mappings_validation(self):
|
|
"""Test that invalid JSON mappings are rejected."""
|
|
|
|
# Test valid JSON mappings
|
|
valid_mappings = json.dumps({
|
|
'placeholders': [
|
|
{
|
|
'key': '{key.name}',
|
|
'value_type': 'user_field',
|
|
'value_field': 'partner_name',
|
|
'custom_text': '',
|
|
}
|
|
]
|
|
})
|
|
|
|
survey = self.env['survey.survey'].create({
|
|
'title': 'Test JSON Survey',
|
|
'custom_cert_mappings': valid_mappings,
|
|
'has_custom_certificate': True,
|
|
})
|
|
self.assertTrue(survey.id, "Valid JSON mappings should be accepted")
|
|
|
|
# Test invalid JSON - not a dictionary
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.survey'].create({
|
|
'title': 'Test Invalid JSON 1',
|
|
'custom_cert_mappings': '["not", "a", "dict"]',
|
|
'has_custom_certificate': True,
|
|
})
|
|
|
|
# Test invalid JSON - missing placeholders key
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.survey'].create({
|
|
'title': 'Test Invalid JSON 2',
|
|
'custom_cert_mappings': '{"wrong_key": []}',
|
|
'has_custom_certificate': True,
|
|
})
|
|
|
|
# Test invalid JSON - invalid placeholder key format
|
|
invalid_key_mappings = json.dumps({
|
|
'placeholders': [
|
|
{
|
|
'key': 'invalid_key',
|
|
'value_type': 'custom_text',
|
|
'value_field': '',
|
|
'custom_text': 'test',
|
|
}
|
|
]
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.survey'].create({
|
|
'title': 'Test Invalid JSON 3',
|
|
'custom_cert_mappings': invalid_key_mappings,
|
|
'has_custom_certificate': True,
|
|
})
|
|
|
|
# Test invalid JSON - invalid value_type
|
|
invalid_type_mappings = json.dumps({
|
|
'placeholders': [
|
|
{
|
|
'key': '{key.test}',
|
|
'value_type': 'invalid_type',
|
|
'value_field': '',
|
|
'custom_text': '',
|
|
}
|
|
]
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
self.env['survey.survey'].create({
|
|
'title': 'Test Invalid JSON 4',
|
|
'custom_cert_mappings': invalid_type_mappings,
|
|
'has_custom_certificate': True,
|
|
})
|
|
|
|
def test_sanitization_methods(self):
|
|
"""Test that sanitization methods work correctly."""
|
|
from ..wizards.survey_custom_certificate_wizard import SurveyCustomCertificateWizard
|
|
|
|
# Test HTML escaping
|
|
html_input = '<script>alert("XSS")</script>'
|
|
sanitized = SurveyCustomCertificateWizard._sanitize_placeholder_value(html_input)
|
|
self.assertNotIn('<script>', sanitized, "HTML tags should be removed/escaped")
|
|
self.assertNotIn('</script>', sanitized, "HTML tags should be removed/escaped")
|
|
|
|
# Test control character removal
|
|
control_chars = 'test\x00\x01\x02string'
|
|
sanitized = SurveyCustomCertificateWizard._sanitize_placeholder_value(control_chars)
|
|
self.assertEqual(sanitized, 'teststring', "Control characters should be removed")
|
|
|
|
# Test length limiting
|
|
very_long = 'x' * 20000
|
|
sanitized = SurveyCustomCertificateWizard._sanitize_placeholder_value(very_long)
|
|
self.assertLessEqual(len(sanitized), 10000, "Long strings should be truncated")
|
|
|
|
# Test empty/None values
|
|
self.assertEqual(
|
|
SurveyCustomCertificateWizard._sanitize_placeholder_value(None),
|
|
'',
|
|
"None should return empty string"
|
|
)
|
|
self.assertEqual(
|
|
SurveyCustomCertificateWizard._sanitize_placeholder_value(''),
|
|
'',
|
|
"Empty string should return empty string"
|
|
)
|
|
|
|
def test_placeholder_key_format_validation(self):
|
|
"""Test the static placeholder key validation method."""
|
|
from ..wizards.survey_custom_certificate_wizard import SurveyCustomCertificateWizard
|
|
|
|
# Valid keys
|
|
self.assertTrue(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('{key.name}')
|
|
)
|
|
self.assertTrue(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('{key.field_name}')
|
|
)
|
|
self.assertTrue(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('{key.field123}')
|
|
)
|
|
|
|
# Invalid keys
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('key.name')
|
|
)
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('{key.name')
|
|
)
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('key.name}')
|
|
)
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('{key.field-name}')
|
|
)
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('{key.field name}')
|
|
)
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key('')
|
|
)
|
|
self.assertFalse(
|
|
SurveyCustomCertificateWizard._validate_placeholder_key(None)
|
|
)
|
|
|
|
def test_json_structure_validation_method(self):
|
|
"""Test the static JSON structure validation method."""
|
|
from ..wizards.survey_custom_certificate_wizard import SurveyCustomCertificateWizard
|
|
|
|
# Valid JSON
|
|
valid_json = json.dumps({
|
|
'placeholders': [
|
|
{
|
|
'key': '{key.test}',
|
|
'value_type': 'custom_text',
|
|
'value_field': '',
|
|
'custom_text': 'test',
|
|
}
|
|
]
|
|
})
|
|
is_valid, error = SurveyCustomCertificateWizard._validate_json_structure(valid_json)
|
|
self.assertTrue(is_valid, f"Valid JSON should pass: {error}")
|
|
|
|
# Invalid JSON - syntax error
|
|
is_valid, error = SurveyCustomCertificateWizard._validate_json_structure('{invalid}')
|
|
self.assertFalse(is_valid, "Invalid JSON syntax should fail")
|
|
|
|
# Invalid JSON - not a dict
|
|
is_valid, error = SurveyCustomCertificateWizard._validate_json_structure('[]')
|
|
self.assertFalse(is_valid, "JSON array should fail")
|
|
|
|
# Invalid JSON - missing placeholders key
|
|
is_valid, error = SurveyCustomCertificateWizard._validate_json_structure('{}')
|
|
self.assertFalse(is_valid, "Missing placeholders key should fail")
|
|
|
|
# Invalid JSON - empty string
|
|
is_valid, error = SurveyCustomCertificateWizard._validate_json_structure('')
|
|
self.assertFalse(is_valid, "Empty string should fail")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|