added user and group API and models
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from flask import Blueprint
|
||||
from flask_restplus import Api
|
||||
from flask_restplus import Api, Namespace
|
||||
|
||||
api_authorizations = {
|
||||
'apikey': {
|
||||
@@ -25,7 +25,15 @@ api_bp = Blueprint('api', __name__, url_prefix='/api')
|
||||
api_v1 = Api(api_bp, prefix="/v1", version='0.1', title='Vue Test API',
|
||||
description='The Vue Test API', doc='/v1/doc/', authorizations=api_authorizations, security='bearerAuth')
|
||||
|
||||
api_user = Namespace('user', description="User management namespace", authorizations=api_authorizations)
|
||||
|
||||
api_v1.add_namespace(api_user)
|
||||
|
||||
auth_api_bp = Blueprint('auth_api', __name__, url_prefix='/api/auth')
|
||||
user_api_bp = Blueprint('user_api', __name__, url_prefix='/api/user')
|
||||
group_api_bp = Blueprint('group_api', __name__, url_prefix='/api/group')
|
||||
|
||||
from .example_api import *
|
||||
from .auth_api import *
|
||||
from .user_api import *
|
||||
from .group_api import *
|
||||
|
||||
@@ -5,10 +5,14 @@ For example: listing of available auth providers or registration of users.
|
||||
|
||||
Login through API does not start a new session, but instead returns JWT.
|
||||
"""
|
||||
import base64
|
||||
import json
|
||||
|
||||
import flask
|
||||
from datetime import datetime, timedelta
|
||||
import jwt
|
||||
from flask import request, jsonify, current_app, url_for
|
||||
from flask import request, jsonify, current_app, url_for, Response, session, redirect, make_response
|
||||
from flask_jwt_extended import create_access_token, create_refresh_token, jwt_refresh_token_required, get_jwt_identity
|
||||
from functools import wraps
|
||||
from random import randint
|
||||
|
||||
@@ -22,14 +26,6 @@ from backend.auth import AUTH_PROVIDERS, oidc_auth
|
||||
from backend.models.user_model import User, Group
|
||||
|
||||
|
||||
def create_jwt(user: User, validity_min=30):
|
||||
return jwt.encode({
|
||||
'sub': user.email,
|
||||
'iat': datetime.utcnow(),
|
||||
'exp': datetime.utcnow() + timedelta(minutes=validity_min)},
|
||||
current_app.config['SECRET_KEY'])
|
||||
|
||||
|
||||
@auth_api_bp.route('/providers', methods=('GET',))
|
||||
def get_auth_providers():
|
||||
providers = dict()
|
||||
@@ -65,8 +61,11 @@ def login():
|
||||
if not user:
|
||||
return jsonify({'message': 'Invalid credentials', 'authenticated': False}), 401
|
||||
|
||||
token = create_jwt(user)
|
||||
return jsonify({'token': token.decode('UTF-8')})
|
||||
token = {
|
||||
'access_token': create_access_token(identity=user.email, fresh=True),
|
||||
'refresh_token': create_refresh_token(identity=user.email)
|
||||
}
|
||||
return jsonify(token), 200
|
||||
|
||||
|
||||
def check_and_create_groups(groups: Iterable[str]):
|
||||
@@ -112,17 +111,38 @@ def create_or_retrieve_user_from_userinfo(userinfo):
|
||||
|
||||
|
||||
@auth_api_bp.route('/oidc', methods=['GET'])
|
||||
@auth_api_bp.route('/oidc/<redirect_url>', methods=['GET'])
|
||||
@oidc_auth.oidc_auth()
|
||||
def oidc():
|
||||
|
||||
def oidc(redirect_url=None):
|
||||
user = create_or_retrieve_user_from_userinfo(flask.session['userinfo'])
|
||||
|
||||
#return jsonify(user.to_dict())
|
||||
return user.toJSON()
|
||||
if user is None:
|
||||
return "Could not authenticate: could not find or create user.", 401
|
||||
if current_app.config.get("AUTH_RETURN_EXTERNAL_JWT", False):
|
||||
token = jwt.encode(flask.session['id_token'], current_app.config['SECRET_KEY'])
|
||||
else:
|
||||
token = create_jwt(user)
|
||||
return token
|
||||
token = json.dumps({
|
||||
'access_token': create_access_token(identity=user.email, fresh=True),
|
||||
'refresh_token': create_refresh_token(identity=user.email)
|
||||
})
|
||||
if redirect_url is None:
|
||||
redirect_url = request.headers.get("Referer")
|
||||
if redirect_url is None:
|
||||
redirect_url = request.args.get('redirect_url')
|
||||
if redirect_url is None:
|
||||
redirect_url = "/"
|
||||
app.logger.info("Token: {}".format(token))
|
||||
response = make_response(redirect(redirect_url))
|
||||
response.set_cookie('tokens', base64.b64encode(token.encode('utf-8')))
|
||||
return response
|
||||
|
||||
|
||||
@app.route('/refresh', methods=['POST'])
|
||||
@jwt_refresh_token_required
|
||||
def refresh():
|
||||
"""Refresh token endpoint. This will generate a new access token from
|
||||
the refresh token, but will mark that access token as non-fresh,
|
||||
as we do not actually verify a password in this endpoint."""
|
||||
current_user = get_jwt_identity()
|
||||
new_token = create_access_token(identity=current_user, fresh=False)
|
||||
ret = {'access_token': new_token}
|
||||
return jsonify(ret), 200
|
||||
|
||||
40
api/group_api.py
Normal file
40
api/group_api.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright (c) 2019. Tobias Kurze
|
||||
"""
|
||||
This module provides functions related to authentication through the API.
|
||||
For example: listing of available auth providers or registration of users.
|
||||
|
||||
Login through API does not start a new session, but instead returns JWT.
|
||||
"""
|
||||
import flask
|
||||
from datetime import datetime, timedelta
|
||||
import jwt
|
||||
from flask import request, jsonify, current_app, url_for
|
||||
from flask_jwt_extended import jwt_required
|
||||
from functools import wraps
|
||||
from random import randint
|
||||
|
||||
from flask_login import logout_user, login_user
|
||||
from typing import Iterable
|
||||
from werkzeug.routing import BuildError
|
||||
|
||||
from backend import db, app
|
||||
from backend.api import auth_api_bp, group_api_bp
|
||||
from backend.auth import AUTH_PROVIDERS, oidc_auth
|
||||
from backend.models.user_model import User, Group
|
||||
|
||||
|
||||
|
||||
@group_api_bp.route('/<id>', methods=['GET'])
|
||||
@jwt_required
|
||||
def get_group():
|
||||
|
||||
user = create_or_retrieve_user_from_userinfo(flask.session['userinfo'])
|
||||
|
||||
return jsonify(user.to_dict())
|
||||
if user is None:
|
||||
return "Could not authenticate: could not find or create user.", 401
|
||||
if current_app.config.get("AUTH_RETURN_EXTERNAL_JWT", False):
|
||||
token = jwt.encode(flask.session['id_token'], current_app.config['SECRET_KEY'])
|
||||
else:
|
||||
token = create_jwt(user)
|
||||
return token
|
||||
58
api/user_api.py
Normal file
58
api/user_api.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright (c) 2019. Tobias Kurze
|
||||
"""
|
||||
This module provides functions related to authentication through the API.
|
||||
For example: listing of available auth providers or registration of users.
|
||||
|
||||
Login through API does not start a new session, but instead returns JWT.
|
||||
"""
|
||||
import flask
|
||||
import jwt
|
||||
from flask import request, jsonify, current_app, url_for
|
||||
from flask_jwt_extended import get_jwt_identity, jwt_optional, jwt_required
|
||||
from flask_restplus import Resource, fields
|
||||
|
||||
from backend import db, app, jwt_auth
|
||||
from backend.api import user_api_bp, api_bp, api_user
|
||||
from backend.auth import oidc_auth
|
||||
from backend.models.user_model import User, Group
|
||||
|
||||
user = api_user.model('User', {
|
||||
'id': fields.String(required=True, description='The user\'s identifier'),
|
||||
'first_name': fields.String(required=True, description='The user\'s first name'),
|
||||
})
|
||||
|
||||
|
||||
@api_user.route('/')
|
||||
class UserList(Resource):
|
||||
"""
|
||||
This is a test class.
|
||||
"""
|
||||
#@jwt_auth.login_required
|
||||
@jwt_required
|
||||
@api_user.doc('users')
|
||||
@api_user.marshal_list_with(user)
|
||||
def get(self):
|
||||
"""
|
||||
just a test!
|
||||
:return: Hello: World
|
||||
"""
|
||||
current_user = get_jwt_identity()
|
||||
app.logger.info(current_user)
|
||||
return User.get_all()
|
||||
|
||||
|
||||
@api_user.route('/<id>')
|
||||
@api_user.param('id', 'The user identifier')
|
||||
@api_user.response(404, 'User not found')
|
||||
class UserResource(Resource):
|
||||
@jwt_auth.login_required
|
||||
@api_user.doc('get_user')
|
||||
@api_user.marshal_with(user)
|
||||
def get(self, id):
|
||||
"""Fetch a user given its identifier"""
|
||||
user = User.get_by_id(id)
|
||||
if user is not None:
|
||||
return user
|
||||
api_user.abort(404)
|
||||
|
||||
# api_user.add_resource(UserResource, '/')
|
||||
Reference in New Issue
Block a user