Password Field Length Django - django

I have written a custom hasher for the passwords and it returns a hashed password length of 148. But Django seems to limit the length of the password in the SQL table to 128 by default. How do I change it?

The correct way would be to use a custom user model that overrides the password field:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model for details.
As an alternative workaround, you can use a third party applicaton called django-primate: https://github.com/aino/django-primate#alternative-password-hashing

Related

Cannot obtain user by using filter with username and password

I am using the following code
email = validated_data["login"]
password = validated_data["password"]
user_obj = User.objects.filter(Q(email__exact=email) & Q(password__exact=password))
I changed the password from admin however no user is returned. However if I remove the password check then I get a user object back.The object that I get back if I remove the Q(password__exact=password) condition has _password field as None. This code has been working fine for a while but today it is not returning back the object. Am I missing something here ? I verified that I am receiving the correct username and password from the client.I also tried accessing the admin with that username and password (The account has staff status) and I was able to log in. So the password is correct but for some reason I cant obtain that user by filtering. ? What might I be doing wrong ?
password isn't stored in plain text, but as a hash (and a little more). Get the user by username and check the password:
# assumes there can be only one
user = User.objects.get(email=email)
# this checks the plaintext password against the stored hash
correct = user.check_password(password)
BTW, you don't need Q objects for logical AND. filter(email__exact=email, password__exact=password) would suffice, even though it doesn't make much sense, in this case.
it is because Django doesn't stores password as the simple text they are hashed, you cant perform a password__exact on that it will return none every time unless you are getting the same hash password = validated_data["password"] here

How to generate hash in django 1.9 like Invitation Link

I want to send the email to the user that will contains url+hash
like this bleow
www.mywebsite.com/user/verify/121#$%3h2%^1kj3#$h2kj1h%$3kj%$21h
and save this hash against the user in the Database like this
ID | Email |Hash
1 | youremail#gmail.com |121#$%3h2%^1kj3#$h2kj1h%$3kj%$21h
When the user received the email it should check and compare the hash with it and perform the action as per situation.
My question is simple how to generate a unique hash for each user and how to store them in the Database.
If by "hash", you mean a unique string, you can just use uuid.uuid4 for that purpose.
>>> import uuid
>>> unique_id = str(uuid.uuid4())
>>> print unique_id
d8814205-f11e-46e1-925e-a878fc75cb8d
>>> # replace dashes, if you like
>>> unique_id.replace("-", "")
I've used this for projects where I need to verify a user's email.
P.S.: It's not called a hash, it's called a unique ID. Hashing is something else, where you generate a value from a given string. See this question for more explanation.
Django has a Cryptographic Signing module, which helps produce unique and verifiable signatures for any data you need. If you are trying to do this to verify that the request is done by the appropriate user or not, you can use the library to verify requests, without storing the hash in the database.

how to verify email through link in rails4 application

How to verify email through link.
I have user edit profile and it is showing user email.I want to give one link to verify email.I do not what to do.
Add one column to your
User Model : email_verification and by default set to zero (0).
Then using persistence_token create a URL and sent to that specific email address. If you dnt have persistence_token as column in your User model then you can add custom column of your choice like verify_email_token as column name and stored 50 random string.
Using
o = [('a'..'z'),('A'..'Z'),('0'..'9')].map{|i| i.to_a}.flatten
string = (0...50).map{ o[rand(o.length)] }.join
URL example :
http://www.yoursitename.com/VerifyEmailAddress/?token=persistence_token ;
When user click on that link, internally call function like VerifyEmailAddress and in that method update email_verification column by one (1).

Understanding User class in django

I create a user in my view.py using this simple code.
if not errors:
user = User.objects.create_user(username, email, password)
user.save()
Except for the validation, there is nothing that I do to the username and password values before creating the object.
But I find this in the User class in Django API. I don't know how to use the help text. If it is help text what does it print? How do I find the default values of algo, salt and hexdigest?
password = models.CharField(_('password'), max_length=128, help_text=_("Use '[algo]$[salt]$[hexdigest]' or use the change password form."))
"If it is help text what does it print?"
-> it prints exactly this: Use '[algo]$[salt]$[hexdigest]'
when you create a user, it will automatically call make_password(password[, salt, hashers])
which: Creates a hashed password in the format used by this application. It takes one mandatory argument: the password in plain-text. Optionally, you can provide a salt and a hashing algorithm to use, if you don't want to use the defaults (first entry of PASSWORD_HASHERS setting). Currently supported algorithms are: 'pbkdf2_sha256', 'pbkdf2_sha1', 'bcrypt' (see Using bcrypt with Django), 'sha1', 'md5', 'unsalted_md5'
are you facing any problems with this?
create_user will automatically generate password hash and it will create user in the database (thus you don't need that user.save())
See docs on creating users.
The help text is basicly just code for the message that shows up in the django admin, when editing a User object. It's meant to explain to someone looking at the edit form, why the password field has something like sha1$12345$1234567890abcdef1234567890abcdef12345678 instead of the password that was set for that user. The reason is, of course that the password is hashed for security, and that representation holds all the information required to verify a user-typed password later.
The admin user edit form has a special page for editing passwords. If you want to edit the users password in your code use the set_password method of the User object, the check_password method is for verifying a supplied password.
The documentation for make_password has more information about the algorithms Django uses and can use. The default for Django <1.3 was sha1, Django 1.4 changed the default to PBKDF2. The default value for salt is a random string (it's there so that two identical passwords don't look the same in the database). Hexdigest is the value of the password string and the salt string hashed with the hashing algorithm. You can read the details in the code on github.

Can I change Django's auth_user.username field to be 100 chars long without breaking anything?

Before somebody marks this question as a duplicate of this question Can django's auth_user.username be varchar(75)? How could that be done? or other such questions on SO, please read this question. The question I linked to asks this question precisely but unfortunately the answers don't address the question that was asked.
Can I change the auth_user.username field to be 100 characters long by doing the following:
Run ALTER table in DB for the username field
Change the max_length here: username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and #/./+/-/_ characters"))
Would it break anything in Django if I were to do this?
That this will break when I update Django to a higher version is not a problem. I'm also not looking at writing other authentication methods.I just want to know if I would break anything if I were to do this.
You need to monkey-patch max-length in several places: model-field's description, form-field's description and max-length validators. Max-length validators are attached to form-fields as well as model-fields.
Here is a code snippet, which will patch everything:
https://gist.github.com/1143957 (tested with django 1.2 and 1.3)
Update:
Good news! Since django 1.5 you can override user model: Customizing the User model
There is no harm in doing that.
Just change the length in the model and in the database :)
Create a user profile model, add your very-long-username field there, and use it. of course this renders the genuine username field useless, but it is much better than hacking Django code, which will get you into trouble when you need to upgrade it.
For me, the code below works and is simple well.
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
....
# your custom fields
MyUser._meta.get_field('username').max_length = 255 # or 100
after you can run your migration
If you change the database manually as well as the model accordingly then there should be no problem.
You can also change back otherwise, and I would say make a backup just in case but I'm not sure its even necessary
for future needs this is the best and easiest way i found out:
https://github.com/GoodCloud/django-longer-username
Another solution is to change your authentication code. When a new user signs up, they enter an email, you save this in the email field so you have it, and if their email is >30 characters, you shorten it before putting it into the user field. Then, change your login authentication for new logins.