diff --git a/hiboo/application/__init__.py b/hiboo/application/__init__.py index 8343071bfb5329dc4f1c03f9866b295f22794f2c..c6916ebc302df3b9c6ff171ba45b91123fe47be3 100644 --- a/hiboo/application/__init__.py +++ b/hiboo/application/__init__.py @@ -9,4 +9,4 @@ from hiboo.application import base register = base.BaseApplication.register registry = base.BaseApplication.registry -from hiboo.application import sso, social, storage \ No newline at end of file +from hiboo.application import sso, infrastructure, social, storage \ No newline at end of file diff --git a/hiboo/application/infrastructure.py b/hiboo/application/infrastructure.py new file mode 100644 index 0000000000000000000000000000000000000000..4d138e63e90f6d80eaaae1078895d206de804dbb --- /dev/null +++ b/hiboo/application/infrastructure.py @@ -0,0 +1,65 @@ +from hiboo.application import register, base +from wtforms import validators, fields +from flask_babel import lazy_gettext as _ + + +@register("gitlab") +class GitlabApplication(base.OIDCApplication): + """ Gitlab is a source code and project management plaform, largely based on Git + """ + + name = _("Gitlab") + + class Form(base.BaseForm): + application_uri = fields.StringField(_("Gitlab URL"), [validators.URL(require_tld=False)]) + submit = fields.SubmitField(_('Submit')) + + def populate_service(self, form, service): + service.profile_regex = "[a-z0-9_.\-]*" + callback_uri = form.application_uri.data + "/users/auth/openid_connect/callback" + service.config.update({ + "application_uri": form.application_uri.data, + "token_endpoint_auth_method": "client_secret_post", + "redirect_uris": [callback_uri], + "grant_types": ["authorization_code"], + "response_types": ["code"], + "special_mappings": ["mask_sub_uuid"] + }) + self.fill_service(service) + + def populate_form(self, service, form): + form.process( + obj=service, + application_uri=service.config.get("application_uri") + ) + + +@register("grafana") +class GrafanaApplication(base.OIDCApplication): + """ Grafana is an infrastructure dashboard application + """ + + name = _("Grafana") + + class Form(base.BaseForm): + application_uri = fields.StringField(_("Grafana URL"), [validators.URL(require_tld=False)]) + submit = fields.SubmitField(_('Submit')) + + def populate_service(self, form, service): + service.profile_regex = "[a-z0-9_.\-]*" + callback_uri = form.application_uri.data + "/login/generic_oauth" + service.config.update({ + "application_uri": form.application_uri.data, + "token_endpoint_auth_method": "client_secret_post", + "redirect_uris": [callback_uri], + "grant_types": ["authorization_code"], + "response_types": ["code"], + "special_mappings": [] + }) + self.fill_service(service) + + def populate_form(self, service, form): + form.process( + obj=service, + application_uri=service.config.get("application_uri") + ) diff --git a/hiboo/application/social.py b/hiboo/application/social.py index c023e433b2b9ff0155cdd2d0654b58723a58b790..e99ad0e460ea920c9b8bc16ba6dce562aa02f487 100644 --- a/hiboo/application/social.py +++ b/hiboo/application/social.py @@ -5,10 +5,10 @@ from flask_babel import lazy_gettext as _ @register("mastodon") class MastodonApplication(base.SAMLApplication): - """ Mastodon social network is an ActivityPub micro-blogging platform + """ Mastodon social network is a popular micro-blogging platform compliant with ActivityPub """ - name = _("Mastodon social network") + name = _("Mastodon") class Form(base.BaseForm): application_uri = fields.StringField(_("Mastodon URL"), [validators.URL(require_tld=False)]) @@ -30,3 +30,31 @@ class MastodonApplication(base.SAMLApplication): obj=service, application_uri=service.config.get("application_uri") ) + + +@register("synapse") +class SynapseApplication(base.SAMLApplication): + """ Synapse is the flagship implmentation of Matrix, a federated, end-to-end-encrypted messaging protocol + """ + + name = _("Synapse") + + class Form(base.BaseForm): + application_uri = fields.StringField(_("Synapse homeserver URL"), [validators.URL(require_tld=False)]) + submit = fields.SubmitField(_('Submit')) + + def populate_service(self, form, service): + service.profile_regex = "[a-zA-Z0-9_\-./=]+" + service.config.update({ + "application_uri": form.application_uri.data, + "acs": form.application_uri.data + "/saml2/authn_response", + "entityid": form.application_uri.data + "/saml2/metadata.xml", + "sign_mode": "response" + }) + self.fill_service(service) + + def populate_form(self, service, form): + form.process( + obj=service, + application_uri=service.config.get("application_uri") + ) diff --git a/hiboo/application/storage.py b/hiboo/application/storage.py index 12e025fcc08e53f0e8dae98823666ea68925e810..ae85e5ae365cd733007555a0467dafb2d431aa68 100644 --- a/hiboo/application/storage.py +++ b/hiboo/application/storage.py @@ -3,27 +3,24 @@ from wtforms import validators, fields from flask_babel import lazy_gettext as _ -@register("gitlab") -class GitlabApplication(base.OIDCApplication): - """ Gitlab is a source code and project management plaform, largely based on Git +@register("nextcloud") +class SeafileApplication(base.SAMLApplication): + """ NextCloud is a free alternative to many cloud vendors (storage, contacts, meetings, etc.) """ - name = _("Gitlab repository manager") + name = _("NextCloud") class Form(base.BaseForm): - application_uri = fields.StringField(_("Gitlab URL"), [validators.URL(require_tld=False)]) + application_uri = fields.StringField(_("NextCloud URL"), [validators.URL(require_tld=False)]) submit = fields.SubmitField(_('Submit')) def populate_service(self, form, service): service.profile_regex = "[a-z0-9_.\-]*" - callback_uri = form.application_uri.data + "/users/auth/openid_connect/callback" service.config.update({ "application_uri": form.application_uri.data, - "token_endpoint_auth_method": "client_secret_post", - "redirect_uris": [callback_uri], - "grant_types": ["authorization_code"], - "response_types": ["code"], - "special_mappings": ["mask_sub_uuid"] + "acs": form.application_uri.data + "/apps/user_saml/saml/acs", + "entityid": form.application_uri.data + "/apps/user_saml/saml/metadata", + "sign_mode": "response" }) self.fill_service(service) @@ -36,7 +33,7 @@ class GitlabApplication(base.OIDCApplication): @register("seafile") class SeafileApplication(base.OIDCApplication): - """ Seafile is a file sharing and synchronization application with a Web viewer + """ Seafile is a file sharing and synchronization application with an embedded Web viewer """ name = _("Seafile") diff --git a/hiboo/application/templates/application_grafana.html b/hiboo/application/templates/application_grafana.html new file mode 100644 index 0000000000000000000000000000000000000000..b15396f7b9893d3762bee506eefa3bd3ae539534 --- /dev/null +++ b/hiboo/application/templates/application_grafana.html @@ -0,0 +1,30 @@ +<h3>Setting up Grafana</h3> +<p>Grafna supports Oauth2 authentication through Omniauth, which is compatible with OIDC.</p> +<p>If you are running Grafana directly, you may add the following lines to your configuration.</p> +<pre> +[server] +root_url = {{ service.config["application_uri"] }} + +[auth.generic_oauth] +enabled = true +allow_sign_up = true +client_id = {{ service.config["client_id"] }} +client_secret = {{ service.config["client_secret"] }} +scopes = openid profile email +auth_url = {{ url_for("sso.oidc_authorize", service_uuid=service.uuid, _external=True) }} +token_url = {{ url_for("sso.oidc_token", service_uuid=service.uuid, _external=True) }} +</pre> + +<p>If you are running the Grafana Docker image, please set the following environment variables.</p> +<pre> +GF_SERVER_ROOT_URL={{ service.config["application_uri"] }} +GF_AUTH_GENERIC_OAUTH_ENABLED=True +GF_AUTH_GENERIC_OAUTH_ALLOW_SIGN_UP=True +GF_AUTH_GENERIC_OAUTH_CLIENT_ID={{ service.config["client_id"] }} +GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET={{ service.config["client_secret"] }} +GF_AUTH_GENERIC_OAUTH_SCOPES=openid profile email +GF_AUTH_GENERIC_OAUTH_AUTH_URL={{ url_for("sso.oidc_authorize", service_uuid=service.uuid, _external=True) }} +GF_AUTH_GENERIC_OAUTH_TOKEN_URL={{ url_for("sso.oidc_token", service_uuid=service.uuid, _external=True) }} +</pre> + +{% include "application_oidc.html" %} \ No newline at end of file diff --git a/hiboo/application/templates/application_nextcloud.html b/hiboo/application/templates/application_nextcloud.html new file mode 100644 index 0000000000000000000000000000000000000000..7373dafa7b4e1d6c93b01ec63e6fc57bf02f8891 --- /dev/null +++ b/hiboo/application/templates/application_nextcloud.html @@ -0,0 +1,29 @@ +<h3>Setting up NextCloud</h3> +<p>NextCloud uses the <a href="https://apps.nextcloud.com/apps/user_saml">user_saml</a> extension in order to handle SAML2 authentication.</p> +<p>You must first install this extension on your instance, then go to your <i>Settings</i> menu and fill in the following parameters.</p> + +<dt>Attribute to map the uid to</dt> +<dd><pre>urn:oid:0.9.2342.19200300.100.1.1</pre></dd> + +<dt>Name id format</dt> +<dd><pre>Persistent</pre></dd> + +<dt>X.509 certificat of the Service Provider</dt> +<dd><pre>{{ "".join(service.config["sp_cert"].strip().split("\n")[1:-1]) }}</pre></dd> + +<dt>Private Key of the Service Provider</dt> +<dd><pre>{{ "".join(service.config["sp_key"].strip().split("\n")[1:-1]) }}</pre></dd> + +<dt>Identifier of the IDP entity</dt> +<dd><pre>{{ url_for("sso.saml_metadata", service_uuid=service.uuid, _external=True) }}</pre></dd> + +<dt>URL target of the IDP where the SP will send the Authentication Request Message</dt> +<dd><pre>{{ url_for("sso.saml_redirect", service_uuid=service.uuid, _external=True) }}</pre></dd> + +<dt>URL location of the IDP where the SP will send the SLO request</dt> +<dd><pre>{{ service.config["application_uri"] }}</pre></dd> + +<dt>Public X.509 certificat of the IDP</dt> +<dd><pre>{{ "".join(service.config["idp_cert"].strip().split("\n")[1:-1]) }}</pre></dd> + +{% include "application_saml.html" %} \ No newline at end of file diff --git a/hiboo/application/templates/application_synapse.html b/hiboo/application/templates/application_synapse.html new file mode 100644 index 0000000000000000000000000000000000000000..03344f422e5ea9708e3c970999009aa9df03b338 --- /dev/null +++ b/hiboo/application/templates/application_synapse.html @@ -0,0 +1,15 @@ +<h3>Setting up Synapse</h3> +<p>Synapse relies on the pysaml2 SAML implementation for SAML2 authentication.</p> +<p>In order to configure SAML for Synapse, you may copy then paste the following lines directly into your homeserver configuration file.</p> +<pre> +saml2_config: + enabled: true + sp_config: + metadata: + remote: + - url: {{ url_for("sso.saml_metadata", service_uuid=service.uuid, _external=True) }} +</pre> + +<p>You should also disable password authentication if you wish to avoid desynchronization and username conflicts.</p> + +{% include "application_saml.html" %} \ No newline at end of file