How to handle AuthAlreadyAssociated at Python-auth/Django-Social? [duplicate] - python

This question already has answers here:
AuthAlreadyAssociated Exception in Django Social Auth
(5 answers)
Closed 9 months ago.
I use this python-social-auth/social-app-django to connect my web with social media
I want to ask how to handle errors when the same account is used to sign up?
For example, I signed up using facebook and I signed up again using twitter. both successfully registered into two separate accounts, when I logged in using my facebook and then on my account settings page, I want to connect my twitter that has been registered before it will display an error message
"AuthAlreadyAssociated at / oauth / complete / twitter /"
AuthAlreadyAssociated
This message appears after I authorize on the twitter redirect page when it gets redirected back to my web.
In short, how to deal with accounts that have been registered in other accounts?
This is my views.py:
#login_required
def settings(request):
user = request.user
try:
github_login = user.social_auth.get(provider='github')
except UserSocialAuth.DoesNotExist:
github_login = None
try:
twitter_login = user.social_auth.get(provider='twitter')
except UserSocialAuth.DoesNotExist:
twitter_login = None
try:
facebook_login = user.social_auth.get(provider='facebook')
except UserSocialAuth.DoesNotExist:
facebook_login = None
can_disconnect = (user.social_auth.count() > 1 or
user.has_usable_password())
return render(request, 'profile/settings.html', {
'github_login': github_login,
'twitter_login': twitter_login,
'facebook_login': facebook_login,
'can_disconnect': can_disconnect
})
And this is my settings.html template:
{% extends "base.html" %}
{% load crispy_forms_tags %}
{% block title %}Navhi Microblog - Profile{% endblock %}
{% block content %}
<div class="col-lg-12 mx-auto">
<br />
<div class="card">
<div class="card-body">
{% include 'profile/base_profile.html' %}
<!--Card Body goes here-->
<div class="card-body">
<div class="card">
<div class="card-body">
{% if github_login %}
{% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'github' %}">
{% csrf_token %}
<button class="btn btn-danger btn-block" type="submit">Disconnect from GitHub</button>
</form>
{% else %}
<p class="text-center" style="color: red">You must define a password for your account before disconnecting from Github.</<p class="text-center">
{% endif %}
{% else %}
<a class="btn btn-sm btn-social btn-github btn-block" href="{% url 'social:begin' 'github' %}?next={{ request.path }}">
<span class="fa fa-github"></span> Connect to Github
</a>
{% endif %}
</div>
</div>
<br />
<div class="card">
<div class="card-body">
{% if twitter_login %}
{% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'twitter' %}">
{% csrf_token %}
<button class="btn btn-danger btn-block" type="submit">Disconnect from Twitter</button>
</form>
{% else %}
<p class="text-center" style="color: red">You must define a password for your account before disconnecting from Twitter.</p>
{% endif %}
{% else %}
<a class="btn btn-sm btn-social btn-twitter btn-block" href="{% url 'social:begin' 'twitter' %}?next={{ request.path }}">
<span class="fa fa-twitter"></span> Connect to Twitter
</a>
{% endif %}
</div>
</div>
<br />
<div class="card">
<div class="card-body">
{% if facebook_login %}
{% if can_disconnect %}
<form method="post" action="{% url 'social:disconnect' 'facebook' %}">
{% csrf_token %}
<button class="btn btn-danger btn-block" type="submit">Disconnect from Facebook</button>
</form>
{% else %}
<p class="text-center" style="color: red">You must define a password for your account before disconnecting from Facebook.</p>
{% endif %}
{% else %}
<a class="btn btn-sm btn-social btn-facebook btn-block" href="{% url 'social:begin' 'facebook' %}?next={{ request.path }}">
<span class="fa fa-facebook"></span> Connect to Facebook
</a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Thank you, I hope somebody can provide a solution for this, and sorry for my bad english.

Your question has been answered here:
AuthAlreadyAssociated Exception in Django Social Auth
Basically the answer is to override the default method process_exception() in the social_auth.middleware.SocialAuthExceptionMiddleware class, and add this middleware to your settings.py.
More on how to override here: How do I handle exceptions on Python Social Auth

Related

improperly configured at /18/delete, Django views issue

I have searched through the other questions similar to my own problem and have come to no solution so im hoping someone can help me figure out where i went wrong.
I'm trying to implement a delete post option in my blog program but it is throwing the following error once you click the 'delete' button:
ImproperlyConfigured at /18/delete/
Deletepost is missing a QuerySet. Define Deletepost.model, Deletepost.queryset, or override Deletepost.get_queryset().
I am nearly sure its a problem with my URLS.py though what exactly i cannot figure out.
the following is the code in question:
Views.py
# delete post
class Deletepost(LoginRequiredMixin, DeleteView):
form_class = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
urls.py
urlpatterns = [
# home
path('', views.postslist.as_view(), name='home'),
# add post
path('blog_post/', views.PostCreateView.as_view(), name='blog_post'),
# posts/comments
path('<slug:slug>/', views.postdetail.as_view(), name='post_detail'),
# edit post
path('<slug:slug>/edit/', views.Editpost.as_view(), name='edit_post'),
# delete post
path('<int:pk>/delete/', views.Deletepost.as_view(), name='delete_post'),
# likes
path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'),
]
post.html
{% extends 'base.html' %} {% block content %}
{% load crispy_forms_tags %}
<div class="masthead">
<div class="container">
<div class="row g-0">
<div class="col-md-6 masthead-text">
<!-- Post title goes in these h1 tags -->
<h1 class="post-title text-success">{{ post.title }}</h1>
<!-- Post author goes before the | the post's created date goes after -->
<p class="post-subtitle text-success">{{ post.author }} | {{ post.created_on }}</p>
</div>
<div class="d-none d-md-block col-md-6 masthead-image">
<!-- The featured image URL goes in the src attribute -->
{% if "placeholder" in post.featured_image.url %}
<img src="https://codeinstitute.s3.amazonaws.com/fullstack/blog/default.jpg" width="100%">
{% else %}
<img src=" {{ post.featured_image.url }}" width="100%">
{% endif %}
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col card mb-4 mt-3 left top">
<div class="card-body text-dark">
<!-- The post content goes inside the card-text. -->
<!-- Use the | safe filter inside the template tags -->
<p class="card-text text-dark">
{{ post.content | safe }}
</p>
<div class="row">
<div class="col-1">
<strong>
{% if user.is_authenticated %}
<form class="d-inline" action="{% url 'post_like' post.slug %}" method="POST">
{% csrf_token %}
{% if liked %}
<button type="submit" name="blogpost_id" value="{{post.slug}}" class="btn-like"><i class="fas fa-heart"></i></button>
{% else %}
<button type="submit" name="blogpost_id" value="{{post.slug}}" class="btn-like"><i class="far fa-heart"></i></button>
{% endif %}
</form>
{% else %}
<span class="text-secondary"><i class="far fa-heart"></i></span>
{% endif %}
<!-- The number of likes goes before the closing strong tag -->
<span class="text-secondary">{{ post.number_of_likes }} </span>
</strong>
</div>
<div class="col-1">
{% with comments.count as total_comments %}
<strong class="text-dark"><i class="far fa-comments"></i>
<!-- Our total_comments variable goes before the closing strong tag -->
{{ total_comments }}</strong>
{% endwith %}
</div>
<div class="col-1">
<a class="btn btn-outline-danger" href="{% url 'delete_post' post.id %}">Delete It</a>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<hr>
</div>
</div>
<div class="row">
<div class="col-md-8 card mb-4 mt-3 ">
<h3 class="text-dark">Comments:</h3>
<div class="card-body">
<!-- We want a for loop inside the empty control tags to iterate through each comment in comments -->
{% for comment in comments %}
<div class="comments text-dark" style="padding: 10px;">
<p class="font-weight-bold">
<!-- The commenter's name goes here. Check the model if you're not sure what that is -->
{{ comment.name }}
<span class=" text-muted font-weight-normal">
<!-- The comment's created date goes here -->
{{ comment.created_on }}
</span> wrote:
</p>
<!-- The body of the comment goes before the | -->
{{ comment.body | linebreaks }}
</div>
<!-- Our for loop ends here -->
{% endfor %}
</div>
</div>
<div class="col-md-4 card mb-4 mt-3 ">
<div class="card-body">
<!-- For later -->
{% if commented %}
<div class="alert alert-success" role="alert">
Your comment is awaiting approval
</div>
{% else %}
{% if user.is_authenticated %}
<h3 class="text-dark">Leave a comment:</h3>
<p class="text-dark">Posting as: {{ user.username }}</p>
<form class="text-dark" method="post" style="margin-top: 1.3em;">
{{ comment_form | crispy }}
{% csrf_token %}
<button type="submit" class="btn btn-signup btn-lg">Submit</button>
</form>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
{% endblock content %}
Any ideas?
I think it should be model not form_class so:
class Deletepost(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def test_func(self):
post = self.get_object()
if self.request.user == post.author:
return True
return False
#SunderamDubey's answer is correct. The test_func will however not run, since this is method of the UserPassesTestMixin [Django-doc], not LoginRequiredMixin.
But using a test function as is done here is not efficient: it will fetch the same object twice from the database. You can simply restrict the queryset, like:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from django.views.generic import DeleteView
class DeletePostView(LoginRequiredMixin, DeleteView):
model = Post
success_url = reverse_lazy('blog:home')
template_name = 'templates/post.html'
def get_queryset(self, *args, **kwargs):
return (
super().get_queryset(*args, **kwargs).filter(author=self.request.user)
)
This will do filtering at the database side, and thus return a 404 in case the logged in user is not the author of the Post object you want to delete.
In the template, you will need to make a mini-form to make a POST request, for example:
<form method="post" action="{% url 'delete_post' post.id %}">
{% csrf_token %}
<button class="btn btn-outline-danger" type="submit">Delete</button>
</form>
In my opinion, you should change url to below
'path('delete/int:pk', views.Deletepost.as_view(), name='delete_post'),'
if didn't work you can do this
def delete_post(request, post_id):
post = Post.objects.get(pk=post_id)
post.delete()
return redirect('blog:home')

Django - ListView with form, How to redirect back to the Form page?

So, I have a ListView with exercices list (paginated 1 per page). In each page I have few input the user need to fill up. I managed to find a solution to how to attached the ListView with the Form but i cant find a solution on how to stay on the same page after the submit.
url's:
urlpatterns = [
path('programs/', ProgramListView.as_view(), name='web-programs'),
path('programs/<int:pk>/', ExerciseListView.as_view(), name='program-detail'),
path('data/', views.add_data, name='data-submit'),
views.py (updated with def form_valid):
class ExerciseListView(LoginRequiredMixin,FormMixin, ListView):
model = Exercise
context_object_name = 'exercises'
form_class = DataForm
paginate_by = 1
def get_queryset(self):
program_num = get_object_or_404(Program, pk=self.kwargs.get('pk'))
return Exercise.objects.filter(program=program_num)
def form_valid(self, dataform):
program_num = get_object_or_404(Program, pk=self.kwargs.get('pk'))
exercises = Exercise.objects.filter(program=program_num)
for exe in exercises:
dataform.instance.exercise = exe.pk
return super(ExerciseListView, self).form_valid(dataform)
def add_data(request):
if request.method == "POST":
form = DataForm(request.POST)
if form.is_valid():
form.save()
# Data.objects.create(address=form.cleaned_data['form'])
return redirect(?)
template.html:
{% extends "program/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<h3> Program Exercises List </h3>
{% for exercise in exercises %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
{% if user.is_superuser %}
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'exercise-update' exercise.id %}">Update</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'exercise-delete' exercise.id %}">Delete</a>
<p class="article-content">{{ exercise.name }}</p>
{% else %}
<p class="article-content">{{ exercise.name }}</p>
{% endif %}
</div>
<div class="article-metadata">
<p class="article-content">{{ exercise.description }}</p>
<p class="article-content">{{ exercise.breath_method}}</p>
<p class="article-content">{{ exercise.recovery_method }}</p>
<p class="article-content">{{ exercise.measure_method }}</p>
<p class="article-content">{{ exercise.load_share }}</p>
<p class="article-content">{{ exercise.notes }}</p>
<p class="article-content">{{ exercise.extra_info }}</p>
<p class="article-content">{{ exercise.reps }}</p>
<p class="article-content">{{ exercise.sets }}</p>
</div>
<form action="{% url 'data-submit' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Exercise Measurements</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Save</button>
</div>
</form>
</div>
</article>
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous Exercise</a>
{% endif %}
{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next Exercise</a>
{% else %}
<a class="btn btn-outline-info mb-4" href="{% url 'web-home' %}">Exit</a>
{% endif %}
{% endif %}
{% endblock content %}
forms.py:
class DataForm(forms.ModelForm):
class Meta:
model = Data
fields = ['exercise', 'set_number', 'spo2', 'hr']
In the views.py, i left the "redirect" with "?" because i don't know what to add there.
I can't change the "action" in the template.html because this link is for def add_data(request)
so it will save my inputs.
Once i submit, it saves the new data to my DB but i don't know how to stay on the same page for continue my exercises.
Thanks.
You have Program in Exercise so use it get program id looking at your DataForm you have exercise field if am not wrong is foreign-key
from django.shortcuts import redirect, reverse
def add_data(request):
page=request.GET.get('page')
page='?page={}'.format(page) if page else ''
if request.method == "POST":
form = DataForm(request.POST)
if form.is_valid():
data=form.save()
return redirect(reverse('program-detail', kwargs={'pk':data.exercise.program.pk})+ page)
For redirecting to same page you check and pass page parmameter in url in form action like
<form action="{% url 'data-submit' %}{%if request.GET.page%}?page={{request.GET.page}}{%endif%}" method="POST" enctype="multipart/form-data">{% csrf_token %}
You need to use jQuery to achieve this result. Download it, paste to js folder and add it to program/base.html
<script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
I'd like to recommend you to add a js block into base.html
somewhere at the bottom of the file
{% block js %}{% endblock js %}
Then, do this:
<block js>
<script>
$("#submit-btn").submit(function(event) {
// prevent default action, so no page refreshing
event.preventDefault();
var form = $(this);
var posting = $.post( form.attr('action'), form.serialize() );
posting.done(function(data) {
// done
});
posting.fail(function(data) {
// fail
});
});
</script>
<endblock>
...
<form action="{% url 'data-submit' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Exercise Measurements</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" id="submit-btn" type="submit">Save</button>
</div>
</form>

reCAPTCHA not stopping users logging in

I am trying to use Google reCAPTCHA for my login form to prevent spam. After following the necessary steps to get it all working, users can still login. They can fill out there details and login with out ticking the checkbox which isn't correct.
I think it might be the placement in the DOM so I tried moving it around and that didn't work.
CODE:
{% extends 'public/base.html' %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{% block head %}
<link rel="stylesheet" type="text/css" href="{% static "public/css/auth.css" %}" />
{% endblock %}
{% block content %}
<div class="container mt-5 mb-5 login-container">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group mt-4">
<legend class="border-bottom mb-4">Log In</legend>
{{ form|crispy }}
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="################################
"></div>
</fieldset>
<div class="form-group">
<button class="btn btn-success" type="submit">Login</button>
<small class="text-muted ml-2">
Forgot Password?
</small>
</div>
</form>
<div class="border-top pt-3 mb-4">
<small class="text-muted">
Need An Account? <a class="ml-2" href="{% url 'register' %}">Sign Up Now</a>
</small>
</div>
</div>
{% endblock %}```
Thanks.
When you use the captcha, a textarea is added dynamically inside <div class="g-recaptcha">.
That textarea is not visible and by default has id="g-recaptcha-response".
You can get it with:
document.getElementById('g-recaptcha-response').value
In your login form you have to check if that textarea has a value or not. If it has a value then user has used successfully the captcha and can continue with the login process.
Something like this:
<form onsubmit="return check_form()">
...
</form>
<script>
function check_form()
{
return document.getElementById('g-recaptcha-response').value != '';
}
</script>
If check_form() returns FALSE, then the form is not submitted.

Request in Flask from a Form in HTML is returning None Value, What should I Do?

I am getting no value on request in flask. It is returning None value.
I have tried changing the method but no use.
The flask code:
#app.route("/login/user/book")
def searchbook():
bookname=request.form.get("search")
return render_template("message.html",heading=bookname ,message=" ")
The webpage:
{% extends "layout.html" %}
{% block heading %}Welcome to BookSarkar{% endblock %}
{% block body %}
<p>Welcome {{ name }}</p>
<form action="{{ url_for('searchbook') }}" method="get" class="form-group">
<div class="form-group">
<input type="text" name="search" class="form-control col-md-6 mt-5 mx-auto" placeholder="Search books">
<p style="text-align:center;">
<button type ="submit" class="btn btn-primary mt-2 mx-auto">Search</button>
</p>
</div>
</form>
<div class="fixed-top m-2">
<a class="btn btn-outline-primary" href="{{ url_for('logout') }}" role="button" style="float:right;">Log out</a>
</div>
{% endblock %}
The message webpage:
{% extends "layout.html" %}
{% block heading %}{{ heading }}{% endblock %}
{% block body %}
{{ message }}
<a class="btn btn-primary" href="{{ url_for('index') }}" role="button">Return to Home Page</a>
{% endblock %}
The layout page has no bugs as all other pages are working fine. I expected the webpage to show the given input but it is showing None
request.form contains values submitted via post or put, while your form uses get. Try using request.args.get("search") instead of request.form.get("search")

django-bootstrap-toolkit for my contact page

I'm new to django. I'm using django-bootstrap-toolkit for my contact page. It works fine when I test it locally. But I'm getting an error on my hosting server, while all other pages work just fine.
Exception Type: TemplateDoesNotExist
Exception Value: bootstrap_toolkit/form.html
Here is contact_us.html page
bootstrap_toolkit/form.html
{% extends 'base.html' %}
{% load bootstrap_toolkit %}
{% block content %}
<div id="wrap">
<div class="container">
<div class="page-header">
<h1 id="contact">Contact</h1>
</div>
<div class="form well" >
<h4 class="">Feedback</h4>
<p class="">Thank you for downloading BookxGeek. I look forward to hearing your feedback!</p>
<form action="." method="post" class="form" >
{% csrf_token %}
{% bootstrap_form form layout="vertical" %}
<br>
<div class="form-actions">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
<hr class="soft">
</div>
{% endblock %}

Categories