2016-03-25 7 views
5

के आधार पर पहुंच संशोधित करें मैंने here से फ्लास्क-एडमिन ऑथ उदाहरण लिया और इसे थोड़ा बदल दिया।फ्लास्क-एडमिन रोल आधारित एक्सेस - भूमिका

मैंने नीचे दिए गए दृश्य में निम्न ब्लॉक जोड़ा, लेकिन यह निर्यात बटन नहीं दिखाता है। मैं इसे व्यवस्थापक विचारों में निर्यात विकल्प जोड़ने की उम्मीद कर रहा था। यह कंसोल पर ---superuser प्रिंट करता है।

 if current_user.has_role('superuser'): 
      can_export = True 
      print ' ---- superuser ' 

मैंने कई बार निर्यात सुविधा का उपयोग किया है। अगर मैं class MyModelView(sqla.ModelView): से नीचे can_export = True कथन डालता हूं तो यह काम करेगा, मैं इसे उपयोगकर्ता भूमिका के आधार पर बनाने/संपादन/आदि तक पहुंच नियंत्रित करने के उदाहरण के रूप में उपयोग कर रहा हूं। उदाहरण के लिए, मैं एक पठनीय भूमिका निभाना चाहूंगा जहां can_create = झूठा, can_edit = झूठा, आदि

क्या कोई मदद कर सकता है? क्या कोई बता सकता है कि मुझसे क्या गलत हो रहा है?

==

यह संपूर्ण दृश्य है।

# Create customized model view class 
class MyModelView(sqla.ModelView): 

    def is_accessible(self): 
     if not current_user.is_active or not current_user.is_authenticated: 
      return False 

     if current_user.has_role('superuser'): 
      return True 

     return False 

    def _handle_view(self, name, **kwargs): 
     """ 
     Override builtin _handle_view in order to redirect users when a view is not accessible. 
     """ 
     if current_user.has_role('superuser'): 
      can_export = True 
      print ' ---- superuser ' 

     if not self.is_accessible(): 
      if current_user.is_authenticated: 
       # permission denied 
       abort(403) 
      else: 
       # login 
       return redirect(url_for('security.login', next=request.url)) 

==

संदर्भ के लिए: मैं सभी कोड here डाल दिया।

+0

निर्यात बटन क्या है? फ्लास्क-एडमिन में कोई निर्यात कार्यक्षमता नहीं है। – dirn

+0

http://flask-admin.readthedocs.org/en/latest/introduction/ कहता है कि यह करता है। वह पृष्ठ कहता है: मॉडल दृश्य के सीएसवी निर्यात को सक्षम करने के लिए: 'can_export = True'। यदि मैं 'can_export = True' नीचे' श्रेणी MyModelView (sqla.ModelView) के नीचे 'can_export = True' डालता हूं, तो मैं बटन शो बना सकता हूं: ' –

+1

कूल। आज मैंने कुछ नया सीखा। उस पृष्ठ के आधार पर, 'can_export' एक वर्ग विशेषता है। आपका स्थानीय रूप से '_handle_view' विधि पर स्कॉप्ड किया गया है। आपको 'self.can_export' का उपयोग करने की आवश्यकता होगी, यद्यपि आपके पास यह सेट करने में बहुत देर हो सकती है। – dirn

उत्तर

0

प्रति @ डीरन की टिप्पणी प्रति, self. इसे जोड़कर जोड़ा गया।

 self.can_export = True 

5

@dirn धन्यवाद आगे विस्तार करने के लिए, मैं ऊपर से एक आधार के रूप में प्रमाणन उदाहरण के साथ जारी रखा और कुछ सरल भूमिका आधारित अभिगम नियंत्रण जोड़ा। मुझे उम्मीद है कि यह किसी की मदद कर सकता है।

पूरा कोड here है। यदि आप यहां कुछ देखते हैं जो एक अच्छा आरबीएसी अभ्यास नहीं है, तो मैं इसके बारे में सुनना चाहता हूं।

मुख्य app.py फ़ाइल है:

import os 
from flask import Flask, url_for, redirect, render_template, request, abort 
from flask_sqlalchemy import SQLAlchemy 
from flask_security import Security, SQLAlchemyUserDatastore, \ 
    UserMixin, RoleMixin, login_required, current_user 
from flask_security.utils import encrypt_password 
import flask_admin 
from flask_admin.contrib import sqla 
from flask_admin import helpers as admin_helpers 

# Create Flask application 
app = Flask(__name__) 
app.config.from_pyfile('config.py') 
db = SQLAlchemy(app) 

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
# Define models directly without reflection... 
class Customer(db.Model): 
    CustomerId = db.Column(db.Integer(), primary_key=True) 
    FirstName = db.Column(db.Unicode(40), nullable=False) 
    LastName = db.Column(db.String(20), nullable=False) 
    City = db.Column(db.Unicode(40)) 
    Email = db.Column(db.Unicode(60), unique = True) 

    def __str__(self): 
     return self.CustomerID 

class City(db.Model): 
    Id = db.Column(db.Integer(), primary_key=True) 
    City = db.Column(db.Unicode(40), unique = True) 

    def __str__(self): 
     return self.ID 

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

# Define models 
roles_users = db.Table(
    'roles_users', 
    db.Column('user_id', db.Integer(), db.ForeignKey('user.id')), 
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id')) 
) 

class Role(db.Model, RoleMixin): 
    id = db.Column(db.Integer(), primary_key=True) 
    name = db.Column(db.String(80), unique=True) 
    description = db.Column(db.String(255)) 

    def __str__(self): 
     return self.name 

class User(db.Model, UserMixin): 
    id = db.Column(db.Integer, primary_key=True) 
    first_name = db.Column(db.String(255)) 
    last_name = db.Column(db.String(255)) 
    email = db.Column(db.String(255), unique=True) 
    password = db.Column(db.String(255)) 
    active = db.Column(db.Boolean()) 
    confirmed_at = db.Column(db.DateTime()) 
    roles = db.relationship('Role', secondary=roles_users, 
          backref=db.backref('users', lazy='dynamic')) 

    def __str__(self): 
     return self.email 

# Setup Flask-Security 
user_datastore = SQLAlchemyUserDatastore(db, User, Role) 
security = Security(app, user_datastore) 

# Flask views 
@app.route('/') 
def index(): 
    return render_template('index.html') 


# Create customized model view class 
class dgBaseView(sqla.ModelView): 

    column_display_pk = True 
    page_size = 20 
    can_view_details = True 
    #can_export = False 
    can_export = True 

    def _handle_view(self, name, **kwargs): 
     """ 
     Override builtin _handle_view in order to redirect users when a view is not accessible. 
     """ 
     if not self.is_accessible(): 
      if current_user.is_authenticated: 
       # permission denied 
       abort(403) 
      else: 
       # login 
       return redirect(url_for('security.login', next=request.url)) 

class regularRbacView(dgBaseView): 

    def is_accessible(self): 

     # set accessibility... 
     if not current_user.is_active or not current_user.is_authenticated: 
      return False 

     # roles not tied to ascending permissions... 
     if not current_user.has_role('export'): 
      self.can_export = False 

     # roles with ascending permissions... 
     if current_user.has_role('adminrole'): 
      self.can_create = True 
      self.can_edit = True 
      self.can_delete = True 
      self.can_export = True 
      return True 
     if current_user.has_role('supervisor'): 
      self.can_create = True 
      self.can_edit = True 
      self.can_delete = False 
      return True 
     if current_user.has_role('user'): 
      self.can_create = True 
      self.can_edit = True 
      self.can_delete = False 
      return True 
     if current_user.has_role('create'): 
      self.can_create = True 
      self.can_edit = False 
      self.can_delete = False 
      return True 
     if current_user.has_role('read'): 
      self.can_create = False 
      self.can_edit = False 
      self.can_delete = False 
      return True 
     return False 

class lookupRbacView(dgBaseView): 

    def is_accessible(self): 
     # set accessibility... 
     if not current_user.is_active or not current_user.is_authenticated: 
      return False 

     # roles not tied to ascending permissions... 
     if not current_user.has_role('export'): 
      self.can_export = False 

     # roles with ascending permissions... 
     if current_user.has_role('adminrole'): 
      self.can_create = True 
      self.can_edit = True 
      self.can_delete = True 
      self.can_export = True 
      return True 
     if current_user.has_role('supervisor'): 
      self.can_create = True 
      self.can_edit = True 
      self.can_delete = False 
      return True 
     if current_user.has_role('user'): 
      self.can_create = False 
      self.can_edit = False 
      self.can_delete = False 
      return True 
     if current_user.has_role('create'): 
      self.can_create = False 
      self.can_edit = False 
      self.can_delete = False 
      return True 
     if current_user.has_role('read'): 
      self.can_create = False 
      self.can_edit = False 
      self.can_delete = False 
      return True 
     return False 

class SuperView(dgBaseView): 

    can_export = True 

    def is_accessible(self): 
     if not current_user.is_active or not current_user.is_authenticated: 
      return False 
     if current_user.has_role('adminrole'): 
      self.can_create = True 
      self.can_edit = True 
      self.can_delete = True 
      #self.can_export = True 
      return True 
     return False 


# define a context processor for merging flask-admin's template context into the 
# flask-security views. 
@security.context_processor 
def security_context_processor(): 
    return dict(
     admin_base_template=admin.base_template, 
     admin_view=admin.index_view, 
     h=admin_helpers, 
    ) 

# Create admin 
admin = flask_admin.Admin(
    app, 'Rbac RoleBasedAccess', base_template='my_master.html', template_mode='bootstrap3', 
) 

class customer_view(regularRbacView): 

    column_searchable_list = ['CustomerId', 'City', 'Email', 'FirstName', 'LastName',] 
    # make sure the type of your filter matches your hybrid_property 
    column_filters = ['FirstName', 'LastName', 'City', 'Email' ] 
    # column_default_sort = ('part_timestamp', True) 
    #column_export_list = ['CustomerId', 'City', 'Email', 'FirstName', 'LastName',] 

# Add model views 
admin.add_view(SuperView(Role, db.session)) 
admin.add_view(SuperView(User, db.session)) 
admin.add_view(customer_view(Customer, db.session)) 
admin.add_view(lookupRbacView(City, db.session)) 


def build_sample_db(): 
    """ 
    Populate a small db with some example entries. 
    """ 
    import string 

    #db.drop_all() 
    db.create_all() 

    with app.app_context(): 
     read_role = Role(name='read') 
     user_role = Role(name='user') 
     super_user_role = Role(name='adminrole') 
     db.session.add(user_role) 
     db.session.add(super_user_role) 
     db.session.add(Role(name='read')) 
     db.session.add(Role(name='create'))  
     db.session.add(Role(name='supervisor')) 
     db.session.add(Role(name='delete')) 
     db.session.add(Role(name='export')) 
     db.session.commit() 

     test_user = user_datastore.create_user(
      first_name='Admin', 
      email='admin', 
      password=encrypt_password('admin'), 
      roles=[user_role, super_user_role] 
     ) 


     first_names = [ 
      'read', 'create', 'user', 'suser', 'delete', 'Charlie', 'Sophie', 'Mia', 
     ] 
     last_names = [ 
      'Brown', 'Smith', 'Patel', 'Jones', 'Williams', 'Johnson', 'Taylor', 'Thomas', 
     ] 
     roles1 = [ 
      'read', 'create', 'user', 'supervisor', 'delete', 'read', 'read', 'read', 
     ] 

     for i in range(len(first_names)): 
      tmp_email = first_names[i].lower() 
      # initialize the users with simple password... 'a' 
      tmp_pass = 'a' 
      user_datastore.create_user(
       first_name=first_names[i], 
       last_name=last_names[i], 
       email=tmp_email, 
       password=encrypt_password(tmp_pass), 
       roles=[read_role, ] 
      ) 
     db.session.commit() 
    return 

if __name__ == '__main__': 

    # Build a sample db on the fly, if one does not exist yet. 
    app_dir = os.path.realpath(os.path.dirname(__file__)) 
    database_path = os.path.join(app_dir, app.config['DATABASE_FILE']) 
    if not os.path.exists(database_path): 
     build_sample_db() 
    app.run(host='0.0.0.0', port=5000, debug=True) 

config.py है:

# http://stackoverflow.com/questions/5055042/whats-the-best-practice-using-a-settings-file-in-python 
import creds 

# Create dummy secret key so we can use sessions 
SECRET_KEY = creds.cred['secretkey'] 

# Create in-memory database 
DATABASE_FILE = 'fground.sqlite' 
SQLALCHEMY_DATABASE_URI = creds.cred['dbspec'] + DATABASE_FILE 
SQLALCHEMY_ECHO = True 

# Flask-Security config 
SECURITY_URL_PREFIX = "/admin" 
SECURITY_PASSWORD_HASH = "pbkdf2_sha512" 
SECURITY_PASSWORD_SALT = creds.cred['csalt'] 

# Flask-Security URLs, overridden because they don't put a/at the end 
SECURITY_LOGIN_URL = "/login/" 
SECURITY_LOGOUT_URL = "/logout/" 
SECURITY_REGISTER_URL = "/register/" 

SECURITY_POST_LOGIN_VIEW = "/admin/" 
SECURITY_POST_LOGOUT_VIEW = "/admin/" 
SECURITY_POST_REGISTER_VIEW = "/admin/" 

# Flask-Security features 
SECURITY_REGISTERABLE = True 
SECURITY_SEND_REGISTER_EMAIL = False 

creds.py है:

cred = dict(
    secretkey = '123232323238', 
    dbspec = 'sqlite:///', 
    csalt  = "ATGUOHAELKiubaq3fgo8hiughaerGOJAEGj", 
    dbu = 'user', 
    dbp = 'pass', 
) 

इस चलाने के लिए, मैं अनुशंसा करते हैं कि आप उपरोक्त फ्लास्क-एडमिन ऑथ उदाहरण से शुरू करें और फिर इन फ़ाइलों को उस उदाहरण में कॉपी करें। इसे चलाने से उपयोगकर्ताओं और भूमिकाओं के साथ डेटाबेस बनाना चाहिए। इसके अलावा, आप github link पर जाने के लिए तैयार सभी कोड प्राप्त कर सकते हैं।

संबंधित मुद्दे