async def add_security_query(self, query, request=None): users = [] roles = [] if request is None: request = get_current_request() interaction = IInteraction(request) for user in interaction.participations: users.append(user.principal.id) users.extend(user.principal.groups) roles_dict = interaction.global_principal_roles( user.principal.id, user.principal.groups) roles.extend([key for key, value in roles_dict.items() if value]) # We got all users and roles # users: users and groups should_list = [{'match': {'access_roles': x}} for x in roles] should_list.extend([{'match': {'access_users': x}} for x in users]) if 'query' not in query: query['query'] = {} if 'bool' not in query['query']: query['query']['bool'] = {} if 'filter' not in query['query']['bool']: query['query']['bool']['filter'] = {} query['query']['bool']['filter'] = { 'bool': { 'should': should_list, 'minimum_number_should_match': 1 } } return query
async def _build_security_query( self, site, query, doc_type=None, size=10, request=None): if query is None: query = {} q = { 'index': self.get_index_name(site) } if doc_type is not None: q['doc_type'] = doc_type # The users who has plone.AccessContent permission by prinperm # The roles who has plone.AccessContent permission by roleperm users = [] roles = [] if request is None: request = get_current_request() interaction = IInteraction(request) for user in interaction.participations: users.append(user.principal.id) users.extend(user.principal.groups) roles_dict = interaction.global_principal_roles( user.principal.id, user.principal.groups) roles.extend([key for key, value in roles_dict.items() if value]) # We got all users and roles # users: users and groups should_list = [{'match': {'access_roles': x}} for x in roles] should_list.extend([{'match': {'access_users': x}} for x in users]) permission_query = { 'query': { 'bool': { 'filter': { 'bool': { 'should': should_list, 'minimum_should_match': 1 } } } } } query = rec_merge(query, permission_query) # query.update(permission_query) q['body'] = query q['size'] = size return q
def check_permission(self, permission_name): if permission_name is None: return True if permission_name not in self.permission_cache: permission = queryUtility(IPermission, name=permission_name) if permission is None: self.permission_cache[permission_name] = True else: security = IInteraction(self.request) self.permission_cache[permission_name] = bool( security.checkPermission(permission.title, self.context)) return self.permission_cache[permission_name]
def get_principals_with_access_content(obj, request=None): if obj is None: return {} if request is None: request = get_current_request() interaction = IInteraction(request) roles = interaction.cached_roles(obj, 'plone.AccessContent', 'o') result = [] for r in roles.keys(): lroles = role.local_roles() if r in lroles: result.append(r) users = interaction.cached_principals(obj, result, 'plone.AccessContent', 'o') return list(users.keys())
def get_roles_with_access_content(obj, request=None): """ Return the roles that has access to the content that are global roles""" if obj is None: return [] if request is None: request = get_current_request() interaction = IInteraction(request) roles = interaction.cached_roles(obj, 'plone.AccessContent', 'o') result = [] for r in roles.keys(): lroles = role.global_roles() if r in lroles: result.append(r) return result
def check_permission(self, permission_name): if permission_name is None: return True if permission_name not in self.permission_cache: permission = queryUtility(IPermission, name=permission_name) if permission is None: self.permission_cache[permission_name] = True else: security = IInteraction(self.request) self.permission_cache[permission_name] = bool( security.check_permission(permission.title, self.context)) return self.permission_cache[permission_name]
def check_setattr(self, obj, name): # Lookup or cached permission lookup portal_type = getattr(obj, 'portal_type', None) permission = self.setters.get((portal_type, name), _marker) # Lookup for the permission if permission is _marker: if name in _available_by_default: return permission = DEFAULT_WRITE_PERMISSION adapted = IResource(obj, None) if adapted is not None: for schema in iter_schemata(adapted): mapping = merged_tagged_value_dict(schema, write_permission.key) if name in mapping: permission = mapping.get(name) break self.setters[(portal_type, name)] = permission if IInteraction(self.request).checkPermission(permission, obj): return # has permission __traceback_supplement__ = (TracebackSupplement, obj) raise Unauthorized(obj, name, permission)
def __call__(self): result = super(SerializeFolderToJson, self).__call__() security = IInteraction(self.request) length = len(self.context) if length > MAX_ALLOWED: result['items'] = [] else: result['items'] = [ getMultiAdapter((member, self.request), ISerializeToJsonSummary)() for ident, member in self.context.items() if not ident.startswith('_') and bool( security.checkPermission('plone.AccessContent', self.context)) ] result['length'] = length return result
def __call__(self): result = super(SerializeFolderToJson, self).__call__() security = IInteraction(self.request) length = len(self.context) if length > MAX_ALLOWED or length == 0: result['items'] = [] else: result['items'] = [ getMultiAdapter( (member, self.request), IResourceSerializeToJsonSummary)() for ident, member in self.context.items() if not ident.startswith('_') and bool(security.check_permission( 'plone.AccessContent', self.context)) ] result['length'] = length return result
def check(self, obj, name): permission = self.get_permissions.get(name) if permission is not None: if permission is CheckerPublic: return # Public request = get_current_request() if IInteraction(request).checkPermission(permission, obj): return else: __traceback_supplement__ = (TracebackSupplement, obj) raise Unauthorized(obj, name, permission) elif name in _available_by_default: return if name != '__iter__' or hasattr(obj, name): __traceback_supplement__ = (TracebackSupplement, obj) raise ForbiddenAttribute(name, obj)
def effective_principals(principal_or_interaction, acc=None): """Returns all the principals including recursive groups""" if acc is None: acc = [] if IInteraction.providedBy(principal_or_interaction): for participation in principal_or_interaction.participations: effective_principals(participation.principal, acc) else: auth = getUtility(IAuthentication, context=None) acc.append(principal_or_interaction) for group in principal_or_interaction.groups: principal = auth.getPrincipal(group) if isinstance(principal, Group) or not isinstance(principal, User): effective_principals(principal, acc) return acc
def check_setattr(self, obj, name): if self.set_permissions: permission = self.set_permissions.get(name) else: permission = None if permission is not None: if permission is CheckerPublic: return # Public request = get_current_request() if IInteraction(request).checkPermission(permission, obj): return # allowed else: __traceback_supplement__ = (TracebackSupplement, obj) raise Unauthorized(obj, name, permission) __traceback_supplement__ = (TracebackSupplement, obj) raise ForbiddenAttribute(name, obj)
def principal_from_request(request=None): """ principal_from_request(request: IRequest) -> IPrincipal Find the primary :class:`IPrincipal` for the *request*. First adapts the request into an :class:`IInteraction` (probably using :func:`interaction_from_request`), and then adapts the interaction into an ``IPrincipal`` (probably using :func:`principal_from_interaction`). If there is no interaction, the unauthenticated principal is returned. This is registered as an adapter on the Pyramid ``IRequest`` interface; to provide a more specific policy, register an adapter on the concrete class. """ try: interaction = IInteraction( request if request is not None else get_current_request(), ) except NoInteraction: return component.getUtility(IFallbackUnauthenticatedPrincipal) return IPrincipal(interaction)
def get_current_interaction(request): interaction = getattr(request, 'security', None) if IInteraction.providedBy(interaction): return interaction return Interaction(request)
async def real_resolve(self, request): """Main function to resolve a request.""" alsoProvides(request, IRequest) alsoProvides(request, IDefaultLayer) request._futures = {} request.security = IInteraction(request) method = app_settings['http_methods'][request.method] language = language_negotiation(request) language_object = language(request) try: resource, tail = await self.traverse(request) except Exception as _exc: request.resource = request.tail = None request.exc = _exc # XXX should only should traceback if in some sort of dev mode? raise HTTPBadRequest(text=json.dumps({ 'success': False, 'exception_message': str(_exc), 'exception_type': getattr(type(_exc), '__name__', str(type(_exc))), # noqa 'traceback': traceback.format_exc() })) request.resource = resource request.tail = tail if request.resource is None: raise HTTPBadRequest(text='Resource not found') traverse_to = None if tail and len(tail) == 1: view_name = tail[0] elif tail is None or len(tail) == 0: view_name = '' else: view_name = tail[0] traverse_to = tail[1:] await self.apply_authorization(request) translator = queryMultiAdapter( (language_object, resource, request), ITranslated) if translator is not None: resource = translator.translate() # Add anonymous participation if len(request.security.participations) == 0: # logger.info("Anonymous User") request.security.add(AnonymousParticipation(request)) # Site registry lookup try: view = queryMultiAdapter( (resource, request), method, name=view_name) except AttributeError: view = None # Traverse view if its needed if traverse_to is not None and view is not None: if not ITraversableView.providedBy(view): return None else: try: view = view.publishTraverse(traverse_to) except Exception as e: logger.error( "Exception on view execution", exc_info=e) return None permission = getUtility(IPermission, name='plone.AccessContent') allowed = request.security.checkPermission(permission.id, resource) if not allowed: # Check if its a CORS call: if IOPTIONS != method or not app_settings['cors']: # Check if the view has permissions explicit if view is None or not view.__allow_access__: logger.warn("No access content {content} with {auths}".format( content=resource, auths=str([x.principal.id for x in request.security.participations]))) raise HTTPUnauthorized() if view is None and method == IOPTIONS: view = DefaultOPTIONS(resource, request) checker = getCheckerForInstancesOf(view.__class__) if checker is not None: view = ProxyFactory(view, checker) # We want to check for the content negotiation renderer = content_type_negotiation(request, resource, view) renderer_object = renderer(request) rendered = queryMultiAdapter( (renderer_object, view, request), IRendered) if rendered is not None: return MatchInfo(resource, request, view, rendered) else: return None