Skip to content
Snippets Groups Projects
user.py 1.97 KiB
Newer Older
Benjamin Bertrand's avatar
Benjamin Bertrand committed
# -*- coding: utf-8 -*-
"""
app.api.user
~~~~~~~~~~~~
Benjamin Bertrand's avatar
Benjamin Bertrand committed

This module implements the user API.
Benjamin Bertrand's avatar
Benjamin Bertrand committed

: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_ldap3_login import AuthenticationResponseStatus
from flask_login import login_required, current_user
Benjamin Bertrand's avatar
Benjamin Bertrand committed
from ..extensions import ldap_manager
from .. import utils, tokens, models
from .utils import get_generic_model
Benjamin Bertrand's avatar
Benjamin Bertrand committed

Benjamin Bertrand's avatar
Benjamin Bertrand committed
bp = Blueprint("user_api", __name__)
Benjamin Bertrand's avatar
Benjamin Bertrand committed
@bp.route("/users")
def get_users():
    """Return users information

    .. :quickref: User; Get users information
    """
Benjamin Bertrand's avatar
Benjamin Bertrand committed
    return get_generic_model(models.User, order_by=models.User.username)
Benjamin Bertrand's avatar
Benjamin Bertrand committed
@bp.route("/profile")
def get_user_profile():
    """Return the current user profile

    .. :quickref: User; Get current user profile
    """
    return jsonify(current_user.to_dict()), 200
Benjamin Bertrand's avatar
Benjamin Bertrand committed
@bp.route("/login", methods=["POST"])
Benjamin Bertrand's avatar
Benjamin Bertrand committed
def login():
    """Return a JSON Web Token
    .. :quickref: User; Get a token
    :jsonparam username: username to login
    :jsonparam password: password
Benjamin Bertrand's avatar
Benjamin Bertrand committed
    data = request.get_json()
    if data is None:
Benjamin Bertrand's avatar
Benjamin Bertrand committed
        raise utils.CSEntryError("Body should be a JSON object")
Benjamin Bertrand's avatar
Benjamin Bertrand committed
    try:
Benjamin Bertrand's avatar
Benjamin Bertrand committed
        username = data["username"]
        password = data["password"]
Benjamin Bertrand's avatar
Benjamin Bertrand committed
    except KeyError:
Benjamin Bertrand's avatar
Benjamin Bertrand committed
        raise utils.CSEntryError(
            "Missing mandatory field (username or password)", status_code=422
        )
Benjamin Bertrand's avatar
Benjamin Bertrand committed
    response = ldap_manager.authenticate(username, password)
    if response.status == AuthenticationResponseStatus.success:
Benjamin Bertrand's avatar
Benjamin Bertrand committed
        current_app.logger.debug(f"{username} successfully logged in")
Benjamin Bertrand's avatar
Benjamin Bertrand committed
        user = ldap_manager._save_user(
Benjamin Bertrand's avatar
Benjamin Bertrand committed
            response.user_dn, response.user_id, response.user_info, response.user_groups
        )
        payload = {"access_token": tokens.generate_access_token(identity=user.id)}
Benjamin Bertrand's avatar
Benjamin Bertrand committed
        return jsonify(payload), 200
Benjamin Bertrand's avatar
Benjamin Bertrand committed
    raise utils.CSEntryError("Invalid credentials", status_code=401)