Commit 93bb40ad authored by Philipp Hörist's avatar Philipp Hörist
Browse files

cfix: Fallback to PRECIS for localpart and resourcepart

Instead of enforcing stringprep or precis, try stringprep and fallback
to precis otherwise.
parent f7ee69fa
Pipeline #10885 passed with stages
in 44 seconds
from precis_i18n import get_profile
_localpart_disallowed_chars = set('"&\'/:<>@')
def enforce_precis_username(localpart: str) -> str:
if _localpart_disallowed_chars & set(localpart):
raise ValueError('Input contains prohibited codepoint: %s' % localpart)
username = get_profile('UsernameCaseMapped')
return username.enforce(localpart)
def enforce_precis_opaque(resourcepart: str) -> str:
opaque = get_profile('OpaqueString')
return opaque.enforce(resourcepart)
......@@ -37,11 +37,12 @@ from dataclasses import asdict
from gi.repository import GLib
import idna
from precis_i18n import get_profile
from nbxmpp.simplexml import Node
from nbxmpp.namespaces import Namespace
from nbxmpp.stringprep import nodeprep
from nbxmpp.stringprep import resourceprep
from nbxmpp.precis import enforce_precis_username
from nbxmpp.precis import enforce_precis_opaque
def ascii_upper(s):
......@@ -256,7 +257,6 @@ _errorcodes = {
}
_localpart_disallowed_chars = set('"&\'/:<>@')
_localpart_escape_chars = ' "&\'/:<>@'
......@@ -487,18 +487,17 @@ def validate_localpart(localpart: str) -> str:
if not localpart or len(localpart.encode()) > 1023:
raise LocalpartByteLimit
if os.environ.get('NBXMPP_USE_PRECIS') is None:
if os.environ.get('NBXMPP_ENFORCE_PRECIS') is None:
try:
return nodeprep(localpart)
except Exception:
raise LocalpartNotAllowedChar
if _localpart_disallowed_chars & set(localpart):
raise LocalpartNotAllowedChar
try:
return enforce_precis_username(localpart)
except Exception:
raise LocalpartNotAllowedChar
try:
username = get_profile('UsernameCaseMapped')
return username.enforce(localpart)
return enforce_precis_username(localpart)
except Exception:
raise LocalpartNotAllowedChar
......@@ -508,15 +507,17 @@ def validate_resourcepart(resourcepart: str) -> str:
if not resourcepart or len(resourcepart.encode()) > 1023:
raise ResourcepartByteLimit
if os.environ.get('NBXMPP_USE_PRECIS') is None:
if os.environ.get('NBXMPP_ENFORCE_PRECIS') is None:
try:
return resourceprep(resourcepart)
except Exception:
raise ResourcepartNotAllowedChar
try:
return enforce_precis_opaque(resourcepart)
except Exception:
raise ResourcepartNotAllowedChar
try:
opaque = get_profile('OpaqueString')
return opaque.enforce(resourcepart)
return enforce_precis_opaque(resourcepart)
except Exception:
raise ResourcepartNotAllowedChar
......
......@@ -51,7 +51,7 @@ class JIDParsing(unittest.TestCase):
JID.from_string(jid)
def test_invalid_precis_jids(self):
os.environ['NBXMPP_USE_PRECIS'] = 'true'
os.environ['NBXMPP_ENFORCE_PRECIS'] = 'true'
tests = [
('henry\U00002163@example.com', LocalpartNotAllowedChar),
('\U0000265A@example.com', LocalpartNotAllowedChar),
......@@ -61,7 +61,7 @@ class JIDParsing(unittest.TestCase):
with self.assertRaises(exception):
JID.from_string(jid)
del os.environ['NBXMPP_USE_PRECIS']
del os.environ['NBXMPP_ENFORCE_PRECIS']
def test_ip_literals(self):
tests = [
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment