diff --git a/doc/contributing/getting_started.rst b/doc/contributing/getting_started.rst index 07019b0c9..165e38e3f 100644 --- a/doc/contributing/getting_started.rst +++ b/doc/contributing/getting_started.rst @@ -18,7 +18,7 @@ Then, just run the following command:: Then if not done already, run this command to create an OIDC application in order to be able to log in from the frontend:: - $ docker exec modoboa-api '/bin/sh -c python3 /code/test_project/manage.py createapplication --name frontend --algorithm RS256 --redirect-uris 'http://localhost:3000/login/logged' public authorization_grant_type authorization-code' + $ docker exec modoboa-api '/bin/sh -c python3 /code/test_project/python manage.py createapplication --name frontend --client-id "LVQbfIIX3khWR3nDvix1u9yEGHZUxcx53bhJ7FlD" --user 1 --algorithm RS256 --redirect-uris 'https://localhost:3000/login/logged' public authorization-code' It will start the docker environment and make a Modoboa instance available at ``http://localhost:8000`` and the new admin interface at ``http://localhost:8080`` diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 29d455c46..cd965d33d 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -13,8 +13,9 @@ RUN python3 -m venv $VIRTUAL_ENV WORKDIR /tmp COPY requirements.txt /tmp COPY test-requirements.txt /tmp +COPY dev-requirements.txt /tmp RUN python -m pip install -U pip -RUN pip install -r requirements.txt -r test-requirements.txt +RUN pip install -r requirements.txt -r test-requirements.txt -r dev-requirements.txt FROM base as run COPY docker/doveadm /usr/local/bin RUN chmod +x /usr/local/bin/doveadm diff --git a/frontend/src/api/auth.js b/frontend/src/api/auth.js index d5257bf0a..f4bda9fe1 100644 --- a/frontend/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -18,5 +18,8 @@ export default { }, endFidoRegistration(data) { return repository.post('/fido/registration/end/', data) - } + }, + getAllFidoRegistred() { + return repository.get('/fido/') + }, } diff --git a/frontend/src/components/account/FidoAuthForm.vue b/frontend/src/components/account/FidoAuthForm.vue index 3a786d62c..72be0cefa 100644 --- a/frontend/src/components/account/FidoAuthForm.vue +++ b/frontend/src/components/account/FidoAuthForm.vue @@ -66,6 +66,9 @@ async function startFidoRegistration() { onMounted(() => { registrationLoading.value = true + authApi.getAllFidoRegistred().then((resp) => { + console.log(resp) + }) authApi.beginFidoRegistration().then((resp) => { creationOption.value = createRequestFromJSON(resp.data) }).finally(() => registrationLoading.value = false) diff --git a/modoboa/core/api/v2/serializers.py b/modoboa/core/api/v2/serializers.py index d037c0c67..e56baa02f 100644 --- a/modoboa/core/api/v2/serializers.py +++ b/modoboa/core/api/v2/serializers.py @@ -241,7 +241,7 @@ class CoreGlobalParametersSerializer(serializers.Serializer): class FIDOSerializer(serializers.ModelSerializer): class Meta: model = models.UserFidoKeys - fields = ["id", "name", "enabled", "added_on", "last_used"] + fields = ["id", "name", "enabled", "added_on", "last_used", "use_count"] class FidoRegistrationSerializer(serializers.Serializer): diff --git a/modoboa/core/api/v2/viewsets.py b/modoboa/core/api/v2/viewsets.py index a86173453..8efe905a1 100644 --- a/modoboa/core/api/v2/viewsets.py +++ b/modoboa/core/api/v2/viewsets.py @@ -195,6 +195,10 @@ class FIDOViewSet(GetThrottleViewsetMixin, serializer = serializers.FidoRegistrationSerializer( data=request.data) serializer.is_valid(raise_exception=True) - f2_auth.end_registration(request.data, + credential_data = f2_auth.end_registration(request.data, request.session.pop("fido2_state"), request.user.id) + models.UserFidoKeys.objects.create(name=request.data["name"], + credential_data=credential_data, + user=request.user) + return response.Response({"success": True}, 200) diff --git a/modoboa/core/fido2_auth.py b/modoboa/core/fido2_auth.py index 536f63eb9..a1012edc3 100644 --- a/modoboa/core/fido2_auth.py +++ b/modoboa/core/fido2_auth.py @@ -3,7 +3,7 @@ from .models import UserFidoKeys from fido2.webauthn import PublicKeyCredentialRpEntity, PublicKeyCredentialUserEntity, AttestedCredentialData, UserVerificationRequirement from fido2.server import Fido2Server -from fido2.utils import websafe_decode +from fido2.utils import websafe_decode, websafe_encode import fido2.features @@ -20,7 +20,7 @@ def create_fido2_server(): def get_creds_from_user(user_id): - [AttestedCredentialData(websafe_decode(uf.token)) for uf in UserFidoKeys.objects.filter(user=user_id)] + return [AttestedCredentialData(websafe_decode(uf.credential_data)) for uf in UserFidoKeys.objects.filter(user=user_id)] def begin_registration(request): @@ -47,4 +47,4 @@ def end_registration(data, fido2_state, user_id): fido2_state, data ) - print(auth_data) + return websafe_encode(auth_data.credential_data) diff --git a/modoboa/core/migrations/0028_userfidokeys.py b/modoboa/core/migrations/0028_userfidokeys.py index 6f16f657c..2ee9150c0 100644 --- a/modoboa/core/migrations/0028_userfidokeys.py +++ b/modoboa/core/migrations/0028_userfidokeys.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.11 on 2024-04-18 15:18 +# Generated by Django 4.2.11 on 2024-05-02 16:58 from django.conf import settings from django.db import migrations, models @@ -8,22 +8,35 @@ import django.db.models.deletion class Migration(migrations.Migration): dependencies = [ - ('core', '0027_alter_user_language'), + ("core", "0027_alter_user_language"), ] operations = [ migrations.CreateModel( - name='UserFidoKeys', + name="UserFidoKeys", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('enabled', models.BooleanField(default=True)), - ('platform', models.CharField(default='', max_length=255)), - ('added_on', models.DateTimeField(auto_now_add=True)), - ('last_used', models.DateTimeField(default=None, null=True)), - ('credential_id', models.CharField(max_length=255, unique=True)), - ('token', models.CharField(max_length=255)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("enabled", models.BooleanField(default=True)), + ("added_on", models.DateTimeField(auto_now_add=True)), + ("last_used", models.DateTimeField(default=None, null=True)), + ("use_count", models.IntegerField(default=0)), + ("credential_data", models.TextField()), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), ], ), ] diff --git a/modoboa/core/models.py b/modoboa/core/models.py index 44a4c0753..3d9376da6 100644 --- a/modoboa/core/models.py +++ b/modoboa/core/models.py @@ -417,8 +417,9 @@ class UserFidoKeys(models.Model): name = models.CharField(max_length=255) enabled = models.BooleanField(default=True) added_on = models.DateTimeField(auto_now_add=True) - last_used = models.DateTimeField(null=True,default=None) - credential_data = models.CharField(max_length=4096) + last_used = models.DateTimeField(null=True, default=None) + use_count = models.IntegerField(default=0) + credential_data = models.TextField() def populate_callback(user, group="SimpleUsers"):