DEV Community

loading...
Cover image for How to hide password hash, algorithm, etc... in django admin

How to hide password hash, algorithm, etc... in django admin

takahisahayashi profile image Takahisa Hayashi Updated on ・4 min read

How to erase password hashes, algorithms, salts, iteration

Django Admin is very useful.
The structure of the admin panel is so simple and powerful that you may want to issue accounts to other people to use the admin panel, in addition to using it yourself.

The default is just a user name, but you can customize it to register with an email address.

I want to hide the password hash.

Well, first of all, in the django admin panel, when you have an area to display username and password, the password section displays information such as "algorithm, iteration, hash, salt", and help text below, there is a link to change the password.

These are useful information from a developer's point of view, but from a user's point of view, they are not important.
I would like to turn these off as they are detrimental to the user experience.

The most familiar approach to hiding it would be to add password to the readonly_field.

## for example.
## project_root/apps/admin.py

readonly_fields=(
    'password',
)
Enter fullscreen mode Exit fullscreen mode

However, unfortunately, this method did not give satisfactory results.
because the output is just a string like {algorithm}${iteration}${hash}${salt} as shown in the following picture.
Sadly, the help_text with a link to the password change form is not displayed.

password_hashed_at_20210215

I tried two patterns.

The first is to utilize the UserChangeForm class.

Create a CustomUserChangeForm.

The first things to do is extend the UserChangeForm.
Also, I have tentatively set the model I am using as Administrator.
Think of the Administrator class as a class that extends AbstractUser . Inheriting a class is not required.
auth.User model is used by default, so if you are not extending anything, you may not need to write the model.

UserChangeForm

However, it has not been tested whether the following can be done without extending the auth.User.
So, I recommend extending it because without extending auth.User.

## project_root/administrators/admin.py
class CustomUserChangeForm(UserChangeForm):

    class Meta:
        ## `auth.User` is used by default.
        model = Administrator 

        ## `__all__` is used by defalt.
        fields = ('password',)
Enter fullscreen mode Exit fullscreen mode

I assigned Administrator to the model variable.
In the fields, only the password is specified.
As you can see in the source code, __all__ is specified by default, and if you do not assign a value to this variable, all items of UserChangeForm will be output.

Add this to project_root/administrators/admin.py.
However, this path will be different for each individual or team, so please change it accordingly.
What we need to do is to change the display items of the User model.

## project_root/administrators/admin.py
@admin.register(Administrator)
class AdministratorAdmin(UserAdmin):
    fieldsets = (
        ('Users', {'fields': (
            'username', 'safe_password',
        )}),
    )
    readonly_fields = (
        'safe_password',
    )
Enter fullscreen mode Exit fullscreen mode

Notice the value we put in the safe_password in the tuple.
This is the main one.
After this, we will define a method with this name.

Here, we don't want to display the password, we just want the help_text, so let's write the following

## project_root/administrators/admin.py
def safe_password(self, obj):

    ## CustomUserChangeForm Object
    custom_user_change_form = CustomUserChangeForm()

    ## custom_user_change_form has fields vars and getting password.
    password = custom_user_change_form.fields.get('password')

    ## password has help_text
    help_text = password.help_text

    ## help_text into format_html method.
    formatted_help_text = format_html(help_text)

    return formatted_help_text

## convert html tag apploved
safe_password.allow_tags = True

## description is `password`
safe_password.short_description = 'password'

Enter fullscreen mode Exit fullscreen mode

django_safe_password_at_20210215

django_display_safe_password_20210215

The link will also transition normally.
The_link_will_also_transition_normally_20210215

It seems to be working properly since the transition is also made successfully.

About ReadOnlyPasswordWidget

When a password is added to the readonly_field, templates/auth/widgets/read_only_password_hash.html will be used as a widget.

ReadOnlyPasswordHashWidget class is what is driving the above widget. This class is included in django.contrib.auth.forms.

On the other hand.

The second way is to work hard.
However, this one is longer, so the above method might be recommended.

@admin.register(Administrator)
class AdministratorAdmin(UserAdmin):
    fieldsets = (
        ('Users', {
            'fields': (
                'username', 'safe_password',
            )}
        ),
    )
    readonly_fields = (
        'safe_password',
    )


    def safe_password(self, obj):
        help_text = _(
            ""
            "Raw passwords are not stored, so there is no way to see this user's "
            "password, but you can change the password using <a href="{}\">this form</a>."
        )
        url = reverse(
            'admin:auth_user_password_change',
            args=(obj.id,)
        )
        url_into_help_text = str(help_text).format(url)

        return format_html(url_into_help_text)

    safe_password.allow_tags = True
    safe_password.short_description = 'password'
Enter fullscreen mode Exit fullscreen mode

The same result can be obtained with this method.
This one is similar to the above method, but not as elegant. This is because it does not take advantage of the standard assets.

Summary

Thank you for reading this far.
There may be other ways to do this.
Please let me know if you have a better way.

Best.

P.S.

As a supplement, we have written the following article for your reference.
https://dev.to/takahisahayashi/there-are-two-types-of-password-change-pages-in-Django-Admin

Discussion (0)

pic
Editor guide