def reset_password(): """ Reset password method. Returns a Jinja2 template. """ key = request.args.get('key') if key is None: abort(403) userdict = {} try: timeout = current_app.config.get('ACCOUNT_LINK_EXPIRATION', 3600) userdict = signer.loads(key, max_age=timeout, salt='password-reset') except BadData: abort(403) username = userdict.get('user') if not username or not userdict.get('password'): abort(403) user = user_repo.get_by_name(username) if user.passwd_hash != userdict.get('password'): abort(403) form = ChangePasswordForm(request.body) if form.validate_on_submit(): user.set_password(form.new_password.data) user_repo.update(user) flash(gettext('You reset your password successfully!'), 'success') return _sign_in_user(user) if request.method == 'POST' and not form.validate(): flash(gettext('Please correct the errors'), 'error') response = dict(template='/account/password_reset.html', form=form) return handle_content_type(response)
def newsletter_subscribe(): """ Register method for subscribing user to PYBOSSA newsletter. Returns a Jinja2 template """ # Save that we've prompted the user to sign up in the newsletter if newsletter.is_initialized() and current_user.is_authenticated(): next_url = request.args.get('next') or url_for('home.home') user = user_repo.get(current_user.id) if current_user.newsletter_prompted is False: user.newsletter_prompted = True user_repo.update(user) if request.args.get('subscribe') == 'True': newsletter.subscribe_user(user) flash("You are subscribed to our newsletter!", 'success') return redirect_content_type(next_url) elif request.args.get('subscribe') == 'False': return redirect_content_type(next_url) else: response = dict(template='account/newsletter.html', title=gettext("Subscribe to our Newsletter"), next=next_url) return handle_content_type(response) else: return abort(404)
def _update_user_with_valid_email(user, email_addr): user.valid_email = True user.confirmation_email_sent = False user.email_addr = email_addr user_repo.update(user) flash(gettext('Your email has been validated.')) return _sign_in_user(user)
def add_subadmin(user_id=None): """Add subadmin flag for user_id.""" try: if user_id: user = user_repo.get(user_id) if not user: return format_error('User not found', 404) if not user.enabled: markup = Markup('<strong>{}</strong> {} <strong>{}</strong>') flash( markup.format(gettext('User account '), user.fullname, gettext(' is disabled'))) return redirect(url_for(".subadminusers")) if not can_have_super_user_access(user): markup = Markup('<strong>{} {}</strong> {} {}') flash( markup.format(gettext('Denied subadmin privileges to'), user.fullname, user.email_addr, 'disqualify for subadmin access.')) return redirect_content_type(url_for(".subadminusers")) ensure_authorized_to('update', user) user.subadmin = True user_repo.update(user) msg = generate_invitation_email_for_admins_subadmins( user, "Subadmin") if msg: mail_queue.enqueue(send_mail, msg) return redirect(url_for(".subadminusers")) except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def newsletter_subscribe(): """ Register method for subscribing user to PyBossa newsletter. Returns a Jinja2 template """ # Save that we've prompted the user to sign up in the newsletter if newsletter.is_initialized() and current_user.is_authenticated(): next_url = request.args.get('next') or url_for('home.home') user = user_repo.get(current_user.id) if current_user.newsletter_prompted is False: user.newsletter_prompted = True user_repo.update(user) if request.args.get('subscribe') == 'True': newsletter.subscribe_user(user) flash("You are subscribed to our newsletter!") return redirect(next_url) elif request.args.get('subscribe') == 'False': return redirect(next_url) else: return render_template('account/newsletter.html', title=gettext("Subscribe to our Newsletter"), next=next_url) else: return abort(404)
def _sign_in_user(user, next_url=None): brand = current_app.config['BRAND'] if not user: flash( gettext('There was a problem signing you in. ' 'Please contact your {} administrator.'.format(brand)), 'error') return redirect(url_for('home.home')) if not user.enabled: flash( gettext('Your account is disabled. ' 'Please contact your {} administrator.'.format(brand)), 'error') return redirect(url_for('home.home')) login_user(user, remember=False) user.last_login = model.make_timestamp() user_repo.update(user) next_url = (next_url or is_own_url_or_else(request.args.get('next'), url_for('home.home')) or url_for('home.home')) if (current_app.config.get('MAILCHIMP_API_KEY') and newsletter.ask_user_to_subscribe(user)): return redirect_content_type( url_for('account.newsletter_subscribe', next=next_url)) return redirect_content_type(next_url)
def manage_user(access_token, user_data): """Manage the user after signin""" # We have to store the oauth_token in the session to get the USER fields user = user_repo.get_by(google_user_id=user_data['id']) # user never signed on if user is None: google_token = dict(oauth_token=access_token) info = dict(google_token=google_token) name = username_from_full_name(user_data['name']) user = user_repo.get_by_name(name) email = user_repo.get_by(email_addr=user_data['email']) if ((user is None) and (email is None)): user = User(fullname=user_data['name'], name=name, email_addr=user_data['email'], google_user_id=user_data['id'], info=info) user_repo.save(user) if newsletter.is_initialized(): newsletter.subscribe_user(user) return user else: return None else: # Update the name to fit with new paradigm to avoid UTF8 problems if type(user.name) == unicode or ' ' in user.name: user.name = username_from_full_name(user.name) user_repo.update(user) return user
def manage_user(access_token, user_data, next_url): """Manage the user after signin""" # We have to store the oauth_token in the session to get the USER fields user = user_repo.get_by(google_user_id=user_data['id']) # user never signed on if user is None: google_token = dict(oauth_token=access_token) info = dict(google_token=google_token) name = user_data['name'].encode('ascii', 'ignore').lower().replace(" ", "") user = user_repo.get_by_name(name) email = user_repo.get_by(email_addr=user_data['email']) if ((user is None) and (email is None)): user = User(fullname=user_data['name'], name=user_data['name'].encode('ascii', 'ignore') .lower().replace(" ", ""), email_addr=user_data['email'], google_user_id=user_data['id'], info=info) user_repo.save(user) return user else: return None else: # Update the name to fit with new paradigm to avoid UTF8 problems if type(user.name) == unicode or ' ' in user.name: user.name = user.name.encode('ascii', 'ignore').lower().replace(" ", "") user_repo.update(user) return user
def confirm_account(): key = request.args.get('key') if key is None: abort(403) try: userdict = signer.loads(key, max_age=3600, salt='account-validation') except BadData: abort(403) # First check if the user exists users = user_repo.filter_by(name=userdict['name']) if len(users) == 1 and users[0].name == userdict['name']: u = users[0] u.valid_email = True u.confirmation_email_sent = False u.email_addr = userdict['email_addr'] user_repo.update(u) flash(gettext('Your email has been validated.')) if newsletter.app: return redirect(url_for('account.newsletter_subscribe')) else: return redirect(url_for('home.home')) account = model.user.User(fullname=userdict['fullname'], name=userdict['name'], email_addr=userdict['email_addr'], valid_email=True) account.set_password(userdict['password']) user_repo.save(account) login_user(account, remember=True) flash(gettext('Thanks for signing-up'), 'success') if newsletter.app: return redirect(url_for('account.newsletter_subscribe')) else: return redirect(url_for('home.home'))
def reset_password(): """ Reset password method. Returns a Jinja2 template. """ key = request.args.get('key') if key is None: abort(403) userdict = {} try: userdict = signer.loads(key, max_age=3600, salt='password-reset') except BadData: abort(403) username = userdict.get('user') if not username or not userdict.get('password'): abort(403) user = user_repo.get_by_name(username) if user.passwd_hash != userdict.get('password'): abort(403) form = ChangePasswordForm(request.form) if form.validate_on_submit(): user.set_password(form.new_password.data) user_repo.update(user) login_user(user) flash(gettext('You reset your password successfully!'), 'success') return redirect(url_for('.signin')) if request.method == 'POST' and not form.validate(): flash(gettext('Please correct the errors'), 'error') return render_template('/account/password_reset.html', form=form)
def reset_password(): """ Reset password method. Returns a Jinja2 template. """ key = request.args.get('key') if key is None: abort(403) userdict = {} try: timeout = current_app.config.get('ACCOUNT_LINK_EXPIRATION', 3600) userdict = signer.loads(key, max_age=timeout, salt='password-reset') except BadData: abort(403) username = userdict.get('user') if not username or not userdict.get('password'): abort(403) user = user_repo.get_by_name(username) if user.passwd_hash != userdict.get('password'): abort(403) form = ChangePasswordForm(request.form) if form.validate_on_submit(): user.set_password(form.new_password.data) user_repo.update(user) flash(gettext('You reset your password successfully!'), 'success') return _sign_in_user(user) if request.method == 'POST' and not form.validate(): flash(gettext('Please correct the errors'), 'error') return render_template('/account/password_reset.html', form=form)
def newsletter_subscribe(): """ Register method for subscribing user to PyBossa newsletter. Returns a Jinja2 template """ # Save that we've prompted the user to sign up in the newsletter if newsletter.app and current_user.is_authenticated(): next_url = request.args.get('next') or url_for('home.home') user = user_repo.get(current_user.id) if current_user.newsletter_prompted is False: user.newsletter_prompted = True user_repo.update(user) if request.args.get('subscribe') == 'True': newsletter.subscribe_user(user) flash("You are subscribed to our newsletter!") return redirect(next_url) elif request.args.get('subscribe') == 'False': return redirect(next_url) else: return render_template( 'account/newsletter.html', title=gettext("Subscribe to our Newsletter"), next=next_url) else: return abort(404)
def _handle_avatar_update(user, avatar_form): if avatar_form.validate_on_submit(): _file = request.files['avatar'] coordinates = (avatar_form.x1.data, avatar_form.y1.data, avatar_form.x2.data, avatar_form.y2.data) prefix = time.time() _file.filename = "%s_avatar.png" % prefix container = "user_%s" % user.id uploader.upload_file(_file, container=container, coordinates=coordinates) # Delete previous avatar from storage if user.info.get('avatar'): uploader.delete_file(user.info['avatar'], container) upload_method = current_app.config.get('UPLOAD_METHOD') avatar_url = get_avatar_url(upload_method, _file.filename, container) user.info['avatar'] = _file.filename user.info['container'] = container user.info['avatar_url'] = avatar_url user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your avatar has been updated! It may \ take some minutes to refresh...'), 'success') return True else: flash("You have to provide an image file to update your avatar", "error") return False
def set(self, user, update_repo=True): """Set a Gravatar for a user. Parameters ---------- user : User The PyBossa user. update_repo : bool, optional True to save changes, False otherwise (the default is True). """ url = self._get_url(user) now = time.time() filename = secure_filename('{0}_avatar.png'.format(now)) container = 'user_{0}'.format(user.id) self._download(filename, container, url) if not user.info: # pragma: no cover user.info = dict() user.info['avatar'] = filename user.info['container'] = container if update_repo: user_repo.update(user) cached_users.delete_user_summary(user.name)
def _handle_avatar_update(user, avatar_form): if avatar_form.validate_on_submit(): _file = request.files['avatar'] coordinates = (avatar_form.x1.data, avatar_form.y1.data, avatar_form.x2.data, avatar_form.y2.data) prefix = time.time() _file.filename = "%s_avatar.png" % prefix container = "user_%s" % user.id uploader.upload_file(_file, container=container, coordinates=coordinates) # Delete previous avatar from storage if user.info.get('avatar'): uploader.delete_file(user.info['avatar'], container) upload_method = current_app.config.get('UPLOAD_METHOD') avatar_url = get_avatar_url(upload_method, _file.filename, container) user.info['avatar'] = _file.filename user.info['container'] = container user.info['avatar_url'] = avatar_url user_repo.update(user) cached_users.delete_user_summary(user.name) flash( gettext('Your avatar has been updated! It may \ take some minutes to refresh...'), 'success') return True else: flash("You have to provide an image file to update your avatar", "error") return False
def confirm_email(): """Send email to confirm user email.""" acc_conf_dis = current_app.config.get('ACCOUNT_CONFIRMATION_DISABLED') if acc_conf_dis: return abort(404) if current_user.valid_email is False: user = user_repo.get(current_user.id) account = dict(fullname=current_user.fullname, name=current_user.name, email_addr=current_user.email_addr) confirm_url = get_email_confirmation_url(account) subject = ('Verify your email in %s' % current_app.config.get('BRAND')) msg = dict(subject=subject, recipients=[current_user.email_addr], body=render_template('/account/email/validate_email.md', user=account, confirm_url=confirm_url)) msg['html'] = render_template('/account/email/validate_email.html', user=account, confirm_url=confirm_url) mail_queue.enqueue(send_mail, msg) msg = gettext("An e-mail has been sent to \ validate your e-mail address.") flash(msg, 'info') user.confirmation_email_sent = True user_repo.update(user) return redirect_content_type(url_for('.profile', name=current_user.name))
def _create_account_Auth(user_data): new_user = model.user.User(fullname=user_data['fullname'], name=user_data['name'], email_addr=user_data['email_addr'], valid_email=True, auth_user_id=user_data['auth_user_id'], admin=False) password = GenPasswd2(8, string.digits) + GenPasswd2( 15, string.ascii_letters) new_user.set_password(password) userxemail = user_repo.get_by(email_addr=user_data['email_addr']) if userxemail: if userxemail.auth_user_id is None: new_user = userxemail new_user.auth_user_id = user_data['auth_user_id'] user_repo.update(new_user) flash(gettext(u'Bienvenido') + " " + new_user.fullname, 'success') return _sign_in_user(new_user) else: flash( gettext( u'El email ya está registrado en nuestro sistema bajo otra cuenta con otras credenciales. No ha sido posible iniciar sesión. Inicie sesión utilizando la cuenta original que uso para registrarse por primera vez con esta dirección de correo.' ), 'error') return redirect_content_type(url_for("home.home")) else: userduplicatename = user_repo.get_by_name(name=new_user.name) if userduplicatename: new_user.name = new_user.name + GenRandomString( 6, string.ascii_lowercase) user_repo.save(new_user) flash(gettext(u'Gracias por registrarte.'), 'success') return _sign_in_user(new_user)
def _sign_in_user(user): login_user(user, remember=False) user.last_login = model.make_timestamp() user_repo.update(user) if newsletter.ask_user_to_subscribe(user): return redirect_content_type(url_for('account.newsletter_subscribe', next=request.args.get('next'))) return redirect_content_type(request.args.get("next") or url_for("home.home"))
def add_metadata(name): """ Admin can save metadata for selected user. Regular user can save their own metadata. Redirects to public profile page for selected user. """ user = user_repo.get_by_name(name=name) (can_update, disabled_fields) = can_update_user_info(current_user, user) if not can_update: abort(403) form_data = get_form_data(request, user, disabled_fields) form = UserPrefMetadataForm(form_data, can_update=(can_update, disabled_fields)) form.set_upref_mdata_choices() if not form.validate(): if current_user.id == user.id: user_dict = cached_users.get_user_summary(user.name) else: user_dict = cached_users.public_get_user_summary(user.name) projects_contributed = cached_users.projects_contributed_cached( user.id) projects_created = cached_users.published_projects_cached(user.id) total_projects_contributed = '{} / {}'.format( cached_users.n_projects_contributed(user.id), n_published()) percentage_tasks_completed = user_dict['n_answers'] * 100 / ( n_total_tasks() or 1) if current_user.is_authenticated and current_user.admin: draft_projects = cached_users.draft_projects(user.id) projects_created.extend(draft_projects) title = "%s · User Profile" % user.name flash("Please fix the errors", 'message') return render_template( '/account/public_profile.html', title=title, user=user, projects=projects_contributed, projects_created=projects_created, total_projects_contributed=total_projects_contributed, percentage_tasks_completed=percentage_tasks_completed, form=form, input_form=True, can_update=can_update, upref_mdata_enabled=bool(app_settings.upref_mdata)) user_pref, metadata = get_user_pref_and_metadata(name, form) user.info['metadata'] = metadata ensure_data_access_assignment_from_form(user.info, form) user.user_pref = user_pref user_repo.update(user) cached_users.delete_user_pref_metadata(user.name) cached_users.delete_user_access_levels_by_id(user.id) delete_memoized(get_user_preferences, user.id) flash("Input saved successfully", "info") return redirect(url_for('account.profile', name=name))
def _handle_external_services_update(user, update_form): del update_form.locale del update_form.email_addr del update_form.fullname del update_form.name if update_form.validate(): user.ckan_api = update_form.ckan_api.data or None user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your profile has been updated!'), 'success') else: flash(gettext('Please correct the errors'), 'error')
def test_manage_user_login_without_user(self, redirect, url_for, flash, login_user, newsletter): """Test TWITTER manage_user_login without user with newsletter works.""" newsletter.app = True next_url = '/' user = UserFactory.create(info={'google_token': 'k'}) user_data = dict(id=user.id, screen_name=user.name) user.email_addr = user.name user_repo.update(user) manage_user_login(None, user_data, next_url) assert login_user.called is False url_for.assert_called_once_with('account.signin')
def update_quiz(project_id, answer, gold_answers): project = project_repo.get(project_id) user = user_repo.get(current_user.id) if not user.get_quiz_in_progress(project): return if gold_answers == answer: user.add_quiz_right_answer(project) else: user.add_quiz_wrong_answer(project) user_repo.update(user)
def test_manage_user_login_with_newsletter_no_email( self, redirect, url_for_app_type, flash, login_user, newsletter): """Test TWITTER manage_user_login without email with newsletter works.""" newsletter.app = True next_url = '/spa/account/profile/update' user = UserFactory.create(name='john', email_addr='john') user_data = dict(id=user.id, screen_name=user.name) user.email_addr = user.name user_repo.update(user) manage_user_login(user, user_data, next_url) login_user.assert_called_once_with(user, remember=True) redirect.assert_called_once_with(next_url)
def _sign_in_user(user): login_user(user, remember=False) user.last_login = model.make_timestamp() user_repo.update(user) next_url = (is_own_url_or_else(request.args.get('next'), url_for('home.home')) or url_for('home.home')) if (current_app.config.get('MAILCHIMP_API_KEY') and newsletter.ask_user_to_subscribe(user)): return redirect_content_type( url_for('account.newsletter_subscribe', next=next_url)) return redirect_content_type(next_url)
def test_manage_user_login_without_user_local(self, redirect, url_for_app_type, flash, login_user, newsletter): """Test TWITTER manage_user_login without user with newsletter works.""" newsletter.app = True next_url = '/' user = UserFactory.create() user_data = dict(id=user.id, screen_name=user.name) user.email_addr = user.name user_repo.update(user) manage_user_login(None, user_data, next_url) assert login_user.called is False url_for_app_type.assert_called_once_with('account.forgot_password')
def _handle_password_update(user, password_form): if password_form.validate_on_submit(): user = user_repo.get(user.id) if user.check_password(password_form.current_password.data): user.set_password(password_form.new_password.data) user_repo.update(user) flash(gettext('Yay, you changed your password succesfully!'), 'success') else: msg = gettext("Your current password doesn't match the " "one in our records") flash(msg, 'error') else: flash(gettext('Please correct the errors'), 'error')
def test_manage_user_login_without_user(self, redirect, url_for_app_type, flash, login_user, newsletter): """Test TWITTER manage_user_login without user with newsletter works.""" newsletter.app = True next_url = '/' user = UserFactory.create(info={'google_token': 'k'}) user_data = dict(id=user.id, screen_name=user.name) user.email_addr = user.name user_repo.update(user) manage_user_login(None, user_data, next_url) assert login_user.called is False url_for_app_type.assert_called_once_with('account.signin')
def test_manage_user_login_with_newsletter_no_email(self, redirect, url_for_app_type, flash, login_user, newsletter): """Test TWITTER manage_user_login without email with newsletter works.""" newsletter.app = True next_url = '/spa/account/profile/update' user = UserFactory.create(name='john', email_addr='john') user_data = dict(id=user.id, screen_name=user.name) user.email_addr = user.name user_repo.update(user) manage_user_login(user, user_data, next_url) login_user.assert_called_once_with(user, remember=True) redirect.assert_called_once_with(next_url)
def test_get_inactive_users_returns_jobs_unsubscribed(self): """Test JOB get inactive users returns an empty list of jobs.""" tr = TaskRunFactory.create(finish_time="2010-07-07T17:23:45.714210") user = user_repo.get(tr.user_id) user.subscribed = False user_repo.update(user) jobs_generator = get_inactive_users_jobs() jobs = [] for job in jobs_generator: jobs.append(job) msg = "There should be zero jobs." assert len(jobs) == 0, msg
def test_get_non_contrib_users_returns_unsubscribed_jobs(self): """Test JOB get non contrib users returns a list of jobs.""" TaskRunFactory.create() user = user_repo.get(1) user.subscribed = False user_repo.update(user) jobs_generator = get_non_contributors_users_jobs() jobs = [] for job in jobs_generator: jobs.append(job) msg = "There should be zero jobs." assert len(jobs) == 0, msg
def test_manage_user_login_without_user_local(self, redirect, url_for, flash, login_user, newsletter): """Test TWITTER manage_user_login without user with newsletter works.""" newsletter.app = True next_url = '/' user = UserFactory.create() user_data = dict(id=user.id, screen_name=user.name) user.email_addr = user.name user_repo.update(user) manage_user_login(None, user_data, next_url) assert login_user.called is False url_for.assert_called_once_with('account.forgot_password')
def _handle_profile_update(user, update_form): acc_conf_dis = current_app.config.get('ACCOUNT_CONFIRMATION_DISABLED') if update_form.validate_on_submit(): user.id = update_form.id.data user.fullname = update_form.fullname.data user.name = update_form.name.data account, domain = update_form.email_addr.data.split('@') if (user.email_addr != update_form.email_addr.data and acc_conf_dis is False and domain not in current_app.config.get('SPAM')): user.valid_email = False user.newsletter_prompted = False account = dict(fullname=update_form.fullname.data, name=update_form.name.data, email_addr=update_form.email_addr.data) confirm_url = get_email_confirmation_url(account) subject = ('You have updated your email in %s! Verify it' % current_app.config.get('BRAND')) msg = dict(subject=subject, recipients=[update_form.email_addr.data], body=render_template('/account/email/validate_email.md', user=account, confirm_url=confirm_url)) msg['html'] = markdown(msg['body']) mail_queue.enqueue(send_mail, msg) user.confirmation_email_sent = True fls = gettext('An email has been sent to verify your \ new email: %s. Once you verify it, it will \ be updated.' % account['email_addr']) flash(fls, 'info') return True if acc_conf_dis is False and domain in current_app.config.get('SPAM'): fls = gettext('Use a valid email account') flash(fls, 'info') return False if acc_conf_dis: user.email_addr = update_form.email_addr.data user.privacy_mode = fuzzyboolean(update_form.privacy_mode.data) user.restrict = fuzzyboolean(update_form.restrict.data) user.locale = update_form.locale.data user.subscribed = fuzzyboolean(update_form.subscribed.data) user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your profile has been updated!'), 'success') return True else: flash(gettext('Please correct the errors'), 'error') return False
def _handle_profile_update(user, update_form): acc_conf_dis = current_app.config.get('ACCOUNT_CONFIRMATION_DISABLED') if update_form.validate_on_submit(): user.id = update_form.id.data user.fullname = update_form.fullname.data user.name = update_form.name.data account, domain = update_form.email_addr.data.split('@') if (user.email_addr != update_form.email_addr.data and acc_conf_dis is False and domain not in current_app.config.get('SPAM')): user.valid_email = False user.newsletter_prompted = False account = dict(fullname=update_form.fullname.data, name=update_form.name.data, email_addr=update_form.email_addr.data) confirm_url = get_email_confirmation_url(account) subject = ('You have updated your email in %s! Verify it' % current_app.config.get('BRAND')) msg = dict(subject=subject, recipients=[update_form.email_addr.data], body=render_template( '/account/email/validate_email.md', user=account, confirm_url=confirm_url)) msg['html'] = markdown(msg['body']) mail_queue.enqueue(send_mail, msg) user.confirmation_email_sent = True fls = gettext('An email has been sent to verify your \ new email: %s. Once you verify it, it will \ be updated.' % account['email_addr']) flash(fls, 'info') return True if acc_conf_dis is False and domain in current_app.config.get('SPAM'): fls = gettext('Use a valid email account') flash(fls, 'info') return False if acc_conf_dis: user.email_addr = update_form.email_addr.data user.privacy_mode = fuzzyboolean(update_form.privacy_mode.data) user.restrict = fuzzyboolean(update_form.restrict.data) user.locale = update_form.locale.data user.subscribed = fuzzyboolean(update_form.subscribed.data) user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your profile has been updated!'), 'success') return True else: flash(gettext('Please correct the errors'), 'error') return False
def grant_access_with_api_key(secure_app): from pybossa.core import user_repo import pybossa.model as model from flask import _request_ctx_stack apikey = None if not secure_app: apikey = request.args.get('api_key', None) if 'Authorization' in request.headers: apikey = request.headers.get('Authorization') if apikey: user = user_repo.get_by(api_key=apikey) if user and user.enabled: user.last_login = model.make_timestamp() user_repo.update(user) _request_ctx_stack.top.user = user
def add_admin(user_id=None): """Add admin flag for user_id""" try: if user_id: user = user_repo.get(user_id) require.user.update(user) if user: user.admin = True user_repo.update(user) return redirect(url_for(".users")) else: msg = "User not found" return format_error(msg, 404) except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def add_admin(user_id=None): """Add admin flag for user_id.""" try: if user_id: user = user_repo.get(user_id) if user: ensure_authorized_to('update', user) user.admin = True user_repo.update(user) return redirect_content_type(url_for(".users")) else: msg = "User not found" return format_error(msg, 404) except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def add_admin(user_id=None): """Add admin flag for user_id.""" try: if user_id: user = user_repo.get(user_id) if user: ensure_authorized_to('update', user) user.admin = True user_repo.update(user) return redirect(url_for(".users")) else: msg = "User not found" return format_error(msg, 404) except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def reset_api_key(name): """ Reset API-KEY for user. Returns a Jinja2 template. """ user = user_repo.get_by_name(name) if not user: return abort(404) ensure_authorized_to('update', user) user.api_key = model.make_uuid() user_repo.update(user) cached_users.delete_user_summary(user.name) msg = gettext('New API-KEY generated') flash(msg, 'success') return redirect(url_for('account.profile', name=name))
def disable_user(user_id=None): """Set enabled flag to False for user_id.""" if user_id: user = user_repo.get(user_id) if user: # avoid disabling admin/subadmin user by subadmin with direct url if not can_update_user_info(current_user, user)[0]: return abort(403) user.enabled = False user_repo.update(user) msg = generate_manage_user_email(user, "disable") if msg: mail_queue.enqueue(send_mail, msg) return redirect(url_for('.manageusers')) msg = "User not found" return format_error(msg, 404)
def add_metadata(name): """ Admin can add metadata for selected user Redirects to public profile page for selected user. """ user = user_repo.get_by_name(name=name) if not can_update_user_info(current_user, user): abort(403) form = MetadataForm(request.form) if not any(value for value in form.data.values()): user.info['metadata'] = {} user.user_pref = {} elif form.validate(): metadata = dict(admin=current_user.name, time_stamp=time.ctime(), user_type=form.user_type.data, start_time=form.start_time.data, end_time=form.end_time.data, review=form.review.data, timezone=form.timezone.data, profile_name=user.name) user.info['metadata'] = metadata user_pref = {} if form.languages.data: user_pref["languages"] = form.languages.data if form.locations.data: user_pref["locations"] = form.locations.data user.user_pref = user_pref else: projects_contributed = cached_users.projects_contributed_cached(user.id) projects_created = cached_users.published_projects_cached(user.id) metadata = cached_users.get_metadata(user.name) if current_user.is_authenticated() and current_user.admin: draft_projects = cached_users.draft_projects(user.id) projects_created.extend(draft_projects) title = "%s · User Profile" % user.name flash("Please fix the errors", 'message') return render_template('/account/public_profile.html', title=title, user=user, metadata=metadata, projects=projects_contributed, form=form, projects_created=projects_created, input_form=True) user_repo.update(user) cached_users.delete_user_metadata(user.name) delete_memoized(get_user_preferences, user.id) flash("Input saved successfully", "info") return redirect(url_for('account.profile', name=name))
def reset_api_key(name): """ Reset API-KEY for user. Returns a Jinja2 template. """ user = user_repo.get_by_name(name) if not user: return abort(404) require.user.update(user) title = ("User: %s · Settings" "- Reset API KEY") % current_user.fullname user.api_key = model.make_uuid() user_repo.update(user) cached_users.delete_user_summary(user.name) msg = gettext('New API-KEY generated') flash(msg, 'success') return redirect(url_for('account.profile', name=name))
def del_admin(user_id=None): """Del admin flag for user_id.""" try: if user_id: user = user_repo.get(user_id) if user: ensure_authorized_to('update', user) user.admin = False user_repo.update(user) return redirect(url_for('.users')) else: msg = "User.id not found" return format_error(msg, 404) else: # pragma: no cover msg = "User.id is missing for method del_admin" return format_error(msg, 415) except Exception as e: # pragma: no cover current_app.logger.error(e) return abort(500)
def reset_api_key(name): """ Reset API-KEY for user. Returns a Jinja2 template. """ if request.method == 'POST': user = user_repo.get_by_name(name) if not user: return abort(404) ensure_authorized_to('update', user) user.api_key = model.make_uuid() user_repo.update(user) cached_users.delete_user_summary(user.name) msg = gettext('New API-KEY generated') flash(msg, 'success') return redirect_content_type(url_for('account.profile', name=name)) else: csrf = dict(form=dict(csrf=generate_csrf())) return jsonify(csrf)
def _handle_avatar_update(user, avatar_form): if avatar_form.validate_on_submit(): _file = request.files['avatar'] coordinates = (avatar_form.x1.data, avatar_form.y1.data, avatar_form.x2.data, avatar_form.y2.data) prefix = time.time() _file.filename = "%s_avatar.png" % prefix container = "user_%s" % user.id uploader.upload_file(_file, container=container, coordinates=coordinates) # Delete previous avatar from storage if user.info.get('avatar'): uploader.delete_file(user.info['avatar'], container) user.info = {'avatar': _file.filename, 'container': container} user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your avatar has been updated! It may \ take some minutes to refresh...'), 'success') else: flash("You have to provide an image file to update your avatar", "error")
def add_metadata(name): """ Admin can save metadata for selected user Redirects to public profile page for selected user. """ user = user_repo.get_by_name(name=name) form = UserPrefMetadataForm(request.form) form.set_upref_mdata_choices() if not form.validate(): if current_user.id == user.id: user_dict = cached_users.get_user_summary(user.name) else: user_dict = cached_users.public_get_user_summary(user.name) projects_contributed = cached_users.projects_contributed_cached(user.id) projects_created = cached_users.published_projects_cached(user.id) if current_user.is_authenticated() and current_user.admin: draft_projects = cached_users.draft_projects(user.id) projects_created.extend(draft_projects) title = "%s · User Profile" % user.name flash("Please fix the errors", 'message') can_update = current_user.admin return render_template('/account/public_profile.html', title=title, user=user_dict, projects=projects_contributed, projects_created=projects_created, form=form, can_update=can_update, input_form=True) user_pref, metadata = get_user_pref_and_metadata(name, form) user.info['metadata'] = metadata user.user_pref = user_pref user_repo.update(user) cached_users.delete_user_pref_metadata(user.name) flash("Input saved successfully", "info") return redirect(url_for('account.profile', name=name))
def confirm_email(): """Send email to confirm user email.""" acc_conf_dis = current_app.config.get('ACCOUNT_CONFIRMATION_DISABLED') if acc_conf_dis: return abort(404) if current_user.valid_email is False: user = user_repo.get(current_user.id) account = dict(fullname=current_user.fullname, name=current_user.name, email_addr=current_user.email_addr) confirm_url = get_email_confirmation_url(account) subject = ('Verify your email in %s' % current_app.config.get('BRAND')) msg = dict(subject=subject, recipients=[current_user.email_addr], body=render_template('/account/email/validate_email.md', user=account, confirm_url=confirm_url)) msg['html'] = render_template('/account/email/validate_email.html', user=account, confirm_url=confirm_url) mail_queue.enqueue(send_mail, msg) msg = gettext("An e-mail has been sent to \ validate your e-mail address.") flash(msg, 'info') user.confirmation_email_sent = True user_repo.update(user) return redirect(url_for('.profile', name=current_user.name))
def update_profile(name): """ Update user's profile. Returns Jinja2 template. """ user = user_repo.get_by_name(name) if not user: return abort(404) require.user.update(user) show_passwd_form = True if user.twitter_user_id or user.google_user_id or user.facebook_user_id: show_passwd_form = False usr = cached_users.get_user_summary(name) # Extend the values user.rank = usr.get('rank') user.score = usr.get('score') # Title page title_msg = "Update your profile: %s" % user.fullname # Creation of forms update_form = UpdateProfileForm(obj=user) update_form.set_locales(current_app.config['LOCALES']) avatar_form = AvatarUploadForm() password_form = ChangePasswordForm() external_form = update_form if request.method == 'GET': return render_template('account/update.html', title=title_msg, user=usr, form=update_form, upload_form=avatar_form, password_form=password_form, external_form=external_form, show_passwd_form=show_passwd_form) else: # Update user avatar if request.form.get('btn') == 'Upload': avatar_form = AvatarUploadForm() if avatar_form.validate_on_submit(): file = request.files['avatar'] coordinates = (avatar_form.x1.data, avatar_form.y1.data, avatar_form.x2.data, avatar_form.y2.data) prefix = time.time() file.filename = "%s_avatar.png" % prefix container = "user_%s" % user.id uploader.upload_file(file, container=container, coordinates=coordinates) # Delete previous avatar from storage if user.info.get('avatar'): uploader.delete_file(user.info['avatar'], container) user.info = {'avatar': file.filename, 'container': container} user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your avatar has been updated! It may \ take some minutes to refresh...'), 'success') return redirect(url_for('.update_profile', name=user.name)) else: flash("You have to provide an image file to update your avatar", "error") return render_template('/account/update.html', form=update_form, upload_form=avatar_form, password_form=password_form, external_form=external_form, title=title_msg, show_passwd_form=show_passwd_form) # Update user profile elif request.form.get('btn') == 'Profile': update_form = UpdateProfileForm() update_form.set_locales(current_app.config['LOCALES']) if update_form.validate(): user.id = update_form.id.data user.fullname = update_form.fullname.data user.name = update_form.name.data user.email_addr = update_form.email_addr.data user.privacy_mode = update_form.privacy_mode.data user.locale = update_form.locale.data user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your profile has been updated!'), 'success') return redirect(url_for('.update_profile', name=user.name)) else: flash(gettext('Please correct the errors'), 'error') title_msg = 'Update your profile: %s' % user.fullname return render_template('/account/update.html', form=update_form, upload_form=avatar_form, password_form=password_form, external_form=external_form, title=title_msg, show_passwd_form=show_passwd_form) # Update user password elif request.form.get('btn') == 'Password': # Update the data because passing it in the constructor does not work update_form.name.data = user.name update_form.fullname.data = user.fullname update_form.email_addr.data = user.email_addr update_form.ckan_api.data = user.ckan_api external_form = update_form if password_form.validate_on_submit(): user = user_repo.get(user.id) if user.check_password(password_form.current_password.data): user.set_password(password_form.new_password.data) user_repo.update(user) flash(gettext('Yay, you changed your password succesfully!'), 'success') return redirect(url_for('.update_profile', name=name)) else: msg = gettext("Your current password doesn't match the " "one in our records") flash(msg, 'error') return render_template('/account/update.html', form=update_form, upload_form=avatar_form, password_form=password_form, external_form=external_form, title=title_msg, show_passwd_form=show_passwd_form) else: flash(gettext('Please correct the errors'), 'error') return render_template('/account/update.html', form=update_form, upload_form=avatar_form, password_form=password_form, external_form=external_form, title=title_msg, show_passwd_form=show_passwd_form) # Update user external services elif request.form.get('btn') == 'External': del external_form.locale del external_form.email_addr del external_form.fullname del external_form.name if external_form.validate(): user.ckan_api = external_form.ckan_api.data or None user_repo.update(user) cached_users.delete_user_summary(user.name) flash(gettext('Your profile has been updated!'), 'success') return redirect(url_for('.update_profile', name=user.name)) else: flash(gettext('Please correct the errors'), 'error') title_msg = 'Update your profile: %s' % user.fullname return render_template('/account/update.html', form=update_form, upload_form=avatar_form, password_form=password_form, external_form=external_form, title=title_msg, show_passwd_form=show_passwd_form) # Otherwise return 415 else: return abort(415)
def test_03_stats(self): """Test STATS stats method works""" self.prepare_data() today = unicode(datetime.date.today()) hour = int(datetime.datetime.utcnow().strftime('%H')) date_ms = time.mktime(time.strptime(today, "%Y-%m-%d")) * 1000 anon = 0 auth = 0 tr1 = TaskRunFactory.create(task=self.project.tasks[0]) tr2 = TaskRunFactory.create(task=self.project.tasks[1]) user = user_repo.get(tr1.user_id) user.restrict = True user_repo.update(user) stats.update_stats(self.project.id) dates_stats, hours_stats, user_stats = stats.get_stats(self.project.id) for item in dates_stats: if item['label'] == 'Anon + Auth': assert item['values'][-1][0] == date_ms, item['values'][0][0] assert item['values'][-1][1] == 10, "There should be 10 answers" if item['label'] == 'Anonymous': assert item['values'][-1][0] == date_ms, item['values'][0][0] anon = item['values'][-1][1] if item['label'] == 'Authenticated': assert item['values'][-1][0] == date_ms, item['values'][0][0] auth = item['values'][-1][1] if item['label'] == 'Total Tasks': assert item['values'][-1][0] == date_ms, item['values'][0][0] assert item['values'][-1][1] == 4, "There should be 4 tasks" if item['label'] == 'Expected Answers': assert item['values'][0][0] == date_ms, item['values'][0][0] for i in item['values']: assert i[1] == 100, "Each date should have 100 answers" assert item['values'][0][1] == 100, "There should be 10 answers" assert auth + anon == 10, "date stats sum of auth and anon should be 10" max_hours = 0 for item in hours_stats: if item['label'] == 'Anon + Auth': max_hours = item['max'] print item assert item['max'] == 10, item['max'] assert item['max'] == 10, "Max hours value should be 10" for i in item['values']: if i[0] == hour: assert i[1] == 10, "There should be 10 answers" assert i[2] == 5, "The size of the bubble should be 5" else: assert i[1] == 0, "There should be 0 answers" assert i[2] == 0, "The size of the buggle should be 0" if item['label'] == 'Anonymous': anon = item['max'] for i in item['values']: if i[0] == hour: assert i[1] == anon, "There should be anon answers" assert i[2] == (anon * 5) / max_hours, "The size of the bubble should be 5" else: assert i[1] == 0, "There should be 0 answers" assert i[2] == 0, "The size of the buggle should be 0" if item['label'] == 'Authenticated': auth = item['max'] for i in item['values']: if i[0] == hour: assert i[1] == auth, "There should be anon answers" assert i[2] == (auth * 5) / max_hours, "The size of the bubble should be 5" else: assert i[1] == 0, "There should be 0 answers" assert i[2] == 0, "The size of the buggle should be 0" assert auth + anon == 10, "date stats sum of auth and anon should be 8" err_msg = "user stats sum of auth and anon should be 7" assert user_stats['n_anon'] + user_stats['n_auth'] == 7, err_msg for u in user_stats['auth']['top5']: assert u['restrict'] is False, u