How to users.set_current_user? - python

How to create a custom login system with google-app-engine's User class?
I'm making my own login system. I have tried os.environ['USER_EMAIL'] = 'john.doe#example.com', but it doesn't work. I guess the information is not saved in a session, so if I visit another page then users.get_current_user() has no memory of what I had set it to previously.
I have seen google-app-engine unit tests that does this to fake a logins. I think these works because the tests are within the same session. I need to store my own custom information across multiple sessions.
I have also tried setting environment variables, but without luck.
os.environ['USER_EMAIL'] = 'john.doe#example.com'
os.environ['USER_ID'] = 'todo_user_id'
os.environ['USER_IS_ADMIN'] = '1'
os.environ['AUTH_DOMAIN'] = 'todo_auth_domain'
os.environ['FEDERATED_IDENTITY'] = 'todo_federated_identity'
os.environ['FEDERATED_PROVIDER'] = 'todo_federated_provider'

You can't - the Users API only supports signing in with methods supported by that API. If you want to implement your own signin, you will need to use a third-party session library and keep track of logged in users the 'regular' way.

Related

Is there a way to create read only dashboard in Apache Superset

So we have been using Apache Superset, It's a great tool.
The only frustration come from that there are a few dashboards we want to share with users outside the company.
I believe right now the way to do it is go from the Gamma user then create a read only role (Correct me if I'm wrong)
There are a few downside of this:
we need to create a view per user on each table to make sure that they do not see the records that they are not supposed to.
the access is given by datasource, so they will be able to see any dashboard that use the same datasource, which can be a problem sometimes.
all of these authentication is a lot of work to maintain.
I'm wondering if there is any way (or even hack) to simply share the graphs and tables as a dashboard, without any database access granted.
Like a frozen or snapshot of dashboard,
like the way Redash does it:
https://redash.io/help/user-guide/dashboards/sharing-dashboards
What you are looking for can be achieved through a combination of the public user and appending ?standalone=true to the dashboard url.
You also don't need the entire list of Gamma user permissions, the most important ones are can explore on superset, explore json on superset and datasource access and csrf token. This basically renders the dashboards without the superset menu and should make everything readonly.
We can achieve this by creating a custom role.
1. Can remove all the menu items
2. Can disable the dashboard edit button
3. Can give access to specific tables.
So a user cannot access any other dashboard or charts
Eg. Dashboard
Public dashboards
This is not meant for production. It’s for experiments or while doing a proof of concept.
#superset_config.py
PUBLIC_ROLE_LIKE_GAMMA = True
or
PUBLIC_ROLE_LIKE: Optional[str] = "Gamma"
After this, we need to re-run the init user (if already run)
docker-compose exec superset superset-init
Dashboards & charts can be embedded without superset header (Nav bar etc) by adding standalone=true parameter to the url, like this :
http://localhost:9000/superset/dashboard/world_health/?standalone=true
We need to grant database source permissions to public role for the data to be visible.
please see: https://sairamkrish.medium.com/apache-superset-custom-authentication-and-integrate-with-other-micro-services-8217956273c1
Superset is great, I'm glad people are talking about it since the days when it was AirBnB's Caravel. It has come a long way.
There is no 'official' solution for what you're looking for but there is a way to effectively get the same result. You said you wouldn't mind a 'hack' so...
Creating a table or a data source and exposing it to the 'public' group should do what you're looking to accomplish.

Transfering data to REST API without a database django

Basically I have a program which scraps some data from a website, I need to either print it out to a django template or to REST API without using a database. How do I do this without a database?
Your best bet is to
a.) Perform the scraping in views themselves, and pass the info in a context dict to the template
or
b.) Write to a file and have your view pull info from the file.
Django can be run without a database, but it depends on what applications you enable. Some of the default functionality (auth, sites, contenttypes) requires a database. So you'd need to disable those. If you need to use them, you're SOL.
Other functionality (like sessions) usually uses a database, but you can configure it to use a cache or file or something else.
I've taken two approaches in the past:
1) Disable the database completely and disable the applications that require the database:
DATABASES = {}
2) Use a dummy sqlite database just so it works out of box with the default apps without too much tweaking, but don't really use it for anything. I find this method faster and good for setting up quick testing/prototyping.
And to actually get the data from the scraper into your view, you can take a number of approaches. Store the data in a cache, or just write it directly to your context variables, etc.

Django : How to count number of people viewed

I'm making a simple BBS application in Django and I want it so that whenever someone sees a post, the number of views on that post (post_view_no) is increased.
At the moment, I face two difficulties:
I need to limit the increase in post_view_no so that one user can only increase it once regardless of how many times the user refreshes/clicks on the post.
I also need to be able to track the users that are not logged in.
Regards to the first issue, it seems pretty easy as long as I create a model called 'View' and check the db but I have a feeling this may be an overkill.
In terms of second issue, all I can think of is using cookies / IP address to track the users but IP is hardly unique and I cannot figure out how to use cookies
I believe this is a common feature on forum/bbs solutions but google search only turned up with plugins or 'dumb' solutions that increase the view each time the post is viewed.
What would be the best way to go about this?
I think you can do both things via cookies. For example, when user visits a page, you can
Check if they have “viewed_post_%s” (where %s is post ID) key set in their session.
If they have, do nothing. If they don't, increase view_count numeric field of your corresponding Post object by one, and set the key (cookie) “viewed_post_%s” in their session (so that it won't count in future).
This would work with both anonymous and registered users, however by clearing cookies or setting up browser to reject them user can game the view count.
Now using cookies (sessions) with Django is quite easy: to set a value for current user, you just invoke something like
request.session['viewed_post_%s' % post.id] = True
in your view, and done. (Check the docs, and especially examples.)
Disclaimer: this is off the top of my head, I haven't done this personally, usually when there's a need to do some page view / activity tracking (so that you see what drives more traffic to your website, when users are more active, etc.) then there's a point in using a specialized system (e.g., Google Analytics, StatsD). But for some specific use case, or as an exercise, this should work.
Just to offer a secondary solution, which I think would work but is also prone to gaming (if coming by proxy or different devices). I haven't tried this either but I think it should work and wouldn't require to think about cookies, plus you aggregate some extra data which is noice.
I would make a model called TrackedPosts.
class TrackedPosts(models.Model):
post = models.ForeignKey(Post)
ip = models.CharField(max_length=16) #only accounting for ipv4
user = models.ForeignKey(User) #if you want to track logged in or anonymous
Then when you view a post, you would take the requests ip.
def my_post_view(request, post_id):
#you could check for logged in users as well.
tracked_post, created = TrackedPost.objects.get_or_create(post__pk=id, ip=request.ip, user=request.user) #note, not actual api
if created:
tracked_post.post.count += 1
tracked_post.post.save()
return render_to_response('')

Django: two sessions in the same browser

I have a Django webapp that allows users to collaborate. Each user is given a link with a unique code they click to go to my site. On the first page visit, I store this unique code in request.session, and then on subsequent page visits I retrieve it to identify the user's record in the DB. I also store various other stuff about the user and their session in request.session.
I would like to allow two sessions to occur in different windows/tabs of the same browser. This is to make testing easier. My colleagues spend a lot of time testing multiple users using the site simultaneously. So far I have been instructing them to use different browsers or different browser profiles, so that the session cookie is not shared. But they always forget this instruction (or do it wrong) and end up confused when the app doesn't work as expected.
My idea is to put the user's unique code (called user_id) in each URL, and then subdivide request.session into multiple dictionaries, so my class-based view would have this:
def dispatch(...):
user_id = kwargs['user_id']
self.request_session = self.request.session[user_id]
Then use this variable self.request_session as I usually would:
self.request_session['time_started'] = now
...
And then before returning my response, assign it back:
self.request.session[user_id] = self.request_session
I think this should be fine, since own code would keep the two sessions isolated in 2 separate dictionaries, but maybe it would break down if Django (or even a 3rd party app) stores something in request.session. Wondering if anyone has a recommendation for another way to handle this.
Modern browsers (e.g. Firefox, Chromium, Brave, …) have the ability to open a page without reference to existing history, cookies, etc.
In Firefox this is termed “Private Browsing”; you open a “Private Window”.
In Brave this is termed a “Private Tab”.
In Chromium this is termed “Incognito Mode”.
By using any of these, you can make a new “session” that will not present as any other logged-in session. This should allow you to have an arbitrary number of sessions at once.

How to do this kind of session related task in App Engine Python?

First than all, I don't even know if this is a session related question. But I could not think a better way to describe it in the title.
I'm developing a web application for registered users so they can create and manage trade unions.
A user can create several unions. Each union can store an image, a description and a name.
The index page shows the list of unions created by the currently registered user.
When the user clicks on a union from the list, all the pages of the application must show
in they headers the corresponding name and image stored for that union.
Also, all the options of the application must refer to the currently selected union.
That is the process for every selected union.
How could I do this on App Engine Python? What technique could I use? Is it something
related to sessions? I do the authentication process with the Gmail service.
I hope I explained myself clearly.
Thanks in advance!
You'd use the datastore to create a union as an entity class, with a description and a name. If your image is small you can store it in your entity, if it's large, you may store it in the blobstore and store a link to it inside your entity.
You can use the python User API for authentication. You don't really need any special session work if you're using the User API.

Categories