How to encrypt django username field in auth model? - django

I want to encrypt the username data before save in django auth User model, and decrypt the username data. we are using model like this
class Profile(models.Model):
user = models.OneToOneField(User,related_name='profile_data',on_delete=models.PROTECT)
Regarding this Any solution reference pls.

You can override the save method, and do the encryption logic in there. It would be executed just before saving anything in Profile Modal. Like this:
class Profile(models.Model):
user = models.OneToOneField(User,related_name='profile_data',on_delete=models.PROTECT)
def encrypt(self, to_be_encrypted_value):
# Here, you would do the logic of encrypting, and return the encrypted value.
# To be used in save method.
...
return encrypted_value
def save(self, *args, **kwargs):
self.user = self.encrypt(self.user)
super().save(*args, **kwargs)

Related

How to skip or remove password field in simplejwt token authentication in django rest framework?

My requirement is, I don't wanted to enter password in simplejwt token authentication. I have added one extra field in the authentication by inheriting the init() method of TokenObtainPairSerializer
as per my requrements.
Currently, I am passing None as in password field but still its showing to user (djnago admin portal). What I want is, I don't wanted to show the password field to user while authentication using simplejwt.
below is my code,
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomSerializer(TokenObtainPairSerializer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields[self.username_field] = serializers.CharField()
self.fields['password'] = PasswordField(default=None)
self.fields['extra'] = serializers.CharField()
def validate(self, attrs):
pass
Is there any ways to set PasswordField as unusable so it wont show to user?
I have followed the below mentioned process to solve the problem,
Override the TokenObtainPairSerializer class __init__ method like below,
Use del self.fields['password'], so It wont ask you the password and add whatever fields you want.
class CustomSerializer(TokenObtainPairSerializer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields[self.username_field] = serializers.CharField()
del self.fields['password']
This works really well. There is a almost same question I have answered, You can check it here for more knowledge.
Let me know if anyone have better solution of this problem.

User current authentication status check endpoint with django and django rest framework

How could I create an endpoint in django-rest-framework that would facilitate checking whether a given user was currently logged in?
The idea would be to supply the authentication token and user name, then get a response like {"Authenticated": True} or {"Authenticated": False"}.
You can try with this example:
models
class LoggedUser(models.Model):
user = models.ForeignKey('YourUserObject', primary_key=True)
def __unicode__(self):
return self.user
def login_user(sender, request, user, **kwargs):
LoggedUser(user=user).save()
def logout_user(sender, request, user, **kwargs):
try:
u = LoggedUser.objects.get(user=user)
u.delete()
except LoggedUser.DoesNotExist:
pass
user_logged_in.connect(login_user)
user_logged_out.connect(logout_user)
After this you can do serialize class to retrive current loged user.

Access session in user model .save()

Is it possible to access the current session in the user model .save()?
pseudo code of what I want to achieve:
# users.models.py
def save(self, *args, **kwargs):
created = True
if self.pk:
created = False
super(AbstractUser, self).save(*args, **kwargs)
# post-save
if created:
look_for_invite_in_session_and_register_if_found(self, session)
Seems it something wrong in your architecture. You shouldn't access request in models layer. All work with request must be done in view. You can do it like this:
user, created = AbstractUser.objects.get_or_create(name=name)
if created:
look_for_invite_in_session_and_register_if_found(user, request.session)

django edit user and userprofile object

so i'm making a generic "accounts" page in django. I've used the django-registration plugin, and currently have a (djang-standard) User object, as well as a UserProfile and UserProfileForm object.
This is a question of style, or best-practices, i suppose. Is what i'm planning "right" or is there a "better/recommended/standard way" to do this?
What i'm planning on doing is creating the UserProfile from the request.user ie:
form = UserProfileForm(instance=User)
(and sending that form to the view), and in the UserProfileForm:
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
def __init__(self,*args,**kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
if kwargs.has_key('instance'):
self.user = kwargs['instance']
where my UserProfile is pretty much like so:
class UserProfile(models.Model):
user = models.OneToOneField(User)
points = models.IntegerField(default=0) #how is the user going with scores?
and where User is of the django.contrib.auth.models variety.
Ok! The handling of the editing and saving will either be done via the mixin django stuff or, more likely because i haven't read up on mixins my own user-defined view that handles post and gets. But ignoring that - because i'm sure i should be using the mixins - is the above "right?" or are there suggestions?
cheers!
Take a look at user profiles on the django docs, the basics are listed there. You should also take a look at using a form in a view.
Some specific feedback:
You got the UserProfile model right, but you have to create an instance of one every time a new user is added (either through the admin interface or programmatically in one of your views). You do this by registering to the User post_save signal:
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
You should init the ModelForm with an instance of the UserProfile, not User. You can always get the current user profile with request.user.get_profile() (if you define AUTH_PROFILE_MODULE in settings.py). Your view might look something like this:
def editprofile(request):
user_profile = request.user.get_profile()
if request.method == 'POST':
form = UserProfileForm(request.POST, instance=user_profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/profile')
else:
form = UserProfileForm(instance=user_profile)
# ...
No need for the init override in your ModelForm. You will be calling it with a UserProfile instance, anyway. If you want to create a new user, just call the User constructor:
user = User()
user.save()
form = UserProfileForm(instance = user.get_profile())
# ...

How to clean form data depending on logged-in user in django admin panel?

I've looked at several questions here that looked similar, but none of them discussed the problem from the perspective of admin panel.
I need to check if user has permission to leave a field empty. I wanted to use request.user but I don't knot how to pass request from EntryAdmin to ModelForm. I wanted to do something like this:
class EntryAdminForm(ModelForm):
class Meta:
model = Entry
def clean_category(self):
if not self.request.user.has_perm('blog.can_leave_empty_category') and not bool(self.category):
raise ValidationError(u'You need to choose a Category!')
else:
return self.cleaned_data['category']
You could override the ModelAdmin.get_form, by adding the request as an attribute of the newly created form class (should be thread-safe).
Something along these lines:
class EntryAdmin(admin.ModelAdmin):
form = EntryAdminForm
def get_form(self, request, *args, **kwargs):
form = super(EntryAdmin, self).get_form(request, *args, **kwargs)
form.request = request
return form
Then the code in your question should work.