I am using social-auth-app-django for signup-signin of new users using google oauth2 authentication.
after signup a new user is created in my db but the is_active is set as false, I want to set is_active
as true only for users created by this social_auth google authentication
(for other users who sign up using email-password I activate them by sending an account activation email) I have tried setting is_active = True for all users with no password , but I feel this way is insecure and hackish . How do I modify the social_auth_login flow to activate users as well ? I am using a custom User model :
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
if not email:
raise ValueError('The Email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
if password:
user.set_password(password)
# else:
# user.is_active = True <-------- tried this , worked too
user.save()
return user
def create_superuser(self, email, password, **extra_fields):
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_active', True)
extra_fields.setdefault('user_type', user_constants.SUPERUSER)
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
..
class User(AbstractUser):
username = None # remove username field, we will use email as unique identifier
email = models.EmailField(unique=True, null=True, db_index=True)
client_id = models.UUIDField(primary_key = True,
default = uuid.uuid4,
editable = False)
name = models.CharField(max_length=255, default="")
is_active = models.BooleanField(default=False)
is_staff = models.BooleanField(default=False)
date_joined = models.DateTimeField(default=timezone.now)
user_type = models.PositiveSmallIntegerField(choices=user_constants.USER_TYPE_CHOICES, default=user_constants.CLIENT_ADMIN)
REQUIRED_FIELDS = []
USERNAME_FIELD = 'email'
objects = UserManager()
..
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details',
'social_core.pipeline.social_auth.social_uid',
'social_core.pipeline.social_auth.auth_allowed',
'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',
)
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
SOCIAL_AUTH_USER_MODEL = 'register.User'
SOCIAL_AUTH_GOOGLE_OAUTH2_USER_FIELDS = ['email']
..
According to Django, the boolean is_active
designates whether this user account should be considered active. We recommend that you set this flag to False instead of deleting accounts; that way, if your applications have any foreign keys to users, the foreign keys won’t break.
In your case, I would put is_active
as True by default (if you want to delete an account, you just put it False).
Following your remark
(for other users who sign up using email-password I activate them by sending an account activation email)
you can add a boolean is_email_verified
: if the user is created by social auth, it means the is_email_verified
is True; if the user is created following email-password, is_email_verified
is False and must be set to True by sending an account activation email.
Thanks to that you can have 4 states with the 2 booleans is_active
and is_email_verified
: a user who wants to connect must have both of them as True. It seems secure to me.