enable login
This commit is contained in:
parent
e02f002f7e
commit
882cfb2a98
@ -114,6 +114,8 @@
|
|||||||
|
|
||||||
.pull-right {
|
.pull-right {
|
||||||
float: right;
|
float: right;
|
||||||
|
right: 50px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
|
@ -1 +1,9 @@
|
|||||||
<a href="{{ url_for('home') }}">Home</a> |
|
<a href="{{ url_for('home') }}">Home</a> |
|
||||||
|
<div class="pull-right">
|
||||||
|
{% if current_user.is_authenticated %}
|
||||||
|
<a href="#">{{ current_user.email }}</a> |
|
||||||
|
<a href="{{ url_for('security.logout') }}">Logout</a> |
|
||||||
|
{% else %}
|
||||||
|
<a href="{{ url_for('security.login') }}">Login</a> |
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
@ -1,12 +1,94 @@
|
|||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
|
from json import JSONEncoder
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from flask_security import Security, SQLAlchemyUserDatastore
|
||||||
|
from sqlalchemy.ext.declarative import declared_attr
|
||||||
|
from flask_security import RoleMixin, UserMixin
|
||||||
|
|
||||||
from config import SQLALCHEMY_DATABASE_URI, MAKEDIRS, DATABASE_FILE
|
from config import SQLALCHEMY_DATABASE_URI, MAKEDIRS, DATABASE_FILE
|
||||||
|
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
|
|
||||||
|
|
||||||
|
class Ownable(object):
|
||||||
|
@declared_attr
|
||||||
|
def user_id(self):
|
||||||
|
return db.Column(db.Integer, db.ForeignKey('user.id'))
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def user(self):
|
||||||
|
return db.relationship("User")
|
||||||
|
|
||||||
|
|
||||||
|
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 ModelJsonEncoder(JSONEncoder):
|
||||||
|
def default(self, o):
|
||||||
|
if isinstance(o, datetime.datetime):
|
||||||
|
return str(o)
|
||||||
|
return o.id
|
||||||
|
|
||||||
|
|
||||||
|
def camel_case_to_snake_case(name):
|
||||||
|
"""
|
||||||
|
Convertes a CamelCase name to snake_case
|
||||||
|
:param name: the name to be converted
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
|
||||||
|
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower()
|
||||||
|
|
||||||
|
|
||||||
|
class ModelController(ModelJsonEncoder):
|
||||||
|
"""
|
||||||
|
This interface is the parent of all models in our database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@declared_attr
|
||||||
|
def __tablename__(self):
|
||||||
|
return camel_case_to_snake_case(self.__name__) # pylint: disable=E1101
|
||||||
|
|
||||||
|
_sa_declared_attr_reg = {'__tablename__': True}
|
||||||
|
__mapper_args__ = {'always_refresh': True}
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
uuid = db.Column(db.Unicode, default=str(uuid4()))
|
||||||
|
|
||||||
|
|
||||||
|
class Role(db.Model, ModelController, RoleMixin):
|
||||||
|
name = db.Column(db.Unicode, unique=True)
|
||||||
|
description = db.Column(db.Unicode)
|
||||||
|
|
||||||
|
|
||||||
|
class User(db.Model, ModelController, UserMixin):
|
||||||
|
email = db.Column(db.Unicode, unique=True)
|
||||||
|
password = db.Column(db.Unicode)
|
||||||
|
|
||||||
|
active = db.Column(db.Boolean(), default=True)
|
||||||
|
confirmed_at = db.Column(db.DateTime())
|
||||||
|
|
||||||
|
timezone = db.Column(db.String, default='UTC')
|
||||||
|
tz_offset_seconds = db.Column(db.Integer, default=0)
|
||||||
|
locale = db.Column(db.String(4), default='en')
|
||||||
|
|
||||||
|
name = db.Column(db.Unicode)
|
||||||
|
profile_image_url = db.Column(db.String)
|
||||||
|
|
||||||
|
roles = db.relationship('Role', secondary=roles_users,
|
||||||
|
backref=db.backref('users', lazy='dynamic'))
|
||||||
|
|
||||||
|
|
||||||
|
security = Security()
|
||||||
|
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
|
||||||
|
|
||||||
|
|
||||||
def init_db(app):
|
def init_db(app):
|
||||||
app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
|
app.config["SQLALCHEMY_DATABASE_URI"] = SQLALCHEMY_DATABASE_URI
|
||||||
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
|
||||||
@ -16,9 +98,11 @@ def init_db(app):
|
|||||||
app.register_blueprint(oshipka_bp)
|
app.register_blueprint(oshipka_bp)
|
||||||
|
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
|
security.init_app(app, user_datastore)
|
||||||
|
|
||||||
for dir in MAKEDIRS:
|
for dir in MAKEDIRS:
|
||||||
os.makedirs(dir, exist_ok=True)
|
os.makedirs(dir, exist_ok=True)
|
||||||
if not os.path.exists(DATABASE_FILE):
|
if not os.path.exists(DATABASE_FILE):
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
db.create_all()
|
db.create_all()
|
||||||
return True
|
return True
|
@ -2,6 +2,7 @@ from flask import Flask, Blueprint
|
|||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.config["SECRET_KEY"] = "UNSECRET_KEY....478932fjkdsl"
|
app.config["SECRET_KEY"] = "UNSECRET_KEY....478932fjkdsl"
|
||||||
|
app.config["SECURITY_PASSWORD_SALT"] = "UNSECRETfdsafsda_KEY....478932fjkdsl"
|
||||||
|
|
||||||
test_bp = Blueprint('test_bp', __name__,
|
test_bp = Blueprint('test_bp', __name__,
|
||||||
url_prefix="/test",
|
url_prefix="/test",
|
||||||
|
@ -1,20 +1,33 @@
|
|||||||
Babel==2.8.0
|
Babel==2.8.0
|
||||||
|
bcrypt==3.1.7
|
||||||
|
blinker==1.4
|
||||||
|
cffi==1.14.0
|
||||||
click==7.1.1
|
click==7.1.1
|
||||||
filelock==3.0.12
|
filelock==3.0.12
|
||||||
Flask==1.1.1
|
Flask==1.1.1
|
||||||
Flask-Babel==1.0.0
|
Flask-Babel==1.0.0
|
||||||
|
Flask-BabelEx==0.9.4
|
||||||
|
Flask-Login==0.5.0
|
||||||
|
Flask-Mail==0.9.1
|
||||||
|
Flask-Principal==0.4.0
|
||||||
|
Flask-Security==3.0.0
|
||||||
Flask-SQLAlchemy==2.4.1
|
Flask-SQLAlchemy==2.4.1
|
||||||
Flask-Table==0.5.0
|
Flask-Table==0.5.0
|
||||||
|
Flask-WTF==0.14.3
|
||||||
importlib-metadata==1.5.2
|
importlib-metadata==1.5.2
|
||||||
inflect==4.1.0
|
inflect==4.1.0
|
||||||
itsdangerous==1.1.0
|
itsdangerous==1.1.0
|
||||||
Jinja2==2.11.1
|
Jinja2==2.11.1
|
||||||
MarkupSafe==1.1.1
|
MarkupSafe==1.1.1
|
||||||
|
passlib==1.7.2
|
||||||
pathtools==0.1.2
|
pathtools==0.1.2
|
||||||
|
pycparser==2.20
|
||||||
pytz==2019.3
|
pytz==2019.3
|
||||||
six==1.14.0
|
six==1.14.0
|
||||||
|
speaklater==1.3
|
||||||
SQLAlchemy==1.3.15
|
SQLAlchemy==1.3.15
|
||||||
SQLAlchemy-Utils==0.36.3
|
SQLAlchemy-Utils==0.36.3
|
||||||
watchdog==0.10.2
|
watchdog==0.10.2
|
||||||
Werkzeug==1.0.0
|
Werkzeug==1.0.0
|
||||||
|
WTForms==2.2.1
|
||||||
zipp==3.1.0
|
zipp==3.1.0
|
||||||
|
Loading…
Reference in New Issue
Block a user