def test_item_need_read(self):
        class BookResource(PrincipalResource):
            class Meta:
                model = self.BOOK
                permissions = {
                    'read': ['owns-copy', 'admin'],
                    'create': 'admin',
                    'owns-copy': 'owns-copy'
                }

        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        # TODO Bulk inserts
        # response = self.client.post('/book', data=[
        # {'title': 'GoT Vol. {}'.format(i + 1)} for i in range(20)
        # ])

        for i in range(20):
            self.client.post('/book',
                             data={'title': 'GoT Vol. {}'.format(i + 1)})

        self.assertEqual(20, len(self.client.get('/book').json))

        self.mock_user = {
            'id':
            2,
            'needs': [
                ItemNeed('owns-copy', i, 'book')
                for i in (1, 4, 6, 8, 11, 15, 19)
            ]
        }
        self.assertEqual(7, len(self.client.get('/book').json))

        self.mock_user = {
            'id': 3,
            'needs': [ItemNeed('owns-copy', i, 'book') for i in (2, 7, 19)]
        }

        self.assertEqual([{
            '$uri': '/book/2',
            'title': 'GoT Vol. 2'
        }, {
            '$uri': '/book/7',
            'title': 'GoT Vol. 7'
        }, {
            '$uri': '/book/19',
            'title': 'GoT Vol. 19'
        }],
                         self.client.get('/book').json)

        self.assert404(self.client.get('/book/15'))
        self.assert200(self.client.get('/book/2'))
        self.assert200(self.client.get('/book/7'))
        self.assert404(self.client.get('/book/1'))
        self.assert404(self.client.get('/book/99'))

        self.mock_user = {'id': 4}
        self.assertEqual([], self.client.get('/book').json)
Ejemplo n.º 2
0
 def __init__(self, project_id):
     coordinator_need = ItemNeed('project_coordinator', int(project_id),
                                 'project_role')
     labeler_need = ItemNeed('data_labeler', int(project_id),
                             'project_role')
     super(AddLabelPermission,
           self).__init__(RoleNeed('admin'),
                          RoleNeed('project_coordinator'),
                          RoleNeed('data_labeler'), coordinator_need,
                          labeler_need)
Ejemplo n.º 3
0
 def __init__(self, project_id):
     coordinator_need = ItemNeed('project_coordinator', int(project_id),
                                 'project_role')
     scientist_need = ItemNeed('data_scientist', int(project_id),
                               'project_role')
     super(UploadDataPermission,
           self).__init__(RoleNeed('admin'),
                          RoleNeed('project_coordinator'),
                          RoleNeed('data_scientist'), coordinator_need,
                          scientist_need)
Ejemplo n.º 4
0
 def __init__(self, project_id):
     coordinator_need = ItemNeed('project_coordinator', int(project_id),
                                 'project_role')
     labeler_need = ItemNeed('data_labeler', int(project_id),
                             'project_role')
     scientist_need = ItemNeed('data_scientist', int(project_id),
                               'project_role')
     super(ViewResultsPermission,
           self).__init__(RoleNeed('admin'),
                          RoleNeed('project_coordinator'),
                          RoleNeed('data_labeler'),
                          RoleNeed('data_scientist'), coordinator_need,
                          labeler_need, scientist_need)
Ejemplo n.º 5
0
def get_quality_assurance_form_dashboard_menu(form_types):
    """Retrieves a list of forms that have the verification flag set

    :param form_type: The form type for the forms to be retrieved
    """
    event = g.event
    return [
        {
            'url':
            url_for('submissions.quality_assurance_dashboard',
                    form_id=form.id),
            'text':
            form.name,
            'visible':
            True
        } for form in [
            f for f in models.Form.query.filter(
                models.Form.form_type.in_(form_types),
                models.Form.quality_checks_enabled == True  # noqa
            ).join(models.Form.events).filter(
                models.Form.events.contains(event)).order_by(models.Form.name)
            if Permission(
                ItemNeed('access_resource', f.resource_id, f.resource_type),
                RoleNeed('admin')).can()
        ]
    ]
Ejemplo n.º 6
0
def generate_sitewide_needs(needs):
    '''
    For a given set of ```ItemNeed``` or ```HybridItemNeed``` instances,
    generates a tuple of needs that ensures that users with sitewide
    permissions on an object type can perform the specified operation(s)
    even if they do not have explicit authorization.

    Parameters
    ----------
    needs : tuple
        The existing needs

    Returns
    -------
    tuple
        A tuple of the sitewide needs for the given needs
    '''

    sitewide_needs = set()

    for need in needs:
        if isinstance(need, HybridItemNeed) or isinstance(need, ItemNeed):
            # The need is already a site-wide need.
            if need.type == 'site':
                continue

            permission = need.method
            resource_type = need.type
            sitewide_needs.add(ItemNeed(permission, None, resource_type))

    return sitewide_needs
    def test_item_need_update(self):
        class BookStoreResource(PrincipalResource):
            class Meta:
                model = self.BOOK_STORE
                permissions = {'create': 'admin', 'update': 'update'}

        self.api.add_resource(BookStoreResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        # response = self.client.post('/book_store', data=[
        # {'name': 'Bar Books'},
        #     {'name': 'Foomazon'}
        # ])
        response = self.client.post('/book_store', data={'name': 'Bar Books'})
        self.assert200(response)
        response = self.client.post('/book_store', data={'name': 'Foomazon'})
        self.assert200(response)

        self.mock_user = {
            'id': 1,
            'needs': [ItemNeed('update', 2, 'book_store')]
        }

        self.assert403(self.client.patch('/book_store/1', data={'name':
                                                                'Foo'}))

        response = self.client.patch('/book_store/2', data={'name': 'Foo'})
        self.assert200(response)
        self.assertEqual({
            '$uri': '/book_store/2',
            'name': 'Foo'
        }, response.json)
Ejemplo n.º 8
0
    def __call__(self, item):
        """ """
        for field in self.fields:
            item = get_value(item, field.attribute)

            if item is None:
                if self.method == 'id':
                    return UserNeed(None)
                return ItemNeed(self.method, None, self.type)

        item_id = get_value(item,
                            self.final_field.resource.manager.id_attribute,
                            None)

        if self.method == 'id':
            return UserNeed(item_id)
        return ItemNeed(self.method, item_id, self.type)
Ejemplo n.º 9
0
 def __call__(self, item):
     if self.method == 'id':
         return UserNeed(
             get_value(item, self.resource.manager.id_attribute, None))
     return ItemNeed(
         self.method,
         get_value(item, self.resource.manager.id_attribute, None),
         self.type)
Ejemplo n.º 10
0
def on_identity_loaded(sender, identity):
    # Set the identity user object
    identity.user = current_user

    # Add the UserNeed to the identity
    if hasattr(current_user, 'id'):
        identity.provides.add(UserNeed(current_user.id))

    # Default role
    identity.provides.add(RoleNeed('data_labeler'))

    # If the user account has the admin flag, make them a global admin
    if hasattr(current_user, 'admin'):
        if current_user.admin:
            identity.provides.add(RoleNeed('admin'))

    # Get all project roles
    # If not assigned to a project, treat it as a global role
    if hasattr(current_user, 'projects'):
        for project in current_user.projects:
            if project.project_coordinator:
                if project.project_id is None:
                    identity.provides.add(RoleNeed('project_coordinator'))
                else:
                    identity.provides.add(
                        ItemNeed('project_coordinator', project.project_id,
                                 'project_role'))
            if project.data_labeler:
                if project.project_id is None:
                    identity.provides.add(RoleNeed('data_labeler'))
                else:
                    identity.provides.add(
                        ItemNeed('data_labeler', project.project_id,
                                 'project_role'))
            if project.data_scientist:
                if project.project_id is None:
                    identity.provides.add(RoleNeed('data_scientist'))
                else:
                    identity.provides.add(
                        ItemNeed('data_scientist', project.project_id,
                                 'project_role'))
Ejemplo n.º 11
0
    def build_permission(self, resource):
        # NOTE(stephen): Lazily import ItemNeed since this class can be
        # referenced from the pipeline where web dependencies are not installed.
        from flask_principal import ItemNeed

        resource_id = resource.id if resource else None
        resource_type = self.resource_type.name.name.lower()
        # We want to take the Enum NAME,
        # not the Enum itself
        permission = self.permission

        return ItemNeed(permission, resource_id, resource_type)
Ejemplo n.º 12
0
 def __init__(self, file_name):
     restricted = LabeledClip.query.filter(
         LabeledClip.file_name == file_name).join(
             Label, Label.id == LabeledClip.label_id).filter(
                 Label.restricted == True).first()
     if restricted:
         audio_file = AudioFile.query.filter(
             AudioFile.name == file_name).first()
         station = audio_file.monitoring_station
         project_need = ItemNeed('project_coordinator',
                                 int(station.project_id), 'project_role')
     else:
         project_need = UserNeed(current_user.id)
     super(ListenPermission, self).__init__(RoleNeed('admin'),
                                            RoleNeed('project_coordinator'),
                                            project_need)
Ejemplo n.º 13
0
def get_checklist_form_dashboard_menu(**kwargs):
    """Retrieves a list of forms that have the verification flag set

    :param form_type: The form type for the forms to be retrieved
    """
    event = g.event
    return [{
        'url': url_for('dashboard.checklists', form_id=form.id),
        'text': form.name,
        'visible': True
    } for form in [
        f for f in models.Form.query.filter_by(
            **kwargs).join(models.Form.events).filter(
                models.Form.events.contains(event)).order_by(models.Form.name)
        if Permission(
            ItemNeed('access_resource', f.resource_id, f.resource_type),
            RoleNeed('admin')).can()
    ]]
Ejemplo n.º 14
0
def _build_resource_specific_needs(resource_type, permission, resource):
    '''Yields any authorization needs that are specifically related to an individual authorization
    resource or authorization resource type.
    '''
    # $CycloneIdaiHack(vedant)
    if resource_type.name == ResourceTypeEnum.ALERT:
        resource_id = resource.id if resource else None
        yield ItemNeed(permission.permission, resource_id, 'alert_definitions')

    if not resource:
        return

    if resource.resource_type.name == ResourceTypeEnum.QUERY_POLICY:
        with Transaction() as transaction:
            query_policy_entity = transaction.find_by_id(
                QueryPolicy, resource.id, 'resource_id')
            query_need = construct_query_need_from_policy(query_policy_entity)
            yield query_need
Ejemplo n.º 15
0
def get_form_list_menu(**kwargs):
    """Retrieves a list of forms that the user has access to and returns it
    in a format that can be rendered on the menu

    :param form_type: The form type for the forms to be retrieved
    """
    event = g.event
    return [{
        'url': url_for('submissions.submission_list', form_id=form.id),
        'text': form.name,
        'icon': '<i class="glyphicon glyphicon-check"></i>',
        'visible': True
    } for form in [
        f for f in models.Form.query.filter_by(
            **kwargs).join(models.Form.events).filter(
                models.Form.events.contains(event)).order_by(models.Form.name)
        if Permission(
            ItemNeed('access_resource', f.resource_id, f.resource_type),
            RoleNeed('admin')).can()
    ]]
Ejemplo n.º 16
0
def install_default_user_permissions(identity):
    '''
    Add permisisons that the current user should be able to perform
    regardless of whatever other roles they possess.
    '''
    identity.provides.add(UserNeed(identity.user.id))

    # TODO(vedant) - This should not be hardcoded.
    # Always allow the user to view their profile
    identity.provides.add(ItemNeed('view_resource', identity.user.id, 'user'))

    # HACK(vedant) - Fixed as part of a short term solution for T2113
    # The long term solution is to define default permissions or a default user group that all new
    # users should be added to.
    identity.provides.add(ItemNeed('create_resource', None, 'dashboard'))

    # Continuation of Work for T2148 but now allowing RO-access to all Potion APIs
    identity.provides.add(ItemNeed('view_resource', None, 'user'))
    identity.provides.add(ItemNeed('view_resource', None, 'group'))
    identity.provides.add(ItemNeed('view_resource', None, 'role'))
    identity.provides.add(ItemNeed('view_resource', None, 'resource'))
    identity.provides.add(ItemNeed('view_resource', None, 'configuration'))
    def test_relationship(self):
        "should require update permission on parent resource for updating, read permissions on both"

        class BookResource(PrincipalResource):
            class Schema:
                author = fields.ToOne('user', nullable=True)

            class Meta:
                model = self.BOOK
                permissions = {
                    'read': ['owns-copy', 'update', 'admin'],
                    'create': 'writer',
                    'update': 'user:author',
                    'owns-copy': 'owns-copy'
                }

        class UserResource(PrincipalResource):
            books = Relation(BookResource)

            class Meta:
                model = self.USER
                permissions = {'create': 'admin'}

        self.api.add_resource(UserResource)
        self.api.add_resource(BookResource)

        self.mock_user = {'id': 1, 'roles': ['admin']}

        for user in [{
                'name': 'Admin'
        }, {
                'name': 'Author 1'
        }, {
                'name': 'Author 2'
        }]:
            response = self.client.post('/user', data=user)
            self.assert200(response)

        response = self.client.post('/book', data={'title': 'Foo'})
        self.assert403(response)

        self.mock_user = {'id': 2, 'roles': ['writer']}
        response = self.client.post('/book',
                                    data={
                                        'author': {
                                            '$ref': '/user/2'
                                        },
                                        'title': 'Bar'
                                    })

        self.assert200(response)

        self.mock_user = {'id': 3, 'roles': ['writer']}

        response = self.client.post('/book', data={'title': 'Spying: Novel'})
        self.assert200(response)

        response = self.client.post('/book',
                                    data={'title': 'Spied: The Sequel'})
        self.assert200(response)

        response = self.client.post('/book',
                                    data={'title': 'Spy: The Prequel'})
        self.assert200(response)
        self.assertJSONEqual(
            {
                '$uri': '/book/4',
                'author': None,
                'title': 'Spy: The Prequel'
            }, response.json)

        self.mock_user = {'id': 1, 'roles': ['admin']}
        self.client.post('/user/3/books', data={'$ref': '/book/2'})
        self.client.post('/user/3/books', data={'$ref': '/book/3'})
        self.client.post('/user/3/books', data={'$ref': '/book/4'})

        self.mock_user = {'id': 3, 'roles': ['writer']}
        self.assert200(response)

        response = self.client.get('/user/3/books')
        self.assert200(response)
        self.assertEqual(3,
                         len(response.json))  # read -> update -> user:author

        self.mock_user = {'id': 4, 'needs': [ItemNeed('owns-copy', 3, 'book')]}

        response = self.client.get('/user/3/books')
        self.assertEqual(1, len(response.json))  # read -> owns-copy

        self.assert200(self.client.get('/book/3'))
        self.assert404(self.client.get('/book/2'))

        self.mock_user = {'id': 5}
        response = self.client.get('/user/3/books')
        self.assertEqual(0, len(response.json))
        self.assert404(self.client.get('/book/2'))
Ejemplo n.º 18
0
 def __init__(self, project_id):
     coordinator_need = ItemNeed('project_coordinator', int(project_id),
                                 'project_role')
     super(ManageLabelsPermission,
           self).__init__(RoleNeed('admin'),
                          RoleNeed('project_coordinator'), coordinator_need)
Ejemplo n.º 19
0
def is_authorized(permission,
                  resource_type,
                  resource_id=None,
                  log_request=True):
    '''
    Determines whether or not the currently loaded user can perform the specified operation
    on the specified resource.

    Parameters
    ----------
    permission : string
        The desired object permission that the user must possess (e.g. 'edit_resource')

    resource_type : string
        The type of resource that the operation is being performed on (e.g. 'dashboard')

        resource_id (optional): int
            The id of the resource in question (based on the `id` attribute of the `Resource`
            model). Do not specify if you are attempting to determine whether the user has a
            sitewide permission for a given resource type.

    log_request (optional): string
        Whether or not to log the authorization check. This should generally be true unless
        the user is simply querying whether or not they have the permission to do so.

    Returns
    -------
    bool
        True if the user is authorized and False otherwise
    '''

    # WARNING: Please be careful what changes you make to this function. It is ultimately
    # the function that decides whether or not to authorize ANY action on the website.
    permission = str(permission).lower()
    resource_type = str(resource_type).lower()
    resource_name = int(resource_id) if resource_id else None
    resource_specific_need = [
        ItemNeed(permission, resource_name, resource_type)
    ]
    required_permission = WhitelistedPermission(resource_specific_need)

    if required_permission.can():
        if log_request:
            g.request_logger.debug(
                'User \'%s\' successfully authorized to perform '
                '\'%s\' on resource \'%s\' of type \'%s\'.',
                get_user_string(current_user),
                permission,
                resource_id,
                resource_type,
            )
        return True

    if log_request:
        g.request_logger.info(
            'User \'%s\' attempted to perform '
            '\'%s\' on resource \'%s\' of type \'%s\' but was unauthorized.',
            get_user_string(current_user),
            permission,
            resource_id,
            resource_type,
        )
    return False
Ejemplo n.º 20
0
def can_access_resource(resource):
    perm = Permission(
        ItemNeed('access_resource', resource.resource_id,
                 resource.resource_type), RoleNeed('admin'))
    return perm.can()
Ejemplo n.º 21
0
def require_item_perm(action, item, http_exception=403):
    perm = Permission(ItemNeed(action, item, 'object'), RoleNeed('admin'))
    if not perm.can():
        abort(http_exception, perm)
Ejemplo n.º 22
0
 def __init__(self, board_name):
     need = ItemNeed(ACTUALIZAR_CONTENIDO, board_name, 'board')
     super().__init__(need, AdminRolNeed, ListarArticulosNeed)
Ejemplo n.º 23
0
 def __init__(self, board_name):
     need = ItemNeed(ENVIAR_CONTENIDO, board_name, 'board')
     super().__init__(need, AdminRolNeed, EnviarAritulosNeed)
Ejemplo n.º 24
0
 def __init__(self, board_name):
     need = ItemNeed(PONER_CONTENIDO, board_name, 'board')
     super().__init__(need, AdminRolNeed, PonerArticulosNeed)