mirror of
https://github.com/dkmstr/openuds.git
synced 2024-12-22 13:34:04 +03:00
Refactor config update method to handle non-existing config values and fixed Radius to allow stripping the domain part from the username
This commit is contained in:
parent
a318e8ca2b
commit
14a58dc423
@ -48,12 +48,17 @@ class Config(Handler):
|
||||
return CfgConfig.get_config_values(self.is_admin())
|
||||
|
||||
def put(self) -> typing.Any:
|
||||
for section, section_dict in typing.cast(
|
||||
dict[str, dict[str, dict[str, str]]], self._params
|
||||
).items():
|
||||
for section, section_dict in typing.cast(dict[str, dict[str, dict[str, str]]], self._params).items():
|
||||
for key, vals in section_dict.items():
|
||||
logger.info(
|
||||
'Updating config value %s.%s to %s by %s', section, key, vals['value'], self._user.name
|
||||
)
|
||||
CfgConfig.update(CfgConfig.SectionType.from_str(section), key, vals['value'])
|
||||
config = CfgConfig.update(CfgConfig.SectionType.from_str(section), key, vals['value'])
|
||||
if config is not None:
|
||||
logger.info(
|
||||
'Updating config value %s.%s to %s by %s',
|
||||
section,
|
||||
key,
|
||||
vals['value'] if not config.is_password else '********',
|
||||
self._user.name,
|
||||
)
|
||||
else:
|
||||
logger.error('Non existing config value %s.%s to %s by %s', section, key, vals['value'], self._user.name)
|
||||
return 'done'
|
||||
|
@ -233,6 +233,10 @@ class Config:
|
||||
|
||||
def get_type(self) -> int:
|
||||
return self._type
|
||||
|
||||
@property
|
||||
def is_password(self) -> bool:
|
||||
return self._type == Config.FieldType.PASSWORD
|
||||
|
||||
def get_params(self) -> typing.Any:
|
||||
return Config._config_params.get(self._section.name() + self._key, None)
|
||||
@ -322,7 +326,7 @@ class Config:
|
||||
yield val
|
||||
|
||||
@staticmethod
|
||||
def update(section: 'Config.SectionType', key: str, value: str, check_type: bool = False) -> bool:
|
||||
def update(section: 'Config.SectionType', key: str, value: str, check_type: bool = False) -> 'None|Config.Value':
|
||||
# If cfg value does not exists, simply ignore request
|
||||
try:
|
||||
cfg: DBConfig = DBConfig.objects.get(section=section, key=key)
|
||||
@ -330,17 +334,17 @@ class Config:
|
||||
Config.FieldType.READ,
|
||||
Config.FieldType.HIDDEN,
|
||||
):
|
||||
return False # Skip non writable elements
|
||||
return None # Skip non writable elements
|
||||
|
||||
if cfg.field_type == Config.FieldType.PASSWORD.value:
|
||||
value = CryptoManager().hash(value)
|
||||
value = CryptoManager.manager().hash(value)
|
||||
|
||||
cfg.value = value
|
||||
cfg.save()
|
||||
cfg.save(update_fields=['value'])
|
||||
logger.debug('Updated value for %s.%s to %s', section, key, value)
|
||||
return True
|
||||
return Config.section(section).value(key, value, type=Config.FieldType.from_int(cfg.field_type))
|
||||
except Exception:
|
||||
return False
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def removed(section: 'Config.SectionType', key: str) -> None:
|
||||
|
@ -61,9 +61,7 @@ class Command(BaseCommand):
|
||||
mod, name = Config.SectionType.from_str(first[0]), first[1]
|
||||
else:
|
||||
mod, name = Config.SectionType.GLOBAL, first[0]
|
||||
if (
|
||||
Config.update(mod, name, value) is False
|
||||
): # If not exists, try to store value without any special parameters
|
||||
if Config.update(mod, name, value) is None:
|
||||
kwargs = {}
|
||||
if options['password']:
|
||||
kwargs['type'] = Config.FieldType.PASSWORD
|
||||
|
@ -35,7 +35,7 @@ import logging
|
||||
|
||||
from django.utils.translation import gettext_noop as _, gettext
|
||||
|
||||
from uds.core import mfas, exceptions
|
||||
from uds.core import mfas, exceptions, types
|
||||
from uds.core.ui import gui
|
||||
|
||||
from uds.auths.Radius import client
|
||||
@ -111,6 +111,18 @@ class RadiusOTP(mfas.MFA):
|
||||
login_without_mfa_policy_networks = fields.login_without_mfa_policy_networks_field()
|
||||
allow_skip_mfa_from_networks = fields.allow_skip_mfa_from_networks_field()
|
||||
|
||||
send_just_username = gui.CheckBoxField(
|
||||
label=_('Send only username (without domain) to radius server'),
|
||||
order=55,
|
||||
default=False,
|
||||
tooltip=_(
|
||||
'If unchecked, username will be sent as is to radius server. \n'
|
||||
'If checked, domain part will be removed from username before sending it to radius server.'
|
||||
),
|
||||
required=False,
|
||||
tab=types.ui.Tab.CONFIG,
|
||||
)
|
||||
|
||||
def radius_client(self) -> client.RadiusClient:
|
||||
"""Return a new radius client ."""
|
||||
return client.RadiusClient(
|
||||
@ -158,9 +170,14 @@ class RadiusOTP(mfas.MFA):
|
||||
# if we are in a "all-users-otp" policy, avoid this step and go directly to ask for OTP
|
||||
if self.all_users_otp.value:
|
||||
return mfas.MFA.RESULT.OK
|
||||
|
||||
|
||||
# The identifier has preference over username, but normally will be empty
|
||||
username = identifier or username
|
||||
|
||||
# Remove domain part from username if needed
|
||||
if self.send_just_username.value:
|
||||
username = username.strip().split('@')[0].split('\\')[-1]
|
||||
|
||||
web_pwd = web_password(request)
|
||||
try:
|
||||
connection = self.radius_client()
|
||||
@ -220,8 +237,14 @@ class RadiusOTP(mfas.MFA):
|
||||
regenerate a new State after a wrong sent OTP code
|
||||
slightly less efficient but a lot simpler
|
||||
'''
|
||||
# The identifier has preference over username, but normally will be empty
|
||||
# This allows derived class to "alter" the username if needed
|
||||
username = identifier or username
|
||||
|
||||
# Remove domain part from username if needed
|
||||
if self.send_just_username.value:
|
||||
username = username.strip().split('@')[0].split('\\')[-1]
|
||||
|
||||
try:
|
||||
err = _('Invalid OTP code')
|
||||
|
||||
|
@ -420,13 +420,15 @@ class SMSMFA(mfas.MFA):
|
||||
phone: str,
|
||||
) -> mfas.MFA.RESULT:
|
||||
url = self.build_sms_url(userid, username, code, phone)
|
||||
if self.http_method.value == 'GET':
|
||||
return self._send_sms_using_get(request, userid, username, url)
|
||||
if self.http_method.value == 'POST':
|
||||
return self._send_sms_using_post(request, userid, username, url, code, phone)
|
||||
if self.http_method.value == 'PUT':
|
||||
return self._send_sms_using_put(request, userid, username, url, code, phone)
|
||||
raise Exception('Unknown SMS sending method')
|
||||
match self.http_method.value:
|
||||
case 'GET':
|
||||
return self._send_sms_using_get(request, userid, username, url)
|
||||
case 'POST':
|
||||
return self._send_sms_using_post(request, userid, username, url, code, phone)
|
||||
case 'PUT':
|
||||
return self._send_sms_using_put(request, userid, username, url, code, phone)
|
||||
case _:
|
||||
raise Exception('Unknown SMS sending method')
|
||||
|
||||
def label(self) -> str:
|
||||
return gettext('MFA Code')
|
||||
|
Loading…
Reference in New Issue
Block a user