mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
Allow only OAUTHTOKEN for sievefilters
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -29,7 +29,6 @@ FILTER_SET_ID = OpenApiParameter(
|
||||
|
||||
|
||||
class FilterSetViewSet(viewsets.ViewSet):
|
||||
|
||||
permission_classes = (HasMailbox,)
|
||||
serializer_class = serializers.FilterSetSerializer
|
||||
|
||||
|
||||
@@ -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"),
|
||||
},
|
||||
),
|
||||
]
|
||||
),
|
||||
},
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user