def authenticate(request: HttpRequest, backends: list[str], **credentials: dict[str, Any]) -> Optional[User]: """If the given credentials are valid, return a User object. Customized version of django's authenticate, which accepts a list of backends""" for backend_path in backends: try: backend: BaseBackend = path_to_class(backend_path)() except ImportError: LOGGER.warning("Failed to import backend", path=backend_path) continue LOGGER.debug("Attempting authentication...", backend=backend_path) user = backend.authenticate(request, **credentials) if user is None: LOGGER.debug("Backend returned nothing, continuing", backend=backend_path) continue # Annotate the user object with the path of the backend. user.backend = backend_path LOGGER.debug("Successful authentication", user=user, backend=backend_path) return user # The credentials supplied are invalid to all backends, fire signal user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials), request=request)
def create(self, request, *args, **kwargs): """ @apiVersion 1.0.0 @api {POST} /auth Login @apiName Login @apiGroup Auth @apiPermission none @apiParam {string} email user's email @apiParam {string} password user's password @apiSuccessExample {json} Success-Response: HTTP/1.1 200 OK { "status": 200, "errors": [], "success": true, "data": { "user": { "is_staff": false, "email": "*****@*****.**", "name": "Dat Nguyen" }, "token": "d5d6d757923c9f67cc8f56eac0460f36a2f14422" } } """ serializer = self.get_serializer(data=request.data) try: serializer.is_valid(raise_exception=True) except exceptions.ValidationError as e: user_login_failed.send(sender=__name__, credentials=request.data) raise e return self.login_success(serializer.validated_data['user'])
def form_valid(self, form): if self.request.user.is_authenticated: return super().form_valid(form) try: from django.contrib.auth import authenticate user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password']) if user is not None and user.profile.tmp_login: return HttpResponseRedirect( ('/user/forgot/{}/{}'.format(user.profile.email, user.profile.token))) if user is not None: login(self.request, user) return super().form_valid(form) except: pass ip = get_client_ip(self.request) user_login_failed.send( sender=User, request=self.request, credentials={'username': form.cleaned_data['username']}) logger.warning('Invalid log-in attempt for user: {} from {}'.format( form.cleaned_data['username'], ip)) form.add_error(None, "Provide a valid username and/or password") return super().form_invalid(form)
def post(self, request, *args, **kwargs): """ Handle POST requests: instantiate a form instance with the passed POST variables and then check if it's valid. """ # If failures is gt 3, than use captcha form instead. form = self.get_form() failures = self.get_failures(request) failures = failures + 1 if failures > 0 else failures if failures >= self.login_failures: form = self.get_form(form_class=CaptchaLoginForm) if form.is_valid(): data = self.form_valid(form) return JsonResponse(data) else: csrf_token = request.COOKIES.get('csrftoken', '') user_login_failed.send( sender=__name__, request=request, credentials={ 'csrftoken': csrf_token } ) data = self.get_form_errors(form) if failures >= self.login_failures: captcha_html = str(form['captcha']) data['captcha'] = captcha_html return JsonResponse(data)
def update(self, request, pk=None): ''' Handles the sign up confirmation ''' #Check ip has not been locked if not AxesProxyHandler.is_allowed(request): raise Http404 try: sign_up = SignUp.objects.get(confirmation_key=pk) except: user_login_failed.send(sender=SignUpViewSet, credentials={'username': pk}, request=request) raise Http404 password = request.data.get("password") #Invalid password should be checked bu UI if len(password) < 8: raise ParseError('Password too Short') user = sign_up.complete_registration(password) serializer = UserSerializer(user) return Response(serializer.data)
def authenticate(zone_name, **credentials): """ If the given credentials are valid, return a User object. """ backend = get_backend(zone_name) if not backend: return None user = None try: user = backend.authenticate(**credentials) except TypeError: # This backend doesn't accept these credentials as arguments. exit pass except PermissionDenied: # This backend says that this user should not be allowed in at all. pass if user: # Annotate the user object with the path of the backend. user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) return user # The credentials supplied are invalid to all backends, fire signal user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials))
def authenticate(**credentials): """ If the given credentials are valid, return a User object. """ for backend, backend_path in _get_backends(return_tuples=True): try: inspect.getcallargs(backend.authenticate, **credentials) except TypeError: # This backend doesn't accept these credentials as arguments. Try the next one. continue try: user = backend.authenticate(**credentials) except PermissionDenied: # This backend says to stop in our tracks - this user should not be allowed in at all. return None if user is None: continue # Annotate the user object with the path of the backend. user.backend = backend_path return user # The credentials supplied are invalid to all backends, fire signal user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials))
def form_invalid(self, form): # The device verification failed, fire login_failed signal like Django # does on failed autentication attempts against all backends. # Token will be excluded from credentials so just provide an empty # dictionary and log the user and device that were protected. user_login_failed.send( sender=__name__, credentials={}, request=self.request, user=self.unverified_user, device=self.object) return super().form_invalid(form)
def clean(self): try: cleaned_data = super(HQBackupTokenForm, self).clean() except ValidationError: user_login_failed.send(sender=__name__, credentials={'username': self.user.username}) couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out() and couch_user.supports_lockout(): raise ValidationError(LOCKOUT_MESSAGE) else: raise couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out() and couch_user.supports_lockout(): raise ValidationError(LOCKOUT_MESSAGE) return cleaned_data
def login(request): if request.method == "GET": form = LogInForm() res_data = {'title': '登入', 'year': datetime.now().year, 'form': form} return render(request, 'app/login.html', res_data) if request.method == "POST": form = LogInForm(request.POST) valid_state = form.is_valid() username = form.cleaned_data['username'] password = form.cleaned_data['password'] ip_address = get_ip(request) failures_res = AccessAttempt.objects.filter(username=username, ip_address=ip_address) # 有超過一筆資料 if failures_res.count() > 0: failure_res = failures_res[0] failure_count = failure_res.failures failure_lasttime = failure_res.attempt_time.replace(tzinfo=None) # 超過登入次數限制 if failure_count >= settings.AXES_FAILURE_LIMIT: nowtime = datetime.utcnow().replace(tzinfo=None) minutes_from_las_attempt = (nowtime - failure_lasttime) # 低於15分鐘內重複登入 if minutes_from_las_attempt < settings.AXES_COOLOFF_TIME: messages.warning(request, '您的帳戶已經被鎖定,請15分鐘後再嘗試。') res_data = {'title': '帳戶鎖定', 'year': datetime.now().year} return render(request, 'app/message.html', res_data) else: failure_res.delete() if valid_state: user = authenticate(username=username, password=password) user_logged_in.send(sender=User, request=request, user=user) auth.login(request, user) if failures_res.count() > 0: failures_res[0].delete() return redirect("/") else: print(form.cleaned_data.get('username')) user_login_failed.send( sender=User, request=request, credentials={'username': form.cleaned_data.get('username')}) res_data = { 'title': 'Login', 'year': datetime.now().year, 'form': form } return render(request, 'app/login.html', res_data)
def _auth_user(self, serializer: serializers.SocialMediaSerializer): user = self.get_backend().authenticate( self.request, serializer.validated_data['data'], create_user=True) if user is None: user_login_failed.send( sender=self.backend_class.__name__, credentials=serializer.validated_data['data'], request=self.request, ) raise SingleValidationError( _('Данный пользователь не существуюет или деактивирован'), ) user_logged_in.send(sender=user.__class__, request=self.request, user=user) return user
def get_invite(self, request, pk): #Check ip has not been locked if not AxesProxyHandler.is_allowed(request): raise Http404 # Check confirmation key exists try: invite = EmailConfirmation.objects.get(confirmation_key=pk) except: user_login_failed.send(sender=InviteEmailViewSet, credentials={'username': pk}, request=request) raise Http404 return invite
def get_invite(self, request, pk): #Check ip has not been locked if not AxesProxyHandler.is_allowed(request): raise PermissionDenied( 'Requests from this ip addess has been locked for 48 hours') # Check confirmation key exists try: invite = EmailConfirmation.objects.get(confirmation_key=pk) except: user_login_failed.send(sender=InviteEmailViewSet, credentials={'username': pk}, request=request) raise PermissionDenied('Invalid invite token') return invite
def authenticate(request=None, **credentials): """ If the given credentials are valid, return a User object. """ for backend, backend_path in _get_backends(return_tuples=True): try: user = _authenticate_with_backend(backend, backend_path, request, credentials) except PermissionDenied: # This backend says to stop in our tracks - this user should not be allowed in at all. break if user is None: continue # Annotate the user object with the path of the backend. user.backend = backend_path return user # The credentials supplied are invalid to all backends, fire signal user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials), request=request)
def authenticate(**credentials): """ If the given credentials are valid, return a User object. """ for backend in get_backends(): try: user = backend.authenticate(**credentials) except TypeError: # This backend doesn't accept these credentials as arguments. Try the next one. continue if user is None: continue # Annotate the user object with the path of the backend. user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__) return user # The credentials supplied are invalid to all backends, fire signal user_login_failed.send(sender=__name__, credentials=_clean_credentials(credentials))
def clean(self): try: cleaned_data = super(HQBackupTokenForm, self).clean() except ValidationError: user_login_failed.send(sender=__name__, credentials={'username': self.user.username}, request=self.request, token_failure=True) couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out(): metrics_counter('commcare.auth.token_lockout') raise ValidationError(LOCKOUT_MESSAGE) else: raise # Handle the edge-case where the user enters a correct token # after being locked out couch_user = CouchUser.get_by_username(self.user.username) if couch_user and couch_user.is_locked_out(): metrics_counter('commcare.auth.lockouts') raise ValidationError(LOCKOUT_MESSAGE) return cleaned_data
def login(request): template_name = 'accounts/login/login-page.html' if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') nxt = request.POST.get('next') if username and password: user = authenticate(request, email=username, password=password) if user is not None: if not user.is_active: messages.error(request, _('Your Account is inactive!'), extra_tags='danger') return HttpResponseRedirect(reverse('accounts:user_login')) else: li(request, user) if user.is_company: nxt = reverse('accounts:console') elif str(nxt) == str(reverse('accounts:user_login')): nxt = '/' return HttpResponseRedirect(nxt) else: user_login_failed.send( sender=User, request=request, credentials={ 'email': username }, ) messages.error(request, _('An account with these credential does not exist. Please try again or reset ' 'your password.')) return HttpResponseRedirect(reverse('accounts:user_login')) return render(request=request, context={}, template_name=template_name)
def post(self, request, *args, **kwargs): message = None form = LoginForm(request.POST) if form.is_valid(): username = request.POST['username'] password = request.POST['password'] user = authenticate(username=username, password=password) if user is not None: if user.is_active: login(request, user) prueba = user.id request.session['usuario'] = prueba request.session['nombreusuario'] = username user_logged_in.send( sender=User, request=request, user=user, ) return render(request, 'main/home.html', {}) else: messages.info( request, 'Autenticasion no exitosa vuelva intentarlo!') user_login_failed.send( sender=User, request=request, credentials={ 'username': form.cleaned_data.get('username') }, ) else: user_login_failed.send(sender=User, request=request, credentials={ 'username': form.cleaned_data.get('username') }) messages.warning(request, 'Usuario o Contraseña no validos!') else: user_login_failed.send( sender=User, request=request, credentials={'username': form.cleaned_data.get('username')}) return render(request, 'main/login.html', { 'message': message, 'form': form })
def _send_fail_signal(request, username): user_login_failed.send(sender=__name__, credentials={'username': username})
def verify_user(request): def render_response(msg, code): _context = { 'status': 'Error' if code > 201 else 'OK', 'message': str(_(msg)) } return HttpResponse(json.dumps(_context), status=code, content_type='application/json') sent_token = request.POST.get('token') sent_token = sanitize_number(sent_token) login_with_email = request.POST.get('login_with_email', False) == 'true' email = request.POST.get('email', '') phone = request.POST.get('phone', '') phone = sanitize_number(phone, True) if login_with_email: username = email _type = 'email' else: username = phone _type = 'phone' anonymous = request.user.is_anonymous if anonymous and username: # fast registration try: user = User.objects.get(username=username) except User.DoesNotExist: user_login_failed.send( sender=User, request=request, credentials={'username': username}, ) return render_response( 'Please make sure your {} is correct'.format(_type), 400) elif anonymous and not username: # Fast registration user_login_failed.send( sender=User, request=request, credentials={'username': username}, ) return render_response('Please enter your {}'.format(_type), 400) else: # Profile page user = request.user try: sms_token = SmsToken.objects.filter(user=user).latest('id') except SmsToken.DoesNotExist: user_login_failed.send( sender=User, request=request, credentials={'username': username}, ) return render_response( 'Your token has expired, ' 'Please request a new token', 400) if sent_token == sms_token.sms_token: if not sms_token.valid: user_login_failed.send( sender=User, request=request, credentials={'username': username}, ) return render_response( 'Your token has expired, ' 'Please request a new token', 410) profile = user.profile if not login_with_email: profile.disabled = False profile.save() sms_token.delete() if anonymous: user.backend = 'django.contrib.auth.backends.ModelBackend' login(request, user) # Fool attacker into thinking that the number is # not registered with 201 user_logged_in.send( sender=User, request=request, user=user, ) return render_response( 'Successfully logged in' if anonymous else '{} verified successfully'.format(_type), 201 if anonymous else 200) else: user_login_failed.send( sender=User, request=request, credentials={'username': username}, ) return render_response('You have entered an incorrect code', 400)
def user_get_or_create(request): """This is used for seemless fast login""" logger = get_nexchange_logger('user_get_or_create') login_with_email = request.POST.get('login_with_email', False) == 'true' phone = request.POST.get('phone', '') phone = sanitize_number(phone, True) email = request.POST.get('email', '') user_data = {} profile_data = {} if not login_with_email: username = profile_data['phone'] = phone _validator = validate_international_phonenumber else: username = user_data['email'] = email _validator = validate_email try: _validator(username) except ValidationError as e: context = {'status': 'error', 'msg': str(e.message)} user_login_failed.send(sender=User, request=request, credentials={'username': username}) return HttpResponse(json.dumps(context), status=400, content_type='application/json') user_data['username'] = username user, u_created = User.objects.get_or_create(**user_data) if u_created: profile_data['disabled'] = True profile_data['user'] = user Profile.objects.get_or_create(**profile_data) try: if not login_with_email: res = send_auth_sms(user) else: res = send_auth_email(user) except Exception as e: logger.error('Exception: {} Traceback: {}'.format(e, get_traceback())) error_tmpl = 'Our {} service provider is down. Please contact ' \ 'administrator.' if not login_with_email: error_msg = _(error_tmpl.format('SMS')) else: error_msg = _(error_tmpl.format('EMAIL')) context = {'status': 'error', 'message': str(error_msg)} user_login_failed.send(sender=User, request=request, credentials={'username': username}) return HttpResponse(json.dumps(context), status=503, content_type='application/json') if isinstance(res, Exception): user_login_failed.send(sender=User, request=request, credentials={'username': username}) return JsonResponse({'status': 'error'}) else: user_login_failed.send(sender=User, request=request, credentials={'username': username}) # user_logged_in.send( # sender=User, # request=request, # user=user # ) return JsonResponse({'status': 'ok'})