diff options
Diffstat (limited to 'python_moonutilities')
-rw-r--r-- | python_moonutilities/.gitignore | 105 | ||||
-rw-r--r-- | python_moonutilities/Changelog | 57 | ||||
-rw-r--r-- | python_moonutilities/python_moonutilities/__init__.py | 4 | ||||
-rw-r--r-- | python_moonutilities/python_moonutilities/cache.py | 32 | ||||
-rw-r--r-- | python_moonutilities/python_moonutilities/context.py | 81 | ||||
-rw-r--r-- | python_moonutilities/python_moonutilities/exceptions.py | 227 | ||||
-rw-r--r-- | python_moonutilities/python_moonutilities/security_functions.py | 54 | ||||
-rw-r--r-- | python_moonutilities/tests/unit_python/requirements.txt | 1 | ||||
-rw-r--r-- | python_moonutilities/tests/unit_python/test_validated_input.py | 143 |
9 files changed, 485 insertions, 219 deletions
diff --git a/python_moonutilities/.gitignore b/python_moonutilities/.gitignore new file mode 100644 index 00000000..7bff7318 --- /dev/null +++ b/python_moonutilities/.gitignore @@ -0,0 +1,105 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + diff --git a/python_moonutilities/Changelog b/python_moonutilities/Changelog index ae7f352f..d001c892 100644 --- a/python_moonutilities/Changelog +++ b/python_moonutilities/Changelog @@ -98,3 +98,60 @@ CHANGES 1.4.10 ----- - Add CategoryNameInvalid and PerimeterNameInvalid exceptions + +1.4.11 +----- +- Add validate_data function + +1.4.12 +----- +- Fix a bug for the authz component +- updating Validation to be on mandatory keys only + +1.4.13 +----- +- Adding InvalidKey , InvalidContent exception +- fix error code of 'CategoryNameInvalid' to be 400 +- updating error of post/patch to mention key name + +1.4.14 +----- +- Adding updates to log +1.4.15 +----- +- Delete the check on each key send in request body for POST /models + +1.4.15-1 +-------- +- Revert to the previous functionality + +1.4.16 +----- +- Adding exceptions for MetaRuleNotLinkedWithPolicyModel , CategoryNotAssignedMetaRule + +1.4.17 +----- +- Update the security verification on attributes + +1.4.18 +----- +- Allow None values in input attributes (None is replaced by an empty string) + +1.4.19 +----- +- Allow boolean values in input attributes + +1.4.20 +----- +- Adding DeleteSubjectCategoryWithMetaRule exception +- Adding MetaRuleUpdate , PolicyUpdateError, ModelContentError exception +- Adding DeleteObjectCategoryWithMetaRule DeleteActionCategoryWithMetaRule exceptions + +1.4.21 +----- +- Allow in the cache the search of a perimeter element by it ID + +1.4.22 +----- +- Enable the target update in context manager +- Fix assignments update in cache diff --git a/python_moonutilities/python_moonutilities/__init__.py b/python_moonutilities/python_moonutilities/__init__.py index 6b30dedc..6e924e93 100644 --- a/python_moonutilities/python_moonutilities/__init__.py +++ b/python_moonutilities/python_moonutilities/__init__.py @@ -3,6 +3,4 @@ # license which can be found in the file 'LICENSE' in this package distribution # or at 'http://www.apache.org/licenses/LICENSE-2.0'. -__version__ = "1.4.10" - - +__version__ = "1.4.22" diff --git a/python_moonutilities/python_moonutilities/cache.py b/python_moonutilities/python_moonutilities/cache.py index 1bb9d09e..49a3ef5b 100644 --- a/python_moonutilities/python_moonutilities/cache.py +++ b/python_moonutilities/python_moonutilities/cache.py @@ -102,14 +102,14 @@ class Cache(object): if policy_id in self.subjects: for _subject_id, _subject_dict in self.subjects[policy_id].items(): - if "name" in _subject_dict and _subject_dict["name"] == name: + if _subject_id == name or _subject_dict.get("name") == name: return _subject_id self.__update_subjects(policy_id) if policy_id in self.subjects: for _subject_id, _subject_dict in self.subjects[policy_id].items(): - if "name" in _subject_dict and _subject_dict["name"] == name: + if _subject_id == name or _subject_dict.get("name") == name: return _subject_id raise exceptions.SubjectUnknown("Cannot find subject {}".format(name)) @@ -131,14 +131,14 @@ class Cache(object): if policy_id in self.objects: for _object_id, _object_dict in self.__OBJECTS[policy_id].items(): - if "name" in _object_dict and _object_dict["name"] == name: + if _object_id == name or _object_dict.get("name") == name: return _object_id self.__update_objects(policy_id) if policy_id in self.objects: for _object_id, _object_dict in self.__OBJECTS[policy_id].items(): - if "name" in _object_dict and _object_dict["name"] == name: + if _object_id == name or _object_dict.get("name") == name: return _object_id raise exceptions.ObjectUnknown("Cannot find object {}".format(name)) @@ -161,13 +161,13 @@ class Cache(object): if policy_id in self.actions: for _action_id, _action_dict in self.__ACTIONS[policy_id].items(): - if "name" in _action_dict and _action_dict["name"] == name: + if _action_id == name or _action_dict.get("name") == name: return _action_id self.__update_actions(policy_id) for _action_id, _action_dict in self.__ACTIONS[policy_id].items(): - if "name" in _action_dict and _action_dict["name"] == name: + if _action_id == name or _action_dict.get("name") == name: return _action_id raise exceptions.ActionUnknown("Cannot find action {}".format(name)) @@ -218,6 +218,17 @@ class Cache(object): # assignment functions + def update_assignments(self, policy_id=None, perimeter_id=None): + if policy_id: + self.__update_subject_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_object_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_action_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + else: + for policy_id in self.__POLICIES: + self.__update_subject_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_object_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + self.__update_action_assignments(policy_id=policy_id, perimeter_id=perimeter_id) + @property def subject_assignments(self): return self.__SUBJECT_ASSIGNMENTS @@ -233,8 +244,7 @@ class Cache(object): if 'subject_assignments' in response.json(): if policy_id not in self.subject_assignments: self.__SUBJECT_ASSIGNMENTS[policy_id] = {} - - self.__SUBJECT_ASSIGNMENTS[policy_id].update(response.json()['subject_assignments']) + self.__SUBJECT_ASSIGNMENTS[policy_id] = response.json()['subject_assignments'] else: raise exceptions.SubjectAssignmentUnknown( "Cannot find subject assignment within policy_id {}".format(policy_id)) @@ -251,7 +261,7 @@ class Cache(object): if perimeter_id == value['subject_id'] and category_id == value['category_id']: return value['assignments'] else: - logger.warning("'subject_id' or 'category_id' or'assignments'" + logger.warning("'subject_id' or 'category_id' or 'assignments'" " keys are not found in subject_assignments") return [] @@ -271,7 +281,7 @@ class Cache(object): if policy_id not in self.object_assignments: self.__OBJECT_ASSIGNMENTS[policy_id] = {} - self.__OBJECT_ASSIGNMENTS[policy_id].update(response.json()['object_assignments']) + self.__OBJECT_ASSIGNMENTS[policy_id] = response.json()['object_assignments'] else: raise exceptions.ObjectAssignmentUnknown( "Cannot find object assignment within policy_id {}".format(policy_id)) @@ -308,7 +318,7 @@ class Cache(object): if policy_id not in self.__ACTION_ASSIGNMENTS: self.__ACTION_ASSIGNMENTS[policy_id] = {} - self.__ACTION_ASSIGNMENTS[policy_id].update(response.json()['action_assignments']) + self.__ACTION_ASSIGNMENTS[policy_id] = response.json()['action_assignments'] else: raise exceptions.ActionAssignmentUnknown( "Cannot find action assignment within policy_id {}".format(policy_id)) diff --git a/python_moonutilities/python_moonutilities/context.py b/python_moonutilities/python_moonutilities/context.py index 1d25cda2..dc140b74 100644 --- a/python_moonutilities/python_moonutilities/context.py +++ b/python_moonutilities/python_moonutilities/context.py @@ -59,19 +59,19 @@ class Context: @property def current_state(self): - self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index]) + self.__validate_meta_rule_content(self.__pdp_set[self.__meta_rule_ids[self.__index]]) return self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] @current_state.setter def current_state(self, state): if state not in ("grant", "deny", "passed"): state = "passed" - self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index]) + self.__validate_meta_rule_content(self.__pdp_set[self.__meta_rule_ids[self.__index]]) self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] = state @current_state.deleter def current_state(self): - self.__validate_meta_rule_content(self.__meta_rule_ids[self.__index]) + self.__validate_meta_rule_content(self.__pdp_set[self.__meta_rule_ids[self.__index]]) self.__pdp_set[self.__meta_rule_ids[self.__index]]['effect'] = "unset" @property @@ -110,38 +110,46 @@ class Context: self.__pdp_set[meta_rule_id]["effect"] = "unset" self.__pdp_set["effect"] = "deny" - # def update_target(self, context): - # # result = dict() - # current_request = context['current_request'] - # _subject = current_request.get("subject") - # _object = current_request.get("object") - # _action = current_request.get("action") - # meta_rule_id = context['headers'][context['index']] - # policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id) - # meta_rules = self.cache.meta_rules() - # # for meta_rule_id in meta_rules: - # for sub_cat in meta_rules[meta_rule_id]['subject_categories']: - # if sub_cat not in context["pdp_set"][meta_rule_id]["target"]: - # context["pdp_set"][meta_rule_id]["target"][sub_cat] = [] - # for assign in self.cache.get_subject_assignments(policy_id, _subject, sub_cat).values(): - # for assign in assign["assignments"]: - # if assign not in context["pdp_set"][meta_rule_id]["target"][sub_cat]: - # context["pdp_set"][meta_rule_id]["target"][sub_cat].append(assign) - # for obj_cat in meta_rules[meta_rule_id]['object_categories']: - # if obj_cat not in context["pdp_set"][meta_rule_id]["target"]: - # context["pdp_set"][meta_rule_id]["target"][obj_cat] = [] - # for assign in self.cache.get_object_assignments(policy_id, _object, obj_cat).values(): - # for assign in assign["assignments"]: - # if assign not in context["pdp_set"][meta_rule_id]["target"][obj_cat]: - # context["pdp_set"][meta_rule_id]["target"][obj_cat].append(assign) - # for act_cat in meta_rules[meta_rule_id]['action_categories']: - # if act_cat not in context["pdp_set"][meta_rule_id]["target"]: - # context["pdp_set"][meta_rule_id]["target"][act_cat] = [] - # for assign in self.cache.get_action_assignments(policy_id, _action, act_cat).values(): - # for assign in assign["assignments"]: - # if assign not in context["pdp_set"][meta_rule_id]["target"][act_cat]: - # context["pdp_set"][meta_rule_id]["target"][act_cat].append(assign) - # # context["pdp_set"][meta_rule_id]["target"].update(result) + def update_target(self): + for meta_rule_id in self.__meta_rule_ids: + result = dict() + _subject = self.__current_request["subject"] + _object = self.__current_request["object"] + _action = self.__current_request["action"] + + meta_rules = self.cache.meta_rules + policy_id = self.cache.get_policy_from_meta_rules(meta_rule_id) + + if 'subject_categories' not in meta_rules[meta_rule_id]: + raise exceptions.MetaRuleContentError(" 'subject_categories' key not found ") + + self.cache.update_assignments(policy_id) + + for sub_cat in meta_rules[meta_rule_id]['subject_categories']: + if sub_cat not in result: + result[sub_cat] = [] + result[sub_cat].extend( + self.cache.get_subject_assignments(policy_id, _subject, sub_cat)) + + if 'object_categories' not in meta_rules[meta_rule_id]: + raise exceptions.MetaRuleContentError(" 'object_categories' key not found ") + + for obj_cat in meta_rules[meta_rule_id]['object_categories']: + if obj_cat not in result: + result[obj_cat] = [] + result[obj_cat].extend( + self.cache.get_object_assignments(policy_id, _object, obj_cat)) + + if 'action_categories' not in meta_rules[meta_rule_id]: + raise exceptions.MetaRuleContentError(" 'action_categories' key not found ") + + for act_cat in meta_rules[meta_rule_id]['action_categories']: + if act_cat not in result: + result[act_cat] = [] + result[act_cat].extend( + self.cache.get_action_assignments(policy_id, _action, act_cat)) + + self.__pdp_set[meta_rule_id]["target"] = result def __add_target(self, meta_rule_id): """build target from meta_rule @@ -341,4 +349,5 @@ pdp_set: {pdp_set} def __validate_meta_rule_content(self, meta_rules): if 'effect' not in meta_rules: - raise exceptions.PdpContentError + logger.error("meta_rules={}".format(meta_rules)) + raise exceptions.PdpContentError("effect not in meta_rules") diff --git a/python_moonutilities/python_moonutilities/exceptions.py b/python_moonutilities/python_moonutilities/exceptions.py index a43ac89f..8ad90e96 100644 --- a/python_moonutilities/python_moonutilities/exceptions.py +++ b/python_moonutilities/python_moonutilities/exceptions.py @@ -133,6 +133,13 @@ class ModelUnknown(MoonError): logger = "Error" +class ModelContentError(MoonError): + description = _("The model content is invalid.") + code = 400 + title = 'Model Unknown' + logger = "Error" + + class ModelExisting(MoonError): description = _("The model already exists.") code = 409 @@ -197,18 +204,13 @@ class AdminRule(AdminException): code = 400 title = 'Rule Exception' + class CategoryNameInvalid(AdminMetaData): description = _("The given category name is invalid.") - code = 409 + code = 400 title = 'Category Name Invalid' logger = "ERROR" -class SubjectCategoryNameExisting(AdminMetaData): - description = _("The given subject category name already exists.") - code = 409 - title = 'Subject Category Name Existing' - logger = "ERROR" - class SubjectCategoryExisting(AdminMetaData): description = _("The given subject category already exists.") @@ -216,28 +218,12 @@ class SubjectCategoryExisting(AdminMetaData): title = 'Subject Category Existing' logger = "ERROR" - -class ObjectCategoryNameExisting(AdminMetaData): - description = _("The given object category name already exists.") - code = 409 - title = 'Object Category Name Existing' - logger = "ERROR" - - class ObjectCategoryExisting(AdminMetaData): description = _("The given object category already exists.") code = 409 title = 'Object Category Existing' logger = "ERROR" - -class ActionCategoryNameExisting(AdminMetaData): - description = _("The given action category name already exists.") - code = 409 - title = 'Action Category Name Existing' - logger = "ERROR" - - class ActionCategoryExisting(AdminMetaData): description = _("The given action category already exists.") code = 409 @@ -252,6 +238,20 @@ class SubjectCategoryUnknown(AdminMetaData): logger = "ERROR" +class DeleteSubjectCategoryWithMetaRule(MoonError): + description = _("Cannot delete subject category used in meta rule ") + code = 400 + title = 'Subject Category With Meta Rule Error' + logger = "Error" + + +class DeleteObjectCategoryWithMetaRule(MoonError): + description = _("Cannot delete Object category used in meta rule ") + code = 400 + title = 'Object Category With Meta Rule Error' + logger = "Error" + + class ObjectCategoryUnknown(AdminMetaData): description = _("The given object category is unknown.") code = 400 @@ -259,19 +259,33 @@ class ObjectCategoryUnknown(AdminMetaData): logger = "ERROR" +class DeleteActionCategoryWithMetaRule(MoonError): + description = _("Cannot delete Action category used in meta rule ") + code = 400 + title = 'Action Category With Meta Rule Error' + logger = "Error" + + class ActionCategoryUnknown(AdminMetaData): description = _("The given action category is unknown.") code = 400 title = 'Action Category Unknown' logger = "ERROR" - -class PerimeterNameInvalid(AdminPerimeter): - description = _("The given name is not valid.") +class PerimeterContentError(AdminPerimeter): + description = _("Perimeter content is invalid.") code = 400 - title = 'Perimeter Name is Invalid' + title = 'Perimeter content is invalid.' logger = "ERROR" + +class DeletePerimeterWithAssignment(MoonError): + description = _("Cannot delete perimeter with assignment") + code = 400 + title = 'Perimeter With Assignment Error' + logger = "Error" + + class SubjectUnknown(AdminPerimeter): description = _("The given subject is unknown.") code = 400 @@ -313,23 +327,24 @@ class ActionExisting(AdminPerimeter): title = 'Action Existing' logger = "ERROR" + class SubjectNameExisting(AdminPerimeter): description = _("The given subject name is existing.") - code = 400 + code = 409 title = 'Subject Name Existing' logger = "ERROR" class ObjectNameExisting(AdminPerimeter): description = _("The given object name is existing.") - code = 400 + code = 409 title = 'Object Name Existing' logger = "ERROR" class ActionNameExisting(AdminPerimeter): description = _("The given action name is existing.") - code = 400 + code = 409 title = 'Action Name Existing' logger = "ERROR" @@ -392,21 +407,21 @@ class ActionScopeExisting(AdminScope): class SubjectScopeNameExisting(AdminScope): description = _("The given subject scope name is existing.") - code = 400 + code = 409 title = 'Subject Scope Name Existing' logger = "ERROR" class ObjectScopeNameExisting(AdminScope): description = _("The given object scope name is existing.") - code = 400 + code = 409 title = 'Object Scope Name Existing' logger = "ERROR" class ActionScopeNameExisting(AdminScope): description = _("The given action scope name is existing.") - code = 400 + code = 409 title = 'Action Scope Name Existing' logger = "ERROR" @@ -434,21 +449,21 @@ class ActionAssignmentUnknown(AdminAssignment): class SubjectAssignmentExisting(AdminAssignment): description = _("The given subject assignment value is existing.") - code = 400 + code = 409 title = 'Subject Assignment Existing' logger = "ERROR" class ObjectAssignmentExisting(AdminAssignment): description = _("The given object assignment value is existing.") - code = 400 + code = 409 title = 'Object Assignment Existing' logger = "ERROR" class ActionAssignmentExisting(AdminAssignment): description = _("The given action assignment value is existing.") - code = 400 + code = 409 title = 'Action Assignment Existing' logger = "ERROR" @@ -475,23 +490,37 @@ class SubMetaRuleAlgorithmNotExisting(AdminMetaRule): class MetaRuleUnknown(AdminMetaRule): - description = _("The given sub meta rule is unknown.") + description = _("The given meta rule is unknown.") code = 400 - title = 'Sub Meta Rule Unknown' + title = 'Meta Rule Unknown' logger = "ERROR" +class MetaRuleNotLinkedWithPolicyModel(MoonError): + description = _("The meta rule is not found in the model attached to the policy.") + code = 400 + title = 'MetaRule Not Linked With Model - Policy' + logger = "Error" + + +class CategoryNotAssignedMetaRule(MoonError): + description = _("The category is not found in the meta rules attached to the policy.") + code = 400 + title = 'Category Not Linked With Meta Rule - Policy' + logger = "Error" + + class SubMetaRuleNameExisting(AdminMetaRule): description = _("The sub meta rule name already exists.") - code = 400 + code = 409 title = 'Sub Meta Rule Name Existing' logger = "ERROR" class MetaRuleExisting(AdminMetaRule): - description = _("The sub meta rule already exists.") - code = 400 - title = 'Sub Meta Rule Existing' + description = _("The meta rule already exists.") + code = 409 + title = 'Meta Rule Existing' logger = "ERROR" @@ -502,13 +531,27 @@ class MetaRuleContentError(AdminMetaRule): logger = "ERROR" +class MetaRuleUpdateError(AdminMetaRule): + description = _("Meta_rule is used in Rule.") + code = 400 + title = 'Meta_Rule Update Error' + logger = "ERROR" + + class RuleExisting(AdminRule): description = _("The rule already exists.") - code = 400 + code = 409 title = 'Rule Existing' logger = "ERROR" +class RuleContentError(AdminRule): + description = _("Invalid content of rule.") + code = 400 + title = 'Rule Error' + logger = "ERROR" + + class RuleUnknown(AdminRule): description = _("The rule for that request doesn't exist.") code = 400 @@ -570,6 +613,7 @@ class ConsulComponentContentError(ConsulError): title = 'Consul Content error' logger = "WARNING" + # Containers exceptions @@ -638,7 +682,7 @@ class PdpExisting(MoonError): class PdpContentError(MoonError): description = _("Invalid content of pdp.") - code = 409 + code = 400 title = 'Pdp Error' logger = "Error" @@ -656,11 +700,24 @@ class PolicyUnknown(MoonError): title = 'Policy Unknown' logger = "Error" +class PolicyContentError(MoonError): + description = _("The policy content is invalid.") + code = 400 + title = 'Policy Content Error' + logger = "Error" + class PolicyExisting(MoonError): description = _("The policy already exists.") code = 409 - title = 'Policy Error' + title = 'Policy Already Exists' + logger = "Error" + + +class PolicyUpdateError(MoonError): + description = _("The policy data is used.") + code = 400 + title = 'Policy update error' logger = "Error" @@ -674,33 +731,103 @@ class DeleteData(MoonError): class DeleteCategoryWithData(MoonError): description = _("Cannot delete category with data") code = 400 - title = 'Category Error' + title = 'Category With Data Error' logger = "Error" class DeleteCategoryWithMetaRule(MoonError): description = _("Cannot delete category with meta rule") code = 400 - title = 'Category Error' + title = 'Category With MetaRule Error' + logger = "Error" + + +class DeleteCategoryWithAssignment(MoonError): + description = _("Cannot delete category with assignment ") + code = 400 + title = 'Category With Assignment Error' logger = "Error" class DeleteModelWithPolicy(MoonError): description = _("Cannot delete model with policy") code = 400 - title = 'Model Error' + title = 'Model With Policy Error' logger = "Error" class DeletePolicyWithPdp(MoonError): description = _("Cannot delete policy with pdp") code = 400 - title = 'Policy Error' + title = 'Policy With PDP Error' + logger = "Error" + + +class DeletePolicyWithPerimeter(MoonError): + description = _("Cannot delete policy with perimeter") + code = 400 + title = 'Policy With Perimeter Error' + logger = "Error" + + +class DeletePolicyWithData(MoonError): + description = _("Cannot delete policy with data") + code = 400 + title = 'Policy With Data Error' + logger = "Error" + + +class DeletePolicyWithRules(MoonError): + description = _("Cannot delete policy with rules") + code = 400 + title = 'Policy With Rule Error' logger = "Error" class DeleteMetaRuleWithModel(MoonError): description = _("Cannot delete meta rule with model") code = 400 - title = 'Meta rule Error' + title = 'Meta rule With Model Error' + logger = "Error" + + +class DeleteMetaRuleWithRule(MoonError): + description = _("Cannot delete meta rule with rule") + code = 400 + title = 'Meta rule With Model Error' + logger = "Error" + + +class DataUnknown(MoonError): + description = _("The data unknown.") + code = 400 + title = 'Data Unknown' + logger = "Error" + + +class ValidationContentError(MoonError): + description = _("The Content validation incorrect.") + code = 400 + title = 'Invalid Content' + logger = "Error" + + def __init__(self, message=""): + self.message = message + super().__init__(message) + + def __str__(self): + return self.message + + +class ValidationKeyError(MoonError): + description = _("The Key validation incorrect.") + code = 400 + title = 'Invalid Key' logger = "Error" + + def __init__(self, message=""): + self.message = message + super().__init__(message) + + def __str__(self): + return self.message diff --git a/python_moonutilities/python_moonutilities/security_functions.py b/python_moonutilities/python_moonutilities/security_functions.py index 5d5275ee..1069eb2f 100644 --- a/python_moonutilities/python_moonutilities/security_functions.py +++ b/python_moonutilities/python_moonutilities/security_functions.py @@ -4,6 +4,7 @@ # or at 'http://www.apache.org/licenses/LICENSE-2.0'. +import html import re import os import types @@ -22,6 +23,7 @@ __targets = {} def filter_input(func_or_str): + def __filter(string): if string and type(string) is str: return "".join(re.findall("[\w\- +]*", string)) @@ -88,28 +90,22 @@ To do should check value of Dictionary but it's dependent on from where it's com def validate_data(data): def __validate_string(string): - if not string: - raise ValueError('Empty String') - ''' - is it valid to contains space inbetween - - ''' - - if " " in string: - raise ValueError('String contains space') + temp_str = html.escape(string) + if string != temp_str: + raise exceptions.ValidationContentError('Forbidden characters in string') def __validate_list_or_tuple(container): - if not container: - raise ValueError('Empty Container') for i in container: validate_data(i) def __validate_dict(dictionary): - if not dictionary: - raise ValueError('Empty Dictionary') for key in dictionary: validate_data(dictionary[key]) + if isinstance(data, bool): + return True + if data is None: + data = "" if isinstance(data, str): __validate_string(data) elif isinstance(data, list) or isinstance(data, tuple): @@ -117,7 +113,7 @@ def validate_data(data): elif isinstance(data, dict): __validate_dict(data) else: - raise ValueError('Value is Not String or Container or Dictionary') + raise exceptions.ValidationContentError('Value is Not String or Container or Dictionary: {}'.format(data)) def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]): @@ -161,24 +157,30 @@ def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]): validate_data(temp_args[i]) while len(kwargs_state) < len(kwargs): - kwargs_state.append(True) + kwargs_state.append(False) counter = 0 for i in kwargs: if kwargs_state[counter]: - validate_data({i: kwargs[i]}) + validate_data(kwargs[i]) counter = counter + 1 if type == "post" or type == "patch": body = request.json - while len(body_state) < len(body): - body_state.append(True) - counter = 0 - for i in body: - if body_state[counter]: - validate_data({i: body[i]}) - - counter = counter + 1 + # while len(body_state) < len(body): + # body_state.append(True) + # counter = 0 + for key in body_state: + if key in body: + if body_state[key]: + try: + validate_data(body.get(key)) + except exceptions.ValidationContentError as e: + raise exceptions.ValidationContentError("Key: '{}', [{}]".format(key, str(e))) + else: + raise exceptions.ValidationKeyError('Invalid Key :{} not found'.format(key)) + + # counter = counter + 1 return func(*args, **kwargs) @@ -189,16 +191,13 @@ def validate_input(type='get', args_state=[], kwargs_state=[], body_state=[]): def enforce(action_names, object_name, **extra): """Fake version of the enforce decorator""" - def wrapper_func(func): def wrapper_args(*args, **kwargs): # LOG.info("kwargs={}".format(kwargs)) # kwargs['user_id'] = kwargs.pop('user_id', "admin") # LOG.info("Calling enforce on {} with args={} kwargs={}".format(func.__name__, args, kwargs)) return func(*args, **kwargs) - return wrapper_args - return wrapper_func @@ -329,5 +328,4 @@ def check_auth(function): user_id = kwargs.pop("user_id", token) result = function(*args, **kwargs, user_id=user_id) return result - return wrapper diff --git a/python_moonutilities/tests/unit_python/requirements.txt b/python_moonutilities/tests/unit_python/requirements.txt index 3c1ad607..b08a2603 100644 --- a/python_moonutilities/tests/unit_python/requirements.txt +++ b/python_moonutilities/tests/unit_python/requirements.txt @@ -1,2 +1 @@ -pytest requests_mock
\ No newline at end of file diff --git a/python_moonutilities/tests/unit_python/test_validated_input.py b/python_moonutilities/tests/unit_python/test_validated_input.py index c8e681e9..723bc8ba 100644 --- a/python_moonutilities/tests/unit_python/test_validated_input.py +++ b/python_moonutilities/tests/unit_python/test_validated_input.py @@ -1,166 +1,129 @@ +# Copyright 2018 Open Platform for NFV Project, Inc. and its contributors +# This software is distributed under the terms and conditions of the 'Apache-2.0' +# license which can be found in the file 'LICENSE' in this package distribution +# or at 'http://www.apache.org/licenses/LICENSE-2.0'. + + import pytest def test_valid_string(): from python_moonutilities.security_functions import validate_data validate_data("CorrectString") + validate_data("Correct String") + validate_data("Correct String!") + validate_data("Correct String@") + validate_data(None) + validate_data(True) -def test_unvalid_string(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data("Notcorrect String") - - assert str(exception_info.value) == 'String contains space' -def test_empty_string(): +def test_invalid_string(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data("") + validate_data("Notcorrect<a>String") - assert str(exception_info.value) == 'Empty String' + assert str(exception_info.value) == 'Forbidden characters in string' def test_none_value(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data(None) + validate_data(object) - assert str(exception_info.value) == 'Value is Not String or Container or Dictionary' + assert 'Value is Not String or Container or Dictionary' in str(exception_info.value) -def test_int_value(): +def test_numeric_value(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: validate_data(1) + assert 'Value is Not String or Container or Dictionary' in str(exception_info.value) - assert str(exception_info.value) == 'Value is Not String or Container or Dictionary' - - -def test_float_value(): - from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: validate_data(1.23) - - assert str(exception_info.value) == 'Value is Not String or Container or Dictionary' + assert 'Value is Not String or Container or Dictionary' in str(exception_info.value) -def test_correct_list(): +def test_correct_list_one_element(): from python_moonutilities.security_functions import validate_data - validate_data(["skjdnfa","dao","daosdjpw"]) + validate_data(["test_1", "test_2", "test_3"]) -def test_correct_list(): +def test_correct_list_multiple_element(): from python_moonutilities.security_functions import validate_data - validate_data(["skjdnfa"]) + validate_data(["test"]) -def test_correct_instead_list(): +def test_correct_nested_list(): from python_moonutilities.security_functions import validate_data - validate_data([["skjdnfa","daswi"],[["daskdlw"],["daklwo"]],["dawl","afioa"],["dawno"]]) - - -def test_empty_list(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data([]) - - assert str(exception_info.value) == 'Empty Container' - - -def test_empty_list_inside_other_list(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data(["dajiwdj",[]]) - - assert str(exception_info.value) == 'Empty Container' + validate_data([["test_1", "test_2"], [["test_3"], ["test_4"]], ["test_5", "test_6"], ["test_7"]]) def test_incorrect_string_inside_list(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data(["dajiwdj",["dakwe","daow awoepa"]]) - - assert str(exception_info.value) == 'String contains space' - + validate_data(["test_1", ["test_2", "forbidden<a>character"]]) -def test_empty_string_inside_list(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data(["dajiwdj", ["dakwe", ""]]) - - assert str(exception_info.value) == 'Empty String' + assert str(exception_info.value) == 'Forbidden characters in string' def test_correct_tuples(): from python_moonutilities.security_functions import validate_data - validate_data(("dasdw","dawdwa")) - - -def test_empty_tuples(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data(()) + validate_data(("test_1", "test_2")) - assert str(exception_info.value) == 'Empty Container' def test_correct_tuple_of_tuple(): from python_moonutilities.security_functions import validate_data - validate_data(("gjosjefa",("diwajdi","oejfoea"),(("jwdi","fjia"),("nfioa","ifao")))) + validate_data(("test_1", ("test_2", "test_3"), (("test_4", "test_5"), ("test_6", "test_7")))) -def test_incorrect_tuple(): +def test_incorrect_string_within_tuple(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data(("djawo","dowa afw")) + validate_data(("test_1", "forbidden<a>character")) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' def test_correct_dictionary(): from python_moonutilities.security_functions import validate_data - validate_data({"daiwdw":"dwioajd"}) - - -def test_incorrect_dictionary(): - from python_moonutilities.security_functions import validate_data - with pytest.raises(Exception) as exception_info: - validate_data({"daiwdw":"dwioa jd"}) + validate_data({"test_1": "test_2"}) - assert str(exception_info.value) == 'String contains space' -def test_empty_dictionary(): +def test_incorrect_string_within_dictionary(): from python_moonutilities.security_functions import validate_data with pytest.raises(Exception) as exception_info: - validate_data({}) + validate_data({"test_1": "forbidden<a>character"}) - assert str(exception_info.value) == 'Empty Dictionary' + assert str(exception_info.value) == 'Forbidden characters in string' def test_correct_function_pass(): from python_moonutilities.security_functions import validate_input @validate_input() - def temp_function(string,list,tuple): - if string!="teststring" : + def temp_function(string, list, tuple): + if string != "teststring": raise ValueError("values which passed incorrect") - temp_function("teststring",["teststring",["teststring"]],("teststring",("teststring"))) + temp_function("teststring", ["teststring", ["teststring"]], ("teststring", ("teststring", ))) -def test_incorrect_function_pass1(): + +def test_incorrect_validating_function_with_kwargs(): from python_moonutilities.security_functions import validate_input - @validate_input() + @validate_input(kwargs_state=[True,True]) def temp_function(string, list, tuple): if string != "teststring": raise ValueError("values which passed incorrect") with pytest.raises(Exception) as exception_info: - temp_function("teststring",list=["teststring", ["testst ring"]],tuple=("teststring", ("teststri ng"))) + temp_function("teststring", list=["teststring", ["testst<a>ring"]],tuple=("teststring", ("teststri<a>ng", ))) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' -def test_incorrect_function_pass2(): +def test_incorrect_validating_function(): from python_moonutilities.security_functions import validate_input @validate_input() @@ -169,23 +132,23 @@ def test_incorrect_function_pass2(): raise ValueError("values which passed incorrect") with pytest.raises(Exception) as exception_info: - temp_function("teststring", ["teststring", ["teststri ng"]], {"teststring": ("teststring")}) + temp_function("teststring", ["teststring", ["teststri<a>ng"]], {"teststring": ("teststring", )}) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' -def test_incorrect_function_pass3(): +def test_incorrect_validating_class_function(): from python_moonutilities.security_functions import validate_input - class x: + class Testclass: @validate_input() - def temp_function(string, list, dictionary): + def temp_function(self, string, list, dictionary): if string != "teststring": raise ValueError("values which passed incorrect") - e=x; + e = Testclass() with pytest.raises(Exception) as exception_info: - e.temp_function("teststring", ["teststring", ["teststri ng"]], {"teststring": ("teststring")}) + e.temp_function("teststring", ["teststring", ["teststri<a>ng"]], {"teststring": ("teststring", )}) - assert str(exception_info.value) == 'String contains space' + assert str(exception_info.value) == 'Forbidden characters in string' |