2020-08-22 14:47:56 +00:00
|
|
|
#############################################
|
|
|
|
# Plugin: Auth #
|
|
|
|
# Functionality: Allow management of #
|
2020-09-07 14:13:18 +00:00
|
|
|
# authentication, login, logout, etc #
|
2020-08-22 14:47:56 +00:00
|
|
|
#############################################
|
|
|
|
|
2020-09-03 20:29:14 +00:00
|
|
|
from flask import Blueprint, request, jsonify
|
2020-09-03 22:55:23 +00:00
|
|
|
from werkzeug.exceptions import Forbidden, BadRequest, Unauthorized
|
2020-08-22 14:47:56 +00:00
|
|
|
from werkzeug.local import LocalProxy
|
|
|
|
|
2020-09-03 20:29:14 +00:00
|
|
|
from flaschengeist import logger
|
2020-08-22 14:47:56 +00:00
|
|
|
from flaschengeist.system.decorator import login_required
|
2020-09-03 22:55:23 +00:00
|
|
|
from flaschengeist.system.controller import accessTokenController, userController
|
2020-09-01 23:09:24 +00:00
|
|
|
|
2020-09-03 22:55:23 +00:00
|
|
|
access_controller = LocalProxy(lambda: accessTokenController.AccessTokenController())
|
2020-08-22 14:47:56 +00:00
|
|
|
|
|
|
|
auth_bp = Blueprint('auth', __name__)
|
|
|
|
|
2020-09-01 23:09:24 +00:00
|
|
|
|
2020-08-22 14:47:56 +00:00
|
|
|
def register():
|
2020-10-03 23:27:05 +00:00
|
|
|
return auth_bp, {}
|
2020-08-22 14:47:56 +00:00
|
|
|
|
2020-09-03 20:29:14 +00:00
|
|
|
#################################################
|
|
|
|
# Routes #
|
|
|
|
# #
|
|
|
|
# /auth POST: login (new token) #
|
|
|
|
# GET: get all tokens for user #
|
|
|
|
# /auth/<token> GET: get lifetime of token #
|
|
|
|
# PUT: set new lifetime #
|
|
|
|
# DELETE: logout / delete token #
|
|
|
|
#################################################
|
2020-08-22 14:47:56 +00:00
|
|
|
|
|
|
|
|
2020-09-03 20:29:14 +00:00
|
|
|
@auth_bp.route("/auth", methods=['POST'])
|
|
|
|
def _create_token():
|
2020-08-22 14:47:56 +00:00
|
|
|
""" Login User
|
|
|
|
|
|
|
|
Login in User and create an AccessToken for the User.
|
2020-10-15 00:19:51 +00:00
|
|
|
Requires POST data {'userid': string, 'password': string}
|
2020-08-22 14:47:56 +00:00
|
|
|
Returns:
|
2020-09-01 23:09:24 +00:00
|
|
|
A JSON-File with user information and created token or errors
|
2020-08-22 14:47:56 +00:00
|
|
|
"""
|
|
|
|
logger.debug("Start log in.")
|
|
|
|
data = request.get_json()
|
2020-10-15 10:05:16 +00:00
|
|
|
try:
|
|
|
|
userid = data['userid']
|
|
|
|
password = data['password']
|
|
|
|
except KeyError:
|
|
|
|
raise BadRequest("Missing parameter(s)")
|
2020-09-03 20:29:14 +00:00
|
|
|
|
2020-10-15 00:19:51 +00:00
|
|
|
logger.debug("search user {{ {} }} in database".format(userid))
|
|
|
|
user = userController.login_user(userid, password)
|
2020-09-03 22:55:23 +00:00
|
|
|
if not user:
|
|
|
|
raise Unauthorized
|
2020-09-03 20:29:14 +00:00
|
|
|
logger.debug("user is {{ {} }}".format(user))
|
|
|
|
token = access_controller.create(user, user_agent=request.user_agent)
|
|
|
|
logger.debug("access token is {{ {} }}".format(token))
|
2020-10-15 00:19:51 +00:00
|
|
|
logger.info("User {{ {} }} success login.".format(userid))
|
2020-09-03 20:29:14 +00:00
|
|
|
|
|
|
|
# Lets cleanup the DB
|
|
|
|
access_controller.clear_expired()
|
2020-10-15 00:19:51 +00:00
|
|
|
return jsonify({"user": user, "token": token, "permissions": user.get_permissions()})
|
2020-09-03 20:29:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
@auth_bp.route("/auth", methods=['GET'])
|
2020-09-01 23:09:24 +00:00
|
|
|
@login_required()
|
2020-09-03 20:29:14 +00:00
|
|
|
def _get_tokens(access_token, **kwargs):
|
|
|
|
tokens = access_controller.get_users_tokens(access_token.user)
|
|
|
|
return jsonify(tokens)
|
2020-09-01 23:09:24 +00:00
|
|
|
|
|
|
|
|
2020-09-03 20:29:14 +00:00
|
|
|
@auth_bp.route("/auth/<token>", methods=['DELETE'])
|
2020-08-25 02:31:34 +00:00
|
|
|
@login_required()
|
2020-09-03 20:29:14 +00:00
|
|
|
def _delete_token(token, access_token, **kwargs):
|
|
|
|
logger.debug("Try to delete access token {{ {} }}".format(token))
|
|
|
|
token = access_controller.get_token(token, access_token.user)
|
|
|
|
if not token:
|
|
|
|
logger.debug("Token not found in database!")
|
|
|
|
# Return 403 error, so that users can not bruteforce tokens
|
|
|
|
# Valid tokens from other users and invalid tokens now are looking the same
|
|
|
|
raise Forbidden
|
|
|
|
access_controller.delete_token(token)
|
|
|
|
access_controller.clear_expired()
|
|
|
|
return jsonify({"ok": "ok"})
|
|
|
|
|
|
|
|
|
|
|
|
@auth_bp.route("/auth/<token>", methods=['GET'])
|
2020-08-25 02:31:34 +00:00
|
|
|
@login_required()
|
2020-09-03 20:29:14 +00:00
|
|
|
def _get_token(token, access_token, **kwargs):
|
|
|
|
logger.debug("get token {{ {} }}".format(token))
|
|
|
|
token = access_controller.get_token(token, access_token.user)
|
|
|
|
if not token:
|
|
|
|
# Return 403 error, so that users can not bruteforce tokens
|
|
|
|
# Valid tokens from other users and invalid tokens now are looking the same
|
|
|
|
raise Forbidden
|
|
|
|
return jsonify(token)
|
2020-08-25 02:31:34 +00:00
|
|
|
|
2020-09-01 23:09:24 +00:00
|
|
|
|
2020-09-03 20:29:14 +00:00
|
|
|
@auth_bp.route("/auth/<token>", methods=['PUT'])
|
2020-08-25 02:31:34 +00:00
|
|
|
@login_required()
|
2020-09-03 20:29:14 +00:00
|
|
|
def _set_lifetime(token, access_token, **kwargs):
|
|
|
|
token = access_controller.get_token(token, access_token.user)
|
|
|
|
if not token:
|
|
|
|
# Return 403 error, so that users can not bruteforce tokens
|
|
|
|
# Valid tokens from other users and invalid tokens now are looking the same
|
|
|
|
raise Forbidden
|
2020-08-25 02:31:34 +00:00
|
|
|
try:
|
2020-09-03 20:29:14 +00:00
|
|
|
lifetime = request.get_json()['value']
|
|
|
|
logger.debug("set lifetime {{ {} }} to access token {{ {} }}".format(lifetime, token))
|
|
|
|
access_controller.set_lifetime(token, lifetime)
|
|
|
|
return jsonify({"ok": "ok"})
|
|
|
|
except (KeyError, TypeError):
|
|
|
|
raise BadRequest
|