예제 #1
0
    def post(self):
        '''
        This login uses parameters to generate auth token
        The alternative is to use the template tag inside "REST" that is called auth_token, that extracts an auth token from an user session
        We can use any of this forms due to the fact that the auth token is in fact a session key
        Parameters:
            mandatory:
                username:
                password:
                authId or auth or authSmallName: (must include at least one. If multiple are used, precedence is the list order)
        Result:
            on success: { 'result': 'ok', 'auth': [auth_code] }
            on error: { 'result: 'error', 'error': [error string] }

        Locale comes on "Header", as any HTTP Request (Accept-Language header)
        Calls to any method of REST that must be authenticated needs to be called with "X-Auth-Token" Header added
        '''
        try:
            if 'authId' not in self._params and 'authSmallName' not in self._params and 'auth' not in self._params:
                raise RequestError('Invalid parameters (no auth)')

            authId = self._params.get('authId', None)
            authSmallName = self._params.get('authSmallName', None)
            authName = self._params.get('auth', None)

            username, password = self._params['username'], self._params['password']
            locale = self._params.get('locale', 'en')
            if authName == 'admin' or authSmallName == 'admin':
                if GlobalConfig.SUPER_USER_LOGIN.get(True) == username and GlobalConfig.SUPER_USER_PASS.get(True) == password:
                    self.genAuthToken(-1, username, locale, True, True)
                    return{'result': 'ok', 'token': self.getAuthToken()}
                else:
                    raise Exception('Invalid credentials')
            else:
                try:
                    # Will raise an exception if no auth found
                    if authId is not None:
                        auth = Authenticator.objects.get(uuid=authId)
                    elif authName is not None:
                        auth = Authenticator.objects.get(name=authName)
                    else:
                        auth = Authenticator.objects.get(small_name=authSmallName)

                    logger.debug('Auth obj: {0}'.format(auth))
                    user = authenticate(username, password, auth)
                    if user is None:  # invalid credentials
                        raise Exception()
                    self.genAuthToken(auth.id, user.name, locale, user.is_admin, user.staff_member)
                    return{'result': 'ok', 'token': self.getAuthToken()}
                except:
                    logger.exception('Credentials ')
                    raise Exception('Invalid Credentials (invalid authenticator)')

            raise Exception('Invalid Credentials')
        except Exception as e:
            logger.exception('exception')
            return {'result': 'error', 'error': unicode(e)}
예제 #2
0
    def post(self):
        '''
        This login uses parameters to generate auth token
        The alternative is to use the template tag inside "REST" that is called auth_token, that extracts an auth token from an user session
        We can use any of this forms due to the fact that the auth token is in fact a session key
        Parameters:
            mandatory:
                username:
                password:
                authId or auth or authSmallName: (must include at least one. If multiple are used, precedence is the list order)
            optional:
                platform: From what platform are we connecting. If not specified, will try to deduct it from user agent.
                Valid values:
                    Linux = 'Linux'
                    WindowsPhone = 'Windows Phone'
                    Windows = 'Windows'
                    Macintosh = 'Mac'
                    Android = 'Android'
                    iPad = 'iPad'
                    iPhone = 'iPhone'
                Defaults to:
                    Unknown = 'Unknown'

        Result:
            on success: { 'result': 'ok', 'auth': [auth_code] }
            on error: { 'result: 'error', 'error': [error string] }

        Locale comes on "Header", as any HTTP Request (Accept-Language header)
        Calls to any method of REST that must be authenticated needs to be called with "X-Auth-Token" Header added
        '''
        try:
            if 'authId' not in self._params and 'authSmallName' not in self._params and 'auth' not in self._params:
                raise RequestError('Invalid parameters (no auth)')

            authId = self._params.get('authId', None)
            authSmallName = self._params.get('authSmallName', None)
            authName = self._params.get('auth', None)
            platform = self._params.get('platform', self._request.os)

            username, password = self._params['username'], self._params[
                'password']
            locale = self._params.get('locale', 'en')
            if authName == 'admin' or authSmallName == 'admin':
                if GlobalConfig.SUPER_USER_LOGIN.get(
                        True) == username and GlobalConfig.SUPER_USER_PASS.get(
                            True) == password:
                    self.genAuthToken(-1, username, locale, platform, True,
                                      True)
                    return {'result': 'ok', 'token': self.getAuthToken()}
                else:
                    raise Exception('Invalid credentials')
            else:
                try:
                    # Will raise an exception if no auth found
                    if authId is not None:
                        auth = Authenticator.objects.get(
                            uuid=processUuid(authId))
                    elif authName is not None:
                        auth = Authenticator.objects.get(name=authName)
                    else:
                        auth = Authenticator.objects.get(
                            small_name=authSmallName)

                    if password == '':
                        password = '******'  # Strange password if credential leaved empty

                    logger.debug('Auth obj: {0}'.format(auth))
                    user = authenticate(username, password, auth)
                    if user is None:  # invalid credentials
                        raise Exception()
                    self.genAuthToken(auth.id, user.name, locale, platform,
                                      user.is_admin, user.staff_member)
                    return {'result': 'ok', 'token': self.getAuthToken()}
                except:
                    logger.exception('Credentials ')
                    raise Exception(
                        'Invalid Credentials (invalid authenticator)')

            raise Exception('Invalid Credentials')
        except Exception as e:
            logger.exception('exception')
            return {'result': 'error', 'error': six.text_type(e)}
예제 #3
0
def login(request, tag=None):
    '''
    View responsible of logging in an user
    :param request:  http request
    :param tag: tag of login auth
    '''
    # request.session.set_expiry(GlobalConfig.USER_SESSION_LENGTH.getInt())

    host = request.META.get('HTTP_HOST') or request.META.get('SERVER_NAME') or 'auth_host'  # Last one is a placeholder in case we can't locate host name

    # Get Authenticators limitation
    logger.debug('Host: {0}'.format(host))
    if GlobalConfig.DISALLOW_GLOBAL_LOGIN.getBool(True) is True:
        if tag is None:
            try:
                Authenticator.objects.get(small_name=host)
                tag = host
            except Exception:
                try:
                    tag = Authenticator.objects.order_by('priority')[0].small_name
                except Exception:  # There is no authenticators yet, simply allow global login to nowhere.. :-)
                    tag = None

    logger.debug('Tag: {0}'.format(tag))

    logger.debug(request.method)
    if request.method == 'POST':
        if 'uds' not in request.COOKIES:
            logger.debug('Request does not have uds cookie')
            return errors.errorView(request, errors.COOKIES_NEEDED)  # We need cookies to keep session data
        request.session.cycle_key()
        form = LoginForm(request.POST, tag=tag)
        if form.is_valid():
            os = OsDetector.getOsFromUA(request.META.get('HTTP_USER_AGENT'))
            try:
                authenticator = Authenticator.objects.get(pk=form.cleaned_data['authenticator'])
            except Exception:
                authenticator = Authenticator()
            userName = form.cleaned_data['user']

            cache = Cache('auth')
            cacheKey = str(authenticator.id) + userName
            tries = cache.get(cacheKey)
            if tries is None:
                tries = 0
            if authenticator.getInstance().blockUserOnLoginFailures is True and tries >= GlobalConfig.MAX_LOGIN_TRIES.getInt():
                form.add_form_error('Too many authentication errors. User temporarily  blocked.')
                authLogLogin(request, authenticator, userName, 'Temporarily blocked')
            else:
                user = authenticate(userName, form.cleaned_data['password'], authenticator)
                logger.debug('User: {}'.format(user))

                if user is None:
                    logger.debug("Invalid credentials for user {0}".format(userName))
                    tries += 1
                    cache.put(cacheKey, tries, GlobalConfig.LOGIN_BLOCK.getInt())
                    form.add_form_error('Invalid credentials')
                    authLogLogin(request, authenticator, userName, 'Invalid credentials')
                else:
                    logger.debug('User {} has logged in'.format(userName))
                    cache.remove(cacheKey)  # Valid login, remove cached tries
                    response = HttpResponseRedirect(reverse('uds.web.views.index'))
                    webLogin(request, response, user, form.cleaned_data['password'])
                    # Add the "java supported" flag to session
                    request.session['OS'] = os
                    authLogLogin(request, authenticator, user.name)
                    return response
    else:
        form = LoginForm(tag=tag)

    response = render_to_response(theme.template('login.html'), {'form': form, 'customHtml': GlobalConfig.CUSTOM_HTML_LOGIN.get(True)},
                                  context_instance=RequestContext(request))

    getUDSCookie(request, response)

    return response
예제 #4
0
    def post(self):
        '''
        This login uses parameters to generate auth token
        The alternative is to use the template tag inside "REST" that is called auth_token, that extracts an auth token from an user session
        We can use any of this forms due to the fact that the auth token is in fact a session key
        Parameters:
            mandatory:
                username:
                password:
                authId or auth or authSmallName: (must include at least one. If multiple are used, precedence is the list order)
            optional:
                platform: From what platform are we connecting. If not specified, will try to deduct it from user agent.
                Valid values:
                    Linux = 'Linux'
                    WindowsPhone = 'Windows Phone'
                    Windows = 'Windows'
                    Macintosh = 'Mac'
                    Android = 'Android'
                    iPad = 'iPad'
                    iPhone = 'iPhone'
                Defaults to:
                    Unknown = 'Unknown'

        Result:
            on success: { 'result': 'ok', 'auth': [auth_code] }
            on error: { 'result: 'error', 'error': [error string] }

        Locale comes on "Header", as any HTTP Request (Accept-Language header)
        Calls to any method of REST that must be authenticated needs to be called with "X-Auth-Token" Header added
        '''
        try:
            if 'authId' not in self._params and 'authSmallName' not in self._params and 'auth' not in self._params:
                raise RequestError('Invalid parameters (no auth)')

            authId = self._params.get('authId', None)
            authSmallName = self._params.get('authSmallName', None)
            authName = self._params.get('auth', None)
            platform = self._params.get('platform', self._request.os)

            username, password = self._params['username'], self._params['password']
            locale = self._params.get('locale', 'en')
            if authName == 'admin' or authSmallName == 'admin':
                if GlobalConfig.SUPER_USER_LOGIN.get(True) == username and GlobalConfig.SUPER_USER_PASS.get(True) == password:
                    self.genAuthToken(-1, username, locale, platform, True, True)
                    return{'result': 'ok', 'token': self.getAuthToken()}
                else:
                    raise Exception('Invalid credentials')
            else:
                try:
                    # Will raise an exception if no auth found
                    if authId is not None:
                        auth = Authenticator.objects.get(uuid=processUuid(authId))
                    elif authName is not None:
                        auth = Authenticator.objects.get(name=authName)
                    else:
                        auth = Authenticator.objects.get(small_name=authSmallName)

                    if password == '':
                        password = '******'  # Strange password if credential leaved empty

                    logger.debug('Auth obj: {0}'.format(auth))
                    user = authenticate(username, password, auth)
                    if user is None:  # invalid credentials
                        raise Exception()
                    self.genAuthToken(auth.id, user.name, locale, platform, user.is_admin, user.staff_member)
                    return{'result': 'ok', 'token': self.getAuthToken()}
                except:
                    logger.exception('Credentials ')
                    raise Exception('Invalid Credentials (invalid authenticator)')

            raise Exception('Invalid Credentials')
        except Exception as e:
            logger.exception('exception')
            return {'result': 'error', 'error': six.text_type(e)}
예제 #5
0
def checkLogin(  # pylint: disable=too-many-branches, too-many-statements
    request: 'HttpRequest',
    form: 'LoginForm',
    tag: typing.Optional[str] = None
) -> typing.Tuple[typing.Optional['User'], typing.Any]:
    host = request.META.get('HTTP_HOST') or request.META.get(
        'SERVER_NAME'
    ) or 'auth_host'  # Last one is a placeholder in case we can't locate host name

    # Get Authenticators limitation
    logger.debug('Host: %s', host)
    if GlobalConfig.DISALLOW_GLOBAL_LOGIN.getBool(False) is True:
        if tag is None:
            try:
                Authenticator.objects.get(small_name=host)
                tag = host
            except Exception:
                try:
                    tag = Authenticator.objects.order_by(
                        'priority')[0].small_name
                except Exception:  # There is no authenticators yet, simply allow global login to nowhere.. :-)
                    tag = None

    logger.debug('Tag: %s', tag)

    if 'uds' not in request.COOKIES:
        logger.debug('Request does not have uds cookie')
        return (None, errors.COOKIES_NEEDED)
    if form.is_valid():
        os = request.os
        try:
            authenticator = Authenticator.objects.get(
                uuid=processUuid(form.cleaned_data['authenticator']))
        except Exception:
            authenticator = Authenticator()
        userName = form.cleaned_data['user']
        if GlobalConfig.LOWERCASE_USERNAME.getBool(True) is True:
            userName = userName.lower()

        cache = Cache('auth')
        cacheKey = str(authenticator.id) + userName
        tries = cache.get(cacheKey) or 0
        triesByIp = cache.get(request.ip) or 0
        maxTries = GlobalConfig.MAX_LOGIN_TRIES.getInt()
        if (authenticator.getInstance().blockUserOnLoginFailures is True and
            (tries >= maxTries) or triesByIp >= maxTries):
            authLogLogin(request, authenticator, userName,
                         'Temporarily blocked')
            return (
                None,
                _('Too many authentication errrors. User temporarily blocked'))

        password = form.cleaned_data['password']
        user = None
        if password == '':
            password = '******'  # Random string, in fact, just a placeholder that will not be used :)
        user = authenticate(userName, password, authenticator)
        logger.debug('User: %s', user)

        if user is None:
            logger.debug("Invalid user %s (access denied)", userName)
            cache.put(cacheKey, tries + 1, GlobalConfig.LOGIN_BLOCK.getInt())
            cache.put(request.ip, triesByIp + 1,
                      GlobalConfig.LOGIN_BLOCK.getInt())
            authLogLogin(request, authenticator, userName,
                         'Access denied (user not allowed by UDS)')
            return (None, _('Access denied'))

        request.session.cycle_key()

        logger.debug('User %s has logged in', userName)
        cache.remove(cacheKey)  # Valid login, remove cached tries

        # Add the "java supported" flag to session
        request.session['OS'] = os
        if form.cleaned_data['logouturl'] != '':
            logger.debug('The logoout url will be %s',
                         form.cleaned_data['logouturl'])
            request.session['logouturl'] = form.cleaned_data['logouturl']
        authLogLogin(request, authenticator, user.name)
        return (user, form.cleaned_data['password'])

    logger.info('Invalid form received')
    return (None, _('Invalid data'))
예제 #6
0
def login(request, tag=None):
    '''
    View responsible of logging in an user
    :param request:  http request
    :param tag: tag of login auth
    '''
    # request.session.set_expiry(GlobalConfig.USER_SESSION_LENGTH.getInt())

    host = request.META.get('HTTP_HOST') or request.META.get('SERVER_NAME') or 'auth_host'  # Last one is a placeholder in case we can't locate host name

    # Get Authenticators limitation
    logger.debug('Host: {0}'.format(host))
    if GlobalConfig.DISALLOW_GLOBAL_LOGIN.getBool(False) is True:
        if tag is None:
            try:
                Authenticator.objects.get(small_name=host)
                tag = host
            except Exception:
                try:
                    tag = Authenticator.objects.order_by('priority')[0].small_name
                except Exception:  # There is no authenticators yet, simply allow global login to nowhere.. :-)
                    tag = None

    logger.debug('Tag: {0}'.format(tag))

    logger.debug(request.method)
    if request.method == 'POST':
        if 'uds' not in request.COOKIES:
            logger.debug('Request does not have uds cookie')
            return errors.errorView(request, errors.COOKIES_NEEDED)  # We need cookies to keep session data
        request.session.cycle_key()
        form = LoginForm(request.POST, tag=tag)
        if form.is_valid():
            os = request.os
            try:
                authenticator = Authenticator.objects.get(pk=form.cleaned_data['authenticator'])
            except Exception:
                authenticator = Authenticator()
            userName = form.cleaned_data['user']
            if GlobalConfig.LOWERCASE_USERNAME.getBool(True) is True:
                userName = userName.lower()

            cache = Cache('auth')
            cacheKey = str(authenticator.id) + userName
            tries = cache.get(cacheKey)
            if tries is None:
                tries = 0
            if authenticator.getInstance().blockUserOnLoginFailures is True and tries >= GlobalConfig.MAX_LOGIN_TRIES.getInt():
                form.add_error(None, 'Too many authentication errors. User temporarily  blocked.')
                authLogLogin(request, authenticator, userName, 'Temporarily blocked')
            else:
                password = form.cleaned_data['password']
                user = None
                if password == '':
                    password = '******'
                user = authenticate(userName, password, authenticator)
                logger.debug('User: {}'.format(user))

                if user is None:
                    logger.debug("Invalid credentials for user {0}".format(userName))
                    tries += 1
                    cache.put(cacheKey, tries, GlobalConfig.LOGIN_BLOCK.getInt())
                    form.add_error(None, ugettext('Invalid credentials'))
                    authLogLogin(request, authenticator, userName, 'Invalid credentials')
                else:
                    logger.debug('User {} has logged in'.format(userName))
                    cache.remove(cacheKey)  # Valid login, remove cached tries
                    response = HttpResponseRedirect(reverse('uds.web.views.index'))
                    webLogin(request, response, user, form.cleaned_data['password'])
                    # Add the "java supported" flag to session
                    request.session['OS'] = os
                    if form.cleaned_data['logouturl'] != '':
                        logger.debug('The logoout url will be {}'.format(form.cleaned_data['logouturl']))
                        request.session['logouturl'] = form.cleaned_data['logouturl']
                    authLogLogin(request, authenticator, user.name)
                    return response
        else:
            logger.info('Invalid form received')
    else:
        form = LoginForm(tag=tag)

    response = render_to_response(
        theme.template('login.html'),
        {
            'form': form,
            'customHtml': GlobalConfig.CUSTOM_HTML_LOGIN.get(True),
            'version': VERSION

        },
        context_instance=RequestContext(request)
    )

    getUDSCookie(request, response)

    return response
예제 #7
0
def checkLogin(request, form, tag=None):
    host = request.META.get('HTTP_HOST') or request.META.get('SERVER_NAME') or 'auth_host'  # Last one is a placeholder in case we can't locate host name

    # Get Authenticators limitation
    logger.debug('Host: {0}'.format(host))
    if GlobalConfig.DISALLOW_GLOBAL_LOGIN.getBool(False) is True:
        if tag is None:
            try:
                Authenticator.objects.get(small_name=host)
                tag = host
            except Exception:
                try:
                    tag = Authenticator.objects.order_by('priority')[0].small_name
                except Exception:  # There is no authenticators yet, simply allow global login to nowhere.. :-)
                    tag = None

    logger.debug('Tag: {0}'.format(tag))

    if 'uds' not in request.COOKIES:
        logger.debug('Request does not have uds cookie')
        return (None, errors.COOKIES_NEEDED)
    if form.is_valid():
        os = request.os
        try:
            authenticator = Authenticator.objects.get(uuid=processUuid(form.cleaned_data['authenticator']))
        except Exception:
            authenticator = Authenticator()
        userName = form.cleaned_data['user']
        if GlobalConfig.LOWERCASE_USERNAME.getBool(True) is True:
            userName = userName.lower()

        cache = Cache('auth')
        cacheKey = str(authenticator.id) + userName
        tries = cache.get(cacheKey)
        if tries is None:
            tries = 0
        if authenticator.getInstance().blockUserOnLoginFailures is True and tries >= GlobalConfig.MAX_LOGIN_TRIES.getInt():
            authLogLogin(request, authenticator, userName, 'Temporarily blocked')
            return (None, _('Too many authentication errrors. User temporarily blocked'))
        else:
            password = form.cleaned_data['password']
            user = None
            if password == '':
                password = '******'  # Random string, in fact, just a placeholder that will not be used :)
            user = authenticate(userName, password, authenticator)
            logger.debug('User: {}'.format(user))

            if user is None:
                logger.debug("Invalid user {0} (access denied)".format(userName))
                tries += 1
                cache.put(cacheKey, tries, GlobalConfig.LOGIN_BLOCK.getInt())
                authLogLogin(request, authenticator, userName, 'Access denied (user not allowed by UDS)')
                return (None, _('Access denied'))
            else:
                request.session.cycle_key()

                logger.debug('User {} has logged in'.format(userName))
                cache.remove(cacheKey)  # Valid login, remove cached tries

                # Add the "java supported" flag to session
                request.session['OS'] = os
                if form.cleaned_data['logouturl'] != '':
                    logger.debug('The logoout url will be {}'.format(form.cleaned_data['logouturl']))
                    request.session['logouturl'] = form.cleaned_data['logouturl']
                authLogLogin(request, authenticator, user.name)
                return (user, form.cleaned_data['password'])

    logger.info('Invalid form received')
    return (None, _('Invalid data'))
예제 #8
0
    def post(self) -> typing.Any:
        """
        This login uses parameters to generate auth token
        The alternative is to use the template tag inside "REST" that is called auth_token, that extracts an auth token from an user session
        We can use any of this forms due to the fact that the auth token is in fact a session key
        Parameters:
            mandatory:
                username:
                password:
                authId or auth or authSmallName: (must include at least one. If multiple are used, precedence is the list order)
            optional:
                platform: From what platform are we connecting. If not specified, will try to deduct it from user agent.
                Valid values:
                    Linux = 'Linux'
                    WindowsPhone = 'Windows Phone'
                    Windows = 'Windows'
                    Macintosh = 'Mac'
                    Android = 'Android'
                    iPad = 'iPad'
                    iPhone = 'iPhone'
                Defaults to:
                    Unknown = 'Unknown'

        Result:
            on success: { 'result': 'ok', 'auth': [auth_code] }
            on error: { 'result: 'error', 'error': [error string] }

        Locale comes on "Header", as any HTTP Request (Accept-Language header)
        Calls to any method of REST that must be authenticated needs to be called with "X-Auth-Token" Header added
        """
        # Checks if client is "blocked"
        cache = Cache('RESTapi')
        fails = cache.get(self._request.ip) or 0
        if fails > ALLOWED_FAILS:
            logger.info('Access to REST API %s is blocked for %s seconds since last fail', self._request.ip, GlobalConfig.LOGIN_BLOCK.getInt())
        
        try:
            if 'authId' not in self._params and 'authSmallName' not in self._params and 'auth' not in self._params:
                raise RequestError('Invalid parameters (no auth)')

            scrambler: str = ''.join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(32))  # @UndefinedVariable
            authId: typing.Optional[str] = self._params.get('authId', None)
            authSmallName: typing.Optional[str] = self._params.get('authSmallName', None)
            authName: typing.Optional[str] = self._params.get('auth', None)
            platform: str = self._params.get('platform', self._request.os)

            username: str
            password: str

            username, password = self._params['username'], self._params['password']
            locale: str = self._params.get('locale', 'en')
            if authName == 'admin' or authSmallName == 'admin':
                if GlobalConfig.SUPER_USER_LOGIN.get(True) == username and GlobalConfig.SUPER_USER_PASS.get(True) == password:
                    self.genAuthToken(-1, username, password, locale, platform, True, True, scrambler)
                    return Login.result(result='ok', token=self.getAuthToken())
                return Login.result(error='Invalid credentials')

            # Will raise an exception if no auth found
            if authId:
                auth = Authenticator.objects.get(uuid=processUuid(authId))
            elif authName:
                auth = Authenticator.objects.get(name=authName)
            else:
                auth = Authenticator.objects.get(small_name=authSmallName)

            if not password:
                password = '******'  # Extrange password if credential left empty. Value is not important, just not empty

            logger.debug('Auth obj: %s', auth)
            user = authenticate(username, password, auth, True)
            if user is None:  # invalid credentials
                # Sleep a while here to "prottect"
                time.sleep(3)  # Wait 3 seconds if credentials fails for "protection"
                # And store in cache for blocking for a while if fails
                cache.put(self._request.ip, fails+1, GlobalConfig.LOGIN_BLOCK.getInt())
                
                return Login.result(error='Invalid credentials')
            return Login.result(
                result='ok',
                token=self.genAuthToken(auth.id, user.name, password, locale, platform, user.is_admin, user.staff_member, scrambler),
                scrambler=scrambler
            )

        except Exception:
            # logger.exception('exception')
            pass

        return Login.result(error='Invalid credentials')