Add simple api package including authentication (BasicAuth and TokenAuth)

This commit is contained in:
Patrick Jentsch
2021-09-14 12:52:23 +02:00
parent def01d474e
commit a5b1df9e95
8 changed files with 168 additions and 7 deletions

27
app/api/__init__.py Normal file
View File

@ -0,0 +1,27 @@
from flask import Blueprint
from flask_restx import Api
from .jobs import ns as jobs_ns
from .tokens import ns as tokens_ns
bp = Blueprint('api', __name__)
authorizations = {
'basicAuth': {
'type': 'basic'
},
'apiKey': {
'type': 'apiKey',
'in': 'header',
'name': 'Authorization'
}
}
api = Api(
bp,
authorizations=authorizations,
description='An API to interact with nopaque',
title='nopaque API',
version='1.0'
)
api.add_namespace(jobs_ns)
api.add_namespace(tokens_ns)

30
app/api/auth.py Normal file
View File

@ -0,0 +1,30 @@
from flask_httpauth import HTTPBasicAuth, HTTPTokenAuth
from sqlalchemy import or_
from werkzeug.http import HTTP_STATUS_CODES
from ..models import User
basic_auth = HTTPBasicAuth()
token_auth = HTTPTokenAuth()
@basic_auth.verify_password
def verify_password(email_or_username, password):
user = User.query.filter(or_(User.username == email_or_username,
User.email == email_or_username.lower())).first()
if user and user.verify_password(password):
return user
@basic_auth.error_handler
def basic_auth_error(status):
return {'error': HTTP_STATUS_CODES.get(status, 'Unknown error')}, status
@token_auth.verify_token
def verify_token(token):
return User.check_token(token) if token else None
@token_auth.error_handler
def token_auth_error(status):
return {'error': HTTP_STATUS_CODES.get(status, 'Unknown error')}, status

18
app/api/jobs.py Normal file
View File

@ -0,0 +1,18 @@
from flask_restx import Namespace, Resource
from .auth import token_auth
from ..models import Job
ns = Namespace('jobs', description='Job operations')
@ns.route('/')
class JobList(Resource):
'''Shows a list of all jobs, and lets you POST to add new job'''
@ns.doc(security='apiKey')
@token_auth.login_required
def get(self):
'''List all jobs'''
jobs = Job.query.all()
return [job.to_dict(include_relationships=False) for job in jobs]

27
app/api/tokens.py Normal file
View File

@ -0,0 +1,27 @@
from flask_restx import Namespace, Resource
from .auth import basic_auth, token_auth
from .. import db
ns = Namespace('token', description='Authentication token operations')
@ns.route('/')
class Token(Resource):
'''Get or revoke a user authentication token'''
@ns.doc(security='basicAuth')
@basic_auth.login_required
def post(self):
'''Get user token'''
token = basic_auth.current_user().get_token()
db.session.commit()
return {'token': 'Bearer ' + token}
@ns.doc(security='apiKey')
@token_auth.login_required
def delete(self):
'''Revoke user token'''
token_auth.current_user().revoke_token()
db.session.commit()
return '', 204