coturn: Validate TURN URIs if provided in form

Signed-off-by: James Valleroy <jvalleroy@mailbox.org>

- Re-use the same validator in Matrix Synapse.
- Avoid importing plinth classes in actions files.
Signed-off-by: Joseph Nuthalapati <njoseph@riseup.net>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
James Valleroy 2021-04-13 21:48:03 -04:00
parent 7a30470cb5
commit 9b446d5dd1
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
5 changed files with 25 additions and 4 deletions

View File

@ -30,6 +30,8 @@ yaml = YAML()
yaml.allow_duplicate_keys = True
yaml.preserve_quotes = True
TURN_URI_REGEX = r'(stun|turn):(.*):([0-9]{4})\?transport=(tcp|udp)'
def parse_arguments():
"""Return parsed command line arguments as dictionary"""
@ -303,7 +305,7 @@ def subcommand_mam(argument):
def _generate_service(uri: str) -> dict:
"""Generate ejabberd mod_stun_disco service config from Coturn URI."""
pattern = re.compile(r'(stun|turn):(.*):([0-9]{4})\?transport=(tcp|udp)')
pattern = re.compile(TURN_URI_REGEX)
typ, domain, port, transport = pattern.match(uri).groups()
return {
"host": domain,

View File

@ -5,10 +5,13 @@
from __future__ import annotations # Can be removed in Python 3.10
import json
import re
from dataclasses import dataclass, field
from plinth import app
TURN_URI_REGEX = r'(stun|turn):(.*):([0-9]{4})\?transport=(tcp|udp)'
@dataclass
class TurnConfiguration:
@ -45,6 +48,12 @@ class TurnConfiguration:
'shared_secret': self.shared_secret
})
@staticmethod
def validate_turn_uris(turn_uris: list[str]) -> bool:
"""Return whether the given TURN URI is valid."""
pattern = re.compile(TURN_URI_REGEX)
return all(map(pattern.match, turn_uris))
class TurnConsumer(app.FollowerComponent):
"""Component to manage coturn configuration.

View File

@ -4,9 +4,11 @@ Forms for Coturn app.
"""
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
from plinth.modules import coturn
from plinth.modules.coturn.components import TurnConfiguration
def get_domain_choices():
@ -14,6 +16,12 @@ def get_domain_choices():
return ((domain, domain) for domain in coturn.get_available_domains())
def turn_uris_validator(turn_uris):
"""Validate list of STUN/TURN Server URIs."""
if not TurnConfiguration.validate_turn_uris(turn_uris.split("\n")):
raise ValidationError(_('Invalid list of STUN/TURN Server URIs'))
class CoturnForm(forms.Form):
"""Form to select a TLS domain for Coturn."""

View File

@ -8,6 +8,7 @@ from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from plinth import cfg
from plinth.modules.coturn.forms import turn_uris_validator
from plinth.utils import format_lazy
@ -35,7 +36,7 @@ class EjabberdForm(forms.Form):
label=_('STUN/TURN Server URIs'), required=False, strip=True,
widget=forms.Textarea(attrs={'rows': 4}),
help_text=_('List of public URIs of the STUN/TURN server, one on each '
'line.'))
'line.'), validators=[turn_uris_validator])
shared_secret = forms.CharField(
label=_('Shared Authentication Secret'), required=False, strip=True,

View File

@ -5,8 +5,9 @@ Forms for the Matrix Synapse module.
from django import forms
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from plinth.modules.coturn.forms import turn_uris_validator
from django.utils.translation import ugettext_lazy as _
from plinth.utils import format_lazy
@ -30,7 +31,7 @@ class MatrixSynapseForm(forms.Form):
label=_('STUN/TURN Server URIs'), required=False, strip=True,
widget=forms.Textarea(attrs={'rows': 4}),
help_text=_('List of public URIs of the STUN/TURN server, one on each '
'line.'))
'line.'), validators=[turn_uris_validator])
shared_secret = forms.CharField(
label=_('Shared Authentication Secret'), required=False, strip=True,