def resend_activation_code_email(): """ request of a new confirmation email """ #if there is not an email in session I need one if not session.get('user_login_email'): form = PreActivateUserForm(csrf_enabled=False) if form.validate_on_submit(): if not login_exists_local(form.act_em.data): if not login_exists_classic(form.act_em.data): flash('There is no user with the provided email. Please sign up first.', 'error') return redirect(generate_redirect_url(url_for('user.signup'))) else: flash('The user is already active. Please log in.', 'warn') return redirect(generate_redirect_url(url_for('user.login'))) elif login_is_active(form.act_em.data): flash('The user is already active. Please log in.', 'warn') return redirect(generate_redirect_url(url_for('user.login'))) #if everything looks fine, the email goes in the session session['user_login_email'] = form.act_em.data else: return render_template('resend_email.html', form=form) #if the email is in the session, time to sent the email success, message, message_type = resend_activation_email(session.get('user_login_email')) flash(message, message_type) if success: statsd.incr("user.resend_activation.success") return redirect(generate_redirect_url(next_=url_for('user.activate'))) else: statsd.incr("user.resend_activation.failed") return redirect(generate_redirect_url(next_=url_for('user.resend_activation_code_email')))
def tab_list(bibcode, list_type): solrdoc = get_document(bibcode) # if there are no references return a 404 if not solrdoc or not solrdoc.has_assoc_list(list_type): abort(404) denormdoc = denormalize_solr_doc(solrdoc) # parse the get options query_components = QueryBuilderSimple.build(request.values, list_type=list_type) # use the appropriate getter method list_method = getattr(solrdoc, "get_%s" % list_type) if not list_method: abort(404) # get the list of associated docs resp = list_method(**query_components) # log the request abstract_view_signal.send(abs_blueprint, bibcode=bibcode, list_type=list_type) statsd.incr("abs.%s.viewed" % list_type) return render_template( "abstract_tabs.html", solrdoc=solrdoc, denormdoc=denormdoc, curview=list_type, article_list=resp )
def change_account_settings(): """ Allows to change user settings (but not the password) """ app.logger.debug('User change settings') #check if the form should be pre-filled with data from the post or from the current user form_params_to_check = ['name', 'lastname', 'login'] form_params = {} for param in form_params_to_check: if not request.values.get(param) and current_user.is_authenticated(): if param == 'name': form_params['name'] = current_user.user_rec.firstname elif param == 'lastname': form_params['lastname'] = current_user.user_rec.lastname elif param == 'login': form_params['login'] = current_user.user_rec.username form_params['confirm_login'] = current_user.user_rec.username form = ChangeUserParamsForm(**form_params) if form.validate_on_submit(): success, message, message_type = change_user_settings(form) flash(message, message_type) if success: statsd.incr("user.account_change.success") return redirect(generate_redirect_url(next_=url_for('user.index'))) else: statsd.incr("user.account_change.failed") return render_template('change_params.html', form=form)
def login(): """ User login view """ app.logger.debug('Login form') if current_user.is_authenticated(): return redirect(request.args.get('next', None) or url_for('user.index')) form = LoginForm(login=request.args.get('login', None), next=request.args.get('next', None), csrf_enabled=config.CSRF_ENABLED) if form.validate_on_submit(): statsd.incr("user.login.attempt") app.logger.debug('Authentication process') user, auth_msg = authenticate(form.login.data, form.password.data) if user and auth_msg == 'SUCCESS': user.set_last_signon() remember = request.form.get('remember') == 'y' if login_user(user, remember=remember): flash("Successfully logged in!", 'success') statsd.incr("user.login.success") return redirect(generate_redirect_url(next_=form.next.data)) elif not user and auth_msg == 'WRONG_PARAMS': flash('Sorry, invalid login parameters', 'error') statsd.incr("user.login.failed") elif not user and auth_msg == 'LOCAL_NOT_ACTIVE': flash('Sorry, the user is not active yet. Please activate it before proceeding.', 'error') session['user_login_email'] = form.login.data statsd.incr("user.login.failed") return redirect(url_for('user.activate')) else: flash('Sorry, authentication error. Please try later.', 'error') statsd.incr("user.login.failed") return render_template('login.html', form=form)
def search(): search_req = ApiSearchRequest(request.args) if not search_req.validate(): statsd.incr("api.search.invalid") raise api_errors.ApiInvalidRequest(search_req.input_errors()) resp = search_req.execute() statsd.incr("api.search.success") return resp.search_response()
def decorator(*args, **kwargs): dev_key = request.args.get('dev_key', None) if not dev_key or len(dev_key) == 0: raise api_errors.ApiNotAuthenticatedError("no developer token provided") try: user = AdsApiUser.from_dev_key(dev_key) except Exception, e: import traceback exc_info = sys.exc_info() app.logger.error("User auth failure: %s, %s\n%s" % (exc_info[0], exc_info[1], traceback.format_exc())) statsd.incr("api.user.authentication.failed") user = None
def index(): """ Index page of the User """ app.logger.debug('Index of user page.') if current_user.is_authenticated(): app.logger.debug('User already authenticated') statsd.incr("user.profile.viewed") return render_template('user_home_page.html') app.logger.debug('User not authenticated: redirect to authentication page.') return redirect(url_for('user.login'))
def send_email_to_user(title, message_html, recipients, sender=None): """ Generic function to send an email to users """ if not sender: sender = '*****@*****.**' msg = Message(title, html=message_html, sender=sender, recipients=recipients) mail.send(msg) #@UndefinedVariable statsd.incr("user.email.sent")
def search_metrics(): search_req = ApiSearchRequest(request.args) if not search_req.validate(): statsd.incr("api.search_metrics.invalid") raise api_errors.ApiInvalidRequest(search_req.input_errors()) resp = search_req.execute() search_response = resp.search_response() bibcodes = map(lambda a: a['bibcode'], filter(lambda a: 'bibcode' in a, search_response['results']['docs'])) metrics = generate_metrics(bibcodes=bibcodes, fmt='API') search_response['results'] = metrics statsd.incr("api.search_metrics.success") return search_response
def f(error): from adsabs.extensions import statsd app.logger.error("[error] %s, %s" % (str(error), request.path)) statsd.incr("error.%s.handled" % str(status_code)) return render_template(template), status_code # @app.errorhandler(MongoGutError) # def handle_error(error): # response = jsonify(error.to_dict()) # response.status_code = error.status_code # return response
def logout(): """ User logout view """ app.logger.debug('User logout') #actual logout logout_user() #set a variable in g to skip the general after_request cookie set up g.skip_general_cookie_setup = True #call of the function that runs a specific after_request to invalidate the user cookies invalidate_user_cookie() flash('You are now logged out', 'success') statsd.incr("user.logout.success") return redirect(generate_redirect_url(next_=request.args.get('next', None)))
def word_cloud(): """ View that creates the data for the word cloud """ query_url = config.SOLRQUERY_URL tvrh_query_url = query_url.rsplit('/', 1)[0] + '/tvrh' try: query_components = json.loads(request.values.get('current_search_parameters')) except (TypeError, JSONDecodeError): #@todo: logging of the error return render_template('errors/generic_error.html', error_message='Error while creating the word cloud (code #1). Please try later.') # get the maximum number of records to use query_components['rows'] = request.values.get('numRecs', config.MAX_EXPORTS['wordcloud']) # checked bibcodes will be input as if request.values.has_key('bibcode'): bibcodes = request.values.getlist('bibcode') query_components['q'] = ' OR '.join(["bibcode:%s" % b for b in bibcodes]) query_components.update({ 'facets': [], 'fields': ['id'], 'highlights': [], 'defType':'aqp', 'tv': 'true', 'tv.tf_idf': 'true', 'tv.tf': 'true', 'tv.positions':'false', 'tf.offsets':'false', 'tv.fl':'abstract,title', 'fl':'abstract,title' }) req = solr.create_request(**query_components) url = tvrh_query_url if 'bigquery' in request.values: from adsabs.core.solr import bigquery bigquery.prepare_bigquery_request(req, request.values['bigquery']) url = config.SOLRBIGQUERY_URL req = solr.set_defaults(req, query_url=url) resp = solr.get_response(req) if resp.is_error(): return render_template('errors/generic_error.html', error_message='Error while creating the word cloud (code #2). Please try later.') statsd.incr("visualization.word_cloud.viewed") return render_template('word_cloud_embedded.html', wordcloud_data=wc_json(resp.raw_response()))
def reset_password(): """ User password reset """ app.logger.debug('User password reset') form = ResetPasswordForm() if form.validate_on_submit(): success, message, message_type = reset_user_password_step_one(form) flash(message, message_type) if success: statsd.incr("user.password.reset.success") return redirect(generate_redirect_url(next_=url_for('user.confirm_reset_password'))) else: statsd.incr("user.password.reset.failed") return render_template('reset_password_1.html', form=form)
def abstract(bibcode=None): if bibcode is None: abort(404) solrdoc = get_document(bibcode) if not solrdoc: abort(404) denormdoc = denormalize_solr_doc(solrdoc) # log the request abstract_view_signal.send(abs_blueprint, bibcode=bibcode, list_type="abstract") statsd.incr("abs.abstract.viewed") return render_template("abstract_tabs.html", solrdoc=solrdoc, denormdoc=denormdoc, curview="abstract")
def change_password(): """ User password change """ app.logger.debug('User password change') form = ChangePasswordForm() if form.validate_on_submit(): success, message, message_type = change_user_password(form) flash(message, message_type) if success: statsd.incr("user.password.changed.success") return redirect(generate_redirect_url(next_=url_for('user.index'))) else: statsd.incr("user.password.changed.failed") return render_template('change_password.html', form=form)
def activate(): """ User activation form """ #if the user is logged in he needs to logout before signup as another user if current_user.is_authenticated(): flash('Please, <a href="%s">logout</a> before activate another user' % url_for('user.logout'), 'warn') return redirect(generate_redirect_url()) #if everything looks fine, it's time to proceed form_params_creation ={'csrf_enabled':False} if request.method == 'GET' and request.values.get('id'): #need to specify the value to initialize the form because it cannot find this value in request.form form_params_creation.update({'id': request.values.get('id')}) form = ActivateUserForm(**form_params_creation) if is_submitted_cust(form): if form.validate(): success, message, message_type = activate_user(form.id.data) if not success: flash('Activation failed: %s' % message, message_type) statsd.incr("user.activate.success") else: flash('Your account is now active.', 'success') statsd.incr("user.activate.failed") session['user_login_email'] = None return redirect(generate_redirect_url(url_for('user.login'))) elif not session.get('user_login_email'): #if there is no email in the session, the user needs to provide it pre_form = PreActivateUserForm(csrf_enabled=False) if not is_submitted_cust(pre_form) or not pre_form.validate(): return render_template('activate.html', form=pre_form, pre_activation=True) #if there is the email as input, check if the user exists locally and is not active if not login_exists_local(pre_form.act_em.data): if not login_exists_classic(pre_form.act_em.data): flash('There is no user with the provided email. Please sign up first.', 'error') return redirect(generate_redirect_url(url_for('user.signup'))) else: flash('The user is already active. Please log in.', 'warn') return redirect(generate_redirect_url(url_for('user.login'))) elif login_is_active(pre_form.act_em.data): flash('The user is already active. Please log in.', 'warn') return redirect(generate_redirect_url(url_for('user.login'))) #if everything looks fine with the user login email, it can be stored in the session session['user_login_email'] = pre_form.act_em.data return render_template('activate.html', form=form, pre_activation=False)
def abstract(bibcode=None): if bibcode is None: abort(404) solrdoc = get_document(bibcode) if not solrdoc: abort(404) denormdoc = denormalize_solr_doc(solrdoc) # get article graphics info graphics = get_thumbnails(bibcode) # log the request abstract_view_signal.send(abs_blueprint, bibcode=bibcode, list_type="abstract") statsd.incr("abs.abstract.viewed") return render_template('abstract_tabs.html', solrdoc=solrdoc, denormdoc=denormdoc, graphics=graphics, curview='abstract')
def paper_network(): """ View that creates the data for the paper network """ #if there are no bibcodes, there should be a query to extract the bibcodes try: query_components = json.loads(request.values.get('current_search_parameters')) except (TypeError, JSONDecodeError): #@todo: logging of the error return render_template('errors/generic_error.html', error_message='Error while creating the paper network (code #1). Please try later.') # get the maximum number of records to use query_components['rows'] = request.values.get('numRecs', config.MAX_EXPORTS['papernetwork']) # checked bibcodes will be input as if request.values.has_key('bibcode'): bibcodes = request.values.getlist('bibcode') query_components['q'] = ' OR '.join(["bibcode:%s" % b for b in bibcodes]) #update the query parameters to return only what is necessary query_components.update({ 'facets': [], 'fields': ['bibcode,title,first_author,year','citation_count','read_count','reference'], 'highlights': [], }) req = solr.create_request(**query_components) url = None if 'bigquery' in request.values: from adsabs.core.solr import bigquery bigquery.prepare_bigquery_request(req, request.values['bigquery']) url = config.SOLRBIGQUERY_URL req = solr.set_defaults(req, query_url=url) resp = solr.get_response(req) if resp.is_error(): return render_template('errors/generic_error.html', error_message='Error while creating the paper network (code #2). Please try later.') # prepare the info to send to the paper network machinery paper_info = [doc.__dict__['data'] for doc in resp.get_docset_objects() if doc.bibcode] statsd.incr("visualization.paper_network.viewed") return render_template('paper_network_embedded.html', network_data=get_papernetwork(paper_info))
def activate_new_email(): """ Activation of the new email address """ form_params_creation ={} if request.method == 'GET' and request.values.get('id'): #need to specify the value to initialize the form because it cannot find this value in request.form form_params_creation.update({'id': request.values.get('id')}) form = ActivateNewUsernameForm(**form_params_creation) if form.validate_on_submit(): success, message, message_type = activate_user_new_email(form) flash(message, message_type) if success: statsd.incr("user.activate_new_email.success") return redirect(generate_redirect_url(next_=url_for('user.index'))) else: statsd.incr("user.activate_new_email.failed") return render_template('activate_new_username.html', form=form)
def author_network(): """ View that creates the data for the author network """ #if there are not bibcodes, there should be a query to extract the authors try: query_components = json.loads(request.values.get('current_search_parameters')) except (TypeError, JSONDecodeError): #@todo: logging of the error return render_template('errors/generic_error.html', error_message='Error while creating the author network (code #1). Please try later.') # get the maximum number of records to use query_components['rows'] = request.values.get('numRecs', config.MAX_EXPORTS['authnetwork']) # checked bibcodes will be input as if request.values.has_key('bibcode'): bibcodes = request.values.getlist('bibcode') query_components['q'] = ' OR '.join(["bibcode:%s" % b for b in bibcodes]) #update the query parameters to return only what is necessary query_components.update({ 'facets': [], 'fields': ['author_norm'], 'highlights': [], }) req = solr.create_request(**query_components) if 'bigquery' in request.values: from adsabs.core.solr import bigquery bigquery.prepare_bigquery_request(req, request.values['bigquery']) req = solr.set_defaults(req) resp = solr.get_response(req) if resp.is_error(): return render_template('errors/generic_error.html', error_message='Error while creating the author network (code #2). Please try later.') #extract the authors lists_of_authors = [doc.author_norm for doc in resp.get_docset_objects() if doc.author_norm] statsd.incr("visualization.author_network.viewed") return render_template('author_network_embedded.html', network_data=get_authorsnetwork(lists_of_authors))
def send_feedback(form): """function that actually sends the email""" anonymous = current_user is None or current_user.is_anonymous() user_id = "%s%s" % (getattr(g, 'user_cookie_id'), anonymous and " (anonymous)" or "") template_ctx = { 'page_url': unquote_plus(form.page_url.data), 'user_id': user_id, 'feedback': form.feedback_text.data, # do a json round-trip to get pretty indenting 'environ': json.dumps(json.loads(form.environ.data), indent=True), } message_body = render_template('message_body.txt', **template_ctx) msg = Message(u"ADSABS2 feedback from %s <%s>: %s" % (form.name.data, form.email.data, form.feedback_type.data), body=message_body, sender=form.email.data, recipients=config.FEEDBACK_RECIPIENTS) mail.send(msg) statsd.incr("feedback.email.sent")
def api_user_required(func): @wraps(func) def decorator(*args, **kwargs): dev_key = request.args.get('dev_key', None) if not dev_key or len(dev_key) == 0: raise api_errors.ApiNotAuthenticatedError("no developer token provided") try: user = AdsApiUser.from_dev_key(dev_key) except Exception, e: import traceback exc_info = sys.exc_info() app.logger.error("User auth failure: %s, %s\n%s" % (exc_info[0], exc_info[1], traceback.format_exc())) statsd.incr("api.user.authentication.failed") user = None if not user: statsd.incr("api.user.authentication.unknown") raise api_errors.ApiNotAuthenticatedError("unknown dev_key: %s" % dev_key) statsd.incr("api.user.authentication.success") statsd.set("api.unique_users", dev_key) g.api_user = user return func(*args, **kwargs)
def alladin_lite(): """ View that creates the data for alladin lite """ #if there are not bibcodes, there should be a query to extract the authors if request.values.has_key('bibcode'): bibcodes = request.values.getlist('bibcode') else: try: query_components = json.loads(request.values.get('current_search_parameters')) except (TypeError, JSONDecodeError): #@todo: logging of the error return render_template('errors/generic_error.html', error_message='Error. Please try later.') # get the maximum number of records to use query_components['rows'] = request.values.get('numRecs', config.MAX_EXPORTS['skymap']) #update the query parameters to return only what is necessary query_components.update({ 'facets': [], 'fields': ['bibcode'], 'highlights': [], }) req = solr.create_request(**query_components) url = None if 'bigquery' in request.values: from adsabs.core.solr import bigquery bigquery.prepare_bigquery_request(req, request.values['bigquery']) url = config.SOLRBIGQUERY_URL req = solr.set_defaults(req, query_url=url) resp = solr.get_response(req) if resp.is_error(): return render_template('errors/generic_error.html', error_message='Error while creating the objects skymap. Please try later.') bibcodes = [x.bibcode for x in resp.get_docset_objects()] statsd.incr("visualization.alladin_lite.viewed") return render_template('alladin_lite_embedded.html', bibcodes={'bibcodes':bibcodes})
def signup(): """ User sign up form """ app.logger.debug('User signup') #if the user is logged in he needs to logout before signup as another user if current_user.is_authenticated(): flash('Please, logout before sign up as another user', 'warn') return redirect(generate_redirect_url()) form = SignupForm() if form.validate_on_submit(): if not login_exists(form.login.data): success, message, message_type = create_user(form) flash(message, message_type) if success: #save the login email in the session session['user_login_email'] = form.login.data statsd.incr("user.signup.success") return redirect(generate_redirect_url(next_=url_for('user.activate'))) else: statsd.incr("user.signup.failed") else: flash('An user with the same email address already exists in the system. <a href="%s">Log in</a>' % url_for('user.login'), 'error') statsd.incr("user.signup.duplicate") return render_template('signup.html', form=form)
def confirm_reset_password(): """ User password reset confirmation """ app.logger.debug('User password reset confirmation') #if everything looks fine, it's time to proceed form_params_creation ={'csrf_enabled':False} if request.method == 'GET': if request.values.get('login'): form_params_creation.update({'login': request.values.get('login')}) if request.values.get('resetcode'): form_params_creation.update({'resetcode': request.values.get('resetcode')}) form = ResetPasswordFormConf(**form_params_creation) if form.validate_on_submit(): success, message, message_type = reset_user_password_step_two(form) flash(message, message_type) if success: statsd.incr("user.password.confirm_reset.success") return redirect(generate_redirect_url(next_=url_for('user.login'))) else: statsd.incr("user.password.confirm_reset.failed") return render_template('reset_password_2.html', form=form)
def record(identifier): record_req = ApiRecordRequest(identifier, request.args) if not record_req.validate(): statsd.incr("api.record.invalid") raise api_errors.ApiInvalidRequest(record_req.errors()) resp = record_req.execute() if not resp.get_hits() > 0: statsd.incr("api.record.not_found") raise api_errors.ApiRecordNotFound(identifier) statsd.incr("api.record.success") return resp.record_response()
def record_metrics(identifier): record_req = ApiRecordRequest(identifier, request.args) if not record_req.validate(): statsd.incr("api.record_metrics.invalid") raise api_errors.ApiInvalidRequest(record_req.errors()) resp = record_req.execute() if not resp.get_hits() > 0: statsd.incr("api.record_metrics.not_found") raise api_errors.ApiRecordNotFound(identifier) statsd.incr("api.record_metrics.success") record = resp.record_response() metrics = generate_metrics(bibcodes=[record['bibcode']], fmt='API') return metrics
def search(): """ returns the results of a search """ if not len(request.values): form = QueryForm(csrf_enabled=False) # prefill the database select menu option form.db_f.default = config.SEARCH_DEFAULT_DATABASE else: form = QueryForm.init_with_defaults(request.values) if form.validate(): query_components = QueryBuilderSearch.build(form, request.values) bigquery_id = request.values.get('bigquery') try: req = solr.create_request(**query_components) url = None if bigquery_id: prepare_bigquery_request(req, request.values['bigquery']) url = config.SOLRBIGQUERY_URL req = solr.set_defaults(req, query_url=url) with statsd.timer("search.solr.query_response_time"): resp = solr.get_response(req) statsd.incr("search.solr.executed") if bigquery_id: facets = resp.get_facet_parameters() facets.append(('bigquery', bigquery_id)) except Exception, e: statsd.incr("search.solr.failed") raise AdsabsSolrqueryException("Error communicating with search service", sys.exc_info()) if resp.is_error(): statsd.incr("search.solr.error") flash(resp.get_error_message(), 'error') return render_template('search_results.html', resp=resp, form=form, query_components=query_components, bigquery_id=bigquery_id) else:
def f(error, template, status_code): from adsabs.extensions import statsd app.logger.error("[error] %s, %s" % (str(error), request.path)) statsd.incr("mongogut.error.%s.handled" % str(status_code)) return render_template(template), status_code
def settings(): perms = g.api_user.get_dev_perms() allowed_fields = g.api_user.get_allowed_fields() perms.update({'allowed_fields': allowed_fields}) statsd.incr("api.settings.success") return perms