Django Integrating Python Social Auth And The Default Auth With A Custom User Model: - django

I have a project I am working on that requires some users to be authenticated via facebook and others to sign up using a custom model. The facebook users will not have the same sign up credentials as the custom model. For example- there will be a restaurant owner sign up and a customer signup. The customer will not have to put a street address location, they can simply login.
My intentions were to have the restaurant owners sign up via the custom profile model and the facebook users to simply login via the defualt social auth, but whenever I combine the two, social auth starts to use the custom model because I define a custom user model within settings. Is there a way to distinguish to the python social auth backend to only use the default or a way to update my current custom user model to have a facebook segment. I have searched the web for a long time for this, but can not seem to find anything that can combine the two besides (1), but it did not work successfully. I can however get one or the other working successfully depending on if I specify a user model in my settings.py file or not.
It is quite simple, but I do not know of a way to get social auth to look at its default and djangos authentication to look at my custom model.
(1)-http://code.techandstartup.com/django/profiles/

In order to distinguish one type of user from another, you can do something like this:
First, in your settings file, store the following:
FIELDS_STORED_IN_SESSION = ['type']
This will be stored in strategy parameter in every function of pipeline
Then, change the pipeline wherever necessary. For example, in your create_user pipeline function, you can do this:
user_type = strategy.session_get('type')
if user_type != 'customuser':
return {
'is_new': True,
'user': strategy.create_user(**fields)
}
else:
return {
'is_new': True,
'user': create_restaurant(**fields)
}

Related

Django: How to create a user action log/trace with vizualization

I am looking for a tool to track user actions like:
user logged in
user changed password
user got bill via email
user logged
user uploaded image
user send message
...
which I can include into my Django project. Afterwards I want to build queries and ask the system stuff like:
how often did a user a message within a month
how often did a user login within a month
does the user uploaded any images
and I would like to have some kind of interface. (Like google analytics)
Any idea? I am pretty sure that this is a common task, but I could not find anything like this.
There are many ways to achieve that. Try reading this link first. Also, you can use LogEntry for tracking the creation, deletion, or changes of the models you have. Also, it shows you the information you need in the admin panel, or also you can use some other third-party packages.
Or you may want to create your own Model to create logs for your application and this link may help you, but do not reinvent the wheel and analyze your situation.
from django.contrib.admin.models import LogEntry, ADDITION
LogEntry.objects.log_action(
user_id=request.user.pk,
content_type_id=get_content_type_for_model(object).pk,
object_id=object.pk,
object_repr=force_text(object),
action_flag=ADDITION
)
Create a model to store the user actions. OP will want the Action model to have at least two fields - user (FK to the user model) and action (user action).
from django.db import models
class Action(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
action = models.CharField(max_length=255)
Create a way to store the user actions.
def store_user_action(user, action):
action = Action(user=user, action=action)
action.save()
Then if one wants to store when the user changed password, one will go to the view that deals with the change password and call our method store_user_action(request.user, 'changed password') when successful.
To then visualise the user actions, OP can see the records in the Django Admin, create views and templates, ... There are different possibilities.

User registration with admin authorization

I was wonder if it is possible to include a way that when someone fill the user registration form to register, can the details be sent to an admin email for authorization before the user can login in django?
Since you did not provide any code I will guide you the process, you can later come back more specific question if you are stuck :
Use the field is_active provided by Django from the User model to authorised access within your website.
Extends the field is_active to set the default to False or set it to false in the begging of your user view
Create a link with the ID of the user and a path to the Django Admin where you can update the user and active to True
In short yes, possible and pretty easy if you know a bit of Django.

Django REST auth - users stored in external service

I've been wondering the best way to handle the case where a Django is used in a service-oriented architecture, so individual Django applications do not maintain their own user stores. One service maintains the user store, and others must call it in order to retrieve user information.
So far example, here is how I was thinking of building a custom authentication class in Django REST to handle this:
class SOAAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
token = request.get_token_from_auth_header()
if not remote_auth_service.is_token_valid(token):
raise AuthFailed('Token is invalid')
user_properties = remote_users_service.get_user(token):
# user_properties is a dict of properties
if not user_properties:
raise AuthFailed('User does not exist.')
user = MyCustomUserClass(**user_properties)
return (user, 'soa')
So no user info would get persisted in the Django application's database, and permission classes could interrogate the instance of MyCustomUserClass to figure out what groups a user belongs to.
Would this approach work for simple group-based authorization? My think is that I don't need object-level permissions, so there's no need to create rows for my users in the Django database.

Where does the function auth.authenticate() check if user exists?

I have a login form. Also I have a huge database. One of the tables in DB is 'zusers', where stores information about users: username, password, 'telefon' and some other columns. I learned about user = auth.authenticate(username = 'John', password = 'pass'). And the question: wheredoes this function check if such user exists or no? And how to do it so that this function check for users in my DB table 'zusers'?
You will need to create a custom authentication backend in Django for your exisiting users. You can read more at the Django Docs: https://docs.djangoproject.com/en/dev/topics/auth/customizing/
You should not need to manual check auth.authenticate but just swap out the backend.
You can also substitute a completely customised model for your Django user to support telefon and the other columns you have https://docs.djangoproject.com/en/dev/howto/custom-model-fields/
I am not going to post any example code as you haven't provided any yourself and the Django links above very clearly show you how to achieve this.

Django: how to store subdomain-based authentication usernames?

I need to create a subdomain based authentication system, like the one 37signals, freshbooks, codebase use. That is, each subdomain of my main application needs to have its own username namespace. I would like to keep as much as possible of the django authentication system.
What is a good way to store the username?
In particular, it should be possible for different users to have the same username as long as their account belongs to a different subdomain.
Some approaches I've considered, for which I can foresee shortcomings:
storing some prefix in the username field of the django auth user model.
extending the user model according to this.
customizing the source of auth to my needs
I have built this functionality for several sites in the past and have found that your first bullet point is the way to go.
It means that you don't have to make massive change to django auth. What I did was set up a custom authentication backend that abstracts away the way usernames are stored.
auth_backends.py
from django.contrib.auth.backends import ModelBackend
from Home.models import Account
class CustomUserModelBackend(ModelBackend):
def authenticate(self, subdomain, email, password):
try:
user = Account.objects.get(username=u'%s.%s' % (subdomain, email))
if user.check_password(password):
return user
except Account.DoesNotExist:
return None
def get_user(self, user_id):
try:
return Account.objects.get(pk=user_id)
except Account.DoesNotExist:
return None
For this particular project Account was the user model and it just inherited directly from User however you could replace Account with whatever you want.
You have to install the custom auth backend in your settings file:
AUTHENTICATION_BACKENDS = (
'auth_backends.CustomUserModelBackend',
'django.contrib.auth.backends.ModelBackend',
)
Then when you call authenticate you need to pass in the subdomain, email and password.
You can also add some other helper functions or model methods that help with making sure that only the user's actual username is displayed, but that is all pretty trivial.
I think this may be a good use case for using django.contrib.sites in combination with the second bullet item you mentioned. You could create a CustomUser model like so:
from django.contrib.sites.models import Site
class CustomUser(User):
"""User with app settings."""
sites = models.ManyToManyField(Site)
Then you could write a custom auth backend to check that the user can sign in to the current subdomain using the supplied credentials. This allows you to have one username for multiple sites (subdomains) without having to hack the internal auth app or store multiple usernames with custom prefixes.
EDIT: you can get the current site by using Site.objects.get_current() and then check to see if the current site is in the user's sites.
You can read more about the sites framework here: http://docs.djangoproject.com/en/dev/ref/contrib/sites/