示例#1
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
示例#2
0
def test_get_reachable_roles(app):
    """Test get roles covered by the given role."""
    roles = UserRecord.get_reachable_roles(UserRecord.ROLE_MODERATOR)
    assert len(roles) == 3
    assert UserRecord.ROLE_MODERATOR in roles
    assert UserRecord.ROLE_SUBMITTER in roles
    assert UserRecord.ROLE_USER in roles

    roles = UserRecord.get_reachable_roles('unknown_role')
    assert not roles
示例#3
0
文件: conftest.py 项目: weblate/sonar
    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
示例#4
0
    def read(cls, user, record):
        """Read permission check.

        :param user: Logged user.
        :param recor: Record to check.
        :returns: True is action can be done.
        """
        if not current_user_record:
            return False

        # Can read himself in all cases
        if current_user_record['pid'] == record['pid']:
            return True

        # If not admin, no access
        if not current_user_record.is_admin:
            return False

        # Superuser is allowed
        if current_user_record.is_superuser:
            return True

        # Cannot read superusers records
        if UserRecord.ROLE_SUPERUSER == record['role']:
            return False

        user = UserRecord.get_record_by_pid(record['pid'])
        user = user.replace_refs()

        if not user.get('organisation'):
            return True

        return current_organisation['pid'] == user['organisation']['pid']
示例#5
0
    def post_process_serialize_search(self, results, pid_fetcher):
        """Post process the search results."""
        if current_user_record:
            # Remove organisation facet for non super users
            if not current_user_record.is_superuser:
                results['aggregations'].pop('organisation', {})

            # Remove user facet for non moderators users
            if not current_user_record.is_moderator:
                results['aggregations'].pop('user', {})

        # Add organisation name
        for org_term in results.get('aggregations',
                                    {}).get('organisation',
                                            {}).get('buckets', []):
            organisation = OrganisationRecord.get_record_by_pid(
                org_term['key'])
            if organisation:
                org_term['name'] = organisation['name']

        # Add user name
        for org_term in results.get('aggregations',
                                    {}).get('user', {}).get('buckets', []):
            user = UserRecord.get_record_by_pid(org_term['key'])
            if user:
                org_term['name'] = '{last_name}, {first_name}'.format(
                    last_name=user['last_name'], first_name=user['first_name'])

        return super(JSONSerializer,
                     self).post_process_serialize_search(results, pid_fetcher)
示例#6
0
    def aggregations(self):
        """Get the search result aggregations."""
        aggregations = self._results.aggregations.to_dict()

        if current_user_record:
            # Remove organisation facet for non super users
            if not current_user_record.is_superuser:
                aggregations.pop('organisation', {})

            # Remove user facet for non moderators users
            if not current_user_record.is_moderator:
                aggregations.pop('user', {})

        # Add organisation name
        for org_term in aggregations.get('organisation',
                                         {}).get('buckets', []):
            organisation = OrganisationRecord.get_record_by_pid(
                org_term['key'])
            if organisation:
                org_term['name'] = organisation['name']

        # Add user name
        for org_term in aggregations.get('user', {}).get('buckets', []):
            user = UserRecord.get_record_by_pid(org_term['key'])
            if user:
                org_term['name'] = '{last_name}, {first_name}'.format(
                    last_name=user['last_name'], first_name=user['first_name'])

        return aggregations
示例#7
0
def test_user_registered_handler(app, roles, user_without_role):
    """Test user confirmed signal."""
    assert not user_without_role.roles
    user_registered_handler(app, user_without_role, None)
    assert user_without_role.roles[0].name == 'user'

    user = UserRecord.get_user_by_email(user_without_role.email)
    assert not user
示例#8
0
def test_get_user_by_current_user(app, client, user_without_role, user):
    """Test getting a user with email taken from logged user."""
    record = UserRecord.get_user_by_current_user(current_user)
    assert record is None

    login_user_via_view(client,
                        email=user_without_role.email,
                        password='******')
    record = UserRecord.get_user_by_current_user(current_user)
    assert record is None

    client.get(url_for_security('logout'))

    login_user_via_view(client, email=user['email'], password='******')
    record = UserRecord.get_user_by_current_user(current_user)
    assert 'email' in record
    assert user['email'] == '*****@*****.**'
示例#9
0
def test_user_resolver(app, organisation, roles):
    """Test user resolver."""
    UserRecord.create({
        'pid': '1',
        'full_name': 'Jules Brochu',
        'email': '*****@*****.**',
        'roles': ['user'],
        'organisation': {
            '$ref': 'https://sonar.ch/api/organisations/org'
        }
    })

    record = DepositRecord.create(
        {'user': {
            '$ref': 'https://sonar.ch/api/users/1'
        }}, with_bucket=False)

    assert record.replace_refs().get('user')['email'] == '*****@*****.**'
示例#10
0
    def post_process_serialize_search(self, results, pid_fetcher):
        """Post process the search results."""
        # Add user name
        for org_term in results.get('aggregations',
                                    {}).get('user', {}).get('buckets', []):
            user = UserRecord.get_record_by_pid(org_term['key'])
            if user:
                org_term['name'] = '{last_name}, {first_name}'.format(
                    last_name=user['last_name'], first_name=user['first_name'])

        return super(JSONSerializer,
                     self).post_process_serialize_search(results, pid_fetcher)
示例#11
0
def test_delete(app, admin):
    """Test removing record."""
    admin.delete(dbcommit=True, delindex=True)

    deleted = UserRecord.get_record(admin.id, with_deleted=True)
    assert deleted.id == admin.id

    with app.app_context():
        datastore = app.extensions['security'].datastore
        user = datastore.find_user(email='*****@*****.**')
        assert not user.roles
        assert not user.is_active
示例#12
0
文件: signals.py 项目: weblate/sonar
def user_registered_handler(app, user, confirm_token):
    """Called when a new user is registered.

    :param app: App context.
    :param user: User account.
    """
    # Add a default role to user
    role = datastore.find_role(UserRecord.ROLE_USER)
    datastore.add_role_to_user(user, role)
    datastore.commit()

    # Create user record
    user_record = UserRecord.get_user_by_email(user.email)
    if not user_record:
        user_record = UserRecord.create(
            {
                'full_name': user.email,
                'email': user.email,
                'roles': [UserRecord.ROLE_USER]
            },
            dbcommit=True)
        user_record.reindex()
示例#13
0
def publish(pid=None):
    """Publish a deposit or send a message for review."""
    deposit = DepositRecord.get_record_by_pid(pid)

    if not deposit or deposit[
            'step'] != DepositRecord.STEP_DIFFUSION or deposit[
                'status'] not in [
                    DepositRecord.STATUS_IN_PROGRESS,
                    DepositRecord.STATUS_ASK_FOR_CHANGES
                ]:
        abort(400)

    user = UserRecord.get_record_by_ref_link(deposit['user']['$ref'])

    # Deposit can be validated directly
    if user.is_granted(UserRecord.ROLE_MODERATOR):
        deposit['status'] = DepositRecord.STATUS_VALIDATED

        # Create document based on deposit
        deposit.create_document()
    else:
        deposit['status'] = DepositRecord.STATUS_TO_VALIDATE

        subdivision = SubdivisionRecord.get_record_by_ref_link(
            user['subdivision']['$ref']) if user.get('subdivision') else None

        moderators_emails = user.get_moderators_emails(
            subdivision['pid'] if subdivision else None)

        email_subject = _('Deposit to validate')
        if subdivision:
            email_subject += f' ({get_language_value(subdivision["name"])})'

        if moderators_emails:
            # Send an email to validators
            send_email(
                moderators_emails, email_subject, 'deposits/email/validation',
                {
                    'deposit': deposit,
                    'user': user,
                    'link': current_app.config.get('SONAR_APP_ANGULAR_URL')
                }, False)

    deposit.log_action(user, 'submit')

    deposit.commit()
    deposit.reindex()
    db.session.commit()

    return make_response()
示例#14
0
    def guess_organisation(self, data, **kwargs):
        """Guess organisation from current logged user.

        :param data: Dict of user data.
        :returns: Modified dict of user data.
        """
        # Organisation already attached to user, we do nothing.
        if data.get('organisation'):
            return data

        # Store current user organisation in new user.
        user = UserRecord.get_user_by_current_user(current_user)
        if user.get('organisation'):
            data['organisation'] = user['organisation']

        return data
示例#15
0
    def dump(self, record, data):
        """Dump the data for indexing."""
        if data['metadata'].get('user'):
            data['metadata']['user'] = {
                'pid':
                UserRecord.get_pid_by_ref_link(
                    data['metadata']['user']['$ref'])
            }

        if data['metadata'].get('organisation'):
            organisation = OrganisationRecord.get_record_by_ref_link(
                data['metadata']['organisation']['$ref'])
            data['metadata']['organisation'] = {
                'pid': organisation['pid'],
                'name': organisation['name']
            }
示例#16
0
def test_is_role_property(organisation, roles):
    """Test if user is in a particular role."""
    user = UserRecord.create(
        {
            'full_name': 'John Doe',
            'email': '*****@*****.**',
            'roles': [UserRecord.ROLE_MODERATOR],
            'organisation': {
                '$ref': 'https://sonar.ch/api/organisations/org'
            }
        },
        dbcommit=True)

    assert user.is_user
    assert user.is_submitter
    assert user.is_moderator
    assert not user.is_admin
    assert not user.is_superuser
示例#17
0
def test_get_moderators(app, organisation, roles):
    """Test search for moderators."""
    user = UserRecord.create(
        {
            'full_name': 'John Doe',
            'email': '*****@*****.**',
            'roles': [UserRecord.ROLE_MODERATOR],
            'organisation': {
                '$ref': 'https://sonar.ch/api/organisations/org'
            }
        },
        dbcommit=True)
    user.reindex()

    moderators = UserSearch().get_moderators()
    assert list(moderators)

    moderators = UserSearch().get_moderators('not_existing_organisation')
    assert not list(moderators)
示例#18
0
文件: views.py 项目: weblate/sonar
def logged_user():
    """Current logged user informations in JSON."""
    if current_user.is_anonymous:
        return jsonify({})

    user = UserRecord.get_user_by_current_user(current_user)

    if user and 'resolve' in request.args:
        user = user.replace_refs()

    data = {}

    if user:
        data['metadata'] = user.dumps()
        data['metadata']['is_superuser'] = user.is_superuser
        data['metadata']['is_admin'] = user.is_admin
        data['metadata']['is_moderator'] = user.is_moderator
        data['metadata']['is_submitter'] = user.is_submitter
        data['metadata']['is_user'] = user.is_user
        data['metadata']['permissions'] = {
            'users': {
                'add': UserPermission.create(user),
                'list': UserPermission.list(user)
            },
            'documents': {
                'add': DocumentPermission.create(user),
                'list': DocumentPermission.list(user)
            },
            'organisations': {
                'add': OrganisationPermission.create(user),
                'list': OrganisationPermission.list(user)
            },
            'deposits': {
                'add': DepositPermission.create(user),
                'list': DepositPermission.list(user)
            }
        }

    # TODO: If an organisation is associated to user and only when running
    # tests, organisation cannot not be encoded to JSON after call of
    # user.replace_refs() --> check why
    return jsonify(data)
示例#19
0
def test_is_granted(app, organisation, roles):
    """Test if user is granted with a role."""
    user = UserRecord.create(
        {
            'full_name': 'John Doe',
            'email': '*****@*****.**',
            'roles': [UserRecord.ROLE_MODERATOR],
            'organisation': {
                '$ref': 'https://sonar.ch/api/organisations/org'
            }
        },
        dbcommit=True)

    assert not user.is_granted(UserRecord.ROLE_ADMIN)
    assert not user.is_granted('fake_role')
    assert user.is_granted(UserRecord.ROLE_MODERATOR)
    assert user.is_granted(UserRecord.ROLE_USER)

    del user['roles']
    assert not user.is_granted(UserRecord.ROLE_MODERATOR)
示例#20
0
    def _load_user(self, record):
        """Check data integrity and load user.

        :param record: Record to check.
        :returns: User record.
        """
        if not current_user_record:
            raise UserNotLoggedError

        if not record['metadata'].get('validation', {}).get('user'):
            raise Exception('No user stored in record')

        record_user = UserRecord.get_record_by_ref_link(
            record['metadata']['validation']['user']['$ref'])

        if not record_user:
            raise UserRecordNotFoundError

        if not self._user_can_moderate() and not self._user_is_owner_of_record(
                record_user):
            raise UserIsNotOwnerOfRecordError

        return record_user
示例#21
0
def test_get_moderators_emails(app, organisation, roles):
    """Test getting list of moderators emails."""
    user = UserRecord.create(
        {
            'full_name': 'John Doe',
            'email': '*****@*****.**',
            'roles': [UserRecord.ROLE_MODERATOR],
            'organisation': {
                '$ref': 'https://sonar.ch/api/organisations/org'
            }
        },
        dbcommit=True)
    user.reindex()

    emails = user.get_moderators_emails()
    assert emails
    assert '*****@*****.**' in emails

    user['organisation'] = {
        '$ref': 'https://sonar.ch/api/organisations/not-existing'
    }
    emails = user.get_moderators_emails()
    assert not emails
示例#22
0
def test_review(client, db, user, moderator, deposit):
    """Test reviewing a deposit."""
    url = url_for('deposits.review', pid=deposit['pid'])

    headers = {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
    }

    # Deposit is not in status to validate
    response = client.post(url)
    assert response.status_code == 400

    # No payload posted
    deposit['status'] = 'to_validate'
    deposit.commit()
    db.session.commit()

    response = client.post(url)
    assert response.status_code == 400

    # Invalid action
    response = client.post(url,
                           data=json.dumps({
                               'action': 'unknown',
                               'comment': None
                           }),
                           headers=headers)
    assert response.status_code == 400

    # User is not a moderator
    response = client.post(url,
                           data=json.dumps({
                               'action': 'approve',
                               'comment': None,
                               'user': {
                                   '$ref':
                                   UserRecord.get_ref_link(
                                       'users', user['pid'])
                               }
                           }),
                           headers=headers)
    assert response.status_code == 403

    login_user_via_view(client, email=moderator['email'], password='******')

    # Valid approval request
    response = client.post(url,
                           data=json.dumps({
                               'action': 'approve',
                               'comment': None,
                               'user': {
                                   '$ref':
                                   UserRecord.get_ref_link(
                                       'users', moderator['pid'])
                               }
                           }),
                           headers=headers)
    assert response.status_code == 200

    # Valid refusal request
    deposit['status'] = 'to_validate'
    deposit.commit()
    db.session.commit()
    response = client.post(url,
                           data=json.dumps({
                               'action': 'reject',
                               'comment': 'Sorry deposit is not valid',
                               'user': {
                                   '$ref':
                                   UserRecord.get_ref_link(
                                       'users', moderator['pid'])
                               }
                           }),
                           headers=headers)
    assert response.status_code == 200

    # Valid ask for changes request
    deposit['status'] = 'to_validate'
    deposit.commit()
    db.session.commit()
    response = client.post(url,
                           data=json.dumps({
                               'action': 'ask_for_changes',
                               'comment': None,
                               'user': {
                                   '$ref':
                                   UserRecord.get_ref_link(
                                       'users', moderator['pid'])
                               }
                           }),
                           headers=headers)
    assert response.status_code == 200
示例#23
0
文件: rest.py 项目: weblate/sonar
def review(pid=None):
    """Review a deposit and change the deposit status depending on action."""
    deposit = DepositRecord.get_record_by_pid(pid)

    if not deposit or deposit['status'] != DepositRecord.STATUS_TO_VALIDATE:
        abort(400)

    payload = request.get_json()

    if not payload:
        abort(400)

    if 'action' not in payload or 'user' not in payload or payload[
            'action'] not in [
                DepositRecord.REVIEW_ACTION_APPROVE,
                DepositRecord.REVIEW_ACTION_REJECT,
                DepositRecord.REVIEW_ACTION_ASK_FOR_CHANGES
            ]:
        abort(400)

    user = UserRecord.get_record_by_ref_link(payload['user']['$ref'])

    if not user or not user.is_moderator:
        abort(403)

    subject = None
    status = None

    if payload['action'] == DepositRecord.REVIEW_ACTION_APPROVE:
        subject = _('Deposit approval')
        status = DepositRecord.STATUS_VALIDATED

        # Create document based on deposit
        deposit.create_document()
    elif payload['action'] == DepositRecord.REVIEW_ACTION_REJECT:
        subject = _('Deposit rejection')
        status = DepositRecord.STATUS_REJECTED
    else:
        subject = _('Ask for changes on deposit')
        status = DepositRecord.STATUS_ASK_FOR_CHANGES

    deposit['status'] = status

    # Log action
    deposit.log_action(payload['user'], payload['action'], payload['comment'])

    # Load user who creates the deposit
    deposit_user = UserRecord.get_record_by_ref_link(deposit['user']['$ref'])

    send_email(
        [deposit_user['email']], subject,
        'deposits/email/{action}'.format(action=payload['action']), {
            'deposit': deposit,
            'deposit_user': deposit_user,
            'user': user,
            'date': datetime.now().strftime('%d.%m.%Y %H:%M:%S'),
            'comment': payload['comment'],
            'link': current_app.config.get('SONAR_APP_ANGULAR_URL')
        }, False)

    deposit.commit()
    deposit.reindex()
    db.session.commit()

    return make_response(jsonify(deposit))