0

I have created a custom AbstractUser user model and I am using python-social-auth to log in the user via Steam. But when I try to log in the user I will get this error. I have tried adding username to REQUIRED_FIELDS but both ways I get the same error.

I have added the managers.py and updated models.py code but still the same error.

models.py

from django.db import models
from django.conf import settings

from django.contrib.auth.models import AbstractUser

from .managers import CustomUserManager


# Create your models here.

class CustomUser(AbstractUser):
    username = models.CharField(max_length=32, blank=True)

    name = models.CharField(max_length=200, unique=True)

    steam_id = models.CharField(max_length=17, unique=True, blank=True, null=True)
    extra_data = models.TextField(null=True)

    is_active = models.BooleanField(default=True, db_column='status')
    is_staff = models.BooleanField(default=False, db_column='isstaff')
    is_superuser = models.BooleanField(default=False, db_column='issuperuser')

    USERNAME_FIELD = "name"
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

pipeline.py

from .models import CustomUser


def save_profile(backend, user, details, response, *args, **kwargs):

    CustomUser.objects.get_or_create(
        username = user,
        steam_id = details['player']['steamid'],
        extra_data = details['player'],
    )

settings.py

AUTH_USER_MODEL = 'main.CustomUser'

SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.social_auth.associate_by_email',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
    'main.pipeline.save_profile',
)

managers.py

from django.contrib.auth.base_user import BaseUserManager

class CustomUserManager(BaseUserManager):
    def _create_user(self, username, password, is_staff, is_superuser, **extra_fields):
        if not username:
            raise ValueError('Steam name must be set')
        username = self.normalize_email(username)
        user = self.model(
            username=username,
            is_staff=is_staff,
            is_active=True,
            is_superuser=is_superuser,
            **extra_fields
            )
        if password:
            user.set_password(password)
        user.save(using=self._db)
        return user




    def create_user(self, username, password=None, **extra_fields):

        return self._create_user(username, password, False, False, **extra_fields)

    def create_superuser(self, username, password=None, **extra_fields):
        user=self._create_user(username, password, True, True, **extra_fields)
        user.save(using=self._db)
        return user
Internal Server Error: /complete/steam/
Traceback (most recent call last):
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\decorators\cache.py", line 57, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_django\utils.py", line 46, in wrapper
    return func(request, backend, *args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_django\views.py", line 31, in complete
    return do_complete(request.backend, _do_login, user=request.user,
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\actions.py", line 45, in do_complete
    user = backend.complete(user=user, *args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\backends\base.py", line 40, in complete
    return self.auth_complete(*args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\backends\open_id.py", line 167, in auth_complete
    return self.strategy.authenticate(self, response=response,
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_django\strategy.py", line 105, in authenticate
    return authenticate(*args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\decorators\debug.py", line 42, in sensitive_variables_wrapper
    return func(*func_args, **func_kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\django\contrib\auth\__init__.py", line 76, in authenticate
    user = backend.authenticate(request, **credentials)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\backends\base.py", line 80, in authenticate
    return self.pipeline(pipeline, *args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\backends\base.py", line 83, in pipeline
    out = self.run_pipeline(pipeline, pipeline_index, *args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\backends\base.py", line 113, in run_pipeline
    result = func(*args, **out) or {}
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\pipeline\user.py", line 78, in create_user
    'user': strategy.create_user(**fields)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_core\strategy.py", line 54, in create_user
    return self.storage.user.create_user(*args, **kwargs)
  File "C:\Users\a\AppData\Local\Programs\Python\Python310\lib\site-packages\social_django\storage.py", line 79, in create_user
    user = cls.user_model()._default_manager.create_user(*args, **kwargs)
TypeError: CustomUserManager.create_user() missing 1 required positional argument: 'username'

pipeline debug

================================================================================
<openid.consumer.consumer.SuccessResponse id='https://steamcommunity.com/openid/id/id_number' signed=['openid.signed', 'openid.op_endpoint', 'openid.claimed_id'
, 'openid.identity', 'openid.return_to', 'openid.response_nonce', 'openid.assoc_handle']>
================================================================================
{'email': '',
 'first_name': '',
 'fullname': '',
 'last_name': '',
 'player': {'avatar': 'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/4f/4f570497f69258a4c87a8094f20594402ddda138.jpg',
            'avatarfull': 'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/4f/4f570497f69258a4c87a8094f20594402ddda138_full.jpg',
            'avatarhash': '4f570497f69258a4c87a8094f20594402ddda138',
            'avatarmedium': 'https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/4f/4f570497f69258a4c87a8094f20594402ddda138_medium.jpg',
            'communityvisibilitystate': 3,
            'lastlogoff': 1643152857,
            'loccountrycode': 'XX',
            'locstatecode': 'XX',
            'personaname': 'Name',
            'personastate': 0,
            'personastateflags': 0,
            'primaryclanid': 'clan_id',
            'profilestate': 1,
            'profileurl': 'profile_url',
            'steamid': 'steam_id',
            'timecreated': time_created},
 'username': 'steam_name'}
================================================================================
()
================================================================================
{'backend': <social_core.backends.steam.SteamOpenId object at 0x0000019BB170BD30>,
 'is_new': True,
 'new_association': True,
 'pipeline_index': 5,
 'request': <WSGIRequest: GET '/complete/steam/?janrain_nonce=2022-02-04T16%3A00%3A23ZtKBWiC&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=id_res&ope
nid.op_endpoint=https%3A%2F%2Fsteamcommunity.com%2Fopenid%2Flogin&openid.claimed_id=https%3A%2F%2Fsteamcommunity.com%2Fopenid%2Fid%2F76561198027134295&openid.identity=h
ttps%3A%2F%2Fsteamcommunity.com%2Fopenid%2Fid%2F76561198027134295&openid.return_to=http%3A%2F%2F127.0.0.1%3A8000%2Fcomplete%2Fsteam%2F%3Fjanrain_nonce%3D2022-02-04T16%2
53A00%253A23ZtKBWiC&openid.response_nonce=2022-02-04T16%3A00%3A24ZXNoCDrzrHsISxrmpnBb31RgC1%2Fs%3D&openid.assoc_handle=1234567890&openid.signed=signed%2Cop_endpoint%2Cc
laimed_id%2Cidentity%2Creturn_to%2Cresponse_nonce%2Cassoc_handle&openid.sig=c7pAEqYLz9Nrt8HcA1wIamQ%2BIaA%3D'>,
 'social': None,
 'storage': <class 'social_django.models.DjangoStorage'>,
 'strategy': <social_django.strategy.DjangoStrategy object at 0x0000019BB17438B0>,
 'uid': 'steam_id',
 'user': None,
 'username': 'steam_name'}
================================================================================
  • You've to provide an username field while creating a customer object as you've mentioned it in `REQUIRED_FIELDS`. – adshin21 Feb 04 '22 at 13:47
  • How exactly am I supposed to do that? The account creation is done by the python-social-auth if I am not wrong? @adshin21 – IonicEcommerce Feb 04 '22 at 13:50
  • And also I have the exact same error if I remove the username from REQUIRED_FIELDS. – IonicEcommerce Feb 04 '22 at 13:56
  • Username is required in auth.models.User, so try to give it some value or set a different field for username. – adshin21 Feb 04 '22 at 14:02
  • Sorry I am little bit confused on what you are suggesting me to do. I am also new to this so sorry if this sounds silly. I am using AbstractUser as my custom user model and I have set AUTH_USER_MODEL to my custom user model. I don't really understand how is auth.model.User related to this. I can also remove the username field and I get the same error. I just don't understand why this is happening, I don't actually even need the username field. @adshin21 – IonicEcommerce Feb 04 '22 at 14:08
  • None of the code you show here can cause the error you are asking about because there is no call to `create_user()`. Please show the full stack trace of the error and the code that causes the error. – Code-Apprentice Feb 04 '22 at 15:41
  • I've added the error log from terminal, is that helpful? @Code-Apprentice – IonicEcommerce Feb 04 '22 at 15:43
  • Yes, that helps. Unfortunately the stack trace refers only to code from the python social auth library. It looks like `args` is an empty list. You will need to debug into this code to find out why it doesn't have a `username`. I suggest using pycharm to do this so you don't have to edit the library code with print() statements. – Code-Apprentice Feb 04 '22 at 15:48
  • I have downloaded the pycharm community edition. How can I use this to debug the code relevant? I have also added a pipeline debug right before the python social auth library create user pipeline which is the last one that runs. I have added that code to the post. I am very new to django so if you have any tips on how to debug this it would be very much appreciated. @Code-Apprentice – IonicEcommerce Feb 04 '22 at 16:03
  • So I was able to create the account when I removed the `'social_core.pipeline.user.create_user',` pipeline and made the account inside pipeline.py that's also shown above. The only problem is that user of `save_profile(backend, user, details, response, *args, **kwargs):` has a value of None, I can still get the value from details but before when I was testing with the django user model this had the value of username. And also the page does not log in or redirect after creating the user, just goes back to the steam authentication page. Any ideas? @Code-Apprentice – IonicEcommerce Feb 04 '22 at 16:29
  • @IonicEcommerce Please post a new question with the pertinent details. – Code-Apprentice Feb 04 '22 at 17:03
  • @IonicEcommerce As for debugging, you can set a breakpoint in the django social auth code and view the values of variables and step through line by line to see how they are changed. You will need to find where `args` is set and populated for the call to `create_user()`. – Code-Apprentice Feb 04 '22 at 17:05

1 Answers1

0

I found a working solution for my project. I am not entirely sure why it is this way but it works fine and I get everything I need.

I had to create my own user manager for my custom user model and I found out that the username inside my create_user method had no value but the value was in extra_fields. So this is my code for the solution that is working for me.

models.py

from django.db import models
from django.conf import settings

from django.contrib.auth.models import AbstractUser

from .managers import CustomUserManager


# Create your models here.

class CustomUser(AbstractUser):
    username = models.CharField(max_length=32, blank=True, null=True)

    name = models.CharField(max_length=200, unique=True, blank=True, null=True)

    steam_id = models.CharField(max_length=17, unique=True, blank=True, null=True, db_column='steam_id')
    player = models.TextField(null=True)
    user_coins = models.FloatField(default=0)

    is_active = models.BooleanField(default=True, db_column='status')
    is_staff = models.BooleanField(default=False, db_column='isstaff')
    is_superuser = models.BooleanField(default=False, db_column='issuperuser')

    USERNAME_FIELD = "name"
    REQUIRED_FIELDS = []

    objects = CustomUserManager()

    def has_perm(self, perm, obj=None):
        return self.is_superuser

    def has_module_perms(self, app_label):
        return self.is_superuser

managers.py

from django.contrib.auth.base_user import BaseUserManager

class CustomUserManager(BaseUserManager):
    def _create_user(self, username, password, is_staff, is_superuser, **extra_fields):
        if not username:
            raise ValueError('Steam name must be set')
        user = self.model(
            username=username,
            steam_id=extra_fields['player']['steamid'],
            is_active=True,
            is_staff=is_staff,
            is_superuser=is_superuser,
            player=extra_fields['player']
            )
        if password:
            user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, password=None, **extra_fields):
        return self._create_user(extra_fields['name'], password, False, False, **extra_fields)

    def create_superuser(self, username, password=None, **extra_fields):
        user=self._create_user(username, password, True, True, **extra_fields)
        user.save(using=self._db)
        return user

settings.py

USER_FIELDS = ['username', 'player']
SOCIAL_AUTH_PIPELINE = (
    'social_core.pipeline.social_auth.social_details',
    'social_core.pipeline.social_auth.social_uid',
    'social_core.pipeline.social_auth.social_user',
    'social_core.pipeline.user.get_username',
    'social_core.pipeline.social_auth.associate_by_email',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',   
)