· 8 years ago · Sep 12, 2017, 06:44 AM
1from flask import Flask
2from flask_sqlalchemy import SQLAlchemy
3
4# create the Flask application
5app = Flask(__name__)
6app.config.from_pyfile('config.py')
7db = SQLAlchemy(app)
8headers = {'content-type': 'application/json'}
9
10from myapp import app
11
12import os
13from flask import Flask, url_for, request, render_template, json, jsonify
14from flask_security import Security, SQLAlchemyUserDatastore
15from flask_security.utils import hash_password
16import flask_admin, requests
17from flask_admin import helpers as admin_helpers
18from myapp import app, db, headers
19from myapp.models import User, Role, MyModelView
20from flask_script import Manager
21from flask_migrate import Migrate, MigrateCommand
22
23
24# Initialize flask-migrate and script manager
25migrate = Migrate(app, db)
26manager = Manager(app)
27
28manager.add_command('db', MigrateCommand)
29
30# Setup Flask-Security
31user_datastore = SQLAlchemyUserDatastore(db.session, User, Role)
32security = Security(app, user_datastore)
33
34# Create admin
35admin = flask_admin.Admin(
36 app,
37 'Administrator',
38 base_template='my_master.html',
39 template_mode='bootstrap3'
40)
41
42# Add model views
43admin.add_view(MyModelView(Role, db.session))
44admin.add_view(MyModelView(User, db.session))
45
46# define a context processor for merging flask-admin's template context into the
47# flask-security views.
48@security.context_processor
49def security_context_processor():
50 return dict(
51 admin_base_template=admin.base_template,
52 admin_view=admin.index_view,
53 h=admin_helpers,
54 get_url=url_for
55 )
56
57
58def build_sample_db():
59 """
60 Populate a small db with some example entries.
61 """
62
63 import string
64 import random
65
66 db.drop_all()
67 db.create_all()
68
69 with app.app_context():
70 user_role = Role(name='user')
71 super_user_role = Role(name='superuser')
72 db.session.add(user_role)
73 db.session.add(super_user_role)
74 db.session.commit()
75
76 test_user = user_datastore.create_user(
77 first_name='Admin',
78 email='admin',
79 password=hash_password('admin'),
80 roles=[user_role, super_user_role]
81 )
82
83 first_names = [
84 'Harry', 'Amelia', 'Oliver', 'Jack', 'Isabella', 'Charlie', 'Sophie', 'Mia',
85 'Jacob', 'Thomas', 'Emily', 'Lily', 'Ava', 'Isla', 'Alfie', 'Olivia', 'Jessica',
86 'Riley', 'William', 'James', 'Geoffrey', 'Lisa', 'Benjamin', 'Stacey', 'Lucy'
87 ]
88 last_names = [
89 'Brown', 'Smith', 'Patel', 'Jones', 'Williams', 'Johnson', 'Taylor', 'Thomas',
90 'Roberts', 'Khan', 'Lewis', 'Jackson', 'Clarke', 'James', 'Phillips', 'Wilson',
91 'Ali', 'Mason', 'Mitchell', 'Rose', 'Davis', 'Davies', 'Rodriguez', 'Cox', 'Alexander'
92 ]
93
94 for i in range(len(first_names)):
95 tmp_email = first_names[i].lower() + "." + last_names[i].lower() + "@example.com"
96 tmp_pass = ''.join(random.choice(string.ascii_lowercase + string.digits) for i in range(10))
97 user_datastore.create_user(
98 first_name=first_names[i],
99 last_name=last_names[i],
100 email=tmp_email,
101 password=hash_password(tmp_pass),
102 roles=[user_role, ]
103 )
104 db.session.commit()
105 return
106
107# Flask views
108@app.route('/')
109def index():
110 return render_template('index.html')
111
112@app.route('/api/posts')
113def getPosts():
114 response = requests.get('...some_url', headers=headers)
115
116 ...some codes here
117
118if __name__ == '__main__':
119
120 # Build a sample db on the fly, if one does not exist yet.
121 app_dir = os.path.realpath(os.path.dirname(__file__))
122 database_path = os.path.join(app_dir, app.config['DATABASE_FILE'])
123 if not os.path.exists(database_path):
124 build_sample_db()
125
126 # Start app
127 app.secret_key = 'secret_key'
128 app.run(debug=True)
129
130 # Start script manager
131 manager.run()
132
133from flask import abort, redirect, url_for, request
134from flask_security import UserMixin, RoleMixin, login_required, current_user
135from flask_admin.contrib import sqla
136from myapp import db
137
138
139# Define models
140roles_users = db.Table(
141 'roles_users',
142 db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
143 db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
144)
145
146
147class Role(db.Model, RoleMixin):
148 id = db.Column(db.Integer(), primary_key=True)
149 name = db.Column(db.String(80), unique=True)
150 description = db.Column(db.String(255))
151
152 def __str__(self):
153 return self.name
154
155
156class User(db.Model, UserMixin):
157 id = db.Column(db.Integer, primary_key=True)
158 first_name = db.Column(db.String(255))
159 last_name = db.Column(db.String(255))
160 email = db.Column(db.String(255), unique=True)
161 password = db.Column(db.String(255))
162 active = db.Column(db.Boolean())
163 confirmed_at = db.Column(db.DateTime())
164 roles = db.relationship('Role', secondary=roles_users,
165 backref=db.backref('users', lazy='dynamic'))
166
167 def __str__(self):
168 return self.email
169
170
171# Create a user to test with
172class MyModelView(sqla.ModelView):
173
174 def is_accessible(self):
175 if not current_user.is_active or not current_user.is_authenticated:
176 return False
177
178 if current_user.has_role('superuser'):
179 return True
180
181 return False
182
183 def _handle_view(self, name, **kwargs):
184 """
185 Override builtin _handle_view in order to redirect users when a view is not accessible.
186 """
187 if not self.is_accessible():
188 if current_user.is_authenticated:
189 # permission denied
190 abort(403)
191 else:
192 # login
193 return redirect(url_for('security.login', next=request.url))
194
1952017-09-12 14:32:37,285 INFO sqlalchemy.engine.base.Engine SELECT user.id AS user_id, user.first_name AS user_first_name, user.last_name AS user_last_name, user.email AS user_email, user.password AS user_password, user.active AS user_active, user.confirmed_at AS user_confirmed_at
196FROM user
197WHERE lower(user.email) = lower(%s)
198 LIMIT %s
1992017-09-12 14:32:37,285 INFO sqlalchemy.engine.base.Engine ('admin', 1)
2002017-09-12 14:32:37,312 INFO sqlalchemy.engine.base.Engine SELECT `role`.id AS role_id, `role`.name AS role_name, `role`.description AS role_description
201FROM `role`, roles_users
202WHERE %s = roles_users.user_id AND `role`.id = roles_users.role_id
2032017-09-12 14:32:37,312 INFO sqlalchemy.engine.base.Engine (1L,)
204[2017-09-12 14:32:37,314] ERROR in app: Exception on /admin/login/ [POST]
205Traceback (most recent call last):
206 File "/home/jenn/analytics/analytics/venv/local/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
207 response = self.full_dispatch_request()
208 File "/home/jenn/analytics/analytics/venv/local/lib/python2.7/site-packages/flask/app.py", line 1615, in full_dispatch_request
209 return self.finalize_request(rv)
210 File "/home/jenn/analytics/analytics/venv/local/lib/python2.7/site-packages/flask/app.py", line 1632, in finalize_request
211 response = self.process_response(response)
212 File "/home/jenn/analytics/analytics/venv/local/lib/python2.7/site-packages/flask/app.py", line 1856, in process_response
213 response = handler(response)
214 File "/home/jenn/analytics/analytics/venv/local/lib/python2.7/site-packages/flask_security/views.py", line 58, in _commit
215 _datastore.commit()
216 File "/home/jenn/analytics/analytics/venv/local/lib/python2.7/site-packages/flask_security/datastore.py", line 31, in commit
217 self.db.session.commit()
218AttributeError: 'scoped_session' object has no attribute 'session'
2192017-09-12 14:32:37,314 INFO sqlalchemy.engine.base.Engine ROLLBACK
220127.0.0.1 - - [12/Sep/2017 14:32:37] "POST /admin/login/ HTTP/1.1" 500 -