summaryrefslogtreecommitdiff
path: root/addons/survey/tests/test_survey_security.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/survey/tests/test_survey_security.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/survey/tests/test_survey_security.py')
-rw-r--r--addons/survey/tests/test_survey_security.py364
1 files changed, 364 insertions, 0 deletions
diff --git a/addons/survey/tests/test_survey_security.py b/addons/survey/tests/test_survey_security.py
new file mode 100644
index 00000000..191e8edd
--- /dev/null
+++ b/addons/survey/tests/test_survey_security.py
@@ -0,0 +1,364 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import datetime
+
+from odoo.addons.survey.tests import common
+from odoo.exceptions import AccessError, UserError
+from odoo.tests import tagged
+from odoo.tests.common import users, HttpCase
+from odoo.tools import mute_logger
+
+
+@tagged('security')
+class TestAccess(common.TestSurveyCommon):
+
+ def setUp(self):
+ super(TestAccess, self).setUp()
+
+ self.answer_0 = self._add_answer(self.survey, self.customer)
+ self.answer_0_0 = self._add_answer_line(self.question_ft, self.answer_0, 'Test Answer')
+ self.answer_0_1 = self._add_answer_line(self.question_num, self.answer_0, 5)
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('user_emp')
+ def test_access_survey_employee(self):
+ # Create: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.survey'].create({'title': 'Test Survey 2'})
+ with self.assertRaises(AccessError):
+ self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'page_id': self.page_0.id})
+
+ # Read: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.survey'].search([('title', 'ilike', 'Test')])
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).read(['title'])
+
+ # Write: nope
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.page_0.with_user(self.env.user).write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.question_ft.with_user(self.env.user).write({'question': 'New Title'})
+
+ # Unlink: nope
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.page_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.question_ft.with_user(self.env.user).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('user_portal')
+ def test_access_survey_portal(self):
+ # Create: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.survey'].create({'title': 'Test Survey 2'})
+ with self.assertRaises(AccessError):
+ self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'page_id': self.page_0.id})
+
+ # Read: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.survey'].search([('title', 'ilike', 'Test')])
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).read(['title'])
+
+ # Write: nope
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.page_0.with_user(self.env.user).write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.question_ft.with_user(self.env.user).write({'question': 'New Title'})
+
+ # Unlink: nope
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.page_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.question_ft.with_user(self.env.user).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('user_public')
+ def test_access_survey_public(self):
+ # Create: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.survey'].create({'title': 'Test Survey 2'})
+ with self.assertRaises(AccessError):
+ self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'page_id': self.page_0.id})
+
+ # Read: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.survey'].search([('title', 'ilike', 'Test')])
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).read(['title'])
+
+ # Write: nope
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.page_0.with_user(self.env.user).write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.question_ft.with_user(self.env.user).write({'question': 'New Title'})
+
+ # Unlink: nope
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.page_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.question_ft.with_user(self.env.user).unlink()
+
+ @users('survey_manager')
+ def test_access_survey_survey_manager(self):
+ # Create: all
+ survey = self.env['survey.survey'].create({'title': 'Test Survey 2'})
+ self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'survey_id': survey.id})
+ self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'survey_id': survey.id})
+
+ # Read: all
+ surveys = self.env['survey.survey'].search([('title', 'ilike', 'Test')])
+ self.assertEqual(surveys, self.survey | survey)
+ surveys.read(['title'])
+
+ # Write: all
+ (self.survey | survey).write({'title': 'New Title'})
+
+ # Unlink: all
+ (self.survey | survey).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('survey_user')
+ def test_access_survey_survey_user(self):
+ # Create: own only
+ survey = self.env['survey.survey'].create({'title': 'Test Survey 2'})
+ self.env['survey.question'].create({'title': 'My Page', 'sequence': 0, 'is_page': True, 'survey_id': survey.id})
+ self.env['survey.question'].create({'title': 'My Question', 'sequence': 1, 'survey_id': survey.id})
+
+ # Read: all
+ surveys = self.env['survey.survey'].search([('title', 'ilike', 'Test')])
+ self.assertEqual(surveys, self.survey | survey)
+ surveys.read(['title'])
+
+ # Write: own only
+ survey.write({'title': 'New Title'})
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).write({'title': 'New Title'})
+
+ # Unlink: own only
+ survey.unlink()
+ with self.assertRaises(AccessError):
+ self.survey.with_user(self.env.user).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('user_emp')
+ def test_access_answers_employee(self):
+ # Create: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].create({'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
+
+ # Read: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].search([('survey_id', 'in', [self.survey.id])])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].search([('survey_id', 'in', [self.survey.id])])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
+
+ # Write: nope
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).write({'state': 'done'})
+
+ # Unlink: nope
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.answer_0_0.with_user(self.env.user).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('user_portal')
+ def test_access_answers_portal(self):
+ # Create: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].create({'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
+
+ # Read: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].search([('survey_id', 'in', [self.survey.id])])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].search([('survey_id', 'in', [self.survey.id])])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
+
+ # Write: nope
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).write({'state': 'done'})
+
+ # Unlink: nope
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.answer_0_0.with_user(self.env.user).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('user_public')
+ def test_access_answers_public(self):
+ # Create: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].create({'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
+
+ # Read: nope
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].search([('survey_id', 'in', [self.survey.id])])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].search([('survey_id', 'in', [self.survey.id])])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
+ with self.assertRaises(AccessError):
+ self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
+
+ # Write: nope
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).write({'state': 'done'})
+
+ # Unlink: nope
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.answer_0_0.with_user(self.env.user).unlink()
+
+ @mute_logger('odoo.addons.base.models.ir_model')
+ @users('survey_user')
+ def test_access_answers_survey_user(self):
+ survey_own = self.env['survey.survey'].create({'title': 'Other'})
+ self.env['survey.question'].create({'title': 'Other', 'sequence': 0, 'is_page': True, 'survey_id': survey_own.id})
+ question_own = self.env['survey.question'].create({'title': 'Other Question', 'sequence': 1, 'survey_id': survey_own.id})
+
+ # Create: own survey only
+ answer_own = self.env['survey.user_input'].create({'survey_id': survey_own.id})
+ answer_line_own = self.env['survey.user_input.line'].create({'question_id': question_own.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': answer_own.id})
+
+ # Read: always
+ answers = self.env['survey.user_input'].search([('survey_id', 'in', [survey_own.id, self.survey.id])])
+ self.assertEqual(answers, answer_own | self.answer_0)
+
+ answer_lines = self.env['survey.user_input.line'].search([('survey_id', 'in', [survey_own.id, self.survey.id])])
+ self.assertEqual(answer_lines, answer_line_own | self.answer_0_0 | self.answer_0_1)
+
+ self.env['survey.user_input'].browse(answer_own.ids).read(['state'])
+ self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
+
+ self.env['survey.user_input.line'].browse(answer_line_own.ids).read(['value_numerical_box'])
+ self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
+
+ # Create: own survey only (moved after read because DB not correctly rollbacked with assertRaises)
+ with self.assertRaises(AccessError):
+ answer_other = self.env['survey.user_input'].create({'survey_id': self.survey.id})
+ with self.assertRaises(AccessError):
+ answer_line_other = self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': self.answer_0.id})
+
+ # Write: own survey only
+ answer_own.write({'state': 'done'})
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).write({'state': 'done'})
+
+ # Unlink: own survey only
+ answer_own.unlink()
+ with self.assertRaises(AccessError):
+ self.answer_0.with_user(self.env.user).unlink()
+ with self.assertRaises(AccessError):
+ self.answer_0_0.with_user(self.env.user).unlink()
+
+ @users('survey_manager')
+ def test_access_answers_survey_manager(self):
+ admin = self.env.ref('base.user_admin')
+ with self.with_user(admin.login):
+ survey_other = self.env['survey.survey'].create({'title': 'Other'})
+ self.env['survey.question'].create({'title': 'Other', 'sequence': 0, 'is_page': True, 'survey_id': survey_other.id})
+ question_other = self.env['survey.question'].create({'title': 'Other Question', 'sequence': 1, 'survey_id': survey_other.id})
+ self.assertEqual(survey_other.create_uid, admin)
+ self.assertEqual(question_other.create_uid, admin)
+
+ # Create: always
+ answer_own = self.env['survey.user_input'].create({'survey_id': self.survey.id})
+ answer_other = self.env['survey.user_input'].create({'survey_id': survey_other.id})
+ answer_line_own = self.env['survey.user_input.line'].create({'question_id': self.question_num.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': answer_own.id})
+ answer_line_other = self.env['survey.user_input.line'].create({'question_id': question_other.id, 'answer_type': 'numerical_box', 'value_numerical_box': 3, 'user_input_id': answer_other.id})
+
+ # Read: always
+ answers = self.env['survey.user_input'].search([('survey_id', 'in', [survey_other.id, self.survey.id])])
+ self.assertEqual(answers, answer_own | answer_other | self.answer_0)
+
+ answer_lines = self.env['survey.user_input.line'].search([('survey_id', 'in', [survey_other.id, self.survey.id])])
+ self.assertEqual(answer_lines, answer_line_own | answer_line_other | self.answer_0_0 | self.answer_0_1)
+
+ self.env['survey.user_input'].browse(answer_own.ids).read(['state'])
+ self.env['survey.user_input'].browse(self.answer_0.ids).read(['state'])
+
+ self.env['survey.user_input.line'].browse(answer_line_own.ids).read(['value_numerical_box'])
+ self.env['survey.user_input.line'].browse(self.answer_0_0.ids).read(['value_numerical_box'])
+
+ # Write: always
+ answer_own.write({'state': 'done'})
+ answer_other.write({'partner_id': self.env.user.partner_id.id})
+
+ # Unlink: always
+ (answer_own | answer_other | self.answer_0).unlink()
+
+
+@tagged('post_install')
+class TestSurveySecurityControllers(common.TestSurveyCommon, HttpCase):
+ def test_survey_start_short(self):
+ # avoid name clash with existing data
+ surveys = self.env['survey.survey'].search([
+ ('state', '=', 'open'),
+ ('session_state', 'in', ['ready', 'in_progress'])
+ ])
+ surveys.write({'state': 'done'})
+ self.survey.write({
+ 'state': 'open',
+ 'session_state': 'ready',
+ 'session_code': '123456',
+ 'session_start_time': datetime.datetime.now(),
+ 'access_mode': 'public',
+ 'users_login_required': False,
+ })
+
+ # right short access token
+ response = self.url_open(f'/s/123456')
+ self.assertEqual(response.status_code, 200)
+ self.assertIn('The session will begin automatically when the host starts', response.text)
+
+ # `like` operator injection
+ response = self.url_open(f'/s/______')
+ self.assertFalse(self.survey.title in response.text)
+
+ # right short token, but wrong state
+ self.survey.state = 'draft'
+ response = self.url_open(f'/s/123456')
+ self.assertFalse(self.survey.title in response.text)
+
+ # right short token, but wrong `session_state`
+ self.survey.write({'state': 'open', 'session_state': False})
+ response = self.url_open(f'/s/123456')
+ self.assertFalse(self.survey.title in response.text)