7
\$\begingroup\$

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.

asked May 28, 2014 at 12:55
\$\endgroup\$
2
  • \$\begingroup\$ Just a nit-pick, near the end of user_authorized, you could simply return rule in user_info.permissions instead of the if-else \$\endgroup\$ Commented May 29, 2014 at 15:31
  • \$\begingroup\$ Thanks. That's a pattern I use quite a lot and the way you mentioned is definitely cleaner. \$\endgroup\$ Commented May 30, 2014 at 1:23

1 Answer 1

1
\$\begingroup\$

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).

answered Jun 22, 2014 at 23:16
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.