Example #1
0
def reset_password(token):
    """ Verify the password reset token, Prompt for new password, and set the user's password."""
    # Verify token
    user_manager = current_app.user_manager
    db_adapter = user_manager.db_adapter

    is_valid, has_expired, user_id = user_manager.verify_token(
            token,
            user_manager.reset_password_expiration)

    if has_expired:
        flash(_('Your reset password token has expired.'), 'error')
        return redirect(url_for('user.login'))

    if not is_valid:
        flash(_('Your reset password token is invalid.'), 'error')
        return redirect(url_for('user.login'))

    user = user_manager.get_user_by_id(user_id)
    if user:
        # Avoid re-using old tokens
        if hasattr(user, 'reset_password_token'):
            verified = user.reset_password_token == token
        else:
            verified = True
    if not user or not verified:
        flash(_('Your reset password token is invalid.'), 'error')
        return redirect(_endpoint_url(user_manager.login_endpoint))

    # Initialize form
    form = user_manager.reset_password_form(request.form)

    # Process valid POST
    if request.method=='POST' and form.validate():
        # Invalidate the token by clearing the stored token
        if hasattr(user, 'reset_password_token'):
            db_adapter.update_object(user, reset_password_token='')

        # Change password
        hashed_password = user_manager.hash_password(form.new_password.data)
        user_auth = user.user_auth if db_adapter.UserAuthClass and hasattr(user, 'user_auth') else user
        db_adapter.update_object(user_auth, password=hashed_password)
        db_adapter.commit()

        # Send 'password_changed' email
        if user_manager.enable_email and user_manager.send_password_changed_email:
            emails.send_password_changed_email(user)

        # Prepare one-time system message
        flash(_("Your password has been reset successfully. Please sign in with your new password"), 'success')

        # Auto-login after reset password or redirect to login page
        next = request.args.get('next', _endpoint_url(user_manager.after_reset_password_endpoint))
        if user_manager.auto_login_after_reset_password:
            return _do_login_user(user, next)                       # auto-login
        else:
            return redirect(url_for('user.login')+'?next='+next)    # redirect to login page

    # Process GET or invalid POST
    return render_template(user_manager.reset_password_template, form=form)
Example #2
0
def delete_account():
    if request.method == 'GET':
        if current_user.is_authenticated:

            # Delete stripe subscription
            customer = stripe.Customer.retrieve(decode(current_user.user_auth.customer))
            customer.cancel_subscription()

            # delete user from database
            id = current_user.user_auth.id
            email = current_user.email
            user = UserAuth.query.filter_by(id=id).first()
            db.session.delete(user)
            db.session.delete(current_user)

            # commit database changes
            db.session.commit()

            #send the email
            send_cancel_email(email)
            flash(_('Your subscription has been successfully canceled.'), 'error')
            return logout()
        else:
            flash(_('Please login first.'), 'error')
            return render_template('pages/index.html')
    else:
        return redirect('/')
Example #3
0
def delete_account():
    if request.method == 'GET':
        if current_user.is_authenticated:

            # Delete stripe subscription
            customer = stripe.Customer.retrieve(
                decode(current_user.user_auth.customer))
            customer.cancel_subscription()

            # delete user from database
            id = current_user.user_auth.id
            email = current_user.email
            user = UserAuth.query.filter_by(id=id).first()
            db.session.delete(user)
            db.session.delete(current_user)

            # commit database changes
            db.session.commit()

            #send the email
            send_cancel_email(email)
            flash(_('Your subscription has been successfully canceled.'),
                  'error')
            return logout()
        else:
            flash(_('Please login first.'), 'error')
            return render_template('pages/index.html')
    else:
        return redirect('/')
Example #4
0
def _do_login_user(user, next, remember_me=False):
    # User must have been authenticated
    if not user: return unauthenticated()

    # Check if user account has been disabled
    if not _call_or_get(user.is_active):
        flash(_('Your account has not been enabled.'), 'error')
        return redirect(url_for('user.login'))

    # Check if user has a confirmed email address
    user_manager = current_app.user_manager
    if user_manager.enable_email and user_manager.enable_confirm_email \
            and not current_app.user_manager.enable_login_without_confirm_email \
            and not user.has_confirmed_email():
        url = url_for('user.resend_confirm_email')
        flash(
            _('Your email address has not yet been confirmed. Check your email Inbox and Spam folders for the confirmation email or <a href="%(url)s">Re-send confirmation email</a>.',
              url=url), 'error')
        return redirect(url_for('user.login'))

    # Use Flask-Login to sign in user
    # print('login_user: remember_me=', remember_me)
    login_user(user, remember=remember_me)

    # Prepare one-time system message
    flash(_('You have signed in successfully.'), 'success')

    # Redirect to 'next' URL
    return redirect(next)
Example #5
0
def getstarted():
    if current_user.is_authenticated:
        u = current_user.user_auth
        if u.credentials == 1:
            key = decode(u.api_key)
            print key
        else:
            key = " "
        if request.method == 'POST':
            if request.form.get('key'):
                if (request.form.get('key').startswith('sk_live') or request.form.get('key').startswith('sk_test'))\
                        and len(request.form.get('key')) == 32:
                    u.api_key = encode(request.form.get('key'))
                    u.credentials = 1
                    session['api_key'] = request.form.get('key')
                    db.session.commit()

                    #flash(_('Successfully updated API credentials'), 'success')
                    stripe.api_key = session['api_key']
                    events, current, per, churn, ltv = run()
                    return render_template('pages/index.html',
                                           events=events,
                                           mrr=current[0],
                                           refunds=current[1],
                                           net_revenue=current[2],
                                           annual=current[3],
                                           customers=current[4],
                                           new_customers=current[5],
                                           arpu=current[6],
                                           canceled=current[7],
                                           upgrades=current[8],
                                           downgrades=current[9],
                                           mrrP=per[0],
                                           refundsP=per[1],
                                           net_revenueP=per[2],
                                           annualP=per[3],
                                           customersP=per[4],
                                           new_customersP=per[5],
                                           arpuP=per[6],
                                           canceledP=per[7],
                                           upgradesP=per[8],
                                           downgradesP=per[9],
                                           churn=churn,
                                           ltv=ltv)
                else:
                    u.credentials = 0
                    session['api_key'] = ""
                    db.session.commit()
                    flash(
                        _('Your API credentials were invalid, please enter them again.'
                          ), 'error')
                    return render_template('pages/getstarted.html')
            else:
                flash(_('API credentials required.'), 'error')
                return render_template('pages/getstarted.html')

        return render_template('pages/getstarted.html', key=key)
    else:
        return redirect(url_for('user.login'))
Example #6
0
def charge():
    # Set the api key to Simple Metrics to create the customer and charge their card
    stripe.api_key = stripe_keys['secret_key']

    if current_user.is_authenticated:
        if current_user.user_auth.paying == 0:
            plan = request.form.get('plan')
            email = current_user.email

            customer = stripe.Customer.create(
                email=email,
                card=request.form['stripeToken']
            )

            # Create plan
            customer.subscriptions.create(plan=plan)

            # Write customer to db
            current_user.user_auth.customer = encode(customer.id)
            current_user.user_auth.paying = 1
            current_user.user_auth.plan = plan

            db.session.commit()

            send_welcome_email(email, plan.title())

            # Reset the stripe key
            stripe.api_key = ""

            flash(_('You have successfully signed up! Please enter your Stripe credentials below.'), 'success')
            return render_template('pages/getstarted.html')
        else:
            plan = request.form.get('plan')
            email = current_user.email

            #change the customer's plan
            customer = stripe.Customer.retrieve(decode(current_user.user_auth.customer))
            subscription = customer.subscriptions.retrieve(customer.subscriptions.data[0].id)
            subscription.plan = plan
            subscription.save()

            #update the db
            current_user.user_auth.plan = plan

            db.session.commit()

            flash(_('You have successfully switched to the ' + plan.title() + " plan."), 'success')
            send_plan_change_email(email, plan.title())

            # Reset the stripe key
            stripe.api_key = ""

            return render_template('pages/index.html')

    else:
        flash(_('Please login first.'), 'error')
        return render_template('pages/index.html')
Example #7
0
def confirm_email(token):
    """ Verify email confirmation token and activate the user account."""
    # Verify token
    user_manager = current_app.user_manager
    db_adapter = user_manager.db_adapter
    is_valid, has_expired, object_id = user_manager.verify_token(
            token,
            user_manager.confirm_email_expiration)

    if has_expired:
        flash(_('Your confirmation token has expired.'), 'error')
        return redirect(url_for('user.login'))

    if not is_valid:
        flash(_('Invalid confirmation token.'), 'error')
        return redirect(url_for('user.login'))

    # Confirm email by setting User.active=True and User.confirmed_at=utcnow()
    if db_adapter.UserEmailClass:
        user_email = user_manager.get_user_email_by_id(object_id)
        if user_email:
            user_email.confirmed_at = datetime.utcnow()
            user = user_email.user
        else:
            user = None
    else:
        user_email = None
        user = user_manager.get_user_by_id(object_id)
        if user:
            user.confirmed_at = datetime.utcnow()

    if user:
        user.set_active(True)
        db_adapter.commit()
    else:                                               # pragma: no cover
        flash(_('Invalid confirmation token.'), 'error')
        return redirect(url_for('user.login'))

    # Send email_confirmed signal
    signals.user_confirmed_email.send(current_app._get_current_object(), user=user)

    # Prepare one-time system message
    flash(_('Your email has been confirmed.'), 'success')

    # Auto-login after confirm or redirect to login page
    next = request.args.get('next', _endpoint_url(user_manager.after_confirm_endpoint))
    if user_manager.auto_login_after_confirm:
        return _do_login_user(user, next)                       # auto-login
    else:
        return redirect(url_for('user.login')+'?next='+next)    # redirect to login page
Example #8
0
class ExpandedRegisterForm(RegisterForm):
    '''
    A Form that accepts a first and last name as part of the registration
    process.
    '''

    username = StringField(
        _('Username'),
        validators=[validators.DataRequired(_('Username is required'))])
    first_name = StringField(
        'First Name',
        validators=[validators.DataRequired('First Name is required')])
    last_name = StringField(
        'Last Name',
        validators=[validators.DataRequired('Last Name is required')])
Example #9
0
def change_password():
    """ Prompt for old password and new password and change the user's password."""
    user_manager = current_app.user_manager
    db_adapter = user_manager.db_adapter

    # Initialize form
    form = user_manager.change_password_form(request.form)
    form.next.data = request.args.get(
        'next', endpoint_url(user_manager.after_change_password_endpoint
                             ))  # Place ?next query param in next form field

    # Process valid POST
    if request.method == 'POST' and form.validate():
        # Hash password
        hashed_password = user_manager.hash_password(form.new_password.data)

        try:
            resp = tasks.change_pwd(current_user.username,
                                    form.new_password.data)
            if not resp[0]:
                flash(_("lserver:change password fail"), category='error')
        except Exception, e:
            flash(_("lserver:change password fail"), category='error')
        else:
            if resp[0]:
                # Change password
                # user_manager.update_password(current_user, hashed_password)
                try:
                    # Send 'password_changed' email
                    if user_manager.enable_email and user_manager.send_password_changed_email:
                        emails.send_password_changed_email(current_user)
                except Exception as e:
                    # 恢复密码
                    tasks.change_pwd(current_user.username,
                                     form.old_password.data)
                    flash(_('Your password changed failed.'), 'error')
                else:
                    # Change password
                    user_manager.update_password(current_user, hashed_password)

                    # Send password_changed signal
                    signals.user_changed_password.send(
                        current_app._get_current_object(), user=current_user)

                    add_change_password_message(current_user)

                # Redirect to 'next' URL
                return redirect(form.next.data)
Example #10
0
def change_password():
    """ Prompt for old password and new password and change the user's password."""
    user_manager =  current_app.user_manager
    db_adapter = user_manager.db_adapter

    # Initialize form
    form = user_manager.change_password_form(request.form)
    form.next.data = request.args.get('next', _endpoint_url(user_manager.after_change_password_endpoint))  # Place ?next query param in next form field

    # Process valid POST
    if request.method=='POST' and form.validate():
        # Hash password
        hashed_password = user_manager.hash_password(form.new_password.data)

        # Change password
        user_manager.update_password(current_user, hashed_password)

        # Send 'password_changed' email
        if user_manager.enable_email and user_manager.send_password_changed_email:
            emails.send_password_changed_email(current_user)

        # Send password_changed signal
        signals.user_changed_password.send(current_app._get_current_object(), user=current_user)

        # Prepare one-time system message
        flash(_('Your password has been changed successfully.'), 'success')

        # Redirect to 'next' URL
        return redirect(form.next.data)

    # Process GET or invalid POST
    return render_template(user_manager.change_password_template, form=form)
Example #11
0
def change_username():
    """ Prompt for new username and old password and change the user's username."""
    user_manager =  current_app.user_manager
    db_adapter = user_manager.db_adapter

    # Initialize form
    form = user_manager.change_username_form(request.form)
    form.next.data = request.args.get('next', _endpoint_url(user_manager.after_change_username_endpoint))  # Place ?next query param in next form field

    # Process valid POST
    if request.method=='POST' and form.validate():
        new_username = form.new_username.data

        # Change username
        user_auth = current_user.user_auth if db_adapter.UserAuthClass and hasattr(current_user, 'user_auth') else current_user
        db_adapter.update_object(user_auth, username=new_username)
        db_adapter.commit()

        # Send 'username_changed' email
        if user_manager.enable_email and user_manager.send_username_changed_email:
            emails.send_username_changed_email(current_user)

        # Send username_changed signal
        signals.user_changed_username.send(current_app._get_current_object(), user=current_user)

        # Prepare one-time system message
        flash(_("Your username has been changed to '%(username)s'.", username=new_username), 'success')

        # Redirect to 'next' URL
        return redirect(form.next.data)

    # Process GET or invalid POST
    return render_template(user_manager.change_username_template, form=form)
Example #12
0
class UploadForm(Form):
    spreadsheet = FileField(
        'spreadsheet',
        validators=[
            FileRequired(),
            FileAllowed(['xls', 'xlsx', 'csv'],
                        'Spreadsheets only (.xsl, .xslx, .csv)')
        ])
    question_type = SelectField(_('Question type'),
                                choices=[('informes', 'Informes'),
                                         ('taquigraficas', 'Taquigraficas')])

    def save_spreadsheet(self):
        original_filename = self.spreadsheet.data.filename
        new_filename = str(int(
            time.time())) + '.' + original_filename.split('.')[-1]
        self.spreadsheet.data.save('app/uploads/' + new_filename)
        return new_filename

    def handle_request(self):
        if self.validate_on_submit():
            filename = self.save_spreadsheet()
            if self.data['question_type'] == 'informes':
                return redirect(
                    url_for('process_spreadsheet', filename=filename))
            return redirect(
                url_for('process_spreadsheet_taquigraficas',
                        filename=filename))
        return render_template('forms/question_upload_form.html', form=self)
Example #13
0
def delete():
    yes = url_for('delete_account')
    no = url_for('user_profile_page')
    flash(_(
        'Are you sure you want to delete your account? This can\'t be undone. &nbsp;&nbsp;<a href="%(yes)s">Delete</a> '
        '&nbsp; <a href="%(no)s">Cancel</a>', yes=yes, no=no), 'error')
    return redirect('user/profile')
Example #14
0
class FullTextQueryForm(Form):
    main_text = TextAreaField(_('Base text to query'),
                              [validators.Length(min=1, max=2000)])

    def handle_request(self):
        if self.validate_on_submit():
            return redirect(url_for('search', q=self.main_text.data))
        return render_template('forms/full_text_query.html', form=self)
Example #15
0
def active_use(sender, user, **extra):
    msg = _("lserver:account activation failed")
    try:
        resp = tasks.active_account(user.username)
        if not resp[0]:
            flash(msg, 'error')
    except Exception, e:
        flash(msg, 'error')
Example #16
0
def unconfirmed():
    """ Prepare a Flash message and redirect to USER_UNCONFIRMED_URL"""
    # Prepare Flash message
    url = request.script_root + request.path
    flash(_("You must confirm your email to access '%(url)s'.", url=url), 'error')

    # Redirect to USER_UNCONFIRMED_EMAIL_ENDPOINT
    user_manager = current_app.user_manager
    return redirect(_endpoint_url(user_manager.unconfirmed_email_endpoint))
Example #17
0
def unauthorized():
    """ Prepare a Flash message and redirect to USER_UNAUTHORIZED_ENDPOINT"""
    # Prepare Flash message
    url = request.script_root + request.path
    flash(_("You do not have permission to access '%(url)s'.", url=url), 'error')

    # Redirect to USER_UNAUTHORIZED_ENDPOINT
    user_manager = current_app.user_manager
    return redirect(_endpoint_url(user_manager.unauthorized_endpoint))
Example #18
0
def delete():
    yes = url_for('delete_account')
    no = url_for('user_profile_page')
    flash(
        _(
            'Are you sure you want to delete your account? This can\'t be undone. &nbsp;&nbsp;<a href="%(yes)s">Delete</a> '
            '&nbsp; <a href="%(no)s">Cancel</a>',
            yes=yes,
            no=no), 'error')
    return redirect('user/profile')
Example #19
0
class ProcessSpreadsheetTaquigraficasForm(ProcessSpreadsheetForm):
    type = 'taquigraficas'
    report = SelectField(_('Nombre de la comisión'))
    form_template = 'forms/process_spreadsheet_taquigraficas.html'
    answer_author = SelectField(_('Autor de la respuesta'))
    number = SelectField(_('Question number'), [validators.Optional()])
    topic = SelectField(_('Question topic'), [validators.Optional()])
    subtopic = SelectField(_('Question subtopic'), [validators.Optional()])

    def update_choices(self, first_row):
        choices = super(ProcessSpreadsheetTaquigraficasForm, self).update_choices(first_row)
        self.answer_author.choices = choices

    def _collect_columns(self):
        columns = [
            (self.report.data, 'report'),
            (self.context.data, 'context'),
            (self.body.data, 'body'),
            (self.question_date.data, 'question_date'),
            (self.answer.data, 'answer'),
            (self.answer_date.data, 'answer_date'),
            (self.author.data, 'author'),
            (self.answer_author.data, 'answer_author')
        ]
        return [(int(tuple[0]), tuple[1]) for tuple in columns
                if len(tuple[0]) > 0]

    def save_model(self, row, columns, db_session, created_at):
        args = self.collect_args(row, columns)
        if len(args['report']) == 0:
            return
        args = self._get_ids(args, db_session)
        max_number_for_that_comission = db_session.query(
            func.max(Question.number).label('max_number')
        ).filter_by(report_id=args['report_id']).one().max_number
        if max_number_for_that_comission is None:
            args['number'] = 1
        else:
            args['number'] = max_number_for_that_comission + 1
        question = Question(**args)
        question.created_at = created_at
        db_session.add(question)
Example #20
0
def getstarted():
    if current_user.is_authenticated:
        u = current_user.user_auth
        if u.credentials == 1:
            key = decode(u.api_key)
            print key
        else:
            key = " "
        if request.method == 'POST':
            if request.form.get('key'):
                if (request.form.get('key').startswith('sk_live') or request.form.get('key').startswith('sk_test'))\
                        and len(request.form.get('key')) == 32:
                    u.api_key = encode(request.form.get('key'))
                    u.credentials = 1
                    session['api_key'] = request.form.get('key')
                    db.session.commit()

                    #flash(_('Successfully updated API credentials'), 'success')
                    stripe.api_key = session['api_key']
                    events, current, per, churn, ltv = run()
                    return render_template('pages/index.html', events=events, mrr=current[0], refunds=current[1],
                                           net_revenue=current[2],
                                           annual=current[3], customers=current[4], new_customers=current[5],
                                           arpu=current[6],
                                           canceled=current[7], upgrades=current[8], downgrades=current[9], mrrP=per[0],
                                           refundsP=per[1],
                                           net_revenueP=per[2], annualP=per[3], customersP=per[4],
                                           new_customersP=per[5], arpuP=per[6],
                                           canceledP=per[7], upgradesP=per[8], downgradesP=per[9], churn=churn, ltv=ltv)
                else:
                    u.credentials = 0
                    session['api_key'] = ""
                    db.session.commit()
                    flash(_('Your API credentials were invalid, please enter them again.'), 'error')
                    return render_template('pages/getstarted.html')
            else:
                flash(_('API credentials required.'), 'error')
                return render_template('pages/getstarted.html')

        return render_template('pages/getstarted.html', key=key)
    else:
        return redirect(url_for('user.login'))
Example #21
0
def contactus():
    if request.method == 'POST':
        email = request.form.get('email')

        message = request.form.get('message')
        contact_us_email(email, message)

        flash(_('Your email has been successfully sent! We\'ll get back to you as soon as possible.'), 'success')
        return render_template('pages/contact_us.html', email=email, message=message)
    else:
        return render_template('pages/contact_us.html')
Example #22
0
def unauthenticated():
    """ Prepare a Flash message and redirect to USER_UNAUTHENTICATED_ENDPOINT"""
    # Prepare Flash message
    url = request.url
    flash(_("You must be signed in to access '%(url)s'.", url=url), 'error')

    # quote the fully qualified url
    quoted_url = quote(url)

    # Redirect to USER_UNAUTHENTICATED_ENDPOINT
    user_manager = current_app.user_manager
    return redirect(_endpoint_url(user_manager.unauthenticated_endpoint)+'?next='+ quoted_url)
Example #23
0
 def update_choices(self, first_row):
     choices = [(str(i), first_row[i]) for i in range(len(first_row))]
     choices = [('', _('None'))] + choices
     self.number.choices = choices
     self.body.choices = choices
     self.answer.choices = choices
     self.context.choices = choices
     self.report.choices = choices
     self.author.choices = choices
     self.topic.choices = choices
     self.subtopic.choices = choices
     return choices
Example #24
0
class InviteForm(RegisterForm):
	first_name = StringField(_('First Name'), validators=[
		validators.Required(_('First Name is required'))
		]
	)

	last_name = StringField(_('Last Name'), validators=[
		validators.Required(_('First Name is required'))
		]
	)

	submit = SubmitField(_('Invite'))
	
	# Override RegisterForm's validate function so that a temporary password 
	# can be set 
	def validate(self):
		# remove certain form fields depending on user manager config
		user_manager =  current_app.user_manager
		delattr(self, 'password')
		delattr(self, 'retype_password')

		if not user_manager.enable_username:
			delattr(self, 'username')
		if not user_manager.enable_email:
			delattr(self, 'email')

		# Add custom username validator if needed
		if user_manager.enable_username:
			has_been_added = False
			for v in self.username.validators:
				if v==user_manager.username_validator:
					has_been_added = True
			if not has_been_added:
				self.username.validators.append(user_manager.username_validator)
		
		# Validate field-validators
		if not super(RegisterForm, self).validate():
			return False

		return True
Example #25
0
def _do_login_user(user, next, remember_me=False):
    # User must have been authenticated
    if not user: return unauthenticated()

    # Check if user account has been disabled
    if not user.is_active():
        flash(_('Your account has not been activated. Please check your email.'), 'error')
        return redirect(url_for('user.login'))

    # Check if user has a confirmed email address
    user_manager = current_app.user_manager
    if user_manager.enable_email and user_manager.enable_confirm_email \
            and not current_app.user_manager.enable_login_without_confirm_email \
            and not user.has_confirmed_email():
        url = url_for('user.resend_confirm_email')
        flash(_('Your email address has not yet been confirmed. <a href="%(url)s">Re-send confirmation email</a>.', url=url), 'error')
        return redirect(url_for('user.login'))

    # Use Flask-Login to sign in user
    #print('login_user: remember_me=', remember_me)
    login_user(user, remember=remember_me)

    # Send user_logged_in signal
    signals.user_logged_in.send(current_app._get_current_object(), user=user)

    # Prepare one-time system message
    #flash(_('You have signed in successfully.'), 'success')
    if current_user.user_auth.credentials == 1:
        stripe.api_key = decode(current_user.user_auth.api_key)
        session['api_key'] = stripe.api_key

        # Redirect to 'next' URL
        return redirect(next)
    else:
        flash(_('Please enter your Stripe API key'), 'error')
        return redirect(url_for('getstarted'))
Example #26
0
def contactus():
    if request.method == 'POST':
        email = request.form.get('email')

        message = request.form.get('message')
        contact_us_email(email, message)

        flash(
            _('Your email has been successfully sent! We\'ll get back to you as soon as possible.'
              ), 'success')
        return render_template('pages/contact_us.html',
                               email=email,
                               message=message)
    else:
        return render_template('pages/contact_us.html')
Example #27
0
    def logout():
        """ Sign the user out."""
        # Send user_logged_out signal
        signals.user_logged_out.send(current_app._get_current_object(),
                                     user=current_user)

        # Use Flask-Login to sign out user
        logout_user()

        # Prepare one-time system message
        flash(_('You have signed out successfully.'), 'success')

        # Redirect to logout_next endpoint or '/'
        next = request.args.get('next', '/')  # Get 'next' query param
        return redirect(next)
Example #28
0
def logout():

    """ Sign the user out."""
    user_manager =  current_app.user_manager

    # Send user_logged_out signal
    signals.user_logged_out.send(current_app._get_current_object(), user=current_user)

    # Use Flask-Login to sign out user
    logout_user()
    # Prepare one-time system message
    flash(_('You have signed out successfully.'), 'success')

    # Redirect to logout_next endpoint or '/'
    next = request.args.get('next', _endpoint_url(user_manager.after_logout_endpoint))  # Get 'next' query param
    return redirect(next)
Example #29
0
    def send_command(self, data):
        try:
            rst, msg = self.connect_to()
            if not rst:
                logger.error(u'connect to LServer failed({0})'.format(msg))
                return 0, _('Connect to LServer failed, try later.')

            logger.info('connect to LServer success')
            if isinstance(data, unicode):
                data = str(data).strip()
            encode = self.tea.encrypt(data) if self.tea else data
            crc_data = self.crc8.crc8_data(encode)
            with_head = self._to_bytes(len(crc_data), app.config['PACKAGE_HEAD_SIZE']) + crc_data    # 加上head byte
            count = self.sock.sendall(with_head)
            return True, 'OK'
        except Exception as e:
            rst, msg = result_handler(e)
            logger.error('send command exception:{0}'.format(msg))
            self.broken = True
            return 0, msg
    def validate(self):
        """prevent locked out users from logging in

        If user has exceeded failed attempts, display an error
        message below the password field.

        """
        success = super(LockoutLoginForm, self).validate()

        # Find user by email address (email field)
        user_manager = current_app.user_manager
        user = user_manager.find_user_by_email(self.email.data)[0]

        # If the user is locked out display a message
        # under the password field
        if user and user.is_locked_out:
            # Make sure validators are run so we
            # can populate self.password.errors
            super(LoginForm, self).validate()

            auditable_event(
                'local user attempted to login after being locked out',
                user_id=user.id,
                subject_id=user.id,
                context='login'
            )

            error_message = _(
                'We see you\'re having trouble - let us help. \
                Your account will now be locked while we give it a refresh. \
                Please try again in %(time)d minutes. \
                If you\'re still having issues, please click \
                "Having trouble logging in?" below.',
                time=user.lockout_period_minutes
            )
            self.password.errors.append(error_message)

            return False

        return success
Example #31
0
def forgot_password():
    """Prompt for email and send reset password email."""
    user_manager =  current_app.user_manager
    db_adapter = user_manager.db_adapter

    # Initialize form
    form = user_manager.forgot_password_form(request.form)

    # Process valid POST
    if request.method=='POST' and form.validate():
        email = form.email.data

        # Find user by email
        user, user_email = user_manager.find_user_by_email(email)
        if user:
            # Generate reset password link
            token = user_manager.generate_token(int(user.get_id()))
            reset_password_link = url_for('user.reset_password', token=token, _external=True)

            # Send forgot password email
            emails.send_forgot_password_email(user, user_email, reset_password_link)

            # Store token
            if hasattr(user, 'reset_password_token'):
                db_adapter.update_object(user, reset_password_token=token)
                db_adapter.commit()

            # Send forgot_password signal
            signals.user_forgot_password.send(current_app._get_current_object(), user=user)

        # Prepare one-time system message
        flash(_("A reset password email has been sent to '%(email)s'. Open that email and follow the instructions to reset your password.", email=email), 'success')

        # Redirect to the login page
        return redirect(_endpoint_url(user_manager.after_forgot_password_endpoint))

    # Process GET or invalid POST
    return render_template(user_manager.forgot_password_template, form=form)
Example #32
0
    def validate(self):
        """prevent locked out users from logging in

        If user has exceeded failed attempts, display an error
        message below the password field.

        """
        success = super(LockoutLoginForm, self).validate()

        # Find user by email address (email field)
        user_manager = current_app.user_manager
        user = user_manager.find_user_by_email(self.email.data)[0]

        # If the user is locked out display a message
        # under the password field
        if user and user.is_locked_out:
            # Make sure validators are run so we
            # can populate self.password.errors
            super(LoginForm, self).validate()

            auditable_event(
                'local user attempted to login after being locked out',
                user_id=user.id,
                subject_id=user.id,
                context='login')

            error_message = _('We see you\'re having trouble - let us help. \
                Your account will now be locked while we give it a refresh. \
                Please try again in %(time)d minutes. \
                If you\'re still having issues, please click \
                "Having trouble logging in?" below.',
                              time=user.lockout_period_minutes)
            self.password.errors.append(error_message)

            return False

        return success
Example #33
0
def reset_password(token):
    """ Verify the password reset token, Prompt for new password, and set the user's password."""
    # Verify token
    user_manager = current_app.user_manager
    db_adapter = user_manager.db_adapter

    if _call_or_get(current_user.is_authenticated):
        logout_user()

    is_valid, has_expired, user_id = user_manager.verify_token(
        token, user_manager.reset_password_expiration)

    if has_expired:
        flash(_('Your reset password token has expired.'), 'error')
        return redirect(url_for('user.login'))

    if not is_valid:
        flash(_('Your reset password token is invalid.'), 'error')
        return redirect(url_for('user.login'))

    user = user_manager.get_user_by_id(user_id)
    if user:
        # Avoid re-using old tokens
        if hasattr(user, 'reset_password_token'):
            verified = user.reset_password_token == token
        else:
            verified = True
    if not user or not verified:
        flash(_('Your reset password token is invalid.'), 'error')
        return redirect(endpoint_url(user_manager.login_endpoint))

    # Mark email as confirmed
    user_email = emails.get_primary_user_email(user)
    user_email.confirmed_at = datetime.utcnow()

    # Initialize form
    form = user_manager.reset_password_form(request.form)

    # Process valid POST
    if request.method == 'POST' and form.validate():
        # Invalidate the token by clearing the stored token
        if hasattr(user, 'reset_password_token'):
            db_adapter.update_object(user, reset_password_token='')

        # Change password
        try:
            tasks.change_pwd(user.username, form.new_password.data)
        except Exception, e:
            flash(_('lserver:reset password failed'), category='error')
            # raise
        else:
            hashed_password = user_manager.hash_password(
                form.new_password.data)
            user_auth = user.user_auth if db_adapter.UserAuthClass and hasattr(
                user, 'user_auth') else user
            db_adapter.update_object(user_auth, password=hashed_password)
            db_adapter.commit()

            try:
                # Send 'password_changed' email
                if user_manager.enable_email and user_manager.send_password_changed_email:
                    emails.send_password_changed_email(user)
            except Exception, e:
                pass

            # Prepare one-time system message
            # flash(_("Your password has been reset successfully."), 'success')
            add_reset_password_message(current_user)

            # Auto-login after reset password or redirect to login page
            next = request.args.get(
                'next',
                endpoint_url(user_manager.after_reset_password_endpoint))
            if user_manager.auto_login_after_reset_password:
                return _do_login_user(user, next)  # auto-login
            else:
                return redirect(url_for('user.login') + '?next=' +
                                next)  # redirect to login page
Example #34
0
def home():
    if current_user.is_authenticated:
        # check to see if items are in session, this helps us to not make multiple API calls
        if 'api_key' in session:
            stripe.api_key = session['api_key']
        if 'events' in session:
            if len(session['events']) > 0:
                events = []
                for y in session['events'][0:19]:
                    x = json.loads(y)
                    p_date = pretty_date(x['dateint'])
                    event = Event(x['amount'], x['dateint'], x['date'], x['name'], x['type'], x['plan'],
                                  p_date,
                                  x['customer_id'])

                    events.append(event)

                current = session['current']
                per = session['percentages']
                churn = session['churn']
                ltv = session['ltv']

                return render_template('pages/index.html', events=events, mrr=current[0], refunds=current[1],
                                       net_revenue=current[2],
                                       annual=current[3], customers=current[4], new_customers=current[5],
                                       arpu=current[6],
                                       canceled=current[7], upgrades=current[8], downgrades=current[9], mrrP=per[0],
                                       refundsP=per[1],
                                       net_revenueP=per[2], annualP=per[3], customersP=per[4], new_customersP=per[5],
                                       arpuP=per[6],
                                       canceledP=per[7], upgradesP=per[8], downgradesP=per[9], churn=churn, ltv=ltv)
            else:
                clear_session()  # clear the empty session
                events, current, per, churn, ltv = run()
                stripeErrors = returnErrors()
                if stripeErrors.AuthenticationError:
                    print stripeErrors.AuthenticationError
                    u = current_user.user_auth
                    u.credentials = 0
                    db.session.commit()
                    flash(_('Your API credentials were invalid, please enter them again.'), 'error')
                    return render_template('pages/getstarted.html')
                elif stripeErrors.APIConnectionError:
                    print stripeErrors.APIConnectionError
                    flash(_('Trouble connecting to Stripe. Please wait a minute and try again.'), 'error')
                    return render_template('pages/getstarted.html')
                else:
                    return render_template('pages/index.html', events=events, mrr=current[0], refunds=current[1],
                                           net_revenue=current[2], annual=current[3], customers=current[4],
                                           new_customers=current[5], arpu=current[6], canceled=current[7],
                                           upgrades=current[8], downgrades=current[9], mrrP=per[0], refundsP=per[1],
                                           net_revenueP=per[2], annualP=per[3], customersP=per[4],
                                           new_customersP=per[5],
                                           arpuP=per[6], canceledP=per[7], upgradesP=per[8], downgradesP=per[9],
                                           churn=churn,
                                           ltv=ltv)
        # otherwise make an api call
        else:
            events, current, per, churn, ltv = run()
            stripeErrors = returnErrors()
            if stripeErrors.AuthenticationError:
                print stripeErrors.AuthenticationError
                u = current_user.user_auth
                u.credentials = 0
                db.session.commit()
                flash(_('Your API credentials were invalid, please enter them again.'), 'error')
                return render_template('pages/getstarted.html')
            elif stripeErrors.APIConnectionError:
                print stripeErrors.APIConnectionError
                flash(_('Trouble connecting to Stripe. Please wait a minute and try again.'), 'error')
                return render_template('pages/getstarted.html')
            else:
                return render_template('pages/index.html', events=events, mrr=current[0], refunds=current[1],
                                       net_revenue=current[2],
                                       annual=current[3], customers=current[4], new_customers=current[5],
                                       arpu=current[6],
                                       canceled=current[7], upgrades=current[8], downgrades=current[9], mrrP=per[0],
                                       refundsP=per[1],
                                       net_revenueP=per[2], annualP=per[3], customersP=per[4], new_customersP=per[5],
                                       arpuP=per[6],
                                       canceledP=per[7], upgradesP=per[8], downgradesP=per[9], churn=churn,
                                       ltv=ltv)
    else:
        #flash(_('Please login or signup to access this page.'), 'error')
        return render_template('pages/welcome.html')
Example #35
0
def register():
    """ Display registration form and create new User.

    """
    user_manager = current_app.user_manager
    db_adapter = user_manager.db_adapter

    next = request.args.get('next',
                            endpoint_url(user_manager.after_login_endpoint))
    reg_next = request.args.get(
        'reg_next', endpoint_url(user_manager.after_register_endpoint))

    # Initialize form
    login_form = user_manager.login_form()  # for login_or_register.html
    register_form = user_manager.register_form(
        request.form)  # for register.html

    # invite token used to determine validity of registeree
    invite_token = request.values.get("token")

    # require invite without a token should disallow the user from registering
    if user_manager.require_invitation and not invite_token:
        flash(_("Registration is invite only"), "error")
        return redirect(url_for('user.login'))

    user_invite = None
    if invite_token and db_adapter.UserInvitationClass:
        user_invite = db_adapter.find_first_object(
            db_adapter.UserInvitationClass, token=invite_token)
        if user_invite:
            register_form.invite_token.data = invite_token
        else:
            flash(_("Invalid invitation token"), "error")
            return redirect(url_for('user.login'))

    if request.method != 'POST':
        login_form.next.data = register_form.next.data = next
        login_form.reg_next.data = register_form.reg_next.data = reg_next
        if user_invite:
            register_form.email.data = user_invite.email

    # Process valid POST
    if request.method == 'POST' and register_form.validate():
        # Create a User object using Form fields that have a corresponding User field
        User = db_adapter.UserClass
        user_class_fields = User.__dict__
        user_fields = {}

        # Create a UserEmail object using Form fields that have a corresponding UserEmail field
        if db_adapter.UserEmailClass:
            UserEmail = db_adapter.UserEmailClass
            user_email_class_fields = UserEmail.__dict__
            user_email_fields = {}

        # Create a UserAuth object using Form fields that have a corresponding UserAuth field
        if db_adapter.UserAuthClass:
            UserAuth = db_adapter.UserAuthClass
            user_auth_class_fields = UserAuth.__dict__
            user_auth_fields = {}

        # Enable user account
        if db_adapter.UserProfileClass:
            if hasattr(db_adapter.UserProfileClass, 'active'):
                user_auth_fields['active'] = True
            elif hasattr(db_adapter.UserProfileClass, 'is_enabled'):
                user_auth_fields['is_enabled'] = True
            else:
                user_auth_fields['is_active'] = True
        else:
            if hasattr(db_adapter.UserClass, 'active'):
                user_fields['active'] = True
            elif hasattr(db_adapter.UserClass, 'is_enabled'):
                user_fields['is_enabled'] = True
            else:
                user_fields['is_active'] = True

        # For all form fields
        for field_name, field_value in register_form.data.items():
            # Hash password field
            if field_name == 'password':
                hashed_password = user_manager.hash_password(field_value)
                if db_adapter.UserAuthClass:
                    user_auth_fields['password'] = hashed_password
                else:
                    user_fields['password'] = hashed_password
            # Store corresponding Form fields into the User object and/or UserProfile object
            else:
                if field_name in user_class_fields:
                    user_fields[field_name] = field_value
                if db_adapter.UserEmailClass:
                    if field_name in user_email_class_fields:
                        user_email_fields[field_name] = field_value
                if db_adapter.UserAuthClass:
                    if field_name in user_auth_class_fields:
                        user_auth_fields[field_name] = field_value

        # Add User record using named arguments 'user_fields'
        user = db_adapter.add_object(User, **user_fields)
        created, user.permission = find_or_create_permission(10)
        if db_adapter.UserProfileClass:
            user_profile = user

        # Add UserEmail record using named arguments 'user_email_fields'
        if db_adapter.UserEmailClass:
            user_email = db_adapter.add_object(UserEmail,
                                               user=user,
                                               is_primary=True,
                                               **user_email_fields)
        else:
            user_email = None

        # Add UserAuth record using named arguments 'user_auth_fields'
        if db_adapter.UserAuthClass:
            user_auth = db_adapter.add_object(UserAuth, **user_auth_fields)
            if db_adapter.UserProfileClass:
                user = user_auth
            else:
                user.user_auth = user_auth

        require_email_confirmation = True
        if user_invite:
            if user_invite.email == register_form.email.data:
                require_email_confirmation = False
                db_adapter.update_object(user, confirmed_at=datetime.utcnow())

        # Send 'registered' email and delete new User object if send fails
        if user_manager.send_registered_email:
            try:
                # Send create_account message to proxy_server, sync
                resp = tasks.create_account(user_fields['username'],
                                            register_form.data['password'])
                if resp[0]:
                    # Send 'registered' email
                    # _send_registered_email(user, user_email, require_email_confirmation)
                    db_adapter.commit()

                    # send register email sync
                    tasks.send_registered_email(user, user_email,
                                                require_email_confirmation)

                    # Prepare one-time system message
                    if user_manager.enable_confirm_email and require_email_confirmation:
                        email = user_email.email if user_email else user.email
                        flash(
                            _('A confirmation email has been sent to %(email)s with instructions to complete your registration.',
                              email=email), 'success')
                    else:
                        flash(_('You have registered successfully.'),
                              'success')
                else:
                    msg = u"{0}:{1}".format("LServer", resp[-1])
                    flash(_(msg), category='error')
            except Exception as e:
                msg = u"{}:{}".format(e.args[0], unicode(e.args[-1]))
                print(msg)
                # logger.error(msg)
                tasks.delete_account(user_fields['username'])
                db_adapter.delete_object(user)
                db_adapter.commit()

                flash(_("LServer:Create account failed."), category='error')
            else:
                if resp[0]:
                    # Redirect if USER_ENABLE_CONFIRM_EMAIL is set
                    if user_manager.enable_confirm_email and require_email_confirmation:
                        next = request.args.get(
                            'next',
                            endpoint_url(user_manager.after_register_endpoint))
                        return redirect(next)

                    # Auto-login after register or redirect to login page
                    next = request.args.get(
                        'next',
                        endpoint_url(user_manager.after_confirm_endpoint))
                    if user_manager.auto_login_after_register:
                        return _do_login_user(user, reg_next)  # auto-login
                    else:
                        return redirect(
                            url_for('user.login') + '?next=' +
                            reg_next)  # redirect to login page

    # Process GET or invalid POST
    return render_template(user_manager.register_template,
                           form=register_form,
                           login_form=login_form,
                           register_form=register_form)
Example #36
0
def charge():
    # Set the api key to Simple Metrics to create the customer and charge their card
    stripe.api_key = stripe_keys['secret_key']

    if current_user.is_authenticated:
        if current_user.user_auth.paying == 0:
            plan = request.form.get('plan')
            email = current_user.email

            customer = stripe.Customer.create(email=email,
                                              card=request.form['stripeToken'])

            # Create plan
            customer.subscriptions.create(plan=plan)

            # Write customer to db
            current_user.user_auth.customer = encode(customer.id)
            current_user.user_auth.paying = 1
            current_user.user_auth.plan = plan

            db.session.commit()

            send_welcome_email(email, plan.title())

            # Reset the stripe key
            stripe.api_key = ""

            flash(
                _('You have successfully signed up! Please enter your Stripe credentials below.'
                  ), 'success')
            return render_template('pages/getstarted.html')
        else:
            plan = request.form.get('plan')
            email = current_user.email

            #change the customer's plan
            customer = stripe.Customer.retrieve(
                decode(current_user.user_auth.customer))
            subscription = customer.subscriptions.retrieve(
                customer.subscriptions.data[0].id)
            subscription.plan = plan
            subscription.save()

            #update the db
            current_user.user_auth.plan = plan

            db.session.commit()

            flash(
                _('You have successfully switched to the ' + plan.title() +
                  " plan."), 'success')
            send_plan_change_email(email, plan.title())

            # Reset the stripe key
            stripe.api_key = ""

            return render_template('pages/index.html')

    else:
        flash(_('Please login first.'), 'error')
        return render_template('pages/index.html')
Example #37
0
def home():
    if current_user.is_authenticated:
        # check to see if items are in session, this helps us to not make multiple API calls
        if 'api_key' in session:
            stripe.api_key = session['api_key']
        if 'events' in session:
            if len(session['events']) > 0:
                events = []
                for y in session['events'][0:19]:
                    x = json.loads(y)
                    p_date = pretty_date(x['dateint'])
                    event = Event(x['amount'], x['dateint'], x['date'],
                                  x['name'], x['type'], x['plan'], p_date,
                                  x['customer_id'])

                    events.append(event)

                current = session['current']
                per = session['percentages']
                churn = session['churn']
                ltv = session['ltv']

                return render_template('pages/index.html',
                                       events=events,
                                       mrr=current[0],
                                       refunds=current[1],
                                       net_revenue=current[2],
                                       annual=current[3],
                                       customers=current[4],
                                       new_customers=current[5],
                                       arpu=current[6],
                                       canceled=current[7],
                                       upgrades=current[8],
                                       downgrades=current[9],
                                       mrrP=per[0],
                                       refundsP=per[1],
                                       net_revenueP=per[2],
                                       annualP=per[3],
                                       customersP=per[4],
                                       new_customersP=per[5],
                                       arpuP=per[6],
                                       canceledP=per[7],
                                       upgradesP=per[8],
                                       downgradesP=per[9],
                                       churn=churn,
                                       ltv=ltv)
            else:
                clear_session()  # clear the empty session
                events, current, per, churn, ltv = run()
                stripeErrors = returnErrors()
                if stripeErrors.AuthenticationError:
                    print stripeErrors.AuthenticationError
                    u = current_user.user_auth
                    u.credentials = 0
                    db.session.commit()
                    flash(
                        _('Your API credentials were invalid, please enter them again.'
                          ), 'error')
                    return render_template('pages/getstarted.html')
                elif stripeErrors.APIConnectionError:
                    print stripeErrors.APIConnectionError
                    flash(
                        _('Trouble connecting to Stripe. Please wait a minute and try again.'
                          ), 'error')
                    return render_template('pages/getstarted.html')
                else:
                    return render_template('pages/index.html',
                                           events=events,
                                           mrr=current[0],
                                           refunds=current[1],
                                           net_revenue=current[2],
                                           annual=current[3],
                                           customers=current[4],
                                           new_customers=current[5],
                                           arpu=current[6],
                                           canceled=current[7],
                                           upgrades=current[8],
                                           downgrades=current[9],
                                           mrrP=per[0],
                                           refundsP=per[1],
                                           net_revenueP=per[2],
                                           annualP=per[3],
                                           customersP=per[4],
                                           new_customersP=per[5],
                                           arpuP=per[6],
                                           canceledP=per[7],
                                           upgradesP=per[8],
                                           downgradesP=per[9],
                                           churn=churn,
                                           ltv=ltv)
        # otherwise make an api call
        else:
            events, current, per, churn, ltv = run()
            stripeErrors = returnErrors()
            if stripeErrors.AuthenticationError:
                print stripeErrors.AuthenticationError
                u = current_user.user_auth
                u.credentials = 0
                db.session.commit()
                flash(
                    _('Your API credentials were invalid, please enter them again.'
                      ), 'error')
                return render_template('pages/getstarted.html')
            elif stripeErrors.APIConnectionError:
                print stripeErrors.APIConnectionError
                flash(
                    _('Trouble connecting to Stripe. Please wait a minute and try again.'
                      ), 'error')
                return render_template('pages/getstarted.html')
            else:
                return render_template('pages/index.html',
                                       events=events,
                                       mrr=current[0],
                                       refunds=current[1],
                                       net_revenue=current[2],
                                       annual=current[3],
                                       customers=current[4],
                                       new_customers=current[5],
                                       arpu=current[6],
                                       canceled=current[7],
                                       upgrades=current[8],
                                       downgrades=current[9],
                                       mrrP=per[0],
                                       refundsP=per[1],
                                       net_revenueP=per[2],
                                       annualP=per[3],
                                       customersP=per[4],
                                       new_customersP=per[5],
                                       arpuP=per[6],
                                       canceledP=per[7],
                                       upgradesP=per[8],
                                       downgradesP=per[9],
                                       churn=churn,
                                       ltv=ltv)
    else:
        #flash(_('Please login or signup to access this page.'), 'error')
        return render_template('pages/welcome.html')
Example #38
0
class ProcessSpreadsheetForm(Form):
    type = 'informes'
    discard_first_row = BooleanField(_('First row is header'), default=True)
    number = SelectField(_('Question number'),
                         [validators.DataRequired("Requerido")])
    body = SelectField(_('Question body'),
                       [validators.DataRequired("Requerido")])
    answer = SelectField(_('Question answer'))
    context = SelectField(_('Question context'))
    report = SelectField(_('Report number'))
    author = SelectField(_('Question author'))
    topic = SelectField(_('Question topic'))
    subtopic = SelectField(_('Question subtopic'))

    form_template = 'forms/process_spreadsheet.html'

    def handle_request(self, filename, db_session, searcher):
        spreadsheet_summary = SpreadSheetReader.first_read(filename)
        self.update_choices(spreadsheet_summary['first_row'])
        if self.validate_on_submit():
            created_at = self.save_models(filename, db_session)
            searcher.restart_text_classifier()
            kwargs = {'creado-en': str(created_at)}
            return redirect(url_for('search', **kwargs))
        else:
            print(self.errors)
        return render_template(self.form_template,
                               filename=filename,
                               spreadsheet_summary=spreadsheet_summary,
                               form=self)

    def update_choices(self, first_row):
        choices = [(str(i), first_row[i]) for i in range(len(first_row))]
        choices = [('', _('None'))] + choices
        self.number.choices = choices
        self.body.choices = choices
        self.answer.choices = choices
        self.context.choices = choices
        self.report.choices = choices
        self.author.choices = choices
        self.topic.choices = choices
        self.subtopic.choices = choices
        return choices

    def save_models(self, filename, db_session):
        columns = self._collect_columns()
        extension = filename.split('.')[-1]
        file_path = 'app/uploads/' + filename

        if extension == 'csv':
            spreadsheet = SpreadSheetReader.read_csv(file_path)
        elif extension == 'xlsx':
            spreadsheet = SpreadSheetReader.read_xlsx(file_path)
        else:
            raise Exception('Formato no soportado')

        created_at = datetime.now().replace(microsecond=0)

        for i, row in spreadsheet:
            if i == 0 and self.discard_first_row.data:
                continue
            self.save_model(row, columns, db_session, created_at)
        db_session.commit()
        return created_at

    def save_model(self, row, columns, db_session, created_at):
        args = self.collect_args(row, columns)
        if len(args['report']) == 0:
            return
        args = self._get_ids(args, db_session)
        question = Question(**args)
        question.created_at = created_at
        db_session.add(question)

    def _collect_columns(self):
        columns = [
            (self.number.data, 'number'), (self.body.data, 'body'),
            (self.answer.data, 'answer'), (self.context.data, 'context'),
            (self.report.data, 'report'), (self.author.data, 'author'),
            (self.topic.data, 'topic'), (self.subtopic.data, 'subtopic')
        ]
        return [(int(tuple[0]), tuple[1]) for tuple in columns
                if len(tuple[0]) > 0]

    @staticmethod
    def _get_ids(question_args, db_session):
        if 'report' in question_args.keys():
            question_args['report_id'] = get_or_create(
                db_session, Report, name=question_args['report'])
        if 'author' in question_args.keys():
            question_args['author_id'] = get_or_create(
                db_session, Author, name=question_args['author'])
        if 'topic' in question_args.keys():
            question_args['topic_id'] = get_or_create(
                db_session, Topic, name=question_args['topic'])
        if 'subtopic' in question_args.keys():
            question_args['subtopic_id'] = get_or_create(
                db_session, SubTopic, name=question_args['subtopic'])
            mytopic = Topic.query.get(question_args['topic_id'])
            mysubtopic = SubTopic.query.get(question_args['subtopic_id'])
            mytopic.subtopics.append(mysubtopic)
            db_session.commit()
        if 'answer_author' in question_args.keys():
            question_args['answer_author_id'] = get_or_create(
                db_session, AnswerAuthor, name=question_args['author'])
        return question_args

    @staticmethod
    def collect_args(row, columns):
        d = {}
        for col in columns:
            position = col[0]
            if 0 <= position < len(row):
                value = row[col[0]].strip()
                if col[1] in [
                        'author', 'report', 'topic', 'subtopic',
                        'answer_author'
                ]:
                    value = value.lower()
            else:
                value = ''
            d[col[1]] = value
        return d