diff --git a/.gitignore b/.gitignore index 0688114..ac511ee 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # C extensions *.so +*.db # Packages *.egg diff --git a/pytest_bdd_example/__init__.py b/pytest_bdd_example/__init__.py index c69cec7..e69de29 100644 --- a/pytest_bdd_example/__init__.py +++ b/pytest_bdd_example/__init__.py @@ -1,31 +0,0 @@ -from flask import Flask -from flask.ext.admin import Admin -from flask.ext.login import LoginManager -from flask.ext.sqlalchemy import SQLAlchemy - -login_manager = LoginManager() - -app = Flask(__name__) -app.config.from_object('settings') -app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' - -db = SQLAlchemy(app) - -from flask.ext.admin.contrib.sqlamodel import ModelView - -from pytest_bdd_example import dashboard -from pytest_bdd_example.dashboard.models import User - - -app.register_blueprint(dashboard.bp, url_prefix='/dashboard') - -login_manager.init_app(app) - - -@login_manager.user_loader -def load_user(userid): - return User.get(userid) - - -admin_panel = Admin(app) -admin_panel.add_view(ModelView(User, db.session, endpoint='users')) diff --git a/pytest_bdd_example/dashboard/__init__.py b/pytest_bdd_example/dashboard/__init__.py index c5eee2d..7b65561 100644 --- a/pytest_bdd_example/dashboard/__init__.py +++ b/pytest_bdd_example/dashboard/__init__.py @@ -1,3 +1,39 @@ -from flask import Blueprint +from flask import Blueprint, Flask, url_for, redirect + +from flask.ext.admin import Admin +from flask.ext.login import LoginManager +from flask.ext.sqlalchemy import SQLAlchemy + +from pytest_bdd_example.dashboard import settings + +login_manager = LoginManager() + +app = Flask(__name__, static_folder=settings.MEDIA_ROOT, template_folder=settings.TEMPLATES_ROOT) +app.config.from_object('pytest_bdd_example.dashboard.settings') +app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' + +db = SQLAlchemy(app) + +from flask.ext.admin.contrib.sqlamodel import ModelView + +from pytest_bdd_example.dashboard.models import User + +from pytest_bdd_example.dashboard.views import * + +app.register_blueprint(bp, url_prefix='/dashboard') + +admin_panel = Admin(app) +admin_panel.add_view(ModelView(User, db.session, endpoint='users')) + +login_manager.init_app(app) + +@login_manager.user_loader +def load_user(userid): + return User.query.get(userid) + +@login_manager.unauthorized_handler +def unauthorized(): + return redirect(url_for('dashboard.login')) + + -bp = Blueprint('dashboard', __name__) diff --git a/pytest_bdd_example/dashboard/decorators.py b/pytest_bdd_example/dashboard/decorators.py new file mode 100644 index 0000000..73e9bd4 --- /dev/null +++ b/pytest_bdd_example/dashboard/decorators.py @@ -0,0 +1,14 @@ +from functools import wraps + +from flask import g, flash, redirect, url_for, request + + +def requires_login(f): + @wraps(f) + def decorated_function(*args, **kwargs): + if g.user is None: + flash(u'You need to be signed in for this page.') + return redirect(url_for('dashboard.login', next=request.path)) + return f(*args, **kwargs) + return decorated_function + diff --git a/pytest_bdd_example/dashboard/forms.py b/pytest_bdd_example/dashboard/forms.py new file mode 100644 index 0000000..b6278e9 --- /dev/null +++ b/pytest_bdd_example/dashboard/forms.py @@ -0,0 +1,8 @@ +from flask.ext.wtf import Form +from wtforms import TextField, PasswordField +from wtforms.validators import Required, Email + + +class LoginForm(Form): + email = TextField('Email address', [Required(), Email()]) + password = PasswordField('Password', [Required()]) \ No newline at end of file diff --git a/pytest_bdd_example/dashboard/models.py b/pytest_bdd_example/dashboard/models.py index 078be4d..a350af7 100644 --- a/pytest_bdd_example/dashboard/models.py +++ b/pytest_bdd_example/dashboard/models.py @@ -1,27 +1,17 @@ -from pytest_bdd_example import db +from flask.ext.security import UserMixin +from pytest_bdd_example.dashboard import db ROLE_USER = 0 ROLE_ADMIN = 1 -class User(db.Model): - uuid = db.Column(db.Integer, primary_key=True) +class User(db.Model, UserMixin): + id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True) email = db.Column(db.String(120), unique=True) password = db.Column(db.String(20)) role = db.Column(db.SmallInteger, default=ROLE_USER) - - def is_authenticated(self): - return True - - def is_active(self): - return True - - def is_anonymous(self): - return False - - def get_id(self): - return unicode(self.id) + is_active = db.Column(db.Boolean, default=False) def __repr__(self): return '' % (self.username) \ No newline at end of file diff --git a/pytest_bdd_example/settings.py b/pytest_bdd_example/dashboard/settings.py similarity index 67% rename from pytest_bdd_example/settings.py rename to pytest_bdd_example/dashboard/settings.py index c5c0c87..a49b414 100644 --- a/pytest_bdd_example/settings.py +++ b/pytest_bdd_example/dashboard/settings.py @@ -3,6 +3,6 @@ import os DEBUG = True BASE_PATH = os.path.dirname(os.path.abspath(__file__)) MEDIA_ROOT = os.path.join(BASE_PATH, '../media') -TEMPLATES_ROOT = os.path.join(BASE_PATH, '../templates', 'admin') +TEMPLATES_ROOT = os.path.join(BASE_PATH, '../templates', 'dashboard') -SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_PATH, '../pytest-bdd-example.db') +SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_PATH, '../dashboard.db') diff --git a/pytest_bdd_example/dashboard/views.py b/pytest_bdd_example/dashboard/views.py index 50f13d3..be45e7b 100644 --- a/pytest_bdd_example/dashboard/views.py +++ b/pytest_bdd_example/dashboard/views.py @@ -1,12 +1,25 @@ -from flask import render_template -from flask.ext.login import current_user +from flask import render_template, Blueprint, url_for, redirect +from flask.ext.login import login_required, login_user -from pytest_bdd_example.dashboard import bp +from pytest_bdd_example.dashboard import User +from pytest_bdd_example.dashboard.forms import LoginForm -# @bp.route('/') -# def index(template='dashboatd.html'): -# -# if not current_user.is_authenticated(): -# template = "login.html" -# -# return render_template(template) +bp = Blueprint('dashboard', __name__) + +@bp.route('/') +@login_required +def index(template='dashboard.html'): + return render_template(template) + +@bp.route('/login/', methods=['GET', 'POST']) +def login(): + login_form = LoginForm() + + if login_form.validate_on_submit(): + user = User.query.filter_by(email=login_form.email.data).first() + login_user(user) + return redirect(url_for('dashboard.index')) + + return render_template("login.html", **{ + 'form': login_form, + }) \ No newline at end of file diff --git a/pytest_bdd_example/manage.py b/pytest_bdd_example/manage.py index da5037a..528d236 100755 --- a/pytest_bdd_example/manage.py +++ b/pytest_bdd_example/manage.py @@ -1,11 +1,21 @@ #!/usr/bin/env python -from flask.ext.script import Manager, Shell, Server +from flask.ext.script import Manager, Shell, Server, Command -from pytest_bdd_example import app +from pytest_bdd_example.dashboard import app as dashboard_app +from pytest_bdd_example.shop import app as shop_app -manager = Manager(app) +def create_app(app=None): + APPS = { + 'dashboard': dashboard_app, + 'shop': shop_app, + } + + return APPS[app] + +manager = Manager(create_app) +manager.add_option("-app", "--application", dest="app", required=True) manager.add_command("runserver", Server("127.0.0.1")) manager.add_command("shell", Shell(use_ipython=True)) manager.run() \ No newline at end of file diff --git a/pytest_bdd_example/templates/dashboard/login.html b/pytest_bdd_example/templates/dashboard/login.html index eb6f932..6b70600 100644 --- a/pytest_bdd_example/templates/dashboard/login.html +++ b/pytest_bdd_example/templates/dashboard/login.html @@ -4,14 +4,25 @@ {% endblock %} {% block content %} -
- - - - - -
+
+ {{ form.csrf_token }} + + +
+
+ {{ form.email(placeholder="Email address", class="input-block-level") }} +
    {% for error in form.email.errors %}
  • {{ error|e }}
  • {% endfor %}
+
+
+ +
+
+ {{ form.password(placeholder="Password", class="input-block-level") }} +
    {% for error in form.password.errors %}
  • {{ error|e }}
  • {% endfor %}
+
+
+ + +
{% endblock %} \ No newline at end of file