Ejemplo n.º 1
0
    async def _authenticate(self, data):
        namespace = manager.get_namespace(data['namespace'])
        collection = namespace.get_collection(data['collection'])

        if not GrantPlugin.is_enabled(collection):
            raise exceptions.PluginNotEnabled(GrantPlugin.NAME)

        if data.get('document'):
            if not collection.plugin('grant').document_enabled:
                raise exceptions.BadRequest(
                    detail=
                    'document permissions must be provided via collection.plugins.grant.document'
                )
            resource = data['document']
        else:
            if not collection.plugin('grant').collection_enabled:
                raise exceptions.BadRequest(
                    detail=
                    'collection permissions must be provided via collection.plugins.grant.collection'
                )
            resource = data['collection']

        async with aiohttp.request(
                'GET',
                '{}/oauth2/profile'.format(settings.OSF['ACCOUNTS_URL']),
                headers={
                    'Authorization':
                    'Bearer {}'.format(data.get('access_token'))
                }) as resp:
            if resp.status != 200:
                raise exceptions.Unauthorized()
            user_id = (await resp.json())['id']

        async with aiohttp.request(
                'GET',
                '{}/v2/nodes/{}/'.format(settings.OSF['API_URL'], resource),
                headers={
                    'Content-Type': 'application/json',
                    'Authorization': 'Bearer {}'.format(data['access_token']),
                }) as resp:
            if resp.status != 200:
                raise exceptions.Unauthorized()

            ref = '{namespace}.{collection}'.format(**data)
            granted = Permissions.from_string(
                data['permissions']) & functools.reduce(
                    lambda acc, x: acc | PERMISSION_MAP.get(
                        x, Permissions.NONE),
                    (await resp.json())['data']['attributes']
                    ['current_user_permissions'], Permissions.NONE)

            if data.get('document'):
                ref += '.' + data['document']
                granted &= collection.plugin('grant').document_permissions
            else:
                granted &= collection.plugin('grant').collection_permissions

            return 'user', 'osf', user_id, .06, False, {ref: granted}
Ejemplo n.º 2
0
    def list(self, filter, sort, page, page_size, user):
        if not user.permissions & Permissions.READ:
            if not user.uid:
                raise exceptions.Unauthorized()
            if filter:
                filter &= Q('created_by', 'eq', user.uid)
            else:
                filter = Q('created_by', 'eq', user.uid)

        return super().list(filter, sort, page, page_size, user)
Ejemplo n.º 3
0
 async def _authenticate(self, data):
     async with aiohttp.request(
             'GET',
             '{}/oauth2/profile'.format(settings.OSF['ACCOUNTS_URL']),
             headers={
                 'Authorization':
                 'Bearer {}'.format(data.get('access_token'))
             }) as resp:
         if resp.status != 200:
             raise exceptions.Unauthorized()
         return 'user', 'osf', (await resp.json())['id']
Ejemplo n.º 4
0
    def check_permissions(self):
        permissions = self._view.get_permissions(self.current_user,
                                                 self._view.loaded)
        required_permissions = self._view.get_required_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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    def list(self, filter, sort, page, page_size, user):
        if not user.permissions & Permissions.ADMIN:
            if not user.uid:
                raise exceptions.Unauthorized()

            query = functools.reduce(operator.or_, [
                Q('data.permissions.*', 'and', Permissions.READ),
                Q('data.permissions.{0.type}-*'.format(user), 'and',
                  Permissions.READ),
                Q('data.permissions.{0.type}-{0.provider}-*'.format(user),
                  'and', Permissions.READ),
                Q('data.permissions.{0.type}-{0.provider}-{0.id}'.format(user),
                  'and', Permissions.READ),
            ])

            if filter:
                filter &= query
            else:
                filter = query

        return super().list(filter, sort, page, page_size, user)
Ejemplo n.º 7
0
    async def _authenticate(self, data):
        namespace = manager.get_namespace(data['namespace'])
        collection = namespace.get_collection(data['collection'])

        # TODO handle exceptions
        if not (collection.schema
                and 'password' in collection.schema._schema['required']
                and collection.schema._schema['properties']['password']
                == self.PASSWORD_SCHEMA):
            raise exceptions.BadRequest()  # TODO Better error message

        # TODO validate retrieved document
        doc = collection.read(data['username'])
        password = doc.data['password'].encode()

        hashed = await asyncio.get_event_loop().run_in_executor(
            None, lambda: bcrypt.hashpw(data['password'].encode(), password))

        if hashed == password:
            return SelfAuthProvider.type, '{}:{}'.format(
                namespace.name, data['collection']), data['username']
        raise exceptions.Unauthorized()
Ejemplo n.º 8
0
    async def _authenticate(self, data):
        namespace = manager.get_namespace(data['namespace'])
        collection = namespace.get_collection(data['collection'])

        if not UserPlugin.is_enabled(collection):
            raise exceptions.PluginNotEnabled(UserPlugin.NAME)

        if not (
            collection.schema
            and 'password' in collection.schema._schema.get('required', [])
            and collection.schema._schema['properties']['password'] == self.PASSWORD_SCHEMA
        ):
            raise exceptions.BadRequest(title='Bad password schema', detail='The schema for password must be {} and must be a required field'.format(self.PASSWORD_SCHEMA))

        # TODO validate retrieved document
        doc = collection.read(data['username'])
        password = doc.data['password'].encode()

        hashed = await asyncio.get_event_loop().run_in_executor(None, lambda: bcrypt.hashpw(data['password'].encode(), password))

        if hashed == password:
            return SelfAuthProvider.type, '{}:{}'.format(namespace.ref, collection.ref), data['username'], 8
        raise exceptions.Unauthorized()