Skip to content

Commit v0.35

kwmccabe edited this page Apr 17, 2018 · 6 revisions

v0.35 - Refine decorator login_required() as role_required(role)


Files changed (4)

File web/app/init.py MODIFIED

  • Because decorators.role_required(role) uses config values as argument defaults, but current_app.config doesn't exist...
  • Expose AppConfig values outside of request context.
 bootstrap = Bootstrap()
 db = SQLAlchemy()
 login_manager = LoginManager()
+config_default = config['default']

File web/app/decorators.py MODIFIED

  • New decorator @role_required(role) created to refine standard @login_required().
  • role parameter is one of USER_ROLE_NONE, USER_ROLE_VIEW, USER_ROLE_EDIT or USER_ROLE_ADMIN.
  • Call login_manager.unauthorized() if no user.
  • Call login_manager.needs_refresh() if user's current role is too low. (FIX THIS: redirect to 'Contact Your Admin' page)
  • Otherwise, let the function continue.
 from flask import request, session
-from . import db
+from flask_login import current_user
+from . import config_default as CONFIG
+from . import db, login_manager

...
 
+# check current user_role >= requested role
+# if not logged in return unauthorized() ; if not allowed: return needs_refresh()
+def role_required( role=CONFIG.USER_ROLE_VIEW ):
+    def _decorator(f):
+        @wraps(f)
+        def _decorated(*args, **kwargs):
+            if not current_user.is_active:
+                logging.info('role_required( %s ) - unauthorized' % (role))
+                return login_manager.unauthorized()
+            if current_user.user_role < role:
+                logging.info('role_required( %s < %s ) - needs_refresh' % (current_user.user_role,role))
+                return login_manager.needs_refresh()
+            logging.debug('role_required( %s >= %s )' % (CONFIG.USER_ROLE[current_user.user_role],CONFIG.USER_ROLE[role]))
+            return f(*args, **kwargs)
+        return _decorated
+    return _decorator

File web/app/item/views.py MODIFIED

  • Import role_required decorator and CONFIG object.
  • Replace @login_required with @role_required(CONFIG.USER_ROLE_EDIT).
+from .. import config_default as CONFIG
 from .. import db, flash_errors
-from ..decorators import get_list_opts
+from ..decorators import get_list_opts, role_required

...
 
 @item.route('/admin/item/action', methods=['POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)

...
 
         if action == 'delete':
             for id in item_ids:
-                item = ItemModel.query.get_or_404(id)
-                db.session.delete(item)
-            db.session.commit()
-            flash('Items Deleted (id='+id_str+')','success')
+                item_delete( id )

...
 
-            flash("Items set %s (id=%s)" % (current_app.config['ITEM_STATUS'][new_status],id_str),'success')
+            flash("Items Set %s (id=%s)" % (current_app.config['ITEM_STATUS'][new_status],id_str),'success')

...
 
 @item.route('/admin/item/delete/<int:id>', methods=['GET','POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def item_delete( id ):
     item = ItemModel.query.get_or_404(id)
-    db.session.delete(item)
-    db.session.commit()
-    flash('Item deleted (id=%s)' % (item.id),'success')
-    logging.info('item_delete( id:%s )' % (item.id))
+    if current_user.id == item.owner_id or current_user.user_role == current_app.config['USER_ROLE_ADMIN']:
+        db.session.delete(item)
+        db.session.commit()
+        flash('Item Deleted (id=%s)' % (item.id),'success')
+        logging.info('item_delete( id:%s )' % (item.id))
+    else:
+        flash('Permission Denied - Item Not Deleted ( id:%s )' % (item.id))

...
 
 @item.route('/admin/item/create', methods=['GET','POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def item_create():

...
 
-        flash('Item created (id=%s)' % (item.id),'success')
+        flash('Item Created (id=%s)' % (item.id),'success')

...
 
 @item.route('/admin/item/edit/<int:id>', methods=['GET','POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def item_edit( id ):

...
 
-        flash('Item updated (id=%s)' % (item.id),'success')
+        flash('Item Updated (id=%s)' % (item.id),'success')

...
 
 @item.route('/admin/item/view/<int:id>')
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)

...
 
 @item.route('/admin/item/list', methods=['GET','POST'])
 @get_list_opts('item_list_opts')
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def item_list():

File web/app/user/views.py MODIFIED

  • Import role_required decorator and CONFIG object.
  • Replace @login_required with @role_required(CONFIG.USER_ROLE_EDIT).
  • For /admin/user/delete/<int:id> restrict access to @role_required(CONFIG.USER_ROLE_ADMIN).
+from .. import config_default as CONFIG
 from .. import db, flash_errors
+from ..decorators import get_list_opts, role_required
-from ..decorators import get_list_opts

...
 
-        flash('Invalid username or password','danger')
+        flash('Invalid Username or Password','danger')

...
 
 @user.route('/admin/user/action', methods=['POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def user_action():

...
 
         if action == 'delete':
             for id in user_ids:
-                user = UserModel.query.get_or_404(id)
-                db.session.delete(user)
-            db.session.commit()
-            flash('Users Deleted (id='+id_str+')','success')
+                user_delete( id )

...
 
-            flash("Users set %s (id=%s)" % (current_app.config['USER_ROLE'][new_role],id_str),'success')
+            flash("Users Set %s (id=%s)" % (current_app.config['USER_ROLE'][new_role],id_str),'success')

...
 
 @user.route('/admin/user/delete/<int:id>', methods=['GET','POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_ADMIN)
 def user_delete( id ):

...
 
-    flash('User deleted (id=%s)' % (user.id),'success')
+    flash('User Deleted (id=%s)' % (user.id),'success')

...
 
 @user.route('/admin/user/create', methods=['GET','POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def user_create():

...
 
-        flash('User created (id=%s)' % (user.id),'success')
+        flash('User Created (id=%s)' % (user.id),'success')

...
 
 @user.route('/admin/user/edit/<int:id>', methods=['GET','POST'])
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def user_edit( id ):

...
 
-        flash('User updated (id=%s)' % (user.id),'success')
+        flash('User Updated (id=%s)' % (user.id),'success')

...
 
 @user.route('/admin/user/view/<int:id>')
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def user_view( id ):

...
 
 @user.route('/admin/user/list', methods=['GET','POST'])
 @get_list_opts('user_list_opts')
-@login_required
+@role_required(CONFIG.USER_ROLE_EDIT)
 def user_list():

Commit-v0.34 | Commit-v0.35 | [Commit-v0.36]

Clone this wiki locally