def account(): """ The current user account main page. """ fix_csrf_session() user_social_auth = get_user_social_auth(current_user.id) context = {} if user_social_auth: context['token'] = user_social_auth.extra_data['access_token'] context['token_age_in_seconds'] = int( time.time()) - user_social_auth.extra_data['auth_time'], return render_template('user/account.html', **context)
def logout(user_social_auth=None): """ Log a user out. Param `user_social_auth`: a `UserSocialAuth` instance. `None` most of the time, except when a user is coming from the `user.account_delete` view. This param is intended to be passed when the view is called directly as a Python function, i.e. not with a `redirect()`. """ if not current_user.is_authenticated: return redirect(url_for('root.home')) logged_with_peam = session.get( 'social_auth_last_login_backend') == PEAMOpenIdConnect.name if logged_with_peam: if not user_social_auth: user_social_auth = get_user_social_auth(current_user.id) if user_social_auth: id_token = user_social_auth.extra_data['id_token'] # Force delete PEAMU token. db_session.query(UserSocialAuth).filter_by(user_id=current_user.id).delete() db_session.commit() # Log the user out and destroy the LBB session. activity.log('deconnexion') logout_user() # Clean the session: drop Python Social Auth info because it isn't done by `logout_user`. if 'social_auth_last_login_backend' in session: # Some backends have a `backend-name_state` stored in session as required by e.g. Oauth2. social_auth_state_key = '%s_state' % session['social_auth_last_login_backend'] if social_auth_state_key in session: session.pop(social_auth_state_key) session.pop('social_auth_last_login_backend') # Log the user out from PEAM and destroy the PEAM session. if logged_with_peam and user_social_auth: params = { 'id_token_hint': id_token, 'redirect_uri': url_for('auth.logout_from_peam_callback', _external=True), } peam_logout_url = '%s/compte/deconnexion?%s' % ( settings.PEAM_AUTH_BASE_URL, urlencode(params)) # After this redirect, the user will be redirected to the LBB website `logout_from_peam_callback` route. return redirect(peam_logout_url) return redirect(url_for('root.home'))
def test_get_user_social_auth(self): """ Test the `get_user_social_auth()` function. """ user = User(email='*****@*****.**', gender='male', first_name='John', last_name='Doe') db_session.add(user) db_session.flush() expected_user_social_auth = UserSocialAuth(provider=PEAMOpenIdConnect.name, extra_data=None, user_id=user.id) db_session.add(expected_user_social_auth) db_session.flush() db_session.commit() self.assertEqual(db_session.query(User).count(), 1) self.assertEqual(db_session.query(UserSocialAuth).count(), 1) user_social_auth = get_user_social_auth(user.id) self.assertEqual(user_social_auth.id, expected_user_social_auth.id)
def account_delete(): """ Ask for a confirmation, then delete the current user account and all of its information. """ form = UserAccountDeleteForm(request.form) if request.method == 'POST' and form.validate(): # Store the current `UserSocialAuth` instance in memory because it will be deleted # but it will also be needed later to properly logout the user from PEAM. user_social_auth = get_user_social_auth(current_user.id) # Now we can safely delete the current `UserSocialAuth` instance. # We have to delete it because it has a foreign key to the User table. # We don't need to deal with the other tables of Social Auth, see: # https://python-social-auth.readthedocs.io/en/latest/storage.html db_session.query(UserSocialAuth).filter_by( user_id=current_user.id).delete() # Delete the current user. # The user's favorites will be deleted at the same time because of the `ondelete='CASCADE'` # on the `user_id` field of the `UserFavoriteOffice` model. db_session.query(User).filter_by(id=current_user.id).delete() db_session.commit() message = "La suppression de votre compte a bien été effectuée." flash(message, 'warning') # Return the `logout` view directly. It allows us to pass the full # `user_social_auth` object as a parameter. return logout(user_social_auth=user_social_auth) context = { 'form': form, } return render_template('user/account_delete.html', **context)