0

Ive been running into a number of problem in relation to using django's custom model. This one in particular is not raising any errors. For some reason after authenticating via steam and returning to the landing page the database tables for both steamuser_user (custom user) and social_auth_usersocialauth are empty. Nothing is being saved, no errors are being displayed etc.

My custom model which is quite similar to the one on django docs official page is as follows:

from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from django.contrib.auth.models import BaseUserManager

# Create your models here.
class UserManager(BaseUserManager):
    def create_user(self, steamid, username, password=None):
        if not steamid:
            msg = 'User has no Steam ID set'
            raise ValueError(msg)
        if not username:
            msg = 'User has no name set'
            raise ValueError(msg)

        user = self.model(steamid=steamid,
                          username=username)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, steamid, username, password):
        super_user = self.create_user(steamid=steamid,
                                      username=username,
                                      password=password)
        super_user.is_staff = True
        super_user.is_admin = True
        super_user.is_mod = True
        super_user.save(using=self._db)
        return super_user


class User(AbstractBaseUser):
    steamid = models.CharField(max_length=20, unique=True)
    username = models.CharField(max_length=80)
    email = models.EmailField(null=True,blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    is_mod = models.BooleanField(default=False)
    date_joined = models.DateTimeField(auto_now_add=True)
    reputation = models.IntegerField(max_length=6, default=0)

    USERNAME_FIELD = 'steamid'

    objects = UserManager()

    def __unicode__(self):
        return self.username

    def get_full_name(self):
        return self.steamid

    def get_short_name(self):
        return self.username

The settings I've used are as follows:

SOCIAL_AUTH_USER_MODEL = 'steamuser.User'

AUTH_USER_MODEL = 'steamuser.User'

TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
                                                                            'social.apps.django_app.context_processors.backends',
                                                                            'social.apps.django_app.context_processors.login_redirect',
                                                                            )

AUTHENTICATION_BACKENDS = (
                           'social.backends.steam.SteamOpenId',
                           'django.contrib.auth.backends.ModelBackend',
                           )
#Steam OpenAuth
SOCIAL_AUTH_STEAM_API_KEY = 'B1D7C629D093D4B72577F2F11DE4EBE2'
LOGIN_URL = '/'
SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/'
SOCIAL_AUTH_ENABLED_BACKENDS = (
                                'steam',
                                )

Any help would be appreciated!

EDIT

Backends steam.py

    def get_user_details(self, response):
    player = self.get_json(USER_INFO, params={
        'key': self.setting('API_KEY'),
        'steamids': self._user_id(response)
    })
    if len(player['response']['players']) > 0:
        player = player['response']['players'][0]
        details = {'steamid': player.get('steamid'),
                   'username': player.get('personaname'),
                   }
    else:
        details = {}
    return details

EDIT 2

Well despite my logical reasoning, I just gave up and created a custom pipeline to create the new steam user as follows:

from django.contrib.auth import get_user_model

def create_steamuser(details, user=None, *args, **kwargs):
    if user:
        return {'is_new': False}

    if not details:
        return

    try:
        steam_user = get_user_model().objects.get(steamid=details['steamid'])
    except steam_user.DoesNotExist:
        get_user_model().objects.create_user(details['steamid'], details['username'])

    return {
        'is_new': True,
    }

Now I still have the problem where social_user is not being created. I've set the social user model to use my new custom model but there must be something that I am missing.

Deep
  • 2,988
  • 4
  • 34
  • 44

1 Answers1

0

python-social-auth won't be able to pass the steamid and date_joined parameters to your custom create_user() method in the manager. To make that possible you have three options:

  1. Set =None to those parameters and set some default vaules for them
  2. Override the default create_user pipeline and pass the extra parameters.
  3. Add a custom pipeline function before create_user and fill details with steamid and date_joined, then define SOCIAL_AUTH_STEAM_USER_FIELDS = ('username', 'email', 'steamid', 'date_joined').
omab
  • 3,721
  • 19
  • 23
  • Thanks for the response, I have a couple of questions though: – Deep Aug 12 '14 at 02:56
  • 1. Why is the social_auth_usersocialauth table not being populated as well? Shouldnt it still record the new user? 2. I have edited the backends 'steam.py' file (ive included it above) to include steamid and username, shouldnt these keys/values be used in the current create_user pipeline e.g done your step 3? – Deep Aug 12 '14 at 03:02
  • 1. `social_auth_usersocialauth` is not populated because there's no `User` reference to link to. 2. You defined `SOCIAL_AUTH_STEAM_USER_FIELDS` too? – omab Aug 12 '14 at 20:14
  • Hi, sorry but I am a little lost. I have set 'SOCIAL_AUTH_USER_MODEL = 'steamuser.User''. Doesnt this mean that python-social is now using my custom user i.e Q1? Secondly I have defined 'SOCIAL_AUTH_STEAM_USER_FIELDS' with the 3 fields above and nothing is being saved. – Deep Aug 16 '14 at 06:50
  • ive managed to figure it out. All i needed to do was create a custom get_username pipline which returned the steamid instead of the normal username since my custom table used this as its username field. – Deep Aug 18 '14 at 07:29