def login(): """ Prompt for username/email and password and sign the user in.""" user_manager = current_app.user_manager db_adapter = user_manager.db_adapter data = request.form 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)) # Immediately redirect already logged in users if _call_or_get(current_user.is_authenticated) and user_manager.auto_login_at_login: return redirect(next) user = None user_email = None # user = user_manager.find_user_by_username(data.get('user_name')) user = db_query(User).filter(or_(User.email == data.get('user_name'), User.username == data.get('user_name'))).first() if not user: return ajax_response(message="Ви ввели невірний логін або пароль") else: if user.password: if not verify_password(user_manager, data.get('password'), user.password): user = None return ajax_response(message="Ви ввели невірний логін або пароль") else: return ajax_response(message="Ви ввели невірний логін або пароль") user_email = None session['login_via'] = request.host remember_me = True if data.get('remember_me') else False if user and db_adapter.UserEmailClass: user_email = db_adapter.find_first_object(db_adapter.UserEmailClass, user_id=int(user.get_id()), is_primary=True, ) if not user and user_manager.enable_email: user, user_email = user_manager.find_user_by_email(data.get('user_name')) if user: _do_login_user(user, request.referrer, remember_me=remember_me) return ajax_response(message="Ви були успішно залоговані", reload_page = True)
def forgot_password(): ''' Display forgot_password form and initiate a password reset. This overrides flask_user's default register() view. This is only accessible when a user goes through the register URL. When an admin manually initiates a reset-password request for a user, that goes through our api.py (and hits send_reset_password directly) instead of going through flask_user's view ''' user_manager = current_app.user_manager # Initialize form form = user_manager.forgot_password_form(request.form) # Process valid POST (when 'Send reset password email' is actually clicked) if request.method == 'POST' and form.validate(): email = form.email.data reset_success = True try: send_reset_password(email) except ItemNotFound: reset_success = False except BadGateway: reset_success = False # Prepare one-time system message. if reset_success: flash(RESET_PASSWORD_SUCCESS_TEMPLATE % email, 'success') else: flash('Could not reset password with this email', 'error') # Redirect to the login page return redirect( _endpoint_url(user_manager.after_forgot_password_endpoint)) template_renderer = current_app.template_renderer # Process GET or invalid POST (e.g. invalid email) template_params = {'form': form} return template_renderer.js_render_helper( user_manager.forgot_password_template, locale='en', js_params=_build_base_js_params(template_renderer), pass_to_template=template_params, lightweight_js_only=True, )
def login(): ''' Prompt for username/email and password and sign the user in.''' user_manager = current_app.user_manager next_endpoint = request.args.get( 'next', _endpoint_url(user_manager.after_login_endpoint)) # Check for session timeout param in query params session_timeout = True if request.args.get('timeout') else False # Immediately redirect already logged in users if current_user.is_authenticated: return redirect(next_endpoint) # Initialize form login_form = user_manager.login_form(request.form) if request.method != 'POST': # GET request: login form is being loaded login_form.next.data = next_endpoint if session_timeout: flash('Your session timed out. Log in to continue.') # Process valid POST (i.e. when they submit the Login form) if request.method == 'POST' and login_form.validate(): # Find user record by username user = user_manager.find_user_by_username(login_form.username.data) if user: # Log user in return _do_login_user(user, login_form.next.data, login_form.remember_me.data) # Process GET or invalid POST login_form.remember_me.label.text = 'Keep me signed in' template_params = { 'form': login_form, 'login_form': login_form, 'session_timeout': session_timeout, } template_renderer = current_app.template_renderer return template_renderer.js_render_helper( user_manager.login_template, locale='en', js_params=_build_base_js_params(template_renderer), pass_to_template=template_params, lightweight_js_only=True, )
def unauthenticated(): """ Prepare a Flash message and redirect to USER_UNAUTHENTICATED_ENDPOINT""" user_manager = current_app.user_manager # Prepare Flash message # Do not flash an error message for default pages as users already know they need # to log in. url = request.url if not (request.path == '/' or request.path == get_configuration(DEFAULT_URL_KEY)): flash(gettext("You must be signed in to access '%(url)s'.", url=url), 'error') # Redirect to USER_UNAUTHENTICATED_ENDPOINT safe_next = user_manager.make_safe_url_function(url) return redirect( _endpoint_url(user_manager.unauthenticated_endpoint) + '?next=' + quote(safe_next))
def patch_forgot_password(): """Need to customize flash message shown in forgot_password No hooks available to customize the message, so this function is intended to be a drop in replacement with only the text of the message altered, as per TN-1030 """ """Prompt for email and send reset password email.""" user_manager = current_app.user_manager # Initialize form form = user_manager.forgot_password_form(request.form) # Process valid POST if request.method == 'POST' and form.validate(): email = form.email.data user, user_email = user_manager.find_user_by_email(email) if user: with force_locale(user.locale_code): user_manager.send_reset_password_email(email) # Prepare one-time system message flash( _( "If the email address '%(email)s' is in the system, a " "reset password email will now have been sent to it. " "Please 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 user_manager.render_function(user_manager.forgot_password_template, form=form)
def patch_forgot_password(): """Need to customize flash message shown in forgot_password No hooks available to customize the message, so this function is intended to be a drop in replacement with only the text of the message altered, as per TN-1030 """ """Prompt for email and send reset password email.""" user_manager = current_app.user_manager # Initialize form form = user_manager.forgot_password_form(request.form) # Process valid POST if request.method == 'POST' and form.validate(): email = form.email.data user, user_email = user_manager.find_user_by_email(email) if user: with force_locale(user.locale_code): user_manager.send_reset_password_email(email) # Prepare one-time system message flash(_("If the email address '%(email)s' is in the system, a " "reset password email will now have been sent to it. " "Please 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 user_manager.render_function( user_manager.forgot_password_template, form=form)
def invite(): """ Display invite 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)) login_form = user_manager.login_form() register_form = user_manager.register_form(request.form) 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 # Process valid POST if request.method=='POST' and register_form.validate(): User = db_adapter.UserClass user_class_fields = User.__dict__ user_fields = {} if db_adapter.UserEmailClass: UserEmail = db_adapter.UserEmailClass user_email_class_fields = UserEmail.__dict__ user_email_fields = {} 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(): # Store corresponding Form fields into the User object and/or # UserProfile object 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 # Generates temporary password password = generate_password(9) if db_adapter.UserAuthClass: user_auth_fields['password'] = password else: user_fields['password'] = password g.temp_password = password # Add User record using named arguments 'user_fields' user = db_adapter.add_object(User, **user_fields) 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 db_adapter.commit() # Send 'invite' email and delete new User object if send fails if user_manager.send_registered_email: try: # Send 'invite' email _send_registered_email(user, user_email) except Exception as e: # delete new User object if send fails db_adapter.delete_object(user) db_adapter.commit() raise e # Send user_registered signal signals.user_registered.send(current_app._get_current_object(), user=user) # Redirect if USER_ENABLE_CONFIRM_EMAIL is set if user_manager.enable_confirm_email: 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)
def register(): """ Display registration form and create new User.""" user_manager = current_app.user_manager db_adapter = user_manager.db_adapter # info = Info(username=request.form.get('username'), email=request.form.get('email'), # password=request.form.get('password')) # info.save() # 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)) # 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 request.method == 'POST': # 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 data = request.form # For all form fields print(request.args) user_fields['registered_via'] = 'api-tvprogram.rhcloud.com' for field_name, field_value in data.items(): # Hash password field if field_name == 'password': if len(field_value) < 7: return ajax_response(message='Пароль повинен містити не менше семи символів') 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) 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 == data.get('email'): require_email_confirmation = False db_adapter.update_object(user, confirmed_at=datetime.datetime.utcnow()) try: db_adapter.commit() except IntegrityError as e: if e.message.find('email') != -1: return ajax_response(message='Така електронна адреса вже зареєстрована на нашому сайті') elif e.message.find('username') != -1: return ajax_response(message='Юзер з таким ніком вже зареєстрований на нашому сайті.' 'Виберіть інший нік') # Send 'registered' email and delete new User object if send fails if user_manager.send_registered_email: try: # Send 'registered' email _send_registered_email(user, user_email, require_email_confirmation) except Exception as e: # delete new User object if send fails db_adapter.delete_object(user) db_adapter.commit() raise # Send user_registered signal signals.user_registered.send(current_app._get_current_object(), user=user, user_invite=user_invite) # 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 ajax_response(message='На вашу електронну адресу був відправленний лист з підтвердженням реєстрації.' 'Перейдіть на вашу поштову скриньку, щоб завершити реєстрацію на нашому ' 'сайті.<h5><a href="{mail_url}" target="_blank">Перейти</a></h5>"Якщо лист не прийшов ' 'перейдіть за <a href="{resend_email}">цим</a> посиланням і ми ' 'відправимо лист ще раз'.format( mail_url='http://'+data.get('email').split('@')[-1]+'/mail', resend_email=url_for('user.resend_confirm_email')), alert='На вашу електронну адресу був відправленний лист з підтвердженням реєстрації.' 'Перейдіть на вашу поштову скриньку, щоб завершити реєстрацію на нашому сайті.') # 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 ajax_response(message='На вашу електронну адресу був відправленний лист з підтвердженням реєстрації.' 'Перейдіть на вашу поштову скриньку, щоб завершити реєстрацію на нашому ' 'сайті.<h5><a href="{mail_url}">Перейти</a></h5>"Якщо лист не прийшов ' 'перейдіть за <a href="{resend_email}" target="_blank">цим</a> посиланням і ми ' 'відправимо лист ще раз'.format( mail_url='http://'+data.get('email').split('@')[-1]+'/mail', resend_email=url_for('user.resend_confirm_email')), alert='На вашу електронну адресу був відправленний лист з підтвердженням реєстрації.' 'Перейдіть на вашу поштову скриньку, щоб завершити реєстрацію на нашому сайті') # Process GET or invalid POST return redirect(request.referrer)
def register(): ''' Display registration form and create new User ''' with Transaction() as transaction: user_manager = current_app.user_manager # Initialize form register_form = user_manager.register_form(request.form) # invite token used to determine validity of registeree invite_token = request.values.get('token') # if there is no token, disallow the user from registering if not invite_token: flash('Registration is invite only', 'error') return redirect(url_for('user.login')) # if the token does not correspond to any user, do not allow registration pending_user = transaction.find_one_by_fields( User, True, {'reset_password_token': invite_token}) if pending_user: register_form.invite_token.data = invite_token else: flash('Invalid invitation link', 'error') return redirect(url_for('user.login')) next_endpoint = 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)) if request.method != 'POST': # GET request: register form is being loaded register_form.next.data = next_endpoint register_form.reg_next.data = reg_next # pre-fill username form data register_form.username.data = pending_user.username # Process valid POST (i.e. when they submit the Register form) if request.method == 'POST' and register_form.validate(): # Enable user account pending_user.status_id = UserStatusEnum.ACTIVE.value # For all form fields for field_name, field_value in list(register_form.data.items()): if field_name == 'password': # Hash password field hashed_password = user_manager.hash_password(field_value) pending_user.password = hashed_password elif field_name == 'username' and field_value != pending_user.username: flash('Registered email does not match the invited email', 'error') return redirect(url_for('user.register')) else: setattr(pending_user, field_name, field_value) # Add User record using named arguments 'user_fields' transaction.add_or_update(pending_user) # Send user_registered signal user_registered.send(current_app._get_current_object(), user=pending_user) # Redirect to login page return redirect(url_for('user.login') + '?next=' + reg_next) template_renderer = current_app.template_renderer # Process GET or invalid POST template_params = {'form': register_form} return template_renderer.js_render_helper( user_manager.register_template, locale='en', js_params=_build_base_js_params(template_renderer), pass_to_template=template_params, lightweight_js_only=True, )