From 5f41066be272c2c0a6198daec0b92d15b3911d20 Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@esss.se> Date: Wed, 19 Jul 2017 09:27:23 +0200 Subject: [PATCH] Add API blueprint --- app/api/__init__.py | 0 app/api/items.py | 54 +++++++++++++++++++++++++++++++++++++++++++++ app/extensions.py | 2 ++ app/factory.py | 5 ++++- environment.yml | 2 ++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 app/api/__init__.py create mode 100644 app/api/items.py diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/api/items.py b/app/api/items.py new file mode 100644 index 0000000..ea9b8a6 --- /dev/null +++ b/app/api/items.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +""" +app.api.items +~~~~~~~~~~~~~ + +This module implements the items API. + +:copyright: (c) 2017 European Spallation Source ERIC +:license: BSD 2-Clause, see LICENSE for more details. + +""" +from flask import (current_app, Blueprint, jsonify, request) +from flask_jwt_extended import create_access_token, jwt_required +from flask_ldap3_login import AuthenticationResponseStatus +from ..extensions import ldap_manager, db +from ..models import User + +bp = Blueprint('api', __name__) + + +@bp.route('/login', methods=['POST']) +def login(): + try: + username = request.get_json()['username'] + password = request.get_json()['password'] + except (TypeError, KeyError): + return jsonify({'msg': 'Bad Request'}), 400 + response = ldap_manager.authenticate(username, password) + if response.status == AuthenticationResponseStatus.success: + current_app.logger.debug(f'{username} successfully logged in') + user = User.query.filter_by(username=username).first() + if user is None: + # LDAP user not in database yet - create it + user = User(username, name=response.user_info['cn'], email=response.user_info['mail']) + db.session.add(user) + db.session.commit() + payload = {'access_token': create_access_token(identity=user.id)} + return jsonify(payload), 200 + return jsonify({'msg': 'Invalid credentials'}), 401 + + +@bp.route('/items') +@jwt_required +def get_items(): + sql = """SELECT item.id, item.name, vendor.name, model.name, location.name, status.name + FROM item + INNER JOIN vendor ON vendor.id = item.vendor_id + INNER JOIN model ON model.id = item.model_id + INNER JOIN location ON location.id = item.location_id + INNER JOIN status ON status.id = item.status_id + """ + result = db.engine.execute(sql) + data = [[item for item in row] for row in result] + return jsonify(data=data) diff --git a/app/extensions.py b/app/extensions.py index 4c2c1a9..87da52a 100644 --- a/app/extensions.py +++ b/app/extensions.py @@ -17,6 +17,7 @@ from flask_migrate import Migrate from flask_bootstrap import Bootstrap from flask_admin import Admin from flask_mail import Mail +from flask_jwt_extended import JWTManager convention = { @@ -36,3 +37,4 @@ ldap_manager = LDAP3LoginManager() bootstrap = Bootstrap() admin = Admin(template_mode='bootstrap3') mail = Mail() +jwt = JWTManager() diff --git a/app/factory.py b/app/factory.py index b1b2977..941db72 100644 --- a/app/factory.py +++ b/app/factory.py @@ -13,10 +13,11 @@ import sqlalchemy as sa from flask import Flask from flask_admin.contrib.sqla import ModelView from . import settings -from .extensions import db, migrate, login_manager, ldap_manager, bootstrap, admin, mail +from .extensions import db, migrate, login_manager, ldap_manager, bootstrap, admin, mail, jwt from .models import User, Role, Action, Vendor, Model, Location, Status, Item from .main.views import bp as main from .users.views import bp as users +from .api.items import bp as api from .defaults import defaults @@ -84,6 +85,7 @@ def create_app(): login_manager.login_view = 'users.login' ldap_manager.init_app(app) mail.init_app(app) + jwt.init_app(app) admin.init_app(app) admin.add_view(ModelView(Role, db.session)) @@ -97,6 +99,7 @@ def create_app(): app.register_blueprint(main) app.register_blueprint(users) + app.register_blueprint(api, url_prefix='/api') register_cli(app) diff --git a/environment.yml b/environment.yml index 2cd6683..20d4c15 100644 --- a/environment.yml +++ b/environment.yml @@ -48,10 +48,12 @@ dependencies: - dominate==2.3.1 - flask-admin==1.5.0 - flask-bootstrap==3.3.7.1 + - flask-jwt-extended==3.1.1 - flask-ldap3-login==0.9.13 - flask-mail==0.9.1 - flask-migrate==2.0.4 - flask-script==2.0.5 - ldap3==2.2.4 - pyasn1==0.2.3 + - pyjwt==1.4.2 - visitor==0.1.3 -- GitLab