I am planning on creating an application for the students of my school, and I want to restrict user registration to emails of the form person#myschool.edu. I would prefer to not manually create the user table and do the password hashing and such. Are there any libraries you can recommend for this?
Thanks for the help.
Sometimes, if you just send the user to a login screen you will end in a redirect loop if the user is already logged with a Google Account.
What i have found to be a good answer to this problem is to redirect the user to a log out page so he can later login with the domain you want.
I have used this for my code
user = users.get_current_user()
#Check if the user is in #mydomain.com
if user:
emailDomain = user.email().split("#")
if emailDomain[1] == "mydomain.com":
return True
else:
self.redirect(users.create_logout_url('/startPage'))
else:
self.redirect(users.create_login_url(self.request.uri))
This way, the application logs you out automatically and asks for your domain credentials
Since you said you don't know how the email are registered, that you don't want to manage a login/password database and you just need a regexp or somethings (I quote here!), I assume you could keep it very simple.
Something like.
user = users.get_current_user()
if user:
emailDomain = user.email().split("#")
if emailDomain == "yourschool.edu":
doSomething()
That way, all the trouble of registering to your app is given to the users (who will need to get a Google Account).
Related
I'm using Django to create a REST API with LDAP. One of the endpoints gets a username (this is not the same username of the logged in user through IsAuthenticated). I want to check if that username exists in the system, even if he never logged-in. My current code was:
try:
user = User.objects.get(username=request.data['username'])
except:
return Response(data={"error": "User does not exist"}, status=status.HTTP_400_BAD_REQUEST)
This of course does not work because the database contains users that have logged in at least once. How can I create the user if he does not exist? I know I can use User.objects.create but I want it to fetch the data from LDAP and not just to pass it the username.
The logic that I'm after:
Check if the username does not belong to any user via LDAP. If so, return error message.
Otherwise, create/populate the user and do other actions (based on the purpose of the endpoint).
I'm using django_auth_ldap.
So i'm piggybacking on this post here:
Python Social Auth duplicating e-mails for different users
Here's my issue:
I provide a user with ability to signup either via regular email sign up, facebook auth or twitter auth.
I'm also using same package Social Django Auth App for the user login pages.
I realized that a user might try sign up with a Facebook account (associated to one email) and then try again later to register with Twitter (which could have the same email address). Based on the aforementioned post, I added a function to check for duplicate emails like so:
def check_email_exists(request, backend, details, uid, user=None, *args, **kwargs):
email = details.get('email', '')
provider = backend.name
# check if social user exists to allow logging in (not sure if this is necessary)
social = backend.strategy.storage.user.get_social_auth(provider, uid)
# check if given email is in use
count = User.objects.filter(username=email).count()
success_message = messages.success(request, 'Sorry User With That Email Already Exists')
# user is not logged in, social profile with given uid doesn't exist
# and email is in use
if not user and not social and count:
return HttpResponseRedirect(reverse('accounts:sign_up', success_message))
and my pipeline with the function:
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',
'dealmazing.utils.check_email_exists',
'social_core.pipeline.social_auth.associate_by_email', # <--- enable this one
'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',
)
UPON Testing--if i go to sign up with Twitter account of an already registered email address--it works. YAY!
BUT the main issue comes when i go to try to login via using either Facebook or Twitter. The function is checking on those logins as well and spitting me back the 'Email Allready Exists..' error.
So I somehow need to decipher between a login and a registration, but I'm having trouble finding how i actually do this with the social auth package.
Any ideas?
The difference between login and register is up to your project, it looks like in your scenario, a user landing in your pipeline function that matches an email in your DB should be considered like a login attempt and not a new singup. That's basically the functionality of associate_by_email method.
You might see the potential risk in this when a user uses a service that doesn't validate the email addresses, they can take control over somebody else account. You can mitigate this by doing validation on your end after any new social account is added, or by trusting services that are known to validate emails on their ends.
I would say, that you have to remove from the pipeline
'social_core.pipeline.social_auth.associate_by_email'
Reason: your application is not supporting unique user emails in User data model, and you are getting yourself into trouble. If you are not verifying user emails, then the trouble might be even bigger.
My company has a Flask application that uses flask-login to handle user logins/logouts and sessions. We use the #login_required decorator to protect views. Our clients log via persistent users stored in a database. However, we want employees of our company to be able to log in to our clients' sites without popping up in their users lists. We verify our own authenticity by CAS login at our own CAS server and checking that the username belongs to our company.
We want the employees to simply be able to login without needing to be persisted in the database but flask-login requires a persisted user model.
Sorry for the troublesome use of words here, but I hope this is understadable.
Every authorization system should check user in some storage by some field and in usual cases return exist or has permisions.
So with flask-login you can implement it with next: user_loader/header_loader/request_loader and UserMixin with user_id.
Every request with login_required call *_loader to get UserMixin. So it can look like next:
#login_manager.request_loader
def loader(request):
identifier = get_identifier_from_request(request)
exist = check_on_cas_server(identifier)
if not exist:
return None
user = UserMixin()
user.id = get_specified_or_random_id(identifier, exist)
return user
Details you can found with https://flask-login.readthedocs.org/en/latest/.
I'm using Django-Allauth to successfully log in with my Facebook account on my webserver. The problem is, when I use the default SignUpView to do so, the username stored in the DB is the username Facebook returns from the social login. Something like this:
<firstname>.<lastname>.<integer>
I've figured out how to connect my Facebook account with an already created standard user account ( not social ) at a later time using the view at:
/accounts/social/connections/
And how to change emails with
/accounts/email/
Can someone please show me how I can force a user to pick a non-facebook username when they log in with Facebook on my site without first creating a standard user?
Thanks!
============ EDIT =======================
So adding this to settings.py prompts for username and password to associate with facebook login, but does not prompty for a password:
SOCIALACCOUNT_AUTO_SIGNUP = False
I still need to figure out how to prompt for a password in this state.
This fixes it - inherit from SignupForm for social auth signup form.
class SignupForm(SignupForm):
Bit of a strange one and I have my reasons for doing this, I know Django does this out-of-the-box so put that to the side when I ask..... is it possible to create a authenticated session in Django for a user that does not exist in the standard user model. i.e I want a one off login (session) created for access that allows me to use request.tempUser.is_authenticated() Almost like anonymous access, but authenticated! I'm not talking about custom user models here, but I want do want use the standard auth stuff in Django, if thats possible?
This is what I have so far where I have tried request.session.save() but that won't ... log-in the user.
if member.check_password(password):
# Start new session for member???????
request.session.save()
return self.create_response(request, {
'success': True
})
I've done this before, we have a session middleware (we wrote) that looks to see if the current user logged in is a valid user or not.
On the login we do the following
def login(request, username, password):
# not the actual code, but you get the gist
logged_in_user = authenticate(username, password)
request['cur_user'] = logged_in_user.username
If that variable is not set or is not set to a proper username we bounce the user and clear out the session.
This will log in the user, essentially you just have to track that variable in your code to ensure that the session has a valid user attached to it.