Optimize onboarding for invitations #225

This commit is contained in:
Daniel Grams 2021-07-20 11:47:21 +02:00
parent daacce232a
commit db51854078
9 changed files with 57 additions and 15 deletions

View File

@ -18,7 +18,7 @@ app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"]
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SECURITY_CONFIRMABLE"] = True
app.config["SECURITY_POST_LOGIN_VIEW"] = "manage"
app.config["SECURITY_POST_LOGIN_VIEW"] = "manage_after_login"
app.config["SECURITY_TRACKABLE"] = True
app.config["SECURITY_REGISTERABLE"] = True
app.config["SECURITY_SEND_REGISTER_EMAIL"] = True

View File

@ -67,11 +67,17 @@ def find_admin_unit_member_invitation(email, admin_unit_id):
return AdminUnitMemberInvitation.query.filter(
and_(
AdminUnitMemberInvitation.admin_unit_id == admin_unit_id,
AdminUnitMemberInvitation.email == email,
func.lower(AdminUnitMemberInvitation.email) == func.lower(email),
)
).first()
def get_admin_unit_member_invitations(email):
return AdminUnitMemberInvitation.query.filter(
func.lower(AdminUnitMemberInvitation.email) == func.lower(email)
).all()
def insert_admin_unit_member_invitation(admin_unit_id, email, role_names):
invitation = AdminUnitMemberInvitation()
invitation.admin_unit_id = admin_unit_id

View File

@ -47,7 +47,7 @@ def upsert_user_role(role_name, role_title, permissions):
def find_user_by_email(email):
return user_datastore.find_user(email=email)
return user_datastore.find_user(email=email, case_insensitive=True)
def get_user(id):

View File

@ -4,7 +4,7 @@
{% block content %}
<h1>{{ _fsdomain('Login') }}</h1>
{% set next = request.args['next'] if 'next' in request.args and 'authorize' in request.args['next'] else 'manage' %}
{% set next = request.args['next'] if 'next' in request.args and 'authorize' in request.args['next'] else 'manage_after_login' %}
<form action="{{ url_for_security('login', next=next) }}" method="POST" name="login_user_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}

View File

@ -46,13 +46,15 @@ def admin_unit_member_invitation(id):
add_user_to_admin_unit_with_roles(
current_user, invitation.adminunit, roles
)
url = url_for("manage_admin_unit", id=invitation.admin_unit_id)
else:
message = gettext("Invitation successfully declined")
url = url_for("manage")
db.session.delete(invitation)
db.session.commit()
flash(message, "success")
return redirect(url_for("manage"))
return redirect(url)
except SQLAlchemyError as e:
db.session.rollback()
flash(handleSqlError(e), "danger")

View File

@ -22,6 +22,7 @@ from project.models import (
EventSuggestion,
User,
)
from project.services.admin_unit import get_admin_unit_member_invitations
from project.services.event import get_events_query
from project.services.event_search import EventSearchParams
from project.services.event_suggestion import get_event_reviews_query
@ -34,6 +35,12 @@ from project.views.utils import (
)
@app.route("/manage_after_login")
@auth_required()
def manage_after_login():
return redirect(url_for("manage", from_login=1))
@app.route("/manage")
@auth_required()
def manage():
@ -47,6 +54,18 @@ def manage():
except Exception:
pass
if "from_login" in request.args:
admin_units = get_admin_units_for_manage()
invitations = get_admin_unit_member_invitations(current_user.email)
if len(admin_units) == 1 and len(invitations) == 0:
return redirect(url_for("manage_admin_unit", id=admin_units[0].id))
if len(admin_units) == 0 and len(invitations) == 1:
return redirect(
url_for("admin_unit_member_invitation", id=invitations[0].id)
)
return redirect(url_for("manage_admin_units"))
@ -54,9 +73,7 @@ def manage():
@auth_required()
def manage_admin_units():
admin_units = get_admin_units_for_manage()
invitations = AdminUnitMemberInvitation.query.filter(
AdminUnitMemberInvitation.email == current_user.email
).all()
invitations = get_admin_unit_member_invitations(current_user.email)
admin_units.sort(key=lambda x: x.name)
invitations.sort(key=lambda x: x.adminunit.name)

View File

@ -2,16 +2,15 @@ from flask import render_template
from flask_security import auth_required, current_user
from project import app
from project.models import AdminUnitMember, AdminUnitMemberInvitation
from project.models import AdminUnitMember
from project.services.admin_unit import get_admin_unit_member_invitations
@app.route("/profile")
@auth_required()
def profile():
admin_unit_members = AdminUnitMember.query.filter_by(user_id=current_user.id).all()
invitations = AdminUnitMemberInvitation.query.filter(
AdminUnitMemberInvitation.email == current_user.email
).all()
invitations = get_admin_unit_member_invitations(current_user.email)
return render_template(
"profile.html", admin_unit_members=admin_unit_members, invitations=invitations

View File

@ -87,8 +87,7 @@ def test_read_accept(client, app, db, utils, seeder):
"accept": "Akzeptieren",
},
)
assert response.status_code == 302
assert response.headers["Location"] == "http://localhost/manage"
utils.assert_response_redirect(response, "manage_admin_unit", id=admin_unit_id)
with app.app_context():
from project.services.admin_unit import (
@ -128,7 +127,7 @@ def test_read_accept_WrongRole(client, app, db, utils, seeder):
"accept": "Akzeptieren",
},
)
utils.assert_response_redirect(response, "manage")
utils.assert_response_redirect(response, "manage_admin_unit", id=admin_unit_id)
def test_read_decline(client, app, db, utils, seeder):

View File

@ -24,6 +24,25 @@ def test_index_withInvalidCookie(client, seeder, utils):
utils.assert_response_redirect(response, "manage_admin_units")
def test_index_after_login(client, app, db, utils, seeder):
user_id = seeder.create_user()
admin_unit_id = seeder.create_admin_unit(user_id, "Meine Crew")
email = "new@member.de"
invitation_id = seeder.create_invitation(admin_unit_id, email)
seeder.create_user(email)
utils.login(email)
response = utils.get_endpoint("manage_after_login")
utils.assert_response_redirect(response, "manage", from_login=1)
response = utils.get_endpoint("manage", from_login=1)
utils.assert_response_redirect(
response, "admin_unit_member_invitation", id=invitation_id
)
def test_admin_unit(client, seeder, utils):
user_id, admin_unit_id = seeder.setup_base()