def get_permissions(self, user, loaded): hoisted_read = Permissions.get_permissions( user, loaded[-1]) & Permissions.READ if self.resource: if super().get_permissions(user, loaded) != Permissions.ADMIN: loaded = loaded[:-1] return super().get_permissions(user, loaded) | hoisted_read
def prepare(self): super().prepare() if self.request.method == 'OPTIONS': return # Dont do anything for OPTIONS requests resources = [] resource = self.resource while resource: resources = [resource] + resources resource = resource.parent loaded = [ r.load(self.path_kwargs[r.name + '_id'], self.request) for r in resources if self.path_kwargs.get(r.name + '_id') ] self.permissions = Permissions.get_permissions(self.current_user, *loaded) # TODO this is kinda hacky self.current_user.permissions = self.permissions # TODO 404s get raised before permissions are checked required_permissions = self.resource.get_permissions(self.request) if (required_permissions & self.permissions) != required_permissions: if self.current_user.uid is None: raise exceptions.Unauthorized() raise exceptions.Forbidden(required_permissions)
def attributes(self): full = self._permission == Permissions.ADMIN or ((self._permission ^ Permissions.get_permissions(self._user, Collection(self._instance))) & Permissions.READ) == Permissions.READ return { 'name': self._instance.ref, 'schema': self._instance.data.get('schema'), **({} if not full else { 'plugins': self._instance.data.get('plugins', {}), 'permissions': { sel: Permissions(perm).name for sel, perm in self._instance.data['permissions'].items() } }) }
def prepare(self): super().prepare() if self.request.method == 'OPTIONS': return # Dont do anything for OPTIONS requests loaded = [] try: for view in self._view_class.lineage(): key = view.name + '_id' if self.path_kwargs[key] is None: break loaded.append(view.load(self.path_kwargs[key], *loaded)) except exceptions.NotFound as e: err = e # Load as many resources as are available to do a permissions check # A 404 will be thrown if the user has the required permissions self._view = view(*loaded) else: err = None self._view = self._view_class(*loaded) # If this is a relationship swap out the current view with the relation if 'relationship' in self.path_kwargs: relationship = self._serializer.relations[self.path_kwargs['relationship']] self._view = relationship.view(*loaded) self._serializer = relationship.serializer() permissions = Permissions.get_permissions(self.current_user, *loaded) required_permissions = self._view.get_permissions(self.request) # For use later on self.current_user.permissions = permissions # Check permissions if (required_permissions & permissions) != required_permissions: if self.current_user.uid is None: raise exceptions.Unauthorized() raise exceptions.Forbidden(required_permissions) # Not found is always raised AFTER permissions checks if err: raise err if self.request.method in ('GET', 'DELETE'): return # GET and DELETE bodies are ignored self.payload # Force payload to load and validate
async def patch(self, handler): if not handler.payload: raise exceptions.BadRequest() if not handler.payload.attributes.get('id'): raise exceptions.BadRequest(detail='Id must be provided') error = None id = handler.payload.attributes.pop('id') try: doc = self.collection.read(id) except exceptions.NotFound as e: error = e permissions = handler.current_user.permissions | Permissions.get_permissions(handler.current_user, doc) if error or not (permissions & Permissions.UPDATE): return handler.write({ 'data': { 'id': id, 'type': 'suppressions', 'attributes': {} } }) email = self.extract_email(doc=doc) headers = {'Authorization': 'Bearer {}'.format(self.sendgrid_key)} for group, subscribe in list(handler.payload.attributes.items()): if subscribe: async with aiohttp.post('https://api.sendgrid.com/v3/asm/groups/{}/suppressions'.format(group), headers=headers, data=json.dumps({'recipient_emails': [email]})) as response: assert response.status == 201 # TODO Handle errors else: async with aiohttp.delete('https://api.sendgrid.com/v3/asm/groups/{}/suppressions/{}'.format(group, quote(email)), headers=headers) as response: assert response.status == 204 # TODO Handle errors handler.payload.attributes[group] = bool(subscribe) return handler.write({ 'data': { 'id': id, 'type': 'supressions', 'attributes': handler.payload.attributes } })
def attributes(self): full = self._permission == Permissions.ADMIN or ( (self._permission ^ Permissions.get_permissions( self._user, Collection(self._instance))) & Permissions.READ) == Permissions.READ return { 'name': self._instance.ref, 'schema': self._instance.data.get('schema'), **({} if not full else { 'plugins': self._instance.data.get('plugins', {}), 'permissions': { sel: Permissions(perm).name for sel, perm in self._instance.data['permissions'].items( ) } }) }
async def get(self, handler): error = None id = handler.get_query_argument('id') try: doc = self.collection.read(id) except exceptions.NotFound as e: error = e permissions = handler.current_user.permissions | Permissions.get_permissions(handler.current_user, doc) if error or not (permissions & Permissions.READ): return handler.write({ 'data': { 'id': id, 'type': 'suppressions', 'attributes': {} } }) attrs = {} email = self.extract_email(doc=doc) groups = handler.get_query_arguments('group[]') for group in groups: async with aiohttp.get('https://api.sendgrid.com/v3/asm/groups/{}/suppressions'.format(group), headers={'Authorization': 'Bearer {}'.format(self.sendgrid_key)}) as response: if response.status != 200 or not isinstance(await response.json(), list): attrs[group] = False else: attrs[group] = email in await response.json() return handler.write({ 'data': { 'id': id, 'type': 'supressions', 'attributes': attrs } })
def get_permissions(self, user, loaded): hoisted_read = Permissions.get_permissions(user, loaded[-1]) & Permissions.READ if self.resource: if super().get_permissions(user, loaded) != Permissions.ADMIN: loaded = loaded[:-1] return super().get_permissions(user, loaded) | hoisted_read
def __init__(self, request, user, inst, *parents): super().__init__(request, user, inst, *parents) self._permission |= Permissions.get_permissions(user, Namespace(inst))
def get_permissions(self, user, loaded): return Permissions.get_permissions(user, *loaded)