forked from Github-Mirrors/canaille
refactor: gather endpoints in a 'endpoints' directory
This commit is contained in:
parent
0ff76823d5
commit
a4a381d088
22 changed files with 143 additions and 143 deletions
|
@ -64,16 +64,16 @@ def setup_jinja(app):
|
|||
|
||||
|
||||
def setup_blueprints(app):
|
||||
import canaille.core.blueprints
|
||||
import canaille.core.endpoints
|
||||
|
||||
app.url_map.strict_slashes = False
|
||||
|
||||
app.register_blueprint(canaille.core.blueprints.bp)
|
||||
app.register_blueprint(canaille.core.endpoints.bp)
|
||||
|
||||
if "OIDC" in app.config:
|
||||
import canaille.oidc.blueprints
|
||||
import canaille.oidc.endpoints
|
||||
|
||||
app.register_blueprint(canaille.oidc.blueprints.bp)
|
||||
app.register_blueprint(canaille.oidc.endpoints.bp)
|
||||
|
||||
|
||||
def setup_flask(app):
|
||||
|
|
|
@ -5,7 +5,7 @@ from . import admin
|
|||
from . import auth
|
||||
from . import groups
|
||||
|
||||
bp = Blueprint("core", __name__, template_folder="templates")
|
||||
bp = Blueprint("core", __name__, template_folder="../templates")
|
||||
|
||||
bp.register_blueprint(account.bp)
|
||||
bp.register_blueprint(admin.bp)
|
|
@ -42,16 +42,16 @@ from flask import url_for
|
|||
from werkzeug.datastructures import CombinedMultiDict
|
||||
from werkzeug.datastructures import FileStorage
|
||||
|
||||
from ..mails import send_confirmation_email
|
||||
from ..mails import send_invitation_mail
|
||||
from ..mails import send_password_initialization_mail
|
||||
from ..mails import send_password_reset_mail
|
||||
from ..mails import send_registration_mail
|
||||
from .forms import build_profile_form
|
||||
from .forms import EmailConfirmationForm
|
||||
from .forms import InvitationForm
|
||||
from .forms import JoinForm
|
||||
from .forms import MINIMUM_PASSWORD_LENGTH
|
||||
from .mails import send_confirmation_email
|
||||
from .mails import send_invitation_mail
|
||||
from .mails import send_password_initialization_mail
|
||||
from .mails import send_password_reset_mail
|
||||
from .mails import send_registration_mail
|
||||
|
||||
|
||||
bp = Blueprint("account", __name__)
|
|
@ -16,13 +16,13 @@ from flask import request
|
|||
from flask import session
|
||||
from flask import url_for
|
||||
|
||||
from ..mails import send_password_initialization_mail
|
||||
from ..mails import send_password_reset_mail
|
||||
from .forms import FirstLoginForm
|
||||
from .forms import ForgottenPasswordForm
|
||||
from .forms import LoginForm
|
||||
from .forms import PasswordForm
|
||||
from .forms import PasswordResetForm
|
||||
from .mails import send_password_initialization_mail
|
||||
from .mails import send_password_reset_mail
|
||||
|
||||
bp = Blueprint("auth", __name__)
|
||||
|
|
@ -3,15 +3,15 @@ from flask import Blueprint
|
|||
from . import authorizations
|
||||
from . import clients
|
||||
from . import consents
|
||||
from . import endpoints
|
||||
from . import oauth
|
||||
from . import tokens
|
||||
from . import well_known
|
||||
|
||||
bp = Blueprint("oidc", __name__, template_folder="templates")
|
||||
bp = Blueprint("oidc", __name__, template_folder="../templates")
|
||||
|
||||
bp.register_blueprint(authorizations.bp)
|
||||
bp.register_blueprint(clients.bp)
|
||||
bp.register_blueprint(consents.bp)
|
||||
bp.register_blueprint(endpoints.bp)
|
||||
bp.register_blueprint(oauth.bp)
|
||||
bp.register_blueprint(well_known.bp)
|
||||
bp.register_blueprint(tokens.bp)
|
|
@ -6,7 +6,6 @@ from canaille.app.flask import render_htmx_template
|
|||
from canaille.app.forms import TableForm
|
||||
from canaille.app.i18n import gettext as _
|
||||
from canaille.app.themes import render_template
|
||||
from canaille.oidc.forms import ClientAddForm
|
||||
from flask import abort
|
||||
from flask import Blueprint
|
||||
from flask import flash
|
||||
|
@ -15,6 +14,8 @@ from flask import request
|
|||
from flask import url_for
|
||||
from werkzeug.security import gen_salt
|
||||
|
||||
from .forms import ClientAddForm
|
||||
|
||||
|
||||
bp = Blueprint("clients", __name__, url_prefix="/admin/client")
|
||||
|
|
@ -10,7 +10,7 @@ from flask import flash
|
|||
from flask import redirect
|
||||
from flask import url_for
|
||||
|
||||
from .utils import SCOPE_DETAILS
|
||||
from ..utils import SCOPE_DETAILS
|
||||
|
||||
|
||||
bp = Blueprint("consents", __name__, url_prefix="/consent")
|
|
@ -23,18 +23,18 @@ from flask import session
|
|||
from flask import url_for
|
||||
from werkzeug.datastructures import CombinedMultiDict
|
||||
|
||||
from ..oauth import authorization
|
||||
from ..oauth import ClientConfigurationEndpoint
|
||||
from ..oauth import ClientRegistrationEndpoint
|
||||
from ..oauth import generate_user_info
|
||||
from ..oauth import get_issuer
|
||||
from ..oauth import get_jwks
|
||||
from ..oauth import IntrospectionEndpoint
|
||||
from ..oauth import require_oauth
|
||||
from ..oauth import RevocationEndpoint
|
||||
from ..utils import SCOPE_DETAILS
|
||||
from .forms import AuthorizeForm
|
||||
from .forms import LogoutForm
|
||||
from .oauth import authorization
|
||||
from .oauth import ClientConfigurationEndpoint
|
||||
from .oauth import ClientRegistrationEndpoint
|
||||
from .oauth import generate_user_info
|
||||
from .oauth import get_issuer
|
||||
from .oauth import get_jwks
|
||||
from .oauth import IntrospectionEndpoint
|
||||
from .oauth import require_oauth
|
||||
from .oauth import RevocationEndpoint
|
||||
from .utils import SCOPE_DETAILS
|
||||
from .well_known import openid_configuration
|
||||
|
||||
|
|
@ -6,12 +6,13 @@ from canaille.app.flask import render_htmx_template
|
|||
from canaille.app.forms import TableForm
|
||||
from canaille.app.i18n import gettext as _
|
||||
from canaille.app.themes import render_template
|
||||
from canaille.oidc.forms import TokenRevokationForm
|
||||
from flask import abort
|
||||
from flask import Blueprint
|
||||
from flask import flash
|
||||
from flask import request
|
||||
|
||||
from .forms import TokenRevokationForm
|
||||
|
||||
bp = Blueprint("tokens", __name__, url_prefix="/admin/token")
|
||||
|
||||
|
34
canaille/oidc/endpoints/well_known.py
Normal file
34
canaille/oidc/endpoints/well_known.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from flask import Blueprint
|
||||
from flask import jsonify
|
||||
from flask import request
|
||||
|
||||
from ..oauth import oauth_authorization_server
|
||||
from ..oauth import openid_configuration
|
||||
|
||||
|
||||
bp = Blueprint("home", __name__, url_prefix="/.well-known")
|
||||
|
||||
|
||||
@bp.route("/oauth-authorization-server")
|
||||
def oauth_authorization_server_endpoint():
|
||||
return jsonify(oauth_authorization_server())
|
||||
|
||||
|
||||
@bp.route("/openid-configuration")
|
||||
def openid_configuration_endpoint():
|
||||
return jsonify(openid_configuration())
|
||||
|
||||
|
||||
@bp.route("/webfinger")
|
||||
def webfinger():
|
||||
return jsonify(
|
||||
{
|
||||
"links": [
|
||||
{
|
||||
"href": openid_configuration()["issuer"],
|
||||
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||
}
|
||||
],
|
||||
"subject": request.args["resource"],
|
||||
}
|
||||
)
|
|
@ -29,7 +29,9 @@ from authlib.oidc.core.grants import OpenIDImplicitGrant as _OpenIDImplicitGrant
|
|||
from authlib.oidc.core.grants.util import generate_id_token
|
||||
from canaille.app import models
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
from flask import request
|
||||
from flask import url_for
|
||||
from werkzeug.security import gen_salt
|
||||
|
||||
|
||||
|
@ -52,6 +54,77 @@ DEFAULT_JWT_MAPPING = {
|
|||
}
|
||||
|
||||
|
||||
def oauth_authorization_server():
|
||||
return {
|
||||
"issuer": get_issuer(),
|
||||
"authorization_endpoint": url_for("oidc.endpoints.authorize", _external=True),
|
||||
"token_endpoint": url_for("oidc.endpoints.issue_token", _external=True),
|
||||
"token_endpoint_auth_methods_supported": [
|
||||
"client_secret_basic",
|
||||
"private_key_jwt",
|
||||
"client_secret_post",
|
||||
"none",
|
||||
],
|
||||
"token_endpoint_auth_signing_alg_values_supported": ["RS256", "ES256"],
|
||||
"userinfo_endpoint": url_for("oidc.endpoints.userinfo", _external=True),
|
||||
"introspection_endpoint": url_for(
|
||||
"oidc.endpoints.introspect_token", _external=True
|
||||
),
|
||||
"jwks_uri": url_for("oidc.endpoints.jwks", _external=True),
|
||||
"registration_endpoint": url_for(
|
||||
"oidc.endpoints.client_registration", _external=True
|
||||
),
|
||||
"scopes_supported": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"address",
|
||||
"phone",
|
||||
"groups",
|
||||
],
|
||||
"response_types_supported": [
|
||||
"code",
|
||||
"token",
|
||||
"id_token",
|
||||
"code token",
|
||||
"code id_token",
|
||||
"token id_token",
|
||||
],
|
||||
"ui_locales_supported": g.available_language_codes,
|
||||
"code_challenge_methods_supported": ["plain", "S256"],
|
||||
}
|
||||
|
||||
|
||||
def openid_configuration():
|
||||
return {
|
||||
**oauth_authorization_server(),
|
||||
"end_session_endpoint": url_for("oidc.endpoints.end_session", _external=True),
|
||||
"claims_supported": [
|
||||
"sub",
|
||||
"iss",
|
||||
"auth_time",
|
||||
"acr",
|
||||
"name",
|
||||
"given_name",
|
||||
"family_name",
|
||||
"nickname",
|
||||
"profile",
|
||||
"picture",
|
||||
"website",
|
||||
"email",
|
||||
"email_verified",
|
||||
"locale",
|
||||
"zoneinfo",
|
||||
"groups",
|
||||
"nonce",
|
||||
],
|
||||
"subject_types_supported": ["pairwise", "public"],
|
||||
"id_token_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
|
||||
"prompt_values_supported": ["none"]
|
||||
+ (["create"] if current_app.config.get("ENABLE_REGISTRATION") else []),
|
||||
}
|
||||
|
||||
|
||||
def exists_nonce(nonce, req):
|
||||
client = models.Client.get(id=req.client_id)
|
||||
exists = models.AuthorizationCode.query(client=client, nonce=nonce)
|
||||
|
@ -366,8 +439,6 @@ class ClientManagementMixin:
|
|||
return True
|
||||
|
||||
def get_server_metadata(self):
|
||||
from .well_known import openid_configuration
|
||||
|
||||
result = openid_configuration()
|
||||
return result
|
||||
|
||||
|
|
|
@ -1,107 +0,0 @@
|
|||
from flask import Blueprint
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
from flask import jsonify
|
||||
from flask import request
|
||||
from flask import url_for
|
||||
|
||||
from .oauth import get_issuer
|
||||
|
||||
|
||||
bp = Blueprint("home", __name__, url_prefix="/.well-known")
|
||||
|
||||
|
||||
def oauth_authorization_server():
|
||||
return {
|
||||
"issuer": get_issuer(),
|
||||
"authorization_endpoint": url_for("oidc.endpoints.authorize", _external=True),
|
||||
"token_endpoint": url_for("oidc.endpoints.issue_token", _external=True),
|
||||
"token_endpoint_auth_methods_supported": [
|
||||
"client_secret_basic",
|
||||
"private_key_jwt",
|
||||
"client_secret_post",
|
||||
"none",
|
||||
],
|
||||
"token_endpoint_auth_signing_alg_values_supported": ["RS256", "ES256"],
|
||||
"userinfo_endpoint": url_for("oidc.endpoints.userinfo", _external=True),
|
||||
"introspection_endpoint": url_for(
|
||||
"oidc.endpoints.introspect_token", _external=True
|
||||
),
|
||||
"jwks_uri": url_for("oidc.endpoints.jwks", _external=True),
|
||||
"registration_endpoint": url_for(
|
||||
"oidc.endpoints.client_registration", _external=True
|
||||
),
|
||||
"scopes_supported": [
|
||||
"openid",
|
||||
"profile",
|
||||
"email",
|
||||
"address",
|
||||
"phone",
|
||||
"groups",
|
||||
],
|
||||
"response_types_supported": [
|
||||
"code",
|
||||
"token",
|
||||
"id_token",
|
||||
"code token",
|
||||
"code id_token",
|
||||
"token id_token",
|
||||
],
|
||||
"ui_locales_supported": g.available_language_codes,
|
||||
"code_challenge_methods_supported": ["plain", "S256"],
|
||||
}
|
||||
|
||||
|
||||
def openid_configuration():
|
||||
return {
|
||||
**oauth_authorization_server(),
|
||||
"end_session_endpoint": url_for("oidc.endpoints.end_session", _external=True),
|
||||
"claims_supported": [
|
||||
"sub",
|
||||
"iss",
|
||||
"auth_time",
|
||||
"acr",
|
||||
"name",
|
||||
"given_name",
|
||||
"family_name",
|
||||
"nickname",
|
||||
"profile",
|
||||
"picture",
|
||||
"website",
|
||||
"email",
|
||||
"email_verified",
|
||||
"locale",
|
||||
"zoneinfo",
|
||||
"groups",
|
||||
"nonce",
|
||||
],
|
||||
"subject_types_supported": ["pairwise", "public"],
|
||||
"id_token_signing_alg_values_supported": ["RS256", "ES256", "HS256"],
|
||||
"prompt_values_supported": ["none"]
|
||||
+ (["create"] if current_app.config.get("ENABLE_REGISTRATION") else []),
|
||||
}
|
||||
|
||||
|
||||
@bp.route("/oauth-authorization-server")
|
||||
def oauth_authorization_server_endpoint():
|
||||
return jsonify(oauth_authorization_server())
|
||||
|
||||
|
||||
@bp.route("/openid-configuration")
|
||||
def openid_configuration_endpoint():
|
||||
return jsonify(openid_configuration())
|
||||
|
||||
|
||||
@bp.route("/webfinger")
|
||||
def webfinger():
|
||||
return jsonify(
|
||||
{
|
||||
"links": [
|
||||
{
|
||||
"href": openid_configuration()["issuer"],
|
||||
"rel": "http://openid.net/specs/connect/1.0/issuer",
|
||||
}
|
||||
],
|
||||
"subject": request.args["resource"],
|
||||
}
|
||||
)
|
|
@ -2,8 +2,8 @@ import datetime
|
|||
from unittest import mock
|
||||
|
||||
import freezegun
|
||||
from canaille.core.account import EmailConfirmationPayload
|
||||
from canaille.core.account import RegistrationPayload
|
||||
from canaille.core.endpoints.account import EmailConfirmationPayload
|
||||
from canaille.core.endpoints.account import RegistrationPayload
|
||||
from flask import url_for
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import datetime
|
||||
|
||||
from canaille.app import models
|
||||
from canaille.core.account import RegistrationPayload
|
||||
from canaille.core.endpoints.account import RegistrationPayload
|
||||
from flask import g
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from canaille.core.account import build_hash
|
||||
from canaille.core.endpoints.account import build_hash
|
||||
|
||||
|
||||
def test_password_reset(testclient, user):
|
||||
|
|
|
@ -2,7 +2,7 @@ from unittest import mock
|
|||
|
||||
import freezegun
|
||||
from canaille.app import models
|
||||
from canaille.core.account import RegistrationPayload
|
||||
from canaille.core.endpoints.account import RegistrationPayload
|
||||
from flask import url_for
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from urllib.parse import parse_qs
|
|||
from urllib.parse import urlsplit
|
||||
|
||||
from canaille.app import models
|
||||
from canaille.core.account import RegistrationPayload
|
||||
from canaille.core.endpoints.account import RegistrationPayload
|
||||
from flask import url_for
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue