Bottle Main raw resource upon request

I watched this post: http://pythonhosted.org/Flask-Principal/#granular-resource-protection

Now that there is nothing wrong with the way it currently works, I don’t see that it is very useful, because at the time of logging in, all messages are read and EditBlogPostNeed added to the identifier.

Imagine that if I write more than the usual number of posts, this will not be a very good strategy for a long time, as I would like to check my mail when I get access to the /posts/<post_id> view.

Is there a way to do this check for each request for presentation using Flask Principal ?

I can, of course, get around this very easily with a lazy query and relationship filter, but I want to use Flask Principal .

+6
source share
3 answers

Not sure if I fully understand your question, but that might help. In the Flask application, I use Flask-Principal to resolve a role, such as admin and editor, and I also use it to granularly protect resources, as described in Docs for Vials . In my case, I check if the user has permission to access a specific account. In each submission, a personality is loaded and permission checked.

In view :

 @login_required def call_list(id, page=1): dept = models.Department.query.get_or_404(id) view_permission = auth.ViewAccountPermission(dept.office.account_id) if view_permission.can(): # do something 

user permission :

 ViewAccount = namedtuple('View', ['method', 'value']) ViewAccountNeed = partial(ViewAccount, 'view') class ViewAccountPermission(Permission): def __init__(self, account_id): need = ViewAccountNeed(unicode(account_id)) super(ViewAccountPermission, self).__init__(need) 

And in the idloader function :

 if hasattr(current_user, 'assigned_accounts'): for account_id in current_user.assigned_accounts(): identity.provides.add(auth.ViewAccountNeed(unicode(account_id))) 
+1
source

While Flask-Principal is the most popular plugin, it is not complicated, and it just does not work in most cases, which I need. I tried to make it work the way I like it, but I never succeeded. Fortunately, I found a very simple and easy module - permission :

Using

First you need to define your own rules by subclassing Rule , then override check() and deny() :

 # rules.py from flask import session, flash, redirect, url_for from permission import Rule class UserRule(Rule): def check(self): """Check if there is a user signed in.""" return 'user_id' in session def deny(self): """When no user signed in, redirect to signin page.""" flash('Sign in first.') return redirect(url_for('signin')) 

Then you define permissions by subclassing Permission and overriding rule() :

 # permissions.py from permission import Permission from .rules import UserRule class UserPermission(Permission): """Only signin user has this permission.""" def rule(self): return UserRule() 

There are 4 ways to use the UserPermission described above:

1. Use as a view decorator

 from .permissions import UserPermission @app.route('/settings') @UserPermission() def settings(): """User settings page, only accessable for sign-in user.""" return render_template('settings.html') 

2. Use in sight

 from .permissions import UserPermission @app.route('/settions') def settings(): permission = UserPermission() if not permission.check() return permission.deny() return render_template('settings.html') 

3. Use in view codes (using the with statement)

 from .permissions import UserPermission @app.route('/settions') def settings(): with UserPermission(): return render_template('settings.html') 

4. Use in Jinja2 templates

First you need to enter certain permissions in the template context:

 from . import permissions @app.context_processor def inject_vars(): return dict( permissions=permissions ) 

then in the templates:

 {% if permissions.UserPermission().check() %} <a href="{{ url_for('new') }}">New</a> {% endif %} 
+1
source

My answer is based on the assumption that you already know how the flask works, and how it integrates with the database.

First, we need to store Needs in a database, if you don’t know why, I do not recommend reading my answer below

Then, back to your question, we need to edit the article, how to characterize it?

 @app.route('/article/edit/<id>'): @Permission(Need('edit', 'article')).require() def article(id): pass 

User ID

 id = identity(user.id) id.provide.add(Need('edit','article')) 

Then the user has permission to edit the article. @Permission(Need('edit', 'article')).require() will return true for each article, even if the user is not the author of the article. This is your problem, right?

Below I will tell you how to solve this problem.

because by default Permission.require () does not provide any arguments that need to be passed, so I define my own Permisson and IdentityContext and pass in the id of the article and in the Model article, then I check the user_id article with the current_user.id flash drive

 class MyPermission(Permission): pass class MyIdentityContext(): pass 

If the user is the author of the article, I return True, the user can edit the article, if not, return False, then it will work.

-------- I will tell you more in more detail ------------

0
source

Source: https://habr.com/ru/post/952053/


All Articles