diff --git a/modoboa/sievefilters/api/v2/serializers.py b/modoboa/sievefilters/api/v2/serializers.py index e7c6b32f2..a8ab5a0a1 100644 --- a/modoboa/sievefilters/api/v2/serializers.py +++ b/modoboa/sievefilters/api/v2/serializers.py @@ -5,12 +5,9 @@ from typing import List, Tuple from sievelib import commands from sievelib.factory import Filter -from django.utils.translation import gettext as _ - from rest_framework import serializers from modoboa.sievefilters import constants, lib -from modoboa.sievefilters.forms import supported_auth_mechs from modoboa.sievefilters.api.v2 import vloaders @@ -22,19 +19,12 @@ class SievefiltersSettingsSerializer(serializers.Serializer): server = serializers.CharField(default="127.0.0.1") port = serializers.IntegerField(default=4190) starttls = serializers.BooleanField(default=False) - authentication_mech = serializers.ChoiceField( - default="auto", choices=[("auto", _("auto"))] - ) # Imap Settings imap_server = serializers.CharField(default="127.0.0.1") imap_secured = serializers.BooleanField(default=False) imap_port = serializers.IntegerField(default=143) - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields["authentication_mech"].choices = supported_auth_mechs() - class FilterSetSerializer(serializers.Serializer): name = serializers.CharField() diff --git a/modoboa/sievefilters/api/v2/tests.py b/modoboa/sievefilters/api/v2/tests.py index b72e4c798..18b7a781c 100644 --- a/modoboa/sievefilters/api/v2/tests.py +++ b/modoboa/sievefilters/api/v2/tests.py @@ -1,19 +1,22 @@ """API v2 tests.""" from unittest import mock +from datetime import timezone, timedelta from django.urls import reverse -from rest_framework.authtoken.models import Token +from oauth2_provider.models import get_access_token_model, get_application_model from modoboa.admin import factories as admin_factories from modoboa.core import models as core_models from modoboa.lib.tests import ModoAPITestCase from modoboa.sievefilters import mocks +Application = get_application_model() +AccessToken = get_access_token_model() + class FilterSetViewSetTestCase(ModoAPITestCase): - @classmethod def setUpTestData(cls): """Create some users.""" @@ -21,6 +24,22 @@ class FilterSetViewSetTestCase(ModoAPITestCase): admin_factories.populate_database() cls.user = core_models.User.objects.get(username="user@test.com") + cls.application = Application.objects.create( + name="Test Application", + redirect_uris="http://localhost", + user=cls.user, + client_type=Application.CLIENT_PUBLIC, + authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE, + ) + + cls.access_token = AccessToken.objects.create( + user=cls.test_user, + scope="read write", + expires=timezone.now() + timedelta(seconds=300), + token="secret-access-token-key", + application=cls.application, + ) + def setUp(self): """Connect with a simpler user.""" super().setUp() @@ -35,11 +54,7 @@ class FilterSetViewSetTestCase(ModoAPITestCase): self.addCleanup(patcher.stop) def authenticate(self, username: str = "user@test.com"): - # FIXME: replace ASAP with an oauth2 token - token = Token.objects.create( - user=core_models.User.objects.get(username=username) - ) - self.client.credentials(HTTP_AUTHORIZATION="Token " + token.key) + self.client.credentials(Authorization="Bearer " + self.access_token.token) def test_list(self): self.authenticate() diff --git a/modoboa/sievefilters/api/v2/viewsets.py b/modoboa/sievefilters/api/v2/viewsets.py index 51b822135..2d701d7da 100644 --- a/modoboa/sievefilters/api/v2/viewsets.py +++ b/modoboa/sievefilters/api/v2/viewsets.py @@ -29,7 +29,6 @@ FILTER_SET_ID = OpenApiParameter( class FilterSetViewSet(viewsets.ViewSet): - permission_classes = (HasMailbox,) serializer_class = serializers.FilterSetSerializer diff --git a/modoboa/sievefilters/app_settings.py b/modoboa/sievefilters/app_settings.py index 339252e44..182b99a4c 100644 --- a/modoboa/sievefilters/app_settings.py +++ b/modoboa/sievefilters/app_settings.py @@ -35,13 +35,6 @@ SIEVEFILTERS_PARAMETERS_STRUCT = collections.OrderedDict( "help_text": _("Use the STARTTLS extension"), }, ), - ( - "authentication_mech", - { - "label": _("Authentication mechanism"), - "help_text": _("Prefered authentication mechanism"), - }, - ), ] ), }, diff --git a/modoboa/sievefilters/forms.py b/modoboa/sievefilters/forms.py index feb8a4dfa..1fb2af009 100644 --- a/modoboa/sievefilters/forms.py +++ b/modoboa/sievefilters/forms.py @@ -1,7 +1,5 @@ """Custom forms.""" -from sievelib.managesieve import SUPPORTED_AUTH_MECHS - from django import forms from django.utils.translation import gettext_lazy @@ -9,13 +7,6 @@ from modoboa.lib import form_utils from modoboa.parameters import forms as param_forms -def supported_auth_mechs(): - values = [("AUTO", "auto")] - for m in SUPPORTED_AUTH_MECHS: - values += [(m, m.lower())] - return values - - class ParametersForm(param_forms.AdminParametersForm): app = "sievefilters" @@ -41,14 +32,6 @@ class ParametersForm(param_forms.AdminParametersForm): help_text=gettext_lazy("Use the STARTTLS extension"), ) - authentication_mech = forms.ChoiceField( - label=gettext_lazy("Authentication mechanism"), - choices=supported_auth_mechs(), - initial="auto", - help_text=gettext_lazy("Prefered authentication mechanism"), - widget=forms.Select(attrs={"class": "form-control"}), - ) - sep2 = form_utils.SeparatorField(label=gettext_lazy("IMAP settings")) imap_server = forms.CharField( diff --git a/modoboa/sievefilters/lib.py b/modoboa/sievefilters/lib.py index 207f08cd0..e0617a635 100644 --- a/modoboa/sievefilters/lib.py +++ b/modoboa/sievefilters/lib.py @@ -1,6 +1,5 @@ """Internal tools.""" -import ssl from typing import Optional, Tuple, Union from sievelib.factory import FiltersSet @@ -25,10 +24,10 @@ class SieveClient: msc: managesieve.Client - def __init__(self, user: Optional[str] = None, password: Optional[str] = None): - if user and password: + def __init__(self, user: Optional[str] = None, oauth_token: Optional[str] = None): + if user and oauth_token: try: - ret, msg = self.login(user, password) + ret, msg = self.login(user, oauth_token) except (managesieve.Error, ConnectionError) as e: raise SieveClientError(str(e)) if not ret: @@ -37,12 +36,9 @@ class SieveClient: def login(self, user: str, password: str) -> Tuple[bool, Union[str, None]]: conf = dict(param_tools.get_global_parameters("sievefilters")) self.msc = managesieve.Client(conf["server"], conf["port"], debug=True) - authmech = conf["authentication_mech"] - if authmech == "AUTO": - authmech = None try: ret = self.msc.connect( - user, password, starttls=conf["starttls"], authmech=authmech + user, password, starttls=conf["starttls"], authmech="OAUTHBEARER" ) except managesieve.Error as err: print(err) diff --git a/modoboa/sievefilters/mocks.py b/modoboa/sievefilters/mocks.py index f80c04742..e1e2b3632 100644 --- a/modoboa/sievefilters/mocks.py +++ b/modoboa/sievefilters/mocks.py @@ -2,7 +2,6 @@ """Mock objects.""" - SAMPLE_SIEVE_SCRIPT = """require ["fileinto", "copy"]; # Filter: test1 @@ -63,7 +62,7 @@ class ManagesieveClientMock: return """ "IMPLEMENTATION" "Example1 ManageSieved v001" "VERSION" "1.0" -"SASL" "PLAIN SCRAM-SHA-1 GSSAPI" +"SASL" "PLAIN SCRAM-SHA-1 GSSAPI OAUTHBEARER" "SIEVE" "fileinto vacation" "STARTTLS" """