· 7 years ago · Mar 27, 2018, 12:56 AM
1# -*- coding: utf-8 -*-
2from flask import Flask, redirect, url_for, flash, render_template, g, current_app, request
3
4from werkzeug.security import generate_password_hash, check_password_hash
5
6from flask_wtf import Form, validators
7from flask_wtf import FlaskForm
8from wtforms import StringField, PasswordField, SubmitField
9from flask_sqlalchemy import SQLAlchemy
10from wtforms.validators import Required, Length, EqualTo
11
12# AUTH
13from flask_sqlalchemy import BaseQuery
14from flask_principal import Principal, RoleNeed, UserNeed, Permission, Identity, identity_changed, identity_loaded, AnonymousIdentity
15from werkzeug.utils import cached_property
16
17app = Flask(__name__)
18app.config.update(
19 SQLALCHEMY_DATABASE_URI = 'sqlite:///test.sqlite',
20 DEBUG = True,
21 SECRET_KEY = 'secret'
22)
23app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
24
25db = SQLAlchemy(app)
26
27Principal(app)
28
29# User Information providers
30@identity_loaded.connect_via(app)
31def on_identity_loaded(sender, identity):
32 g.user = User.query.from_identity(identity)
33
34# Permission
35admin = Permission(RoleNeed('admin'))
36member = Permission(RoleNeed('member'))
37
38# MODELS
39class UserQuery(BaseQuery):
40
41 def from_identity(self, 100):
42 try:
43 user = self.get(int(identity))
44 except ValueError:
45 user = current_user
46
47 if user:
48 identity.provides.update(user.provides)
49
50 identity.user = user
51
52 return user
53
54class User(db.Model):
55
56 query_class = UserQuery
57
58 MEMBER = 100
59 ADMIN = 300
60
61 __tablename__ = 'user'
62 id = db.Column(db.Integer, unique=True, nullable=False, primary_key=True)
63 username = db.Column(db.String(80), unique=True, nullable=False)
64 password = db.Column(db.String(80))
65 role = db.Column(db.Integer, default=100)
66
67 @cached_property
68 def permissions(self):
69 return self.Permissions(self)
70
71 @cached_property
72 def provides(self):
73 needs = [RoleNeed('authenticated'), UserNeed(self.id)]
74
75 if self.is_member:
76 needs.append(RoleNeed('member'))
77
78 if self.is_admin:
79 needs.append(RoleNeed('admin'))
80
81 return needs
82
83 @property
84 def is_member(self):
85 return self.role == self.MEMBER
86
87 @property
88 def is_admin(self):
89 return self.role == self.ADMIN
90
91# FORMS
92class SignupForm(Form):
93 username = StringField('Username', validators=[Required(), Length(1, 9)])
94 password = PasswordField("Password", validators=[Required(), Length(1, 9)])
95 submit = SubmitField("Signup")
96
97class LoginForm(Form):
98 username = StringField('Username', validators=[Required(), Length(1, 9)])
99 password = PasswordField("Password", validators=[Required(), Length(1, 9)])
100 submit = SubmitField("Login")
101
102# VIEWS
103@app.route('/')
104def index():
105 users = User.query.all()
106 return render_template('index.html', users=users)
107
108@app.route('/signup', methods=('GET', 'POST'))
109def signup():
110
111 form = SignupForm()
112
113 if form.validate_on_submit():
114 user = User()
115 form.populate_obj(user)
116
117 db.session.add(user)
118 db.session.commit()
119
120 flash('Signup Success %s' % user.username, 'success')
121
122 return redirect(url_for('index'))
123
124 return render_template('signup.html', form=form)
125
126@app.route('/login', methods=('GET', 'POST',))
127def login():
128
129 form = LoginForm()
130
131 if form.validate_on_submit():
132 user = User.query.filter(User.username==form.username.data).first()
133 if user:
134 if user.password != form.password.data:
135 flash('ooo!')
136
137 identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
138
139 flash('ooo, %s' % user.username)
140
141 return redirect(url_for('index'))
142 else:
143 flash('00000!')
144
145 return render_template('login.html', form=form)
146
147@app.route('/logout')
148def logout():
149 identity_changed.send(current_app._get_current_object(), identity=AnonymousIdentity())
150 flash('oooo!')
151
152 return redirect(url_for('index'))
153
154@app.route('/page')
155@admin.require(401)
156def page():
157 return render_template('page.html')
158
159@app.errorhandler(401)
160def unauthorized(error):
161 flash('Please login to see this page', 'error')
162 return redirect(url_for('login', next=request.path))
163
164db.create_all()
165
166if __name__ == '__main__':
167 app.run()