Skip to content

Commit

Permalink
Merge branch 'issue-168-signup-redirections' into 'main'
Browse files Browse the repository at this point in the history
user login redirections

Closes #168

See merge request yaal/canaille!151
  • Loading branch information
azmeuk committed Sep 1, 2023
2 parents 8be771e + a7b3d4b commit 602da81
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 120 deletions.
11 changes: 9 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@ All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog <https://keepachangelog.com/en/1.0.0/>`_,
and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0.html>`_.

Fixed
Added
*****

- OIDC jwks endpoint do not return empty kid claim
- If users register or authenticate during a OAuth Authorization
phase, they get redirected back to that page afterwards.
:issue:`168` :pr:`151`

[0.0.33] - 2023-08-26
=====================

Fixed
*****

- OIDC jwks endpoint do not return empty kid claim

Added
*****

Expand Down
8 changes: 7 additions & 1 deletion canaille/core/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from flask import redirect
from flask import request
from flask import send_file
from flask import session
from flask import url_for
from flask_babel import gettext as _
from flask_babel import refresh
Expand Down Expand Up @@ -339,7 +340,12 @@ def registration(data=None, hash=None):
user = profile_create(current_app, form)
login_user(user)
flash(_("Your account has been created successfully."), "success")
return redirect(url_for("core.account.profile_edition", edited_user=user))
return redirect(
session.pop(
"redirect-after-login",
url_for("core.account.profile_edition", edited_user=user),
)
)


@bp.route("/email-confirmation/<data>/<hash>")
Expand Down
7 changes: 5 additions & 2 deletions canaille/core/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def password():
_("Connection successful. Welcome %(user)s", user=user.formatted_name[0]),
"success",
)
return redirect(url_for("core.account.index"))
return redirect(session.pop("redirect-after-login", url_for("core.account.index")))


@bp.route("/logout")
Expand Down Expand Up @@ -214,6 +214,9 @@ def reset(user, hash):
login_user(user)

flash(_("Your password has been updated successfully"), "success")
return redirect(url_for("core.account.profile_edition", edited_user=user))
return session.pop(
"redirect-after-login",
url_for("core.account.profile_edition", edited_user=user),
)

return render_template("reset-password.html", form=form, user=user, hash=hash)
4 changes: 0 additions & 4 deletions canaille/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ class PasswordForm(Form):
)


class FullLoginForm(LoginForm, PasswordForm):
pass


class ForgottenPasswordForm(Form):
login = wtforms.StringField(
_("Login"),
Expand Down
4 changes: 0 additions & 4 deletions canaille/core/templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ <h2 class="ui center aligned header">
{% call fui.render_form(form) %}
{% block login_field scoped %}{{ login_field.render_field(form.login, class="autofocus") }}{% endblock %}

{% if "password" in form %}
{% block password_field scoped %}{{ login_field.render_field(form.password) }}{% endblock %}
{% endif %}

<div class="ui right aligned container">
<div class="ui stackable buttons">
{% if has_registration %}
Expand Down
30 changes: 4 additions & 26 deletions canaille/oidc/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
from canaille import csrf
from canaille.app import models
from canaille.app.flask import current_user
from canaille.app.flask import login_user
from canaille.app.flask import logout_user
from canaille.app.flask import set_parameter_in_url_query
from canaille.app.themes import render_template
from canaille.core.forms import FullLoginForm
from flask import abort
from flask import Blueprint
from flask import current_app
Expand Down Expand Up @@ -69,26 +67,8 @@ def authorize():
if request.args.get("prompt") == "none":
return jsonify({"error": "login_required"})

form = FullLoginForm(request.form or None)
if request.method == "GET":
return render_template("login.html", form=form, menu=False)

user = models.User.get_from_login(form.login.data)
if not form.validate() or not user:
flash(_("Login failed, please check your information"), "error")
return render_template("login.html", form=form, menu=False)

success, message = user.check_password(form.password.data)
if not success:
flash(
_(message or "Login failed, please check your information"),
"error",
)
return render_template("login.html", form=form, menu=False)

login_user(user)

return redirect(request.url)
session["redirect-after-login"] = request.url
return redirect(url_for("core.auth.login"))

if not user.can_use_oidc:
abort(400)
Expand Down Expand Up @@ -133,11 +113,9 @@ def authorize():
form=form,
)

# request.method == "POST"
if request.form["answer"] == "logout":
del session["user_id"]
flash(_("You have been successfully logged out."), "success")
return redirect(request.url)
session["redirect-after-login"] = request.url
return redirect(url_for("core.auth.logout"))

if request.form["answer"] == "deny":
grant_user = None
Expand Down
46 changes: 0 additions & 46 deletions canaille/oidc/templates/login.html

This file was deleted.

9 changes: 0 additions & 9 deletions canaille/oidc/templates/partial/login_field.html

This file was deleted.

39 changes: 26 additions & 13 deletions tests/oidc/test_authorization_code_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,16 +234,20 @@ def test_logout_login(testclient, logged_user, client):
status=200,
)

res = res.form.submit(name="answer", value="logout", status=302)
res = res.form.submit(name="answer", value="logout")
res = res.follow()
g.user = None
res = res.follow(status=200)
res = res.follow()
res = res.follow()

res.form["login"] = logged_user.user_name[0]
res = res.form.submit()
res = res.follow()

res.form["password"] = "wrong password"
res = res.form.submit(status=200)
assert ("error", "Login failed, please check your information") in res.flashes

res.form["login"] = logged_user.user_name[0]
res.form["password"] = "correct horse battery staple"
res = res.form.submit(status=302)
res = res.follow(status=200)
Expand Down Expand Up @@ -322,14 +326,16 @@ def test_refresh_token(testclient, user, client):
scope="openid profile",
nonce="somenonce",
),
status=200,
)
res = res.follow()

res.form["login"] = "user"
res = res.form.submit(name="answer", value="accept")
res = res.follow()
res.form["password"] = "correct horse battery staple"
res = res.form.submit(name="answer", value="accept", status=302)
res = res.form.submit(name="answer", value="accept")
res = res.follow()
res = res.form.submit(name="answer", value="accept", status=302)
res = res.form.submit(name="answer", value="accept")

assert res.location.startswith(client.redirect_uris[0])
params = parse_qs(urlsplit(res.location).query)
Expand Down Expand Up @@ -591,11 +597,12 @@ def test_authorization_code_flow_but_user_cannot_use_oidc(
scope="openid profile",
nonce="somenonce",
),
status=200,
)
res = res.follow()

res.form["login"] = "user"
res = res.form.submit(status=200)
res = res.form.submit()
res = res.follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(status=302)
Expand Down Expand Up @@ -784,9 +791,12 @@ def test_authorization_code_expired(testclient, user, client):
scope="openid profile email groups address phone",
nonce="somenonce",
),
status=200,
)
res = res.follow()

res.form["login"] = "user"
res = res.form.submit(name="answer", value="accept").follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(name="answer", value="accept").follow()
res = res.form.submit(name="answer", value="accept", status=302)
Expand Down Expand Up @@ -829,9 +839,11 @@ def test_code_with_invalid_user(testclient, admin, client):
scope="openid profile email groups address phone",
nonce="somenonce",
),
status=200,
)
).follow()

res.form["login"] = "temp"
res = res.form.submit(name="answer", value="accept", status=302).follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(name="answer", value="accept", status=302).follow()
res = res.form.submit(name="answer", value="accept", status=302)
Expand Down Expand Up @@ -877,10 +889,11 @@ def test_refresh_token_with_invalid_user(testclient, client):
scope="openid profile",
nonce="somenonce",
),
status=200,
)
).follow()

res.form["login"] = "temp"
res = res.form.submit(name="answer", value="accept", status=302).follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(name="answer", value="accept", status=302).follow()
res = res.form.submit(name="answer", value="accept", status=302)
Expand Down
8 changes: 4 additions & 4 deletions tests/oidc/test_hybrid_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ def test_oauth_hybrid(testclient, backend, user, client):
scope="openid profile",
nonce="somenonce",
),
status=200,
)
).follow()
assert "text/html" == res.content_type, res.json

res.form["login"] = user.user_name[0]
res = res.form.submit(status=302).follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(status=302)
res = res.form.submit(status=302).follow()

res = res.follow(status=200)
assert "text/html" == res.content_type, res.json

res = res.form.submit(name="answer", value="accept", status=302)
Expand Down
21 changes: 12 additions & 9 deletions tests/oidc/test_implicit_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ def test_oauth_implicit(testclient, user, client):
scope="profile",
nonce="somenonce",
),
)
).follow()
assert "text/html" == res.content_type

res.form["login"] = "user"
res = res.form.submit(status=302).follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(status=302)
res = res.form.submit(status=302).follow()

res = res.follow()
assert "text/html" == res.content_type, res.json

res = res.form.submit(name="answer", value="accept", status=302)
Expand Down Expand Up @@ -63,14 +64,15 @@ def test_oidc_implicit(testclient, keypair, user, client, other_client):
scope="openid profile",
nonce="somenonce",
),
)
).follow()
assert "text/html" == res.content_type

res.form["login"] = "user"
res = res.form.submit(status=302).follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(status=302)
res = res.form.submit(status=302).follow()

res = res.follow(status=200)
assert "text/html" == res.content_type, res.json

res = res.form.submit(name="answer", value="accept", status=302)
Expand Down Expand Up @@ -117,14 +119,15 @@ def test_oidc_implicit_with_group(
scope="openid profile groups",
nonce="somenonce",
),
)
).follow()
assert "text/html" == res.content_type

res.form["login"] = "user"
res = res.form.submit(status=302).follow()

res.form["password"] = "correct horse battery staple"
res = res.form.submit(status=302)
res = res.form.submit(status=302).follow()

res = res.follow(status=200)
assert "text/html" == res.content_type, res.json

res = res.form.submit(name="answer", value="accept", status=302)
Expand Down

0 comments on commit 602da81

Please sign in to comment.