storing and accessing users properly in django session - python

Here I am trying to store selected users in some django session and for this I have tried like this but while retrieving the users from session in another view I am getting empty queryset.How can i get the users which are stored in session in another django fucntion?
storing selected users in session
selected_users = get_user_model().objects.filter(id__in=request.POST.getlist('users'))
initial = {'users':[]}
session = request.session.get('users',initial)
if selected_users:
for user in selected_users:
if not user in session['users']:
session['users'].append(user.email)
print(session['users'])
here trying to retrieve these session's users in another view
sess = request.session.get('users',{'users':[]})
users = get_user_model().objects.filter(pk__in=sess["users"])
print('sess',users) #didn't worked
request.session['users'] # didn't worked either

You are not setting the user list in session. You are setting email in the variable session["user"] but querying id. Also, you are trying to set the session value as a list object but using default value as a dict object.
selected_users = get_user_model().objects.filter(id__in=request.POST.getlist('users'))
session_users = request.session.get('users',[])
if selected_users:
for user in selected_users:
if not user in session_users:
session_users.append(user.id) # append id instead of email
print(session_users)
# set the value in session
request.session["users"] = session_users
Now you can retrieve the list of user.id.
sess_users = request.session.get('users',[])
users = get_user_model().objects.filter(pk__in=sess_users)
print('sess',users)
print request.session['users']

Related

Change user state in database based on session

I have webapp that shows who is currently logged in on it's front page. I did that by having isActive field in user model, if user is logged isActive = True if user is logged out isActive = False. Unfortunately now I needed to implement auto log out on browser close and I've achieved that thanks to
REMEMBER_COOKIE_DURATION = datetime.timedelta(minutes=0)
app.config["SESSION_PERMANENT"] = False
But this obviously doesn't change state in database
My approach was to check active users and check sessions, get the ID's of both and compare them. If user ID is in active_user_list and not in session_id get this user ID and change it's state in database.
def checking_loop():
delay = 180
while True:
active_users = User.query.filter_by(isActive=True).all()
#don't worry about querying database in a loop It's stored locally
#on the PC
active_users_id = []
user_in_session = []
if session.get('_user_id'):
user_in_session.append(session['_user_id'])
for x in active_users:
active_users_id.append(x.id)
users_to_logout = [x for x in active_users_id if x not in user_in_session]
time.sleep(delay)
logout_loop = Thread(target=checking_loop)
logout_loop.start()
So, what's not working? I didn't know that when I call session I only get one ID.
Can I make this work somehow or do you have a better approach for this?
I don't think this will work. Flask session depends on context https://flask.palletsprojects.com/en/2.0.x/reqcontext/#how-the-context-works. I don't know how your code works without view context, but generally global session derives it's value from currently served request (the assumption is only one request can be handled at the time). So in session you'll get current user, not all users.
I'm not sure when session connected to user is deleted or how to iterate over active sessions, but if they are stored in cookies backend won't be able to do that.

How to set user name in session and get the user name in other view methods

I'm new to Python and Django.
I'm using PHP form for login mechanism and once the login is successful, I'm sending the user name to Django application to carry on with other operations but I'm stuck in finding a best way to store the user name in session so that it can be used in other view methods
Below are some of my tries which failed:
1) Storing the user name in a global variable and access throughout the application but when another user login from their machine, user name gets changed in my machine.
2) Storing the user name in Django DB session but another user logs in with different user, it's showing the old user only.
3) I tried storing in the cache but still, it's not working.
DB session handler: It works fine when I access in sessionHandler method but it throws key error when i try to access in login method.
def sessionHandler(request):
userName = request.GET.get('uname')
request.session['user'] = userName
print("current logged in user: " + request.session['user'])
return JsonResponse({'Response': 'success'})
def login(request):
uname = request.session.get('user')
UserName = {"Name": uname}
return render(request, 'login/login.html', UserName)
My use case is that any user who logs in their own machine and with own user name and password should be saved in the session data. Please help me to move further with this.
Thanks in advance !!!

Querying information for HTTPBasicAuth

For my site for auth I'm using https://flask-httpauth.readthedocs.io/en/latest/ . Now I'm trying to make it that it's using data from database. To do that i created database named Users and created columns named username and password.
To get data from this table after defining its class as model I've made get_user functions which looks like it:
#staticmethod
def get_user():
query = (Users
.select())
user = []
for s in query:
user.append(s)
return user
(I'm not sure if it's correct)
Next I had to modify get_pw function but I also wasn't sure how to modify it so I made it look like it:
#auth.get_password
def get_pw(username):
if username in Users.get_user():
return users.get(Users.get_user())
return None
Now after running the site I get prompt to give login and password but those that I set up in my database doesn't seem to work so there must be a problem with get_pw function. Also I'm using peewee SQL to manage database : http://docs.peewee-orm.com/en/latest/peewee/querying.html
You can get rid of your get_user method since you are issuing a very large select query that fetches all records from user table. The get_pw can be redefined as:
def get_pw(username):
user = Users.get(Users.name == username) #assuming you have a username field in model
return user.password #assuming a password field
Also, its a good practice to define your model class as a singular noun rather than plural. So, its better to call it User rather than Users.
This'll help you get started in no time: http://docs.peewee-orm.com/en/latest/peewee/quickstart.html#quickstart

Saving user settings when using federated login

I need to save settings for each user on my application.
I tried to use the user as a parent of my settings object, but I cannot do this since users do not have keys.
I then created an instance in my settings object that has a reference to user property, but in the docs it says UserProperty is unstable if the user changes their email address.
I then decided to save the user_id in a StringProperty() but if the user logs in with OpenId, the user_id element is None.
Is there a way to tie the user settings to the user object that works for both google accounts and open_id accounts?
Couldn't you add a wrapper class around the google account / open_id account, so you can use the parent relationship? Something like the following:
UserWrapper(db.Model):
user = db.UserProperty()
UserSettings(db.Model):
...
# New User
user = users.get_current_user()
new_user_settings = UserSettings(...)
new_user_wrapper = UserWrapper(key=user.nickname(),
parent=new_user_settings,
user=user)
# Login Existing User
user = users.get_current_user()
user_wrapper = UserWrapper.get_by_key_name(user.nickname())
user_settings = user_wrapper.parent()
If the user wants to change their email address, look up the UserSettings with the old email, delete the associated UserWrapper, create a new UserWrapper for the new email address and associate with the old UserSettings.
Note I've made the UserSettings a parent of UserWrapper, in case associating multiple email addresses with the same account may be something of interest.

Google App Engine (Python) : use UserProperty with Webapp2 User Model

i have an application where we allow users to use Oauth2 for authentication and even Custom User Registrations. All the Users are saved into the default User entity in the datastore. If the user is logging in using Oauth2 for the first time a new record in the default User entity is created like this:
"""Check if user is already logged in"""
if self.logged_in:
logging.info('User Already Logged In. Updating User Login Information')
u = self.current_user
u.auth_ids.append(auth_id)
u.populate(**self._to_user_model_attrs(data, self.USER_ATTRS[provider]))
u.put()
else:
"""Create a New User"""
logging.info('Creating a New User')
ok, user = self.auth.store.user_model.create_user(auth_id, **self._to_user_model_attrs(data, self.USER_ATTRS[provider]))
if ok:
self.auth.set_session(
self.auth.store.user_to_dict(user)
)
self.redirect(continue_url)
for custom registrations records are inserted through the following handler.
class RegistrationHandler(TemplateHandler, SimpleAuthHandler):
def get(self):
self.render('register.html')
def post(self):
"""Process registration form."""
user = 'appname:%s' % self.request.get('email')
name = '%s %s' % (self.request.get('first_name'), self.request.get('last_name'))
password = self.request.get('password')
avatar = self.request.get('avatar')
act_url = user_activation.Activate(self.request.get('first_name'), self.request.get('email'))
ok, user = User.create_user(auth_id=user, name=name, password_raw=password, email=self.request.get('email'))
if ok:
self.auth.set_session(self.auth.store.user_to_dict(user))
acc = models.Account(display_name=self.request.get('first_name'), act_url=act_url, act_key=act_url.split('activate/')[1], user=users.User(User.get_by_auth_id(self.current_user.auth_ids[0]).email))
acc.put()
if avatar:
avt = models.Picture(is_avatar=True, is_approved=True, image=avatar, user=users.User(User.get_by_auth_id(self.current_user.auth_ids[0]).email))
avt.put()
self.redirect('/')
Now we are using webapp2_extras.sessions for session handling. We have different models like, Comments, Images, Reviews etc in which we want to use db.UserProperty() as the author field. However, the author field shows blank or None whenever we enter a record into any of these models using 'users.get_current_user()'. I think this is because we are handling the sessions through webapp2 sessions.
What we want to achieve is to be able to use the db.UserProperty field in various models and link appropriately to the current user using webapp2 sessions ?
the UserProperty() has to be passed with a User Object in order for it to properly insert the records. Even though we are able to enter the records using the following code :
user = users.User(User.get_by_auth_id(self.current_user.auth_ids[0]).email)
or
user = users.User(User.get_by_auth_id(self.current_user.auth_ids[0]).name)
but then we are not able to get the whole user object by referencing to model.author
Any ideas how we should achieve this ?
OAuth 2.0 is not currently supported by Users service. Supported options are
Google Accounts
OpenId
OAuth 1.0
I don't frankly understand what you're trying to accomplish with introducing db.User in to the codebase. Given there's self.current_user, I assume you're already handling authentication process.
When you do self.auth.store.user_model.create_user - that already gives you a webapp2's user object/entity (it has nothing to do with db.User though). I believe that's what you'll have to use as your author field given OAuth 2.0 constraint.
users.get_current_user() relies on a special cookie (App Engine internal). In fact, it has nothing to do with webapp2's session (or any other "custom" session for that matter). You could hack it by setting the cookie to a value that App Engine internals can understand and be tricked as if a user were logged in with one of the methods I mentioned, but I wouldn't recommend this approach. It is not documented (cookie name, format, etc.) and might be changed at any time.
Instead of using UserProperty to store references to the webapp2 user objects, you should instead store the auth_id as a StringProperty and add a convenience method for fetching the corresponding webapp2 user entity.
Something like this
from webapp2_extras.appengine.auth.models import User
class Comment(db.model):
text = db.StringProperty()
author = db.StringProperty()
def get_author(self):
return User.get_by_auth_id(self.author)

Categories

Resources