Exemple #1
0
def create_userprofile_for(email, username, full_name):
    """Create a fake user profile."""
    user = User.query.filter_by(email=email).one_or_none()
    if user:
        profile = UserProfile(user_id=int(user.get_id()))
        profile.username = username
        profile.full_name = full_name
        db.session.add(profile)
        db.session.commit()
Exemple #2
0
def authorize(name):
    ui_flag = session.pop('ui', None)

    client = current_auth.create_client(name)
    try:
        token = client.authorize_access_token()
    except HTTPException:
        return render_template(
            current_app.config['AUTHENTICATION_POPUP_TEMPLATE'],
            msg=f'Access not provided to {name} service.'), 400

    configs = OAUTH_SERVICES.get(name.upper(), {})
    extra_data_method = configs.get('extra_data_method')

    # TOFIX Add error handlers for reject, auth errors, etc
    extra_data = {}
    if extra_data_method:
        extra_data = extra_data_method(client, token)

    _token = _create_or_update_token(name, token)
    _token.extra_data = extra_data

    db.session.add(_token)

    # Add extra data to user profile.
    # If user profile doesn't exist yet, it creates one.
    _profile = UserProfile.get_by_userid(current_user.id)
    if not _profile:
        _profile = UserProfile(user_id=current_user.id)
        db.session.add(_profile)

    profile_data = get_oauth_profile(name, token=_token, client=client)

    if _profile.extra_data:
        profile_services = _profile.extra_data.get("services", {})
    else:
        profile_services = {}
    profile_services[name] = profile_data
    _profile.extra_data = {"services": profile_services}
    flag_modified(_profile, "extra_data")

    db.session.commit()

    if ui_flag:
        return render_template(
            current_app.config['AUTHENTICATION_POPUP_TEMPLATE'],
            msg=f'Authorization to {name} succeeded.'), 302
    else:
        return jsonify({"message": f"Authorization to {name} succeeded."}), 200
Exemple #3
0
    def _import_users(users, users_identities, users_profiles,
                      remote_accounts):
        """Import users in db."""
        click.secho('Migrating {0} users'.format(len(users)), fg='green')
        for user in users:
            user = User(**user)
            db.session.add(user)

        click.secho('Migrating {0} user identities'.format(
            len(users_identities)),
                    fg='green')

        for identity in users_identities:
            user_identity = UserIdentity(**identity)
            db.session.add(user_identity)

        click.secho('Migrating {0} user profiles'.format(len(users_profiles)),
                    fg='green')
        for profile in users_profiles:
            user_profile = UserProfile(**profile)
            db.session.add(user_profile)

        click.secho('Migrating {0} remote accoutns'.format(
            len(remote_accounts)),
                    fg='green')
        client_id = current_app.config['CERN_APP_CREDENTIALS']['consumer_key']
        for account in remote_accounts:
            remote_account = RemoteAccount(client_id=client_id, **account)
            db.session.add(remote_account)

        db.session.commit()
Exemple #4
0
def system_user(app, db):
    """Create a regular system user."""
    user = User(**dict(email="*****@*****.**", active=True))
    db.session.add(user)
    db.session.commit()

    user_id = user.id

    identity = UserIdentity(**dict(id="1", method="cern", id_user=user_id))
    db.session.add(identity)

    profile = UserProfile(
        **dict(
            user_id=user_id,
            _displayname="id_" + str(user_id),
            full_name="System User",
        )
    )
    db.session.add(profile)

    remote_account = RemoteAccount(
        client_id="CLIENT_ID",
        **dict(
            user_id=user_id,
            extra_data=dict(person_id="1", department="Department"),
        )
    )
    db.session.add(remote_account)
    db.session.commit()
    return user
Exemple #5
0
def user_exists(email):
    """Validate that a user exists."""
    try:
        profile = UserProfile.get_by_username(email)
    except NoResultFound:
        if not current_datastore.get_user(email):
            raise ValidationError('USER_DOES_NOT_EXIST')
Exemple #6
0
    def update(self, data):
        """User record update.

        :param data - dictionary representing a user record to update
        """
        from ..patrons.listener import update_from_profile
        self._validate(data=data)
        email = data.pop('email', None)
        roles = data.pop('roles', None)
        user = self.user
        with db.session.begin_nested():
            if user.profile is None:
                user.profile = UserProfile(user_id=user.id)
            profile = user.profile
            for field in self.profile_fields:
                if field == 'birth_date':
                    setattr(profile, field,
                            datetime.strptime(data.get(field), '%Y-%m-%d'))
                else:
                    setattr(profile, field, data.get(field, ''))
            # change password
            if data.get('password'):
                user.password = hash_password(data['password'])

            if email and email != user.email:
                user.email = email
            # remove the email from user data
            elif not email and user.email:
                user.email = None
            db.session.merge(user)
        db.session.commit()
        confirm_user(user)
        update_from_profile('user', self.user.profile)
        return self
Exemple #7
0
def patron1(app, db):
    """Create a patron user."""
    user = User(**dict(email="*****@*****.**", active=True))
    db.session.add(user)
    db.session.commit()

    user_id = user.id

    identity = UserIdentity(**dict(id="1", method="cern", id_user=user_id))
    db.session.add(identity)

    profile = UserProfile(
        **dict(
            user_id=user_id,
            _displayname="id_" + str(user_id),
            full_name="System User",
        )
    )
    db.session.add(profile)

    client_id = app.config["CERN_APP_OPENID_CREDENTIALS"]["consumer_key"]
    remote_account = RemoteAccount(
        client_id=client_id,
        **dict(
            user_id=user_id,
            extra_data=dict(person_id="1", department="Department"),
        )
    )
    db.session.add(remote_account)
    db.session.commit()
    return user
Exemple #8
0
    def import_users(self):
        """Return location and internal location records."""
        def _commit_user(user_data):
            """Commit new user in db."""
            user = User(**self.import_user(user_data))
            db.session.add(user)
            db.session.commit()
            return user.id

        for ldap_user in self.ldap_users:
            print("Importing user with person id {}".format(
                ldap_user["employeeID"][0].decode("utf8")))

            user_id = _commit_user(ldap_user)
            identity = UserIdentity(
                **self.import_user_identity(user_id, ldap_user))
            db.session.add(identity)

            profile = UserProfile(
                **self.import_user_profile(user_id, ldap_user))
            db.session.add(profile)

            client_id = (current_app.config.get(
                "CERN_APP_CREDENTIALS", {}).get("consumer_key") or "CLIENT_ID")
            remote_account = RemoteAccount(client_id=client_id,
                                           **self.import_remote_account(
                                               user_id, ldap_user))
            db.session.add(remote_account)

        db.session.commit()
def authorize(name):
    ui_flag = session.pop('ui', None)

    client = current_auth.create_client(name)
    token = client.authorize_access_token()

    configs = OAUTH_SERVICES.get(name.upper(), {})
    extra_data_method = configs.get('extra_data_method')

    # TOFIX Add error handlers for reject, auth errors, etc
    extra_data = {}
    if extra_data_method:
        extra_data = extra_data_method(client, token)

    _token = _create_or_update_token(name, token)
    _token.extra_data = extra_data

    db.session.add(_token)

    # Add extra data to user profile.
    # If user profile doesn't exist yet, it creates one.
    _profile = UserProfile.get_by_userid(current_user.id)
    if not _profile:
        _profile = UserProfile(user_id=current_user.id)
        db.session.add(_profile)

    profile_data = get_oauth_profile(name, token=_token, client=client)

    if _profile.extra_data:
        profile_services = _profile.extra_data.get("services", {})
    else:
        profile_services = {}
    profile_services[name] = profile_data
    _profile.extra_data = {"services": profile_services}
    flag_modified(_profile, "extra_data")

    db.session.commit()

    if ui_flag:
        if current_app.config['DEBUG']:
            redirect_url = "http://localhost:3000/settings/auth/connect"
        else:
            redirect_url = "/settings/auth/connect"
        return redirect(redirect_url)
    else:
        return jsonify(
            {"message": "Authorization to {} succeeded".format(name)}), 200
Exemple #10
0
 def create_invenio_user_profile(self, user_id, ldap_user):
     """Return new user profile."""
     display_name = ldap_user["user_profile_full_name"]
     return UserProfile(
         user_id=user_id,
         _displayname="id_{}".format(user_id),
         full_name=display_name,
     )
Exemple #11
0
 def get_user(self, email=None, **kwargs):
     """Retrieve a user by the provided arguments."""
     try:
         profile = UserProfile.get_by_username(email)
         return profile.user
     except NoResultFound:
         pass
     return current_datastore.get_user(email)
Exemple #12
0
def test_template_filter(app):
    """Test template filter."""
    with app.app_context():
        user = User(email='*****@*****.**', password='******')
        db.session.add(user)
        db.session.commit()
        user.profile = UserProfile(username='******', full_name='name')
        db.session.commit()

        assert userprofile(user.profile.user_id) == user.profile
Exemple #13
0
    def get_by_username(cls, username):
        """Get a user by a username.

        :param username - the user name
        :return: the user record
        """
        try:
            profile = UserProfile.get_by_username(username)
            return cls(profile.user)
        except NoResultFound:
            return None
Exemple #14
0
def current_user_invenio_profile():
    """Controller to get current user profile"""
    if current_user.is_authenticated:
        profile = UserProfile.get_by_userid(current_user.get_id())
        return {
            "name": getattr(profile, "full_name", None),
            "email": getattr(current_user, "email", None),
            "is_authenticated": True
        }
    return {
        "is_authenticated": False
    }
Exemple #15
0
def _register_or_update_user(entries, user_account=None):
    """Register or update a user."""
    email = entries[app.config['LDAPCLIENT_EMAIL_ATTRIBUTE']].values[0]
    username = entries[app.config['LDAPCLIENT_USERNAME_ATTRIBUTE']].values[0]
    if 'LDAPCLIENT_FULL_NAME_ATTRIBUTE' in app.config:
        full_name = entries[
            app.config['LDAPCLIENT_FULL_NAME_ATTRIBUTE']].values[0]

    if user_account is None:
        kwargs = dict(email=email, active=True, password=uuid.uuid4().hex)
        _datastore.create_user(**kwargs)
        user_account = User.query.filter_by(email=email).one_or_none()
        profile = UserProfile(user_id=int(user_account.get_id()))
    else:
        user_account.email = email
        db.session.add(user_account)
        profile = user_account.profile

    profile.full_name = full_name
    profile.username = username
    db.session.add(profile)
    return user_account
Exemple #16
0
def disconnect(name):
    _profile = UserProfile.get_by_userid(current_user.id)
    _token = OAuth2Token.get(name=name, user_id=current_user.id)

    if _profile and _token:
        del _profile.extra_data['services'][name]

        flag_modified(_profile, "extra_data")
        db.session.delete(_token)
        db.session.commit()

        return jsonify(
            {'message': 'Disconnected from {} '
             'successfully.'.format(name)}), 200
    else:
        abort(403, "Unable to disconnect from {} service.".format(name))
Exemple #17
0
def get_user():
    """Return logged in user."""
    deposit_groups = get_user_deposit_groups()

    profile = UserProfile.get_by_userid(current_user.id)
    extra_data = {}
    if profile:
        extra_data = profile.extra_data
    _user = {
        "id": current_user.id,
        "email": current_user.email,
        "deposit_groups": deposit_groups,
        "profile": extra_data
    }

    response = jsonify(_user)
    response.status_code = 200
    return response
Exemple #18
0
def patron2(app, db):
    """Create a patron user without remote account."""
    user = User(**dict(email="*****@*****.**", active=True))
    db.session.add(user)
    db.session.commit()

    user_id = user.id

    profile = UserProfile(
        **dict(
            user_id=user_id,
            _displayname="id_" + str(user_id),
            full_name="System User",
        )
    )
    db.session.add(profile)
    db.session.commit()
    return user
Exemple #19
0
    def sync_user_and_profile(cls, data):
        """Create or update the rero user with the patron data.

        :param data - dict representing the patron data
        """
        created = False
        # start a session to be able to rollback if the data are not valid
        user = cls._get_user_by_data(data)
        with db.session.begin_nested():
            # need to create the user
            if not user:
                birth_date = data.get('birth_date')
                # sanity check
                if not birth_date:
                    raise RecordValidationError('birth_date field is required')
                # the default password is the birth date
                user = User(email=data.get('email'),
                            password=hash_password(birth_date),
                            profile=dict(),
                            active=True)
                db.session.add(user)
                created = True
            else:
                if user.email != data.get('email'):
                    user.email = data.get('email')
            # update all common fields
            if user.profile is None:
                user.profile = UserProfile(user_id=user.id)
            profile = user.profile
            for field in cls.profile_fields:
                # date field need conversion
                if field == 'birth_date':
                    setattr(profile, field,
                            datetime.strptime(data.get(field), '%Y-%m-%d'))
                elif field == 'keep_history':
                    setattr(profile, field,
                            data.get('patron', {}).get(field, True))
                else:
                    setattr(profile, field, data.get(field, ''))
            db.session.merge(user)
            data['user_id'] = user.id
            if created:
                # the fresh created user
                return user
Exemple #20
0
    def _get_user_by_data(cls, data):
        """Get the user using a dict representing a patron.

        Try to get an existing user by: user_id, email, username.
        :param cls: Class itself.
        :param data: dict representing a patron.
        :return: a patron object or None.
        """
        user = None
        if data.get('user_id'):
            user = User.query.filter_by(id=data.get('user_id')).first()
        if not user and data.get('username'):
            try:
                user = UserProfile.get_by_username(data.get('username')).user
            except NoResultFound:
                user = None
        if not user and data.get('email'):
            user = User.query.filter_by(email=data.get('email')).first()
        return user
def get_user():
    """Return logged in user."""
    deposit_groups = get_user_deposit_groups()

    profile = UserProfile.get_by_userid(current_user.id)
    extra_data = profile.extra_data if profile else {}
    cern_profile = get_remote_account_by_id(current_user.id)['profile']

    if cern_profile:
        extra_data['cern'] = cern_profile

    _user = {
        "id": current_user.id,
        "email": current_user.email,
        "deposit_groups": deposit_groups,
        "profile": extra_data
    }

    response = jsonify(_user)
    response.status_code = 200
    return response
def get_patron_activity(patron_pid):
    """Get activity related to the given patron pid."""
    if patron_pid is None:
        raise ValueError("No patron pid was provided.")

    patron = get_patron_or_unknown_dump(patron_pid)

    def dump(search):
        return [hit.to_dict() for hit in search.scan()]

    DocumentRequestSearch = current_app_ils.document_request_search_cls
    patron_document_requests = dump(
        DocumentRequestSearch().search_by_patron_pid(patron_pid)
    )

    BorrowingRequestsSearch = current_ils_ill.borrowing_request_search_cls
    patron_borrowing_requests = dump(
        BorrowingRequestsSearch().search_by_patron_pid(patron_pid)
    )

    OrderSearch = current_ils_acq.order_search_cls
    patron_acquisitions = dump(OrderSearch().search_by_patron_pid(patron_pid))

    patron_loans = dump(get_loans_by_patron_pid(patron_pid))

    patron_profile = UserProfile.get_by_userid(patron_pid).__dict__
    del patron_profile["_sa_instance_state"]

    patron_data = {
        "patron": patron,
        "profile": patron_profile,
        "document_requests": patron_document_requests,
        "borrowing_requests": patron_borrowing_requests,
        "acquisitions": patron_acquisitions,
        "loans": patron_loans,
    }

    return patron_data
Exemple #23
0
def import_users(infile, append, verbose, password, lazy, dont_stop_on_error,
                 debug):
    """Import users.

    :param verbose: this function will be verbose.
    :param password: the password to use for user by default.
    :param lazy: lazy reads file
    :param dont_stop_on_error: don't stop on error
    :param infile: Json user file.
    """
    click.secho('Import users:', fg='green')

    if lazy:
        # try to lazy read json file (slower, better memory management)
        data = read_json_record(infile)
    else:
        # load everything in memory (faster, bad memory management)
        data = json.load(infile)
    pids = []
    error_records = []
    for count, patron_data in enumerate(data):
        email = patron_data.get('email')
        password = patron_data.get('password', password)
        username = patron_data['username']
        if email is None:
            click.secho(
                '{count: <8} User {username} do not have email!'.format(
                    count=count, username=username),
                fg='yellow')
        if password:
            patron_data.pop('password', None)
        # do nothing if the patron alredy exists
        patron = Patron.get_patron_by_username(username)
        if patron:
            click.secho('{count: <8} Patron already exist: {username}'.format(
                count=count, username=username),
                        fg='yellow')
            continue

        if verbose:
            click.secho('{count: <8} Creating user: {username}'.format(
                count=count, username=username))
            try:
                profile = UserProfile.get_by_username(username)
                click.secho(
                    '{count: <8} User already exist: {username}'.format(
                        count=count, username=username),
                    fg='yellow')
            except NoResultFound:
                pass
        try:
            # patron creation
            patron = Patron.create(
                patron_data,
                # delete_pid=True,
                dbcommit=False,
                reindex=False,
                email_notification=False)
            user = patron.user
            user.password = hash_password(password)
            user.active = True
            db.session.merge(user)
            db.session.commit()
            confirm_user(user)
            patron.reindex()
            pids.append(patron.pid)
        except Exception as err:
            error_records.append(data)
            click.secho('{count: <8} User create error: {err}'.format(
                count=count, err=err),
                        fg='red')
            if debug:
                traceback.print_exc()
            if not dont_stop_on_error:
                sys.exit(1)
            if debug:
                traceback.print_exc()
            if not dont_stop_on_error:
                sys.exit(1)
    if append:
        click.secho(
            'Append fixtures new identifiers: {len}'.format(len=len(pids)))
        identifier = Patron.provider.identifier
        try:
            append_fixtures_new_identifiers(identifier,
                                            sorted(pids, key=lambda x: int(x)),
                                            PatronProvider.pid_type)
        except Exception as err:
            click.secho(
                "ERROR append fixtures new identifiers: {err}".format(err=err),
                fg='red')
    if error_records:
        name, ext = os.path.splitext(infile.name)
        err_file_name = '{name}_errors{ext}'.format(name=name, ext=ext)
        click.secho('Write error file: {name}'.format(name=err_file_name))
        with open(err_file_name, 'w') as error_file:
            error_file.write('[\n')
            for error_record in error_records:
                for line in json.dumps(error_record, indent=2).split('\n'):
                    error_file.write('  ' + line + '\n')
            error_file.write(']')