I'm trying to set up a very lightweight permission system using Google App Engine and Flask.
The end result I am hoping for is that each individual view is its own permission, and in an admin panel you can assign the views each user is allowed to see.
How would I set this up better? It works fine, but I'm going to be querying ndb on operator for each and every view everytime a page loads.
from google.appengine.api import users
from google.appengine.ext import ndb
import logging
from flask import Flask, redirect, make_response, request
def user_authorized(rule):
user = users.get_current_user()
username = str(user)
user_info = Operators.query(Operators.username == username).get()
if not user_info:
return False
if rule in user_info.permissions:
return True
else:
return False
def forbidden_view():
return make_response(
'You do not have permission or this user does not exist. <a href="{0}">Login</a>'.format(users.create_login_url(request.url)),
403
)
class FlaskWithPermissions(Flask):
def route(self, rule, **options):
def decorator(f):
endpoint = options.pop('endpoint', f.__name__)
if user_authorized(rule):
self.add_url_rule(rule, endpoint, f, **options)
return f
else:
self.add_url_rule(rule, endpoint, forbidden_view, **options)
return decorator
app = FlaskWithPermissions(__name__)
class Operators(ndb.Model):
username = ndb.StringProperty()
permissions = ndb.StringProperty(repeated=True)
@app.route('/')
def index():
return 'OK /'
@app.route('/test')
def test():
return 'OK /test'
@app.route('/testfail')
def testfail():
return 'OK /testfail'
The test data I have in the database is:
Operators(username='[email protected]', permissions=['/', '/test']).put()
And then log in as [email protected], of course.
1 Answer 1
The first thing that comes to mind is just to cache user permissions in memcache, but that might or might not be necessary. I'd try this way first and see if you run into issues.
A simpler approach would be to define each user's key to be their username, then use get_by_id(). That has the advantage of being automatically memcached by ndb and being faster (I think).
user_authorized
, you could simplyreturn rule in user_info.permissions
instead of theif-else
\$\endgroup\$