Example #1
0
 def var(var: str):
     try:
         if '.' in var:
             return _extract_attr(scope=Config.vars, attr_path=var)
         else:
             return Config.vars[var]
     except (KeyError, TypeError):
         raise InvalidVarException(var=var)
Example #2
0
    def l10n(*, locale: str, term: str):
        if locale not in Config.l10n.keys():
            raise InvalidLocaleException(locale=locale)

        try:
            if '.' in term:
                return _extract_attr(scope=Config.l10n[locale], attr_path=term)
            else:
                return Config.l10n[locale][term]
        except (KeyError, TypeError):
            raise InvalidLocaleTermException(locale=locale, term=term)
Example #3
0
class File(BaseModule):
	'''`File` module provides functionality for `File Upload Workflow`.'''

	collection = 'files'
	attrs = {
		'user': ATTR.ID(desc='`_id` of `User` doc file belongs to.'),
		'file': ATTR.FILE(desc='File object.'),
		'create_time': ATTR.DATETIME(
			desc='Python `datetime` ISO format of the doc creation.'
		),
	}
	methods = {
		'read': METHOD(permissions=[PERM(privilege='__sys')]),
		'create': METHOD(
			permissions=[PERM(privilege='create')],
			post_method=True,
		),
		'delete': METHOD(permissions=[PERM(privilege='__sys')]),
	}

	async def on_read(self, results, skip_events, env, query, doc, payload):
		for i in range(len(results['docs'])):
			results['docs'][i]['file']['lastModified'] = int(
				results['docs'][i]['file']['lastModified']
			)
		return (results, skip_events, env, query, doc, payload)

	async def pre_create(self, skip_events, env, query, doc, payload):
		if Config.file_upload_limit != -1 and len(doc['file']) > Config.file_upload_limit:
			raise self.exception(
				status=400,
				msg=f'File size is beyond allowed limit.',
				args={
					'code': 'INVALID_SIZE',
					'attr': doc['__attr'].decode('utf-8'),
					'name': doc['name'].decode('utf-8'),
				},
			)
		if (module := doc['__module'].decode('utf-8')) not in Config.modules.keys():
			raise self.exception(
				status=400,
				msg=f'Invalid module \'{module}\'',
				args={'code': 'INVALID_MODULE'},
			)

		try:
			attr_type = _extract_attr(
				scope=Registry.module(module).attrs,
				attr_path='$__' + (attr := doc['__attr'].decode('utf-8')),
			)
Example #4
0
async def _extend_doc(
    *,
    env: NAWAH_ENV,
    doc: NAWAH_DOC,
    attr: Optional[NAWAH_DOC],
    extn_id: ObjectId,
    extn: EXTN,
    extn_models: Dict[str, Optional[BaseModel]] = {},
) -> Optional[BaseModel]:
    # [DOC] Check if extn module is dynamic value
    if extn.module.startswith('$__'):
        extn_module = Config.modules[_extract_attr(scope={
            'doc': doc,
            'attr': attr
        },
                                                   attr_path=extn.module)]
    else:
        extn_module = Config.modules[extn.module]
    # [DOC] Check if extn attr set to fetch all or specific attrs
    if type(extn.attrs) == str and extn.attrs.startswith(
            '$__'):  # type: ignore
        extn.attrs = cast(str, extn.attrs)
        extn_attrs = _extract_attr(scope={
            'doc': doc,
            'attr': attr
        },
                                   attr_path=extn.attrs)
        if extn_attrs[0] == '*':
            extn_attrs = {
                attr: extn_module.attrs[attr]
                for attr in extn_module.attrs.keys()
            }
    elif extn.attrs[0] == '*':
        extn_attrs = {
            attr: extn_module.attrs[attr]
            for attr in extn_module.attrs.keys()
        }
    else:
        extn_attrs = {attr: extn_module.attrs[attr] for attr in extn.attrs}
    # [DOC] Implicitly add _id key to extn attrs so that we don't delete it in process
    extn_attrs['_id'] = 'id'
    # [DOC] Set skip events
    skip_events = [Event.PERM]
    # [DOC] Check if extn instruction is explicitly requires second-dimension extn.
    if extn.force == False:
        skip_events.append(Event.EXTN)
    elif type(extn.force) == str and extn.force.startswith(
            '$__'):  # type: ignore
        extn.force = cast(str, extn.force)
        if not _extract_attr(scope={
                'doc': doc,
                'attr': attr
        },
                             attr_path=extn.force):
            skip_events.append(Event.EXTN)
    # [DOC] Read doc if not in extn_models
    if str(extn_id) not in extn_models.keys():
        extn_results = await extn_module.methods['read'](
            skip_events=skip_events + (extn.skip_events or []),
            env=env,
            query=[{
                '_id': extn_id
            }] + (extn.query or []),  # type: ignore
        )
        if extn_results['args']['count']:
            extn_models[str(extn_id)] = extn_results['args']['docs'][0]
        else:
            extn_models[str(extn_id)] = None
    # [DOC] Set attr to extn_models doc
    extn_doc = copy.deepcopy(extn_models[str(extn_id)])
    # [DOC] delete all unneeded keys from the resulted doc
    if extn_doc:
        extn_doc = BaseModel({
            attr: extn_doc[attr]
            for attr in extn_attrs.keys() if attr in extn_doc
        })
    return extn_doc
Example #5
0
def test_extract_attr_list_item(attr_obj):
    attr_val = _extract_attr(scope=attr_obj, attr_path='$__list_item1:1')
    assert attr_val == 'list_child2'
Example #6
0
def test_extract_attr_nested_obj_dict_item(attr_obj):
    attr_val = _extract_attr(scope=attr_obj,
                             attr_path='$__nested_obj.dict.list:0')
    assert attr_val == 'item1'
Example #7
0
def test_extract_attr_nested_obj_list_item(attr_obj):
    attr_val = _extract_attr(scope=attr_obj,
                             attr_path='nested_obj.list:1.item2')
    assert attr_val == 'val2'
Example #8
0
def test_extract_attr_item(attr_obj):
    attr_val = _extract_attr(scope=attr_obj, attr_path='item2')
    assert attr_val == 'val2'
Example #9
0
def test_extract_attr_nested_list_item(attr_obj):
    attr_val = _extract_attr(scope=attr_obj, attr_path='nested_list:1:0')
    assert attr_val == 'child_child_item21'
Example #10
0
def test_extract_attr_nested_dict_item(attr_obj):
    attr_val = _extract_attr(
        scope=attr_obj,
        attr_path='$__nested_dict.child_dict.child_child_item1')
    assert attr_val == 'child_child_val1'
Example #11
0
def test_extract_attr_dict_item(attr_obj):
    attr_val = _extract_attr(scope=attr_obj,
                             attr_path='dict_item1.dict_child2')
    assert attr_val == 'child_val2'
Example #12
0
async def _parse_permission_args(
    skip_events: List[Event],
    env: NAWAH_ENV,
    query: Union[NAWAH_QUERY, Query],
    doc: NAWAH_DOC,
    permission_args: Any,
):
    user = env['session'].user

    args_iter: Iterable

    if type(permission_args) == list:
        args_iter = range(len(permission_args))
    elif type(permission_args) == dict:
        args_iter = list(permission_args.keys())

    for j in args_iter:
        if type(permission_args[j]) == ATTR:
            try:
                permission_args[j] = await validate_attr(
                    mode='create',
                    attr_name=j,
                    attr_type=permission_args[j],
                    attr_val=doc[j],
                    skip_events=[],
                    env=env,
                    query=query,
                    doc=doc,
                    scope=doc,
                )
            except InvalidAttrException as e:
                raise e
            except:
                # [DOC] There is a chance doc[j] is invalid, so try to get the type in try..except
                try:
                    raise InvalidAttrException(
                        attr_name=j,
                        attr_type=permission_args[j],
                        val_type=type(doc[j]),
                    )
                except:
                    raise InvalidAttrException(
                        attr_name=j,
                        attr_type=permission_args[j],
                        val_type=None,
                    )
        elif type(permission_args[j]) == dict:
            # [DOC] Check opers
            for oper in [
                    '$gt',
                    '$lt',
                    '$gte',
                    '$lte',
                    '$bet',
                    '$ne',
                    '$regex',
                    '$all',
                    '$in',
                    '$nin',
            ]:
                if oper in permission_args[j].keys():
                    if oper == '$bet':
                        permission_args[j][
                            '$bet'] = await _parse_permission_args(
                                skip_events=skip_events,
                                env=env,
                                query=query,
                                doc=doc,
                                permission_args=permission_args[j]['$bet'],
                            )
                    else:
                        permission_args[j][
                            oper] = await _parse_permission_args(
                                skip_events=skip_events,
                                env=env,
                                query=query,
                                doc=doc,
                                permission_args={
                                    oper: permission_args[j][oper]
                                },
                            )
                        permission_args[j][oper] = permission_args[j][oper][
                            oper]
                    # [DOC] Continue the iteration
                    continue
            # [DOC] Child args, parse
            permission_args[j] = await _parse_permission_args(
                skip_events=skip_events,
                env=env,
                query=query,
                doc=doc,
                permission_args=permission_args[j],
            )
        elif type(permission_args[j]) == list:
            permission_args[j] = await _parse_permission_args(
                skip_events=skip_events,
                env=env,
                query=query,
                doc=doc,
                permission_args=permission_args[j],
            )
        elif type(permission_args[j]) == str:
            # [DOC] Check for variables
            if permission_args[j] == '$__user':
                permission_args[j] = user._id
            elif permission_args[j].startswith('$__user.'):
                try:
                    permission_args[j] = _extract_attr(
                        scope=user,
                        attr_path=permission_args[j].replace(
                            '$__user.', '$__'),
                    )
                except Exception as e:
                    # [TODO] Log exception
                    # [DOC] For values that are expected to have a list value, return empty list
                    if type(permission_args) == dict and j in ['$in', '$nin']:
                        permission_args[j] = [None]
                    else:
                        permission_args[j] = None
            elif permission_args[j] == '$__access':
                permission_args[j] = {
                    '$__user': user._id,
                    '$__groups': user.groups
                }
            elif permission_args[j] == '$__datetime':
                permission_args[j] = datetime.datetime.utcnow().isoformat()
            elif permission_args[j] == '$__date':
                permission_args[j] = datetime.date.today().isoformat()
            elif permission_args[j] == '$__time':
                permission_args[j] = datetime.datetime.now().time().isoformat()

    return permission_args