Пример #1
0
def oauth2(app, db):
    """Creates authentication tokens for test.

    Add these attributes in the app object and return app:
    - user: a fake user that have authorization to archive_read and write
    - token: api token for user
    """
    from invenio_access.models import ActionUsers
    from invenio_oauth2server.models import Token

    from invenio_archivematica.permissions import archive_read, archive_write

    datastore = app.extensions['security'].datastore
    app.user = datastore.create_user(email='*****@*****.**',
                                     password='******',
                                     active=True)
    db.session.commit()
    db.session.add(ActionUsers.allow(archive_read, user=app.user))
    db.session.add(ActionUsers.allow(archive_write, user=app.user))
    app.token = Token.create_personal('test-',
                                      app.user.id,
                                      scopes=['archive:actions'],
                                      is_internal=True).access_token
    db.session.commit()

    return app
def create_record(collection):
    """Basic test view."""

    collection = Collection.query.filter(
        Collection.name == collection).first_or_404()

    schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'),
                     url_for('records.jsonschema',
                             collection=collection.name))

    data, pid, recid = construct_record(collection,
                                        json.loads(request.get_data()),
                                        current_user.id,
                                        schema)

    try:
        record = Record.create(data, id_=recid)
    except ValidationError as error:
        print("============================")
        print(error.message)
        print("============================")

        db.session.rollback()
        resp = jsonify(**{'message': error.message})
        resp.status_code = 400
        return resp

    # Invenio-Indexer is delegating the document inferring to
    # Invenio-Search which is analysing the string splitting by `/` and
    # using `.json` to be sure that it cans understand the mapping.
    record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

    indexer = RecordIndexer()
    indexer.index(record)

    # Creating permission needs for the record
    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    # Giving index, read, write permissions to user/creator
    db.session.add(ActionUsers.allow(action_edit_record, user=current_user))
    db.session.add(ActionUsers.allow(action_read_record, user=current_user))
    db.session.add(ActionUsers.allow(action_index_record, user=current_user))

    db.session.commit()

    resp = jsonify(**{'pid': pid})
    resp.status_code = 200
    return resp
def create_record(collection):
    """Basic test view."""

    collection = Collection.query.filter(
        Collection.name == collection).first_or_404()

    schema = urljoin(current_app.config.get('JSONSCHEMAS_HOST'),
                     url_for('records.jsonschema',
                             collection=collection.name))

    data, pid, recid = construct_record(collection,
                                        json.loads(request.get_data()),
                                        current_user.id,
                                        schema)

    try:
        record = Record.create(data, id_=recid)
    except ValidationError as error:
        print("============================")
        print(error.message)
        print("============================")

        db.session.rollback()
        resp = jsonify(**{'message': error.message})
        resp.status_code = 400
        return resp

    # Invenio-Indexer is delegating the document inferring to
    # Invenio-Search which is analysing the string splitting by `/` and
    # using `.json` to be sure that it cans understand the mapping.
    record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

    indexer = RecordIndexer()
    indexer.index(record)

    # Creating permission needs for the record
    action_edit_record = RecordUpdateActionNeed(str(recid))
    action_read_record = RecordReadActionNeed(str(recid))
    action_index_record = RecordIndexActionNeed(str(recid))

    # Giving index, read, write permissions to user/creator
    db.session.add(ActionUsers.allow(action_edit_record, user=current_user))
    db.session.add(ActionUsers.allow(action_read_record, user=current_user))
    db.session.add(ActionUsers.allow(action_index_record, user=current_user))

    db.session.commit()

    resp = jsonify(**{'pid': pid})
    resp.status_code = 200
    return resp
Пример #4
0
    def _add_experiment_permissions(cls, data, id_):
        """Add read permissions to everybody assigned to experiment."""
        exp_need = exp_need_factory(data['_experiment'])

        # give read access to members of collaboration
        for au in ActionUsers.query_by_action(exp_need).all():
            try:
                ActionUsers.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']).filter_by(
                        user=au.user).one()
            except NoResultFound:
                db.session.add(
                    ActionUsers.allow(RECORD_ACTION_NEEDS(id_)['record-read'],
                                      user=au.user))
                data['_access']['record-read']['users'].append(au.user.id)

        for ar in ActionRoles.query_by_action(exp_need).all():
            try:
                ActionRoles.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']).filter_by(
                        role=ar.role).one()
            except NoResultFound:
                db.session.add(
                    ActionRoles.allow(RECORD_ACTION_NEEDS(id_)['record-read'],
                                      role=ar.role))
                data['_access']['record-read']['roles'].append(ar.role.id)
Пример #5
0
    def grant_vocabulary_editor_permission(cls, user_id,
                                           vocabulary_id) -> Dict[str, bool]:
        done = False
        msg = ''
        try:
            vocabulary = Vocabulary.query.filter_by(
                identifier=vocabulary_id).first()
            user = User.query.filter_by(id=user_id).first()
            if not vocabulary:
                msg = 'Vocabulary not found'
            elif not user:
                msg = 'User not found'
            else:
                db.session.add(
                    ActionUsers.allow(ObjectVocabularyEditor(vocabulary.id),
                                      user=user))
                db.session.commit()
                msg = 'Vocabulary Editor Permission granted over {0}'.format(
                    vocabulary.name)
                done = True

        except Exception as e:
            msg = str(e)
            # print(str(e))

        return msg, done
def users(app, db):
    """Create users."""
    users = {
        'cms_user': create_user_with_role('*****@*****.**',
                                          '*****@*****.**'),
        'cms_user2': create_user_with_role('*****@*****.**',
                                           '*****@*****.**'),
        'alice_user': create_user_with_role('*****@*****.**',
                                            '*****@*****.**'),
        'alice_user2': create_user_with_role('*****@*****.**',
                                             '*****@*****.**'),
        'atlas_user': create_user_with_role('*****@*****.**',
                                            '*****@*****.**'),
        'atlas_user2': create_user_with_role('*****@*****.**',
                                             '*****@*****.**'),
        'lhcb_user': create_user_with_role('*****@*****.**',
                                           '*****@*****.**'),
        'lhcb_user2': create_user_with_role('*****@*****.**',
                                            '*****@*****.**'),
        'superuser': create_user_with_role('*****@*****.**',
                                           '*****@*****.**'),
    }
    db.session.add(ActionUsers.allow(superuser_access, user=users['superuser']))
    db.session.commit()

    return users
    def _add_deposit_permissions(cls, data, id_):
        """Inherit permissions after deposit."""
        data['_access'] = {
            DEPOSIT_TO_RECORD_ACTION_MAP[action]: permission
            for action, permission in data['_access'].items()
        }

        for action, permission in data['_access'].items():
            for role in permission['roles']:
                role = Role.query.filter_by(id=role).one()
                try:
                    ActionRoles.query.filter_by(action=action,
                                                argument=str(id_),
                                                role_id=role.id).one()
                except NoResultFound:
                    db.session.add(
                        ActionRoles.allow(RECORD_ACTION_NEEDS(id_)[action],
                                          role=role))
            for user in permission['users']:
                user = User.query.filter_by(id=user).one()
                try:
                    ActionUsers.query.filter_by(action=action,
                                                argument=str(id_),
                                                user_id=user.id).one()
                except NoResultFound:
                    db.session.add(
                        ActionUsers.allow(RECORD_ACTION_NEEDS(id_)[action],
                                          user=user))
Пример #8
0
    def create_user(self, email, entry):
        """Load a single user."""
        # when the user's password is set in the configuration, then
        # this overrides everything else
        password = current_app.config.get("RDM_RECORDS_USER_FIXTURE_PASSWORDS",
                                          {}).get(email)

        if not password:
            # for auto-generated passwords use letters, digits,
            # and some punctuation marks
            alphabet = string.ascii_letters + string.digits + "+,-_."
            gen_passwd = "".join(secrets.choice(alphabet) for i in range(20))
            password = entry.get("password") or gen_passwd

        user_data = {
            "email": email,
            "active": entry.get("active", False),
            "password": hash_password(password),
        }
        user = current_datastore.create_user(**user_data)

        for role in entry.get("roles", []):
            current_datastore.add_role_to_user(user, role)

        for action in entry.get("allow", []):
            action = current_access.actions[action]
            db.session.add(ActionUsers.allow(action, user_id=user.id))

        db.session.commit()
    def give_admin_access_for_user(self, user):
        """Give admin access for users."""
        assert self.id

        db.session.add(ActionUsers.allow(SchemaAdminAction(self.id),
                                         user=user))
        db.session.flush()
Пример #10
0
def test_file_permissions(app, db, record_with_files_creation, user,
                          access_right, expected):
    """Test file permissions."""
    pid, record, record_url = record_with_files_creation

    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(ActionUsers.allow(ActionNeed('admin-access'), user=admin))
    db.session.commit()

    # Create test record
    record['access_right'] = access_right
    record['owners'] = [owner.id]
    record.commit()
    db.session.commit()

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value=pid.pid_value,
        filename='Test.pdf',
    )
    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
    def _add_experiment_permissions(cls, data, id_):
        """Add read permissions to everybody assigned to experiment."""
        exp_need = exp_need_factory(data['_experiment'])

        # give read access to members of collaboration
        for au in ActionUsers.query_by_action(exp_need).all():
            try:
                ActionUsers.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']
                ).filter_by(user=au.user).one()
            except NoResultFound:
                db.session.add(
                    ActionUsers.allow(
                        RECORD_ACTION_NEEDS(id_)['record-read'],
                        user=au.user
                    )
                )
                data['_access']['record-read']['users'].append(au.user.id)

        for ar in ActionRoles.query_by_action(exp_need).all():
            try:
                ActionRoles.query_by_action(
                    RECORD_ACTION_NEEDS(id_)['record-read']
                ).filter_by(role=ar.role).one()
            except NoResultFound:
                db.session.add(
                    ActionRoles.allow(
                        RECORD_ACTION_NEEDS(id_)['record-read'],
                        role=ar.role
                    )
                )
                data['_access']['record-read']['roles'].append(ar.role.id)
Пример #12
0
    def _make_user(role_name,
                   organisation='org',
                   organisation_is_shared=True,
                   access=None):
        name = role_name

        if organisation:
            make_organisation(organisation, is_shared=organisation_is_shared)
            name = organisation + name

        email = '{name}@rero.ch'.format(name=name)

        datastore = app.extensions['security'].datastore

        user = datastore.find_user(email=email)

        if user:
            record = UserRecord.get_user_by_email(email)
            return record

        user = datastore.create_user(email=email,
                                     password=hash_password('123456'),
                                     active=True)
        datastore.commit()

        role = datastore.find_role(role_name)
        if not role:
            role = Role(name=role_name)

        role.users.append(user)

        db.session.add(role)

        if access:
            db.session.add(ActionUsers.allow(ActionNeed(access), user=user))

        db.session.commit()

        data = {
            'pid': name,
            'email': email,
            'first_name': name[0].upper() + name[1:],
            'last_name': 'Doe',
            'role': role_name
        }

        if organisation:
            data['organisation'] = {
                '$ref':
                'https://sonar.ch/api/organisations/{organisation}'.format(
                    organisation=organisation)
            }

        record = UserRecord.create(data, dbcommit=True)
        record.reindex()
        db.session.commit()

        return record
Пример #13
0
def create_user_with_access(session, username, action):
    user = _datastore.find_user(email=username)

    if not user:
        user = create_test_user(email=username, password='******')

    session.add(ActionUsers.allow(ActionNeed(action), user=user))

    return user
Пример #14
0
def admin_user(users, roles):
    """Give admin rights to a user."""
    user = users["user1"]
    role = roles["admin"]
    current_datastore.add_role_to_user(user, role)
    action = current_access.actions["superuser-access"]
    db.session.add(ActionUsers.allow(action, user_id=user.id))

    return user
def add_record(metadata, collection, schema, force):
    """Add record."""

    collection = Collection.query.filter(
        Collection.name == collection).first()

    if collection is None:
        return

    data, pid, recid = construct_record(
        collection, metadata, 1, {} if force else schema)

    try:
        record = Record.create(data, id_=recid)
        # Invenio-Indexer is delegating the document inferring to
        # Invenio-Search which is analysing the string splitting by `/` and
        # using `.json` to be sure that it cans understand the mapping.
        record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

        indexer = RecordIndexer()
        indexer.index(record)

        # Creating permission needs for the record
        action_edit_record = RecordUpdateActionNeed(str(recid))
        action_read_record = RecordReadActionNeed(str(recid))
        action_index_record = RecordIndexActionNeed(str(recid))

        # Giving index, read, write permissions to user/creator
        db.session.add(ActionUsers.allow(action_edit_record))
        db.session.add(ActionUsers.allow(action_read_record))
        db.session.add(ActionUsers.allow(action_index_record))

        db.session.commit()

        print("DONE!!!")

    except ValidationError as error:
        print("============================")
        pprint(error.message)
        pprint(error.path)
        print("============================")

        db.session.rollback()
Пример #16
0
    def _add_user_permissions(self, user, permissions, session):
        """Adds permissions for user for this deposit."""
        for permission in permissions:
            session.add(
                ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
                                  user=user))

            session.flush()

            self['_access'][permission]['users'].append(user.id)
Пример #17
0
def test_file_permissions(app, db, test_object,  # fixtures
                          user, access_right, expected):
    """Test file permissions."""
    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(
        ActionUsers.allow(ActionNeed('admin-access'), user=admin)
    )

    # Create test record
    rec_uuid = uuid.uuid4()
    PersistentIdentifier.create(
        'recid',
        '1',
        object_type='rec',
        object_uuid=rec_uuid,
        status=PIDStatus.REGISTERED
    )
    Record.create({
        'recid': 1,
        'owners': [2],
        'access_right': access_right,
        '_files': [
            {
                'key': test_object.key,
                'bucket': str(test_object.bucket_id),
                'checksum': 'invalid'
            },
        ]
    }, id_=rec_uuid)
    db.session.add(
        RecordsBuckets(record_id=rec_uuid, bucket_id=test_object.bucket_id)
    )

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value='1',
        filename=test_object.key
    )

    db.session.commit()

    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
def add_record(metadata, collection, schema, force):
    """Add record."""

    collection = Collection.query.filter(Collection.name == collection).first()

    if collection is None:
        return

    data, pid, recid = construct_record(collection, metadata, 1,
                                        {} if force else schema)

    try:
        record = Record.create(data, id_=recid)
        # Invenio-Indexer is delegating the document inferring to
        # Invenio-Search which is analysing the string splitting by `/` and
        # using `.json` to be sure that it cans understand the mapping.
        record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

        indexer = RecordIndexer()
        indexer.index(record)

        # Creating permission needs for the record
        action_edit_record = RecordUpdateActionNeed(str(recid))
        action_read_record = RecordReadActionNeed(str(recid))
        action_index_record = RecordIndexActionNeed(str(recid))

        # Giving index, read, write permissions to user/creator
        db.session.add(ActionUsers.allow(action_edit_record))
        db.session.add(ActionUsers.allow(action_read_record))
        db.session.add(ActionUsers.allow(action_index_record))

        db.session.commit()

        print("DONE!!!")

    except ValidationError as error:
        print("============================")
        pprint(error.message)
        pprint(error.path)
        print("============================")

        db.session.rollback()
Пример #19
0
def test_monitoring_check_es_db_counts(app, client, contribution_person_data,
                                       system_librarian_martigny):
    """Test monitoring check_es_db_counts."""
    res = client.get(url_for('api_monitoring.check_es_db_counts', delay=0))
    assert res.status_code == 200
    assert get_json(res) == {'data': {'status': 'green'}}

    pers = Contribution.create(data=contribution_person_data,
                               delete_pid=False,
                               dbcommit=True,
                               reindex=False)
    flush_index(ContributionsSearch.Meta.index)
    res = client.get(url_for('api_monitoring.check_es_db_counts', delay=0))
    assert res.status_code == 200
    assert get_json(res) == {
        'data': {
            'status': 'red'
        },
        'errors': [{
            'code': 'DB_ES_COUNTER_MISSMATCH',
            'details': 'There are 1 items from cont missing in ES.',
            'id': 'DB_ES_COUNTER_MISSMATCH',
            'links': {
                'about': 'http://localhost/monitoring/check_es_db_counts',
                'cont': 'http://localhost/monitoring/missing_pids/cont'
            },
            'title': "DB items counts don't match ES items count."
        }]
    }

    # this view is only accessible by monitoring
    res = client.get(url_for('api_monitoring.missing_pids', doc_type='cont'))
    assert res.status_code == 401

    login_user_via_session(client, system_librarian_martigny.user)
    res = client.get(url_for('api_monitoring.missing_pids', doc_type='cont'))
    assert res.status_code == 403

    # give user superuser admin rights
    db.session.add(
        ActionUsers.allow(superuser_access,
                          user=system_librarian_martigny.user))
    db.session.commit()
    res = client.get(
        url_for('api_monitoring.missing_pids', doc_type='cont', delay=0))
    assert res.status_code == 200

    assert get_json(res) == {
        'data': {
            'DB': [],
            'ES': ['http://localhost/contributions/cont_pers'],
            'ES duplicate': []
        }
    }
def create_user_with_access(username, action):
    user = _datastore.find_user(email=username)

    if not user:
        user = create_test_user(email=username, password='******')

    db_.session.add(ActionUsers.allow(
        ActionNeed(action), user=user))

    db_.session.commit()

    return user
Пример #21
0
    def _make_user(role_name, organisation='org'):
        make_organisation(organisation)

        name = role_name
        if organisation:
            name = organisation + name

        email = '{name}@rero.ch'.format(name=name)

        datastore = app.extensions['security'].datastore

        user = datastore.find_user(email=email)

        if user:
            record = UserRecord.get_user_by_email(email)
            return record

        user = datastore.create_user(email=email,
                                     password=hash_password('123456'),
                                     active=True)
        datastore.commit()

        role = datastore.find_role(role_name)
        if not role:
            role = Role(name=role_name)

        role.users.append(user)

        db.session.add(role)
        db.session.add(
            ActionUsers.allow(ActionNeed(
                '{role}-access'.format(role=role_name)),
                              user=user))
        db.session.commit()

        record = UserRecord.create(
            {
                'pid': name,
                'email': email,
                'full_name': name,
                'roles': [role_name],
                'organisation': {
                    '$ref':
                    'https://sonar.ch/api/organisations/{organisation}'.format(
                        organisation=organisation)
                }
            },
            dbcommit=True)
        record.reindex()
        db.session.commit()

        return record
Пример #22
0
def test_patron_loans_view(app, patron1, testdata, client):
    """Test check for users update in sync command."""

    db.session.add(
        ActionUsers.allow(retrieve_patron_loans_access_action, user=patron1))
    db.session.commit()

    patron = Patron(patron1.id)
    PatronIndexer().index(patron)
    current_search.flush_and_refresh(index="*")

    login_user_via_session(client, email=patron1.email)

    resp = client.get(url_for("cds_ils_patron_loans.patron_loans",
                              person_id=1))

    assert resp.status_code == 200

    expected_books_on_loan = [{
        "barcode":
        "123456789-3",
        "end_date":
        "2018-07-28",
        "library":
        "Main Library",
        "location":
        "Route de Meyrin",
        "title":
        "Prairie Fires: The American Dreams of "
        "Laura Ingalls Wilder",
    }]
    expected_loan_requests = [{
        "request_start_date":
        "2018-06-28",
        "request_end_date":
        "2018-07-28",
        "library":
        "Main Library",
        "location":
        "Route de Meyrin",
        "title":
        "The Gulf: The Making of An American Sea",
    }]
    data = resp.json
    assert data["books_on_loan"] == expected_books_on_loan
    assert data["loan_requests"] == expected_loan_requests

    # test extra_info
    assert patron.extra_info
    assert data["person_id"] == patron.extra_info["person_id"]
    assert data["department"] == patron.extra_info["department"]
def change_record_privacy(pid_value=None):
    resolver = Resolver(
        pid_type='recid',
        object_type='rec',
        getter=Record.get_record)

    pid, record = resolver.resolve(pid_value)

    permission_update_record = update_permission_factory(record)
    if not permission_update_record.can():
        abort(403)

    index_instance = ActionUsers.query.filter(
        ActionUsers.action == "records-index",
        ActionUsers.argument == str(record.id),
        ActionUsers.user_id.is_(None)).first()

    read_instance = ActionUsers.query.filter(
        ActionUsers.action == "records-read",
        ActionUsers.argument == str(record.id),
        ActionUsers.user_id.is_(None)).first()

    with db.session.begin_nested():
        if index_instance:
            db.session.delete(index_instance)
            db.session.delete(read_instance)
        else:
            action_read_record = RecordReadActionNeed(str(record.id))
            action_index_record = RecordIndexActionNeed(str(record.id))
            db.session.add(ActionUsers.allow(action_read_record))
            db.session.add(ActionUsers.allow(action_index_record))

    db.session.commit()

    resp = jsonify()
    resp.status_code = 200
    return resp
def change_record_privacy(pid_value=None):
    resolver = Resolver(
        pid_type='recid',
        object_type='rec',
        getter=Record.get_record)

    pid, record = resolver.resolve(pid_value)

    permission_update_record = update_permission_factory(record)
    if not permission_update_record.can():
        abort(403)

    index_instance = ActionUsers.query.filter(
        ActionUsers.action == "records-index",
        ActionUsers.argument == str(record.id),
        ActionUsers.user_id.is_(None)).first()

    read_instance = ActionUsers.query.filter(
        ActionUsers.action == "records-read",
        ActionUsers.argument == str(record.id),
        ActionUsers.user_id.is_(None)).first()

    with db.session.begin_nested():
        if index_instance:
            db.session.delete(index_instance)
            db.session.delete(read_instance)
        else:
            action_read_record = RecordReadActionNeed(str(record.id))
            action_index_record = RecordIndexActionNeed(str(record.id))
            db.session.add(ActionUsers.allow(action_read_record))
            db.session.add(ActionUsers.allow(action_index_record))

    db.session.commit()

    resp = jsonify()
    resp.status_code = 200
    return resp
    def _add_user_permissions(self,
                              user,
                              permissions,
                              session):
        """Adds permissions for user for this deposit."""
        for permission in permissions:
            session.add(
                ActionUsers.allow(
                    DEPOSIT_ACTIONS_NEEDS(self.id)[permission],
                    user=user
                )
            )

            session.flush()

            self['_access'][permission]['users'].append(user.id)
Пример #26
0
def set_user_permissions(user, permissions, deposit, session, access, force=False):
    _permissions = (p for p in permissions if p.get(
        "action", "") in DEPOSIT_ACTIONS)

    for permission in _permissions:

        if permission.get("op", "") == "add":
            if (not force and ActionUsers.query.filter_by(
                    action=permission['action'],
                    user_id=user.id,
                    argument=str(deposit.id)
            ).all()):
                return
            try:
                session.add(ActionUsers.allow(
                    DEPOSIT_ACTIONS_NEEDS(deposit.id).get(
                        permission.get("action", ""),
                        ""),
                    user=user
                ))
            except:
                return

            access.get(permission["action"], {}).get(
                'user', []).append(user.id)

        elif permission.get("op", "") == "remove":
            if (not force and not ActionUsers.query.filter_by(
                    action=permission['action'],
                    user_id=user.id,
                    argument=str(deposit.id)
            ).all()):
                return
            try:
                au = ActionUsers.query.filter(
                    ActionUsers.action == permission.get("action", ""),
                    ActionUsers.argument == str(deposit.id),
                    ActionUsers.user_id == user.id).first()
                if au:
                    session.delete(au)

            except:
                return

            access.get(permission["action"], {}).get(
                'user', []).remove(user.id)
    return access
Пример #27
0
    def create_user(self, email, entry):
        """Load a single user."""
        password = self._get_password(email, entry)
        user_data = {
            "email": email,
            "active": entry.get("active", False),
            "password": hash_password(password),
        }
        user = current_datastore.create_user(**user_data)

        for role in entry.get("roles", []) or []:
            current_datastore.add_role_to_user(user, role)

        for action in entry.get("allow", []) or []:
            action = current_access.actions[action]
            db.session.add(ActionUsers.allow(action, user_id=user.id))

        db.session.commit()
Пример #28
0
def users(app, db, roles_data, users_data, create_roles):
    """Create test users."""
    ds = app.extensions['invenio-accounts'].datastore
    result = {}

    with app.app_context():
        with db.session.begin_nested():

            for user_key, user_data in iteritems(users_data):
                user_data['password'] = hash_password(user_data['password'])
                user = ds.create_user(**user_data)
                result[user_key] = user

            roles = Role.query.filter(
                Role.id.in_(role['id'] for role in create_roles[:5])).all()
            result['user1'].roles.extend(roles)

            db.session.add(
                ActionUsers.allow(
                    superuser_access,
                    user=result['admin'],
                ))

            for user in result.values():
                scopes = current_oauth2server.scope_choices()
                db.session.add(user)

                user.allowed_token = Token.create_personal(
                    name='allowed_token',
                    user_id=user.id,
                    scopes=[s[0] for s in scopes]).access_token

            user_ref = namedtuple('UserRef', 'id, allowed_token, data')

            result_user = {
                name: user_ref(
                    id=user.id,
                    data=users_data[name],
                    allowed_token=user.allowed_token,
                )
                for name, user in six.iteritems(result)
            }
        db.session.commit()
    return result_user
Пример #29
0
def create_user(name,
                roles=None,
                permissions=None,
                admin_communities=None,
                member_communities=None):
    """Create a user.

    Args:
        name (str): user's name.
        roles (list): roles assigned to this new user.

    Returns:
        (UserInfo) created user's information.
    """

    users_password = '******'
    accounts = current_app.extensions['invenio-accounts']
    security = current_app.extensions['security']

    email = '{}@example.org'.format(name)
    with db.session.begin_nested():
        user = accounts.datastore.create_user(
            email=email,
            password=encrypt_password(users_password),
            active=True,
        )
        db.session.add(user)

        if roles is not None:
            for role in roles:
                security.datastore.add_role_to_user(user, role)

        if permissions is not None:
            for permission in permissions:
                # permissions of the form [('action name', 'argument'), (...)]
                if len(permission) == 2:
                    permission = ParameterizedActionNeed(
                        permission[0], permission[1])
                db.session.add(ActionUsers.allow(permission, user=user))

    return UserInfo(email=email, password=users_password, id=user.id)
Пример #30
0
def create_user(name, roles=None, permissions=None, admin_communities=None,
                member_communities=None):
    """Create a user.

    Args:
        name (str): user's name.
        roles (list): roles assigned to this new user.

    Returns:
        (UserInfo) created user's information.
    """

    users_password = '******'
    accounts = current_app.extensions['invenio-accounts']
    security = current_app.extensions['security']

    email = '{}@example.org'.format(name)
    with db.session.begin_nested():
        user = accounts.datastore.create_user(
            email=email,
            password=hash_password(users_password),
            active=True,
        )
        db.session.add(user)

        if roles is not None:
            for role in roles:
                security.datastore.add_role_to_user(user, role)

        if permissions is not None:
            for permission in permissions:
                # permissions of the form [('action name', 'argument'), (...)]
                if len(permission) == 2:
                    permission = ParameterizedActionNeed(permission[0],
                                                         permission[1])
                db.session.add(ActionUsers.allow(permission, user=user))

    return UserInfo(email=email, password=users_password, id=user.id)
Пример #31
0
    def create(self, entry):
        """Load a single user."""
        email = entry.pop("email")
        password = self._get_password(email, entry)
        user_data = {
            "email": email,
            "active": entry.get("active", False),
            "password": hash_password(password),
        }
        try:
            user = current_datastore.create_user(**user_data)

            for role in entry.get("roles", []) or []:
                current_datastore.add_role_to_user(user, role)

            for action in entry.get("allow", []) or []:
                action = current_access.actions[action]
                db.session.add(ActionUsers.allow(action, user_id=user.id))

            db.session.commit()
        except IntegrityError:
            current_app.logger.info(
                f"skipping creation of {email}, already existing")
Пример #32
0
def set_user_permissions(user, permissions, id, session, access):
    _permissions = (p for p in permissions if p.get(
        "action", "") in DEPOSIT_ACTIONS)

    for permission in _permissions:

        if (permission.get("op", "") == "add"):
            try:
                session.add(ActionUsers.allow(
                    DEPOSIT_ACTIONS_NEEDS(id).get(
                        permission.get("action", ""),
                        ""),
                    user=user
                ))
            except:
                return

            access.get(permission["action"], {}).get(
                'user', []).append(user.id)

        elif (permission.get("op", "") == "remove"):
            try:
                au = ActionUsers.query.filter(
                    ActionUsers.action == permission.get("action", ""),
                    ActionUsers.argument == str(id),
                    ActionUsers.user_id == user.id).first()

                if au:
                    session.delete(au)

            except:
                return

            access.get(permission["action"], {}).get(
                'user', []).remove(user.id)

    return access
Пример #33
0
    def grant_notification_viewed_permission(cls, user_id, notification_id, is_flush=True) -> Dict[
        str, bool]:
        done = False
        msg = ''
        try:
            user = User.query.filter_by(id=user_id)
            if not user:
                msg = 'User not found'
            else:
                db.session.add(
                    ActionUsers.allow(ObjectNotificationEditor(notification_id), user=user)
                    )
                if is_flush:
                    db.session.flush()
                else:
                    db.session.commit()
                msg = 'Notification marking viewed Permission granted '
                done = True

        except Exception as e:
            msg = str(e)
            # print(str(e))

        return msg, done
    def _add_deposit_permissions(cls, data, id_):
        """Inherit permissions after deposit."""
        data['_access'] = {
            DEPOSIT_TO_RECORD_ACTION_MAP[action]: permission
            for action, permission in data['_access'].items()
        }

        for action, permission in data['_access'].items():
            for role in permission['roles']:
                role = Role.query.filter_by(id=role).one()
                db.session.add(
                    ActionRoles.allow(
                        RECORD_ACTION_NEEDS(id_)[action],
                        role=role
                    )
                )
            for user in permission['users']:
                user = User.query.filter_by(id=user).one()
                db.session.add(
                    ActionUsers.allow(
                        RECORD_ACTION_NEEDS(id_)[action],
                        user=user
                    )
                )
Пример #35
0
def test_file_permissions(app, db, record_with_files_creation,
                          user, access_right, expected):
    """Test file permissions."""
    pid, record, record_url = record_with_files_creation

    # Create test users
    admin = User(email='*****@*****.**', password='******')
    owner = User(email='*****@*****.**', password='******')
    auth = User(email='*****@*****.**', password='******')
    db.session.add_all([admin, owner, auth])
    db.session.add(
        ActionUsers.allow(ActionNeed('admin-access'), user=admin)
    )
    db.session.commit()

    # Create test record
    record['access_right'] = access_right
    record['owners'] = [owner.id]
    record.commit()
    db.session.commit()

    file_url = url_for(
        'invenio_records_ui.recid_files',
        pid_value=pid.pid_value,
        filename='Test.pdf',
    )
    with app.test_client() as client:
        if user:
            # Login as user
            with client.session_transaction() as sess:
                sess['user_id'] = User.query.filter_by(
                    email='{}@zenodo.org'.format(user)).one().id
                sess['_fresh'] = True

        res = client.get(file_url)
        assert res.status_code == expected
Пример #36
0
def add_record(metadata, collection, schema, force, files=[]):
    """Add record."""

    collection = Collection.query.filter(Collection.name == collection).first()

    if collection is None:
        return

    data, pid, recid = construct_record(collection, metadata, 1,
                                        {} if force else schema)
    d = current_app.config['DATADIR']

    buckets = []
    data['_files'] = []

    for file in files:
        bucket = Bucket.create(default_location=Location.get_default())
        buckets.append(bucket)

        with open(
                pkg_resources.resource_filename(
                    'cap.modules.fixtures',
                    os.path.join('data', 'files', file)), 'rb') as fp:
            obj = ObjectVersion.create(bucket, file, stream=fp)

            data['_files'].append({
                'bucket': str(obj.bucket_id),
                'key': obj.key,
                'size': obj.file.size,
                'checksum': str(obj.file.checksum),
                'version_id': str(obj.version_id),
            })
    try:
        record = Record.create(data, id_=recid)

        for bucket in buckets:
            rb = RecordsBuckets(record_id=record.id, bucket_id=bucket.id)
            db.session.add(rb)

        # Invenio-Indexer is delegating the document inferring to
        # Invenio-Search which is analysing the string splitting by `/` and
        # using `.json` to be sure that it cans understand the mapping.
        record['$schema'] = 'mappings/{0}.json'.format(collection.name.lower())

        indexer = RecordIndexer()
        indexer.index(record)

        # Creating permission needs for the record
        action_edit_record = RecordUpdateActionNeed(str(recid))
        action_read_record = RecordReadActionNeed(str(recid))
        action_index_record = RecordIndexActionNeed(str(recid))

        # Giving index, read, write permissions to user/creator
        db.session.add(ActionUsers.allow(action_edit_record))
        db.session.add(ActionUsers.allow(action_read_record))
        db.session.add(ActionUsers.allow(action_index_record))

        db.session.commit()

        print("DONE!!!")

    except ValidationError as error:
        print("============================")
        pprint(error.message)
        pprint(error.path)
        print("============================")

        db.session.rollback()
Пример #37
0
    def create(cls, data, id_=None, owner=current_user):
        """Create a new deposit.

        :param data: metadata, need to contain $schema|$ana_type field
        :type data: dict
        :param id_: specify a UUID to use for the new record, instead of
                    automatically generated
        :type id_: `uuid.UUID`
        :param owner: owner of a new deposit (will get all permissions)
        :type owner: `invenio_accounts.models.User`

        :warn: if user session owner will be automatically current_user

        :return: newly created deposit
        :rtype: `CAPDeposit`

        Process:
        * fill deposit metadata based on given data
        * initialize the follow internal fields (underscore prefixed):
            _experiment: 'experiment_of_given_schema'
            _deposit: {
                'id': pid_value,
                'status': 'draft',
                'owners': [owner_id],
                'created_by': owner_id
            }
            _access: {
                'deposit-admin': {
                    'roles': [],
                    'users': [owner.id]
                },
                'deposit-update': {
                    'roles': [],
                    'users': [owner.id]
                },
                'deposit-read': {
                    'roles': [],
                    'users': [owner.id]
                }
            }
        * validate metadata against given schema (defined by $schema|$ana_type)
        * create RecordMetadata instance
        * create bucket for storing deposit files
        * set owner permissions in the db
        * index deposit in elasticsearch
        """
        if current_user and current_user.is_authenticated:
            owner = current_user

        with db.session.begin_nested():
            uuid_ = id_ or uuid.uuid4()

            data = cls._preprocess_create_data(data, uuid_, owner)

            # create RecordMetadata instance
            deposit = Record.create(data,
                                    id_=uuid_,
                                    validator=NoRequiredValidator)
            deposit.__class__ = cls

            # create files bucket
            bucket = Bucket.create()
            RecordsBuckets.create(record=deposit.model, bucket=bucket)
            # give owner permissions to the deposit
            if owner:
                for permission in DEPOSIT_ACTIONS:
                    db.session.add(
                        ActionUsers.allow(DEPOSIT_ACTIONS_NEEDS(
                            deposit.id)[permission],
                                          user=owner))

                    db.session.flush()

            return deposit
Пример #38
0
def update_record_permissions(pid_value=None):
    resolver = Resolver(pid_type='recid',
                        object_type='rec',
                        getter=Record.get_record)

    pid, record = resolver.resolve(pid_value)

    emails = []
    roles = []
    userrole_list = request.get_json().keys()

    if not (current_app.config.get('EMAIL_REGEX', None)):
        resp = jsonify(**{message: "ERROR in email regex ;)"})
        resp.status_code = 400
        return resp

    email_regex = re.compile(current_app.config.get('EMAIL_REGEX'), )

    for userrole in userrole_list:
        if email_regex.match(userrole):
            emails.append(userrole)
        else:
            #: [TOBEFIXED] Needs to check if E-Group exists
            try:
                role = Role.query.filter(Role.name == userrole).first()
                if not role:
                    tmp_role = _datastore.create_role(name=userrole)
                roles.append(userrole)
            except:
                print("Something happened when trying to create '" + userrole +
                      "' role")
            # Role.add(tmp_role)

    users = User.query.filter(User.email.in_(emails)).all()
    roles = Role.query.filter(Role.name.in_(roles)).all()

    action_edit_record = RecordUpdateActionNeed(str(record.id))
    action_read_record = RecordReadActionNeed(str(record.id))
    action_index_record = RecordIndexActionNeed(str(record.id))

    with db.session.begin_nested():
        for user in users:
            for action in request.get_json().get(user.email, None):
                if (action.get("action", None) == "records-read"
                        and action.get("op", None) == "add"):
                    db.session.add(
                        ActionUsers.allow(action_read_record, user=user))
                elif (action.get("action", None) == "records-index"
                      and action.get("op", None) == "add"):
                    db.session.add(
                        ActionUsers.allow(action_index_record, user=user))
                elif (action.get("action", None) == "records-update"
                      and action.get("op", None) == "add"):
                    db.session.add(
                        ActionUsers.allow(action_edit_record, user=user))
                elif (action.get("action", None) == "records-read"
                      and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(
                        ActionUsers.action == "records-read",
                        ActionUsers.argument == str(record.id),
                        ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-index"
                      and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(
                        ActionUsers.action == "records-index",
                        ActionUsers.argument == str(record.id),
                        ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-update"
                      and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(
                        ActionUsers.action == "records-update",
                        ActionUsers.argument == str(record.id),
                        ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)

        # db.session.begin(nested=True)
        for role in roles:
            for action in request.get_json().get(role.name, None):
                if (action.get("action", None) == "records-read"
                        and action.get("op", None) == "add"):
                    db.session.add(
                        ActionRoles.allow(action_read_record, role=role))
                elif (action.get("action", None) == "records-index"
                      and action.get("op", None) == "add"):
                    db.session.add(
                        ActionRoles.allow(action_index_record, role=role))
                elif (action.get("action", None) == "records-update"
                      and action.get("op", None) == "add"):
                    db.session.add(
                        ActionRoles.allow(action_edit_record, role=role))
                elif (action.get("action", None) == "records-read"
                      and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(
                        ActionRoles.action == "records-read",
                        ActionRoles.argument == str(record.id),
                        ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-index"
                      and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(
                        ActionRoles.action == "records-index",
                        ActionRoles.argument == str(record.id),
                        ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-update"
                      and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(
                        ActionRoles.action == "records-update",
                        ActionRoles.argument == str(record.id),
                        ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)

    db.session.commit()

    resp = jsonify()
    resp.status_code = 200
    return resp
def add_record_index_permissions(recid=None, user=None):
    action_index_record = RecordIndexActionNeed(str(recid))
    db.session.add(ActionUsers.allow(action_index_record, user=user))
Пример #40
0
def delete_record_read_permissions(recid=None, user=None):
    action_read_record = RecordReadActionNeed(str(recid))
    db.session.delete(ActionUsers.allow(action_read_record, user=user))
def add_record_edit_permissions(recid=None, user=None):
    action_edit_record = RecordUpdateActionNeed(str(recid))
    db.session.add(ActionUsers.allow(action_edit_record, user=user))
def delete_record_read_permissions(recid=None, user=None):
    action_read_record = RecordReadActionNeed(str(recid))
    db.session.delete(ActionUsers.allow(action_read_record, user=user))
def update_record_permissions(pid_value=None):
    resolver = Resolver(
        pid_type='recid',
        object_type='rec',
        getter=Record.get_record)

    pid, record = resolver.resolve(pid_value)


    emails = []
    roles = []
    userrole_list = request.get_json().keys()

    if not (current_app.config.get('EMAIL_REGEX', None)):
        resp = jsonify(**{message: "ERROR in email regex ;)"})
        resp.status_code = 400
        return resp

    email_regex = re.compile(current_app.config.get('EMAIL_REGEX'), )

    for userrole in userrole_list:
        if email_regex.match(userrole):
            emails.append(userrole)
        else:
            #: [TOBEFIXED] Needs to check if E-Group exists
            try:
                role = Role.query.filter(Role.name == userrole).first()
                if not role:
                    tmp_role = _datastore.create_role(name=userrole)
                roles.append(userrole)
            except:
                print("Something happened when trying to create '"+userrole+"' role")
            # Role.add(tmp_role)

    users = User.query.filter(User.email.in_(emails)).all()
    roles = Role.query.filter(Role.name.in_(roles)).all()

    action_edit_record = RecordUpdateActionNeed(str(record.id))
    action_read_record = RecordReadActionNeed(str(record.id))
    action_index_record = RecordIndexActionNeed(str(record.id))

    with db.session.begin_nested():
        for user in users:
            for action in request.get_json().get(user.email, None):
                if (action.get("action", None) == "records-read" and action.get("op", None) == "add"):
                    db.session.add(ActionUsers.allow(action_read_record, user=user))
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "add"):
                    db.session.add(ActionUsers.allow(action_index_record, user=user))
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "add"):
                    db.session.add(ActionUsers.allow(action_edit_record, user=user))
                elif (action.get("action", None) == "records-read" and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(ActionUsers.action == "records-read", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(ActionUsers.action == "records-index", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "remove"):
                    au = ActionUsers.query.filter(ActionUsers.action == "records-update", ActionUsers.argument == str(record.id), ActionUsers.user_id == user.id).first()
                    if (au):
                        db.session.delete(au)

        # db.session.begin(nested=True)
        for role in roles:
            for action in request.get_json().get(role.name, None):
                if (action.get("action", None) == "records-read" and action.get("op", None) == "add"):
                    db.session.add(ActionRoles.allow(action_read_record, role=role))
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "add"):
                    db.session.add(ActionRoles.allow(action_index_record, role=role))
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "add"):
                    db.session.add(ActionRoles.allow(action_edit_record, role=role))
                elif (action.get("action", None) == "records-read" and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(ActionRoles.action == "records-read", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-index" and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(ActionRoles.action == "records-index", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)
                elif (action.get("action", None) == "records-update" and action.get("op", None) == "remove"):
                    au = ActionRoles.query.filter(ActionRoles.action == "records-update", ActionRoles.argument == str(record.id), ActionRoles.role_id == role.id).first()
                    if (au):
                        db.session.delete(au)

    db.session.commit()

    resp = jsonify()
    resp.status_code = 200
    return resp
Пример #44
0
def add_record_edit_permissions(recid=None, user=None):
    action_edit_record = RecordUpdateActionNeed(str(recid))
    db.session.add(ActionUsers.allow(action_edit_record, user=user))
Пример #45
0
def add_record_index_permissions(recid=None, user=None):
    action_index_record = RecordIndexActionNeed(str(recid))
    db.session.add(ActionUsers.allow(action_index_record, user=user))