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()
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
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()
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
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')
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
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
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
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, )
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)
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
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
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 }
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
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))
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
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
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
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
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(']')