Got AttributeError when attempting to get a value for field `email` on serializer `LoginSerializer` - serialization

Creating a Django API and want to login the user, the login is working but the exceptions not so much.
It was working until i wanted to return status
AttributeError at /login/
Got AttributeError when attempting to get a value for field email on serializer LoginSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Response instance.
Original exception text was: 'Response' object has no attribute 'email'.
I saw a few answers but the context didnt match.
What am i missing or doing wrong?
class LoginSerializer(serializers.ModelSerializer):
email = serializers.EmailField()
password = serializers.CharField(max_length=68, min_length=6, write_only = True)
username = serializers.CharField(
read_only=True
)
tokens = serializers.CharField(max_length=68, min_length=6, read_only=True)
class Meta:
model=User
fields = ['email', 'username', 'password', 'tokens']
def validate(self, attrs):
email = attrs.get('email', '')
password = attrs.get('password', '')
user = auth.authenticate(email=email, password=password)
if user is None:
return Response({'msg':'No such user'}, status=status.HTTP_401_UNAUTHORIZED)
# raise AuthenticationFailed({'status':False,'message': ' username is worng'}, status=status.HTTP_401_UNAUTHORIZED)
if not user.is_active:
raise AuthenticationFailed({'msg':'Account is disabled'})
if not user.is_verified:
raise AuthenticationFailed({'msg': 'Email is not verified'})
if not user:
return Response({'msg':'Invalid credentials, try again'}, status=status.HTTP_401_Unauthorized)
return{
'email':user.email,
'username':user.username,
'tokens':user.tokens()
}
return super.validate(attrs)
'views.py'
class LoginAPIView(APIView):
serializer_class = LoginSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception = True)
return Response(serializer.data, status=status.HTTP_200_OK)
custom user model
class UserManager(BaseUserManager):
def create_user(self, username, email, password):
if username is None:
raise TypeError("User should be provide username")
if email is None:
raise TypeError("User should be provide email")
if password is None:
raise TypeError("User should be provide password")
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, password):
user = self.create_user(username, email, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=255, db_index=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_verified = models.BooleanField(default=False)
# is_authenticated = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def __str__(self):
return self.email
def tokens(self):
refresh = RefreshToken.for_user(self)
return {
'refresh': str(refresh),
'access': str(refresh.access_token)
}

def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
user = auth.authenticate(email=email, password=password)
print (user)
if not user:
raise AuthenticationFailed({'msg': 'No such user'}, code=status.HTTP_401_UNAUTHORIZED)
if user is None:
raise AuthenticationFailed({'message': ' Your Email or Password is wrong'}, code=status.HTTP_401_UNAUTHORIZED)
# raise AuthenticationFailed({'message': ' username is wrong'})
if not user.is_active:
raise AuthenticationFailed({'msg':'Account is disabled'},code=status.HTTP_403_FORBIDDEN)
if not user.is_verified:
raise AuthenticationFailed({'msg': 'Email is not verified'}, code=status.HTTP_401_UNAUTHORIZED)
This did the job for me. I guess the error came because the 'auth' did not take 'Response'

Related

Django rest framework Logout and Login View don't work

I'm doing a user registration via email with email confirmation. Then user gets a email letter to activate and finish its registration, login methods works. But I cant logout that user, and log him again. Could you suggest any other methods got logout and login with similar register View.
Here is my RegisterView, that works good.
class RegisterView(APIView):
permission_classes = [AllowAny]
def post(self, request, *args, **kwargs):
email = request.data.get('email', False)
password = request.data.get('password', False)
role = request.data.get('role')
if email and password and role:
user = User.objects.filter(email=email)
if user.exists():
return JsonResponse('Такой email уже существует', safe=False)
else:
temp_data = {
'email': email,
'password': password,
'role': role
}
serializer = CreateUserSerializer(data=temp_data)
serializer.is_valid(raise_exception=True)
user.is_active = False
user = serializer.save()
# user = authenticate(request, email=email, password=password)
user.set_password(user.password)
user.save()
current_site = get_current_site(request)
print(current_site)
subject = 'Activate Your MySite Account'
message = render_to_string('account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
print(message)
from_email = settings.EMAIL_HOST_USER
to_email = serializer.validated_data.get('email')
email = EmailMessage(
subject, message, from_email, to=[to_email],
)
print(email)
email.send()
# return Response(serializer.data, status=status.HTTP_201_CREATED)
return HttpResponse('Please confirm your email address to complete the registration')
else:
return JsonResponse('Email не указан', safe=False)
Here is function for registration activating
def activate(request, uidb64, token):
try:
uid = force_text(urlsafe_base64_decode(uidb64))
user = User.objects.get(pk=uid)
except(TypeError, ValueError, OverflowError, User.DoesNotExist):
user = None
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.set_password(user.password)
user.save()
login(request, user)
return HttpResponse('Thank you')
else:
return HttpResponse('Activation link is invalid!')
But my logout and login views dont work
class LogoutView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated,]
def post(self, request):
# django_logout(request)
request.user.auth_token.delete()
return Response(status=204)
class LoginView(KnoxLoginView):
permission_classes = (AllowAny,) #условие, если email не подтвержден, не поулчится залогиниться
def post(self, request, format=None):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data['user']
# token, created = Token.objects.get_or_create(user=user)
# return Response({"token": token.key, 'id': token.user.id}, status=200)
login(request, user)
return super().post(request, format=None)
class LoginSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField(style={'input_type': 'password'}, trim_whitespace=False)
def validate(self, data):
email = data.get('email')
print(email)
password = data.get('password')
if email and password:
if User.objects.filter(email=email).exists():
print(email, password)
user = authenticate(request=self.context.get('request'), email=email, password=password)
print(user)
else:
msg = {
'status': False,
'detail': 'Email is not found'
}
raise serializers.ValidationError(msg)
if not user:
msg = {
'status': False,
'detail': 'Эмейлы не совпадают'
}
raise serializers.ValidationError(msg, code='authorization')
else:
msg = {
'status': False,
'detail': 'Email is not found in request'
}
raise serializers.ValidationError(msg, code='authorization')
data['user'] = user
return data

graphQL vue this.$apollo.query doesn't work with parameter (variables)

I have an application in Vuejs, and a function that downloads questionnaire via graphQL. Function works perfect until I add variables to the query.
The working code of function is:
downloadQuestionnaire() {
console.log("downloadQuestionnaire: " + questionnaireVersion);
this.$apollo
.query({
query: gql`
query questionnaire {
questionnaire(inputParams: { language: "en", version: 1 }) {
sections {
section
cssClass
remainingItemsType
endingMessageText
questions {
qId
label
question
inputType
possibleAnswers {
paId
text
}
multipleAnswersAccepted
individualFormat
answers
}
}
}
}
`,
client: "questionnaire",
variables: {
version: questionnaireVersion
}
})
.then(data => {
// this.sections = data.questionnaire;
// console.log(data);
this.copyQuestionnaie(data.data.questionnaire.sections);
// console.log(JSON.stringify(data.data.questionnaire.sections));
})
.catch(error => {
this.error = error;
alert("E " + error);
});
},
and I need to parametrise the version in the the query, by changing it to:
downloadQuestionnaire() {
console.log("downloadQuestionnaire: " + questionnaireVersion);
this.$apollo
.query({
query: gql`
query questionnaire($version: Int) {
questionnaire(
inputParams: { language: "en", version: $version }
) {
sections {
section
cssClass
remainingItemsType
endingMessageText
questions {
qId
label
question
inputType
possibleAnswers {
paId
text
}
multipleAnswersAccepted
individualFormat
answers
}
}
}
}
`,
client: "questionnaire",
variables: {
version: 1
}
})
.then(data => {
// this.sections = data.questionnaire;
// console.log(data);
this.copyQuestionnaie(data.data.questionnaire.sections);
// console.log(JSON.stringify(data.data.questionnaire.sections));
})
.catch(error => {
this.error = error;
alert("E " + error);
console.log("ERROR: " + error);
});
},
And then I get the error:
RROR: Error: Network error: Response not successful: Received status code 400
I was trying to use the same syntax as in example here.
Am I injecting the parameters in a wrong way or I oversee some typo?
Update:
Below is the schema python code for the backend:
import graphene
from .db import get_questionnaire_in_dict, getAnswers, putAnswers
class InputParam(graphene.InputObjectType): # type: ignore
"""Input parameters for questionnaire."""
language = graphene.String(required=True)
version = graphene.Int(required=True)
class PossibleAnswer(graphene.ObjectType): # type: ignore
"""Possible answers pair of key and text."""
paId = graphene.String(description="Answer id")
text = graphene.String(description="Answer text")
def __init__(self, paId: str, text: str) -> None:
self.paId = paId
self.text = text
def display(self) -> None:
"""Print self content."""
print("Label: {label},\nQuestion: {question}".format(
label=self.label, question=self.question))
class Question(graphene.ObjectType): # type: ignore
"""Question object."""
qId = graphene.String()
label = graphene.String(description="Translated question label")
question = graphene.String(description="Translated question")
# qPointer = graphene.Field(QuestionItems)
multipleAnswersAccepted = graphene.Boolean()
possibleAnswers = graphene.List(PossibleAnswer)
answers = graphene.List(graphene.String)
inputType = graphene.String(description="HTML input type")
individualFormat = graphene.String()
def __init__(self, questionObj):
self.qId = questionObj["qPointer"]
self.label = questionObj["label"]
self.question = questionObj["question"]
self.inputType = questionObj["inputType"]
self.multipleAnswersAccepted = questionObj["multipleAnswersAccepted"]
if "individualFormat" in questionObj:
self.individualFormat = questionObj["individualFormat"]
else:
self.individualFormat = None
if questionObj["possibleAnswersPointer"]:
self.possibleAnswers = []
for key, value in enumerate(questionObj["possibleAnswersPointer"]):
possibleAnswer = PossibleAnswer(key, value)
self.addPossibleAnswer(possibleAnswer)
else:
self.possibleAnswers = None
self.answers = []
def display(self):
print("Question {inputType}".format(inputType=self.inputType))
self.qPointer.display()
def addPossibleAnswer(self, possibleAnswer):
self.possibleAnswers.append(possibleAnswer)
class Section(graphene.ObjectType):
section = graphene.String()
css_class = graphene.String()
remainingItemsCount = graphene.Int
remainingItemsType = graphene.String()
endingMessageText = graphene.String()
questions = graphene.List(graphene.NonNull(Question))
def __init__(self, sectionObj):
self.section = sectionObj["section"]
self.css_class = sectionObj["class"]
self.remainingItemsCount = sectionObj["remainingItemsCount"]
self.remainingItemsType = sectionObj["remainingItemsType"]
self.endingMessageText = sectionObj["endingMessageText"]
self.questions = []
def display(self):
print("Section {section}, class: {css_class}".format(
section=self.section, css_class=self.css_class))
def addQuestion(self, question):
self.questions.append(question)
class Questionnaire(graphene.ObjectType): # type: ignore
lang = graphene.String()
sections = graphene.List(Section)
def __init__(self, lang):
self.lang = lang.language
self.sections = []
def addSection(self, section):
self.sections.append(section)
class AnswersInputParam(graphene.InputObjectType): # type: ignore
userId = graphene.String(required=True)
version = graphene.Int(required=True)
class Answer(graphene.ObjectType): # type: ignore
qId = graphene.String()
answers = graphene.List(graphene.String)
def __init__(self, answerObj):
print("Answer creator: {}".format(answerObj))
self.qId = answerObj["qId"]
self.answers = answerObj["answers"]
class Answers(graphene.ObjectType): # type: ignore
userId = graphene.String()
version = graphene.Int()
answers = graphene.List(Answer)
def __init__(self, answersObj, userId, version):
self.userId = userId
self.version = version
self.answers = []
# print("answersObj[\"answers\"]: {}".format(answersObj))
for index, value in enumerate(answersObj):
print("_XXX_: {idx}={val}".format(idx=index, val=value))
answer = Answer(value)
self.addAnswer(answer)
def addAnswer(self, answer):
self.answers.append(answer)
class SaveAnswers(graphene.Mutation):
class Arguments:
userId = graphene.String(required=True)
version = graphene.Int(required=True)
answers = graphene.JSONString(required=True)
Output = Answers
def mutate(self, info, answers, version, userId):
putAnswers(userId, version, answers)
return Answers(answers, userId, version)
class Mutation(graphene.ObjectType):
save_answers = SaveAnswers.Field()
class Query(graphene.ObjectType):
answers = graphene.Field(
Answers, inputParams=AnswersInputParam(required=True))
def resolve_answers(self, info, inputParams):
answers = getAnswers(inputParams.userId, inputParams.version)
return Answers(answers, inputParams.userId, inputParams.version)
questionnaire = graphene.Field(
Questionnaire, inputParams=InputParam(required=True))
def resolve_questionnaire(self, info, inputParams):
qest = Questionnaire(inputParams)
_struct = get_questionnaire_in_dict(
inputParams.language, inputParams.version)
for _sectionRef, sectionData in _struct.items():
s = Section(sectionObj=sectionData)
# s.display()
for key, value in sectionData.items():
# print(key, value)
if key == "questions":
for _questionNum, questionData in enumerate(value):
q = Question(questionObj=questionData)
# q.display()
s.addQuestion(question=q)
qest.addSection(s)
return qest
schema1 = graphene.Schema(query=Query, mutation=Mutation)
# sample calls
# mutation{
# saveAnswers
# (
# userId: "U123",
# version: 1,
# answers: "[{\"qId\":\"s1q4\",\"answers\":\"0\"},{\"qId\":\"s2q1\",\"answers\":\"1\"},{\"qId\":\"s2q10\",\"answers\":[\"1\",\"3\"]}]"
# ) {
# userId
# version
# answers {
# qId
# answers
# }
# }
# }
# {
# answers(inputParams: {userId: "U123", version: 1})
# {
# answers{
# qId
# answers
# }
# }
# }

How to get logged username in template

I am using Django 1.8 with Python 3.4
I had no idea why my template doesn't show my username on template profile.html :/
profile.py
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'accounts/css/style.css' %}" />
{% block content %}
<h2>My profile</h2>
<p>{{ request.user.username }}</p>
{% endblock %}
views.py
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.contrib.auth import authenticate, login
def login_view(request):
if request.method == 'POST':
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)
return HttpResponseRedirect('/accounts/profile')
else:
# Return a 'disabled account' error message
...
pass
else:
# Return an 'invalid login' error message.
pass
form = AuthenticationForm()
args = {}
args.update(csrf(request))
args['form']= AuthenticationForm()
return render_to_response('accounts/login.html', args)
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
print(request.user)
if user.is_active:
login(request, user)
return HttpResponseRedirect('/accounts/profile')
else:
# Return a 'disabled account' error message
...
else:
# Return an 'invalid login' error message.
...
def profile(request):
username = request.user.username
return render_to_response('accounts/profile.html', username)
def register_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args = {}
args.update(csrf(request))
args['form']= UserCreationForm()
return render_to_response('accounts/register_user.html', args)
def register_success(request):
return render_to_response('accounts/register_success.html')
What's the best way to get user information from a django template?
Add django.template.context_processors.request to context_processors options of TEMPLATE variable in your settings.py file :
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request', # add this line
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

Mock Grails Spring Security Logged in User

Looking for a way to mock spring security in some unit/integration tests.
Grails: V2.1.0
Spring Security Core: V1.2.7.3
Controller has the following:
// some action
def index(){
def user = getLoggedInUser()
render ....
}
...
private getLoggedInUser(){
return User.get(springSecurityService.principal.id)
}
I tried the following and various other ways but can't see to get it to work:
void testSomething(){
def dc = new SomeController()
dc.springSecurityService = [
encodePassword: 'password',
reauthenticate: { String u -> true},
loggedIn: true,
principal: [username:"Bob"]]
dc.index()
... assertion....
It seems that the user is not getting created and can't get the principal.id. Any suggestions or better alternatives?
I think the user is just being created, but not saved, and that's why it doesn't have an ID.
The solution could be this:
void testSomething(){
def dc = new SomeController()
def loggedInUser = new User(username: "Bob").save() // This way the user will have an ID
dc.springSecurityService = [
encodePassword: 'password',
reauthenticate: { String u -> true},
loggedIn: true,
principal: loggedInUser]
dc.index() ... assertion....
There's an alternative:
void testSomething(){
def dc = new SomeController()
def loggedInUser = new User(...).save()
dc.metaClass.getLoggedInUser = { loggedInUser }
...
I would suggest a refactor to getLoggedInUser:
private getLoggedInUser(){
return springSecurityService.currentUser
}
With this change, you could write:
void testSomething(){
def dc = new SomeController()
def loggedInUser = new User(...).save()
dc.springSecurityService = [
encodePassword: 'password',
reauthenticate: { String u -> true},
loggedIn: true,
getCurrenUser: { loggedInUser }]
...

Login with Kohana auth module - what am I doing wrong?

I'm trying to login with the following controller action, but my login attempt keeps failing (I get the 'invalid username and/or password' message). What am I doing wrong? I also tried the other method given in the examples in the auth documentation, Auth::instance()->login($user->username, $form->password);, but I get the same result. Kohana version is 2.3.4.
public function login() {
$auth = Auth::instance();
if ($auth->logged_in()) {
url::redirect('/account/summary');
}
$view = new View('login');
$view->username = '';
$view->password = '';
$post = $this->input->post();
$form = new Validation($post);
$form->pre_filter('trim', 'username')
->pre_filter('trim', 'password')
->add_rules('username', 'required');
$failed = false;
if (!empty($post) && $form->validate()) {
$login = array(
'username' => $form->username,
'password' => $form->password,
);
if (ORM::factory('user')->login($login)) {
url::redirect('/accounts/summary');
} else {
$view->username = $form->username;
$view->message = in_array('required', $form->errors()) ?
'Username and password are required.' :
'Invalid username and/or password.';
}
}
$view->render(true);
}
Figured out my problem... Something in my registration process is missing, because it's creating the user record but not the role-to-user assoc record. Login needs a specific role to log in to, or it won't work even with a valid username and password. Manually inserting the record allowed my to log in, so I'll just have to debug my registration action a bit.