Added "visibleFrom" to authenticators, so we can add custom filters for showing them on login screen

This commit is contained in:
Adolfo Gómez García 2021-09-16 13:14:33 +02:00
parent de9c06bc2c
commit d531a1612a
4 changed files with 42 additions and 8 deletions

View File

@ -38,11 +38,7 @@ from django.utils.translation import ugettext_noop as _
from uds.core import auths
from uds.core.util import net
from uds.core.ui import gui
from uds.core.util.request import getRequest
# Not imported at runtime, just for type checking
if typing.TYPE_CHECKING:
from django.http import HttpRequest # pylint: disable=ungrouped-imports
from uds.core.util.request import getRequest, ExtendedHttpRequest
logger = logging.getLogger(__name__)
@ -51,7 +47,7 @@ class IPAuth(auths.Authenticator):
acceptProxy = gui.CheckBoxField(
label=_('Accept proxy'),
defvalue=gui.FALSE,
order=3,
order=50,
tooltip=_(
'If checked, requests via proxy will get FORWARDED ip address'
' (take care with this bein checked, can take internal IP addresses from internet)'
@ -59,6 +55,14 @@ class IPAuth(auths.Authenticator):
tab=gui.ADVANCED_TAB
)
visibleFromNets = gui.TextField(
order=50,
label=_('Visible only from this networks'),
defvalue='',
tooltip=_('This authenticator will be visible only from these networks. Leave empty to allow all networks'),
tab=gui.ADVANCED_TAB
)
typeName = _('IP Authenticator')
typeType = 'IPAuth'
typeDescription = _('IP Authenticator')
@ -93,6 +97,15 @@ class IPAuth(auths.Authenticator):
return True
return False
def isVisibleFrom(self, request: 'ExtendedHttpRequest'):
"""
Used by the login interface to determine if the authenticator is visible on the login page.
"""
validNets = self.visibleFromNets.value.strip()
if not validNets or net.ipInNetwork(request.ip, validNets):
return True
return False
def internalAuthenticate(self, username: str, credentials: str, groupsManager: 'auths.GroupsManager') -> bool:
# In fact, username does not matter, will get IP from request
username = self.getIp() # Override provided username and use source IP
@ -108,7 +121,7 @@ class IPAuth(auths.Authenticator):
def check(self):
return _("All seems to be fine.")
def getJavascript(self, request: 'HttpRequest') -> typing.Optional[str]:
def getJavascript(self, request: 'ExtendedHttpRequest') -> typing.Optional[str]:
# We will authenticate ip here, from request.ip
# If valid, it will simply submit form with ip submited and a cached generated random password
ip = self.getIp()

View File

@ -333,6 +333,12 @@ class Authenticator(Module): # pylint: disable=too-many-public-methods
"""
return False
def isVisibleFrom(self, request: 'HttpRequest'):
"""
Used by the login interface to determine if the authenticator is visible on the login page.
"""
return True
def transformUsername(self, username: str) -> str:
"""
On login, this method get called so we can "transform" provided user name.

View File

@ -97,8 +97,11 @@ def checkLogin( # pylint: disable=too-many-branches, too-many-statements
(cache.get(request.ip) or 0) if GlobalConfig.LOGIN_BLOCK_IP.getBool() else 0
)
maxTries = GlobalConfig.MAX_LOGIN_TRIES.getInt()
# Get instance..
authInstance = authenticator.getInstance()
# Check if user is locked
if (
authenticator.getInstance().blockUserOnLoginFailures is True
authInstance.blockUserOnLoginFailures is True
and (tries >= maxTries)
or triesByIp >= maxTries
):
@ -107,6 +110,15 @@ def checkLogin( # pylint: disable=too-many-branches, too-many-statements
None,
_('Too many authentication errrors. User temporarily blocked'),
)
# check if authenticator is visible for this requests
if authInstance.isVisibleFrom(request=request) is False:
authLogLogin(
request,
authenticator,
userName,
'Access tried from an unallowed source',
)
return (None, _('Access tried from an unallowed source'))
password = form.cleaned_data['password']
user = None

View File

@ -103,6 +103,9 @@ def udsJs(request: 'ExtendedHttpRequest') -> str:
else:
authenticators = Authenticator.objects.all().exclude(visible=False)
# Filter out non visible authenticators
authenticators = [a for a in authenticators if a.getInstance().isVisibleFrom(request)]
# logger.debug('Authenticators PRE: %s', authenticators)
if (