diff --git a/sipa/blueprints/usersuite.py b/sipa/blueprints/usersuite.py
index 1c6cda44..182b4cde 100644
--- a/sipa/blueprints/usersuite.py
+++ b/sipa/blueprints/usersuite.py
@@ -3,6 +3,7 @@
from collections import OrderedDict
import logging
from datetime import datetime
+from io import BytesIO
from babel.numbers import format_currency
from flask import (
@@ -14,6 +15,7 @@
abort,
request,
current_app,
+ send_file,
)
from flask_babel import format_date, gettext
from flask_login import current_user, login_required
@@ -622,3 +624,32 @@ def reset_wifi_password():
return render_template('generic_form.html',
page_title=gettext("Neues WLAN Passwort"),
form_args=form_args)
+
+
+@bp_usersuite.route("/get-apple-wlan-mobileconfig", methods=["GET"])
+@login_required
+def get_apple_wlan_mobileconfig():
+ """
+ Get the mobileconfig for the agdsn WLAN for an Apple device.
+ """
+
+ login = current_user.login.raw_value
+ wifi_password = current_user.wifi_password.raw_value
+
+ if not wifi_password:
+ abort(404)
+
+ return send_file(
+ BytesIO(
+ bytes(
+ render_template(
+ "apple-mobileconfig.xml.j2",
+ login=login,
+ wifi_password=wifi_password,
+ ),
+ encoding="utf-8",
+ )
+ ),
+ as_attachment=True,
+ download_name="agdsn.mobileconfig",
+ )
diff --git a/sipa/static/js/usersuite_index.js b/sipa/static/js/usersuite_index.js
index d0d194fe..d448858d 100644
--- a/sipa/static/js/usersuite_index.js
+++ b/sipa/static/js/usersuite_index.js
@@ -11,3 +11,7 @@ tocbot.init({
positionFixedSelector: '#usersuite-sidebar-nav',
extraLinkClasses: 'text-decoration-none'
});
+
+// Enable popovers, see https://getbootstrap.com/docs/5.3/components/popovers/
+const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
+const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
diff --git a/sipa/templates/apple-mobileconfig.xml.j2 b/sipa/templates/apple-mobileconfig.xml.j2
new file mode 100644
index 00000000..308e27e1
--- /dev/null
+++ b/sipa/templates/apple-mobileconfig.xml.j2
@@ -0,0 +1,250 @@
+
+
+
+
+ PayloadContent
+
+
+ PayloadCertificateFileName
+ 485bce6d-706a-2c6e-f08e-0d8cfd51760d.der
+ PayloadContent
+
+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
+ PayloadDescription
+ Das Identitätsprovider CA Zertifikat
+ PayloadDisplayName
+ Identitätsprovider CA #1 (Wurzel)
+ PayloadIdentifier
+ org.1x-config.agdsn.de.ag_dsn.ag_dsn.credential.0
+ PayloadOrganization
+ agdsn.1x-config.org
+ PayloadType
+ com.apple.security.root
+ PayloadUUID
+ 485bce6d-706a-2c6e-f08e-0d8cfd51760d
+ PayloadVersion
+ 1
+
+
+ PayloadCertificateFileName
+ 226c10b6-f359-6eb7-282d-7a98772d17e8.der
+ PayloadContent
+
+MIIGiTCCBHGgAwIBAgIQAKlt3DnTbr8VpJk/0Ci0djANBgkqhkiG9w0BAQsFADBF
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
+d2lzc1NpZ24gR29sZCBDQSAtIEcyMB4XDTIxMDgwMzEzNDcxOVoXDTM2MTAyMzEz
+NDcxOVowUTELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkG
+A1UEAxMiU3dpc3NTaWduIFJTQSBUTFMgUm9vdCBDQSAyMDIxIC0gMTCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBALzhzfwsQT177CwJfd954sSdhnx9hFrZ
+pI7GEBHcuDroMf3wbD9LlPLb9/WqwwD4KMadimwny9JZabm5IBJXG5o21NI02bV7
+0LLYRsogKkynMMlhCFmjb/aBhHWv0mpQZ6xR1FjOLzWOpRjCbOm31AHH9oZvTjbG
+6F0ZnQHEOpTzlMIEUjI+VmHV8eIXgLw7TVrabOfk1mz9OuVgnYorrjSkz9JuBdp5
+iN+Y/iCi84v4hHBmaoArJP0EQM8bJXtpYyb5NPYonfbX6vHNBsyAkraXxQiuDr3w
+GbXrYC3filOyg1dXTDRmKmNzNiiy942fKsmJ+3vXMYLjMYb/tUZcPeUCFMzLh7dQ
+i4gsS24/Vy4JesGNy08JNzBrYnPZE42RYXm9nMbsPX8E0YyYx8b6xGsd4Rx3rMSz
+zV+IoJoJnPGIeOnZJKF3AxsLxnlnUzOgchb8kl03fY59SZwrXh/kdcxWH9WfO7d2
+NShu2gDdk2t6wSkmbuXWvuzDCpClHDOkj5IaSd+7IvNDY28CrAzVj6dPRBglxhlK
+qIjo3vAoj1XVIzwyM00X2GyDAbQ4GYYmFu6p8p2xKgLOmmTfuwAtddSCdMY9+Wt7
+dW+7BYOxph95De2Loi3W+c+PfFPj1lv5h9K4XbkvVPf/jjukRL/Nvg8inThYNY3g
+KVx8rig3jINtAgMBAAGjggFnMIIBYzAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
+BBSA84/Z/IJogVPB5IuXUB6p+cYctTAfBgNVHSMEGDAWgBRbJXuWpGVRfrg588B4
+Zl7oOufw7jAOBgNVHQ8BAf8EBAMCAQYwgf8GA1UdHwSB9zCB9DBHoEWgQ4ZBaHR0
+cDovL2NybC5zd2lzc3NpZ24ubmV0LzVCMjU3Qjk2QTQ2NTUxN0VCODM5RjNDMDc4
+NjY1RUU4M0FFN0YwRUUwgaiggaWggaKGgZ9sZGFwOi8vZGlyZWN0b3J5LnN3aXNz
+c2lnbi5uZXQvQ049NUIyNTdCOTZBNDY1NTE3RUI4MzlGM0MwNzg2NjVFRTgzQUU3
+RjBFRSUyQ089U3dpc3NTaWduJTJDQz1DSD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25M
+aXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwDQYJKoZI
+hvcNAQELBQADggIBAACe84DiHCZxPRIEZSRBIg2MzdYbmrMNPz9yiITWDxAGde85
+9NYhCDtTN1t1VVRG6PkSmMDOhZ/YFRZ49VYqTGmLpCQufSdGZZHGkTMRbrRge5Jr
+HLMbZr6Jufhad049iEJW2Iwn3ESR4vxQ4nsYcbpvL+CZXspcXGYclCzlpjHsG7YW
+biGWhMzT04fvOebO6JWDfRKWV8eEfpqIYaAMrfQBSqWK1Gi4zNFRo6g8jvDzIJch
+BS7DSBLBxTcUkm4qAvtGrTvPtBMP9nZ+Q04BOXds72pS16R87lbhHx3hvgevIFDY
+8iwdTl3o/9LfHc4zpaa8+lP/r08TBRXGhT614AhpFuzK+RHkaHKFPYjFA1Vd5DxU
+6os5l/clzDBSB3VRfci+cXD6KmnkCuEhFuOjrpilTMVjJss1FbkSzyXecyNtbYia
+k7aR3lXRjvqUPSN+JiRk/DvwrIb1VsqmlYmig0+UD6lrGGVlnxWq8A8krbOSIotf
+SZxO85QgNalf17zyHuY6btD5nDDEjeecU9CpCbp8YuoGd1/TML+zovEMwJj57uNO
+dwnuUojcDbtIw3t3PUb92ItVJj2Iljxi+E30rjgSjHzd74f2RzAvBF6zW8994Zzl
+BHN5upD76jjk1rDSBEl6PJOoZCDiyVw17mhw10E44oCy+CtMKDL4lHI9RsGa
+ PayloadDescription
+ Das Identitätsprovider CA Zertifikat
+ PayloadDisplayName
+ Identitätsprovider CA #2 (Zwischenstelle)
+ PayloadIdentifier
+ org.1x-config.agdsn.de.ag_dsn.ag_dsn.credential.1
+ PayloadOrganization
+ agdsn.1x-config.org
+ PayloadType
+ com.apple.security.root
+ PayloadUUID
+ 226c10b6-f359-6eb7-282d-7a98772d17e8
+ PayloadVersion
+ 1
+
+
+ PayloadCertificateFileName
+ fb9cb854-1ec3-8b65-4a9b-ff0d067aea7f.der
+ PayloadContent
+
+MIIHVzCCBT+gAwIBAgIQAN5Yhr4YCoH/Vnm/sJqnZzANBgkqhkiG9w0BAQsFADBR
+MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSswKQYDVQQDEyJT
+d2lzc1NpZ24gUlNBIFRMUyBSb290IENBIDIwMjEgLSAxMB4XDTIxMDgwMzE4Mzcz
+NFoXDTM2MDczMDE4MzczNFowUDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNz
+U2lnbiBBRzEqMCgGA1UEAxMhU3dpc3NTaWduIFJTQSBUTFMgRFYgSUNBIDIwMjEg
+LSAxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuS6VTH2Rj/ANrxtK
+BirJk5ZOhgK9rk/g+/voIDIQ1HpLISBC5Rc8W5HRDmk2kOmmV1qsrjSXFM4Y4t+K
+Gcgflg7fAw3V9OiKI5VjvC/Dg165rrfB0H5gr2VwKAQPP9cHiK/siOsj78gbOr88
++chCDk5A2fZbvstBZrK8zpNVObcsMbWZgDHRM1brVPf8U1/7zHRk3BVHtdsETbzk
++F/gHjs85DkIxPs7kdeJba7AtReFDiw4sL9uUrYRXKICZES/gU7BbRaBGXloykk9
+ntfZkJ3xwhj7lk2hePFxs81nAb3VwHyLhhWOEryb63iHZn27ut9SVkCFfWGOyGgJ
+op6K4HNDTFxqOSw2vpOMfzoZ/L8NlwJq/sRvxGBhhN430SkiA4sGukm55GZ2J6wM
+C4IzRv4MQTRTFgIU1mo09ZC2wWestw4CeIPykNVq0K70OoqWs8YmLhkDLlhXN7P+
+ACFfwu8Lu2Adlby9oVpmCFq//3icIspzsc3MTHizGB8/f80/NjKgQhvDnH+wWdW8
+/TDrV3swugtMxmxh1IMNJXEEEBGl9snLDX5PI5UK3toZevfzDnQeK1WXGbL8A7de
+5YCoA7ANMIPvSL0Zmvlxpy0xT9xKYfQFNKFzLzD8c2Dt28SDDbqM0txS9y58gsff
+Qwe6fmQr3pKENfGHzBHgWxUuIxsCAwEAAaOCAiowggImMA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB
+/wIBADAdBgNVHQ4EFgQUPJ5SeQNjb0+cgRvTKHAMJFrqpYcwHwYDVR0jBBgwFoAU
+gPOP2fyCaIFTweSLl1AeqfnGHLUwgf8GA1UdHwSB9zCB9DBHoEWgQ4ZBaHR0cDov
+L2NybC5zd2lzc3NpZ24ubmV0LzgwRjM4RkQ5RkM4MjY4ODE1M0MxRTQ4Qjk3NTAx
+RUE5RjlDNjFDQjUwgaiggaWggaKGgZ9sZGFwOi8vZGlyZWN0b3J5LnN3aXNzc2ln
+bi5uZXQvQ049ODBGMzhGRDlGQzgyNjg4MTUzQzFFNDhCOTc1MDFFQTlGOUM2MUNC
+NSUyQ089U3dpc3NTaWduJTJDQz1DSD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0
+P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwKQYDVR0gBCIw
+IDAKBghghXQBWQIBATAIBgZngQwBAgEwCAYGBACPegEGMHQGCCsGAQUFBwEBBGgw
+ZjBkBggrBgEFBQcwAoZYaHR0cDovL3N3aXNzc2lnbi5uZXQvY2dpLWJpbi9hdXRo
+b3JpdHkvZG93bmxvYWQvODBGMzhGRDlGQzgyNjg4MTUzQzFFNDhCOTc1MDFFQTlG
+OUM2MUNCNTANBgkqhkiG9w0BAQsFAAOCAgEAaw8l7Y1DquXDxSxTSnUc0YaC73V+
+uHw/ksizATpHy6R5PLZqhfRTd1L0MbSe8ixQ28h/++H1+OmV1MpKayS1U/8dmhQB
+qOic9bCytIbuTeYEXzwSWDz6ZG5BZJveHj+z/v0wZCDU7ciF1zZbMY3deKOcAk+N
+bD+LoAUxaMEarrkmAKRFRuYZPtKqcbRC3SQUVuem7sz/bpkIBJoaE/04G2Th/bNY
+kRdcuVk239EjXWFerCfjmY6WrHYT3Bo7D1VEiZJEJwpY/TR89CNtRsgkLkDBbLdH
+mXMpgxVfXcBPRfWrWYPdKTP5kuL3uBX6/UpnMs+GJWHUYoCU4NfDFFhAXglyjW0S
+nDFr8efbPQf6S8gjs+P0Cviwcg8gSq3APfOrACgRs6M+jscQo0+ru+Jx0ACnhm6x
+Xzl3Jq5Dbt9sAVrAlJRFYDD6Tm6ZfXPRFsSHUYtmEm8+wmJCNsrpQVkpwWEB8ATa
+2ZeRpcPd201t/bYWdV++EIIkSwQYrbbT4Vwu6m/jOga7/GS/VazYOu3fnLZ9XcAO
+bZ9uub9Xd8prtYO4DlEBxFHKAbBXlNLQEYYHrbF/OdqBCvVhtns0Dck2Q2Dr3bCU
+7dNSJ5mtqaoIiqnYpWJoqUhwOo/vJSbgFkzVGheRWo8yaUh7JfswYAkW5hPaShF0
+LMVpEb0hwOAW4Fg=
+ PayloadDescription
+ Das Identitätsprovider CA Zertifikat
+ PayloadDisplayName
+ Identitätsprovider CA #3 (Zwischenstelle)
+ PayloadIdentifier
+ org.1x-config.agdsn.de.ag_dsn.ag_dsn.credential.2
+ PayloadOrganization
+ agdsn.1x-config.org
+ PayloadType
+ com.apple.security.root
+ PayloadUUID
+ fb9cb854-1ec3-8b65-4a9b-ff0d067aea7f
+ PayloadVersion
+ 1
+
+
+ EAPClientConfiguration
+
+ AcceptEAPTypes
+
+ 21
+
+ UserName
+ {{ login }}
+ UserPassword
+ {{ wifi_password }}
+ EAPFASTProvisionPAC
+
+ EAPFASTUsePAC
+
+ EAPFastProvisionPACAnonymously
+
+ OneTimeUserPassword
+
+ OuterIdentity
+ wifi@agdsn.de
+ PayloadCertificateAnchorUUID
+
+ 485bce6d-706a-2c6e-f08e-0d8cfd51760d
+ 226c10b6-f359-6eb7-282d-7a98772d17e8
+ fb9cb854-1ec3-8b65-4a9b-ff0d067aea7f
+
+ TLSAllowTrustExceptions
+
+ TLSTrustedServerNames
+
+ radius.agdsn.de
+
+ TTLSInnerAuthentication
+ PAP
+
+ EncryptionType
+ WPA2
+ HIDDEN_NETWORK
+
+ PayloadDescription
+ Organisation Custom Network Konfiguration für das Netzwerk agdsn
+ PayloadDisplayName
+ Organisation Custom Network - SSID agdsn
+ PayloadIdentifier
+ org.1x-config.agdsn.de.ag_dsn.ag_dsn.de_DE.wifi.0
+ PayloadOrganization
+ agdsn.1x-config.org
+ PayloadType
+ com.apple.wifi.managed
+ ProxyType
+ Auto
+ ProxyPACFallbackAllowed
+
+ PayloadUUID
+ 8ee5540e-1d3c-f9ac-a662-8760e60a1e7e
+ PayloadVersion
+ 1
+ SSID_STR
+ agdsn
+
+
+ PayloadDescription
+ Netzwerkprofil 'AG DSN' von 'AG DSN' - bereitgestellt von AG DSN
+ PayloadDisplayName
+ AG DSN
+ PayloadIdentifier
+ org.1x-config.agdsn.de.ag_dsn.ag_dsn.de_DE
+ PayloadOrganization
+ AG DSN
+ PayloadType
+ Configuration
+ PayloadUUID
+ d483aa96-74cd-0219-b9ff-4709da705721
+ PayloadVersion
+ 1
+
+
diff --git a/sipa/templates/usersuite/_index_status.html b/sipa/templates/usersuite/_index_status.html
index fec98db8..092c87b6 100644
--- a/sipa/templates/usersuite/_index_status.html
+++ b/sipa/templates/usersuite/_index_status.html
@@ -48,6 +48,21 @@
{% endif %}
{% endif %}
+
+
+