provisionning: add hex digest to truncated role's name (#56295)
Max length of role's name is also augmented to 150 starting with Django 2.2.
This commit is contained in:
parent
49a95cbc4b
commit
739bffb78b
|
@ -14,9 +14,11 @@
|
|||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
import random
|
||||
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db import IntegrityError
|
||||
from django.db.transaction import atomic
|
||||
|
||||
|
@ -105,6 +107,19 @@ class NotificationProcessing:
|
|||
for user in User.objects.filter(saml_identifiers__name_id__in=uuids):
|
||||
user.delete()
|
||||
|
||||
group_name_max_length = Group._meta.get_field('name').max_length
|
||||
|
||||
@classmethod
|
||||
def truncate_role_name(cls, name):
|
||||
"""Truncate name to 150 characters by adding a 4-chars partial-MD5 hex
|
||||
digest for disambiguation."""
|
||||
if len(name) <= cls.group_name_max_length: # Group.name has max_length=150 since Django 2.2
|
||||
return name
|
||||
else:
|
||||
return (
|
||||
name[: cls.group_name_max_length - 7] + ' (%4s)' % hashlib.md5(name.encode()).hexdigest()[:4]
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def provision_role(cls, issuer, action, data, full=False):
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -114,9 +129,7 @@ class NotificationProcessing:
|
|||
uuids.add(o['uuid'])
|
||||
if action == 'provision':
|
||||
assert cls.check_valid_role(o)
|
||||
role_name = o['name']
|
||||
if len(role_name) > 70:
|
||||
role_name = role_name[:70] + '(...)'
|
||||
role_name = cls.truncate_role_name(o['name'])
|
||||
try:
|
||||
role = Role.objects.get(uuid=o['uuid'])
|
||||
created = False
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
from hobo.provisionning.utils import NotificationProcessing
|
||||
|
||||
|
||||
def test_truncate_role_name():
|
||||
seen = set()
|
||||
max_length = NotificationProcessing.group_name_max_length
|
||||
|
||||
assert max_length == 150 # value on Django 2.2
|
||||
|
||||
for length in range(max_length - 10, max_length):
|
||||
name = 'a' * length
|
||||
truncated = NotificationProcessing.truncate_role_name(name)
|
||||
assert len(truncated) == length
|
||||
assert truncated not in seen
|
||||
seen.add(truncated)
|
||||
|
||||
for length in range(max_length + 1, max_length + 10):
|
||||
name = 'a' * length
|
||||
truncated = NotificationProcessing.truncate_role_name(name)
|
||||
assert len(truncated) == max_length
|
||||
assert truncated not in seen
|
||||
seen.add(truncated)
|
Loading…
Reference in New Issue