ungleich-otp/flaskapp/app.py

67 lines
2.1 KiB
Python

from flask import Flask, request, jsonify, json
from flask_restful import Resource, Api
import requests
from decouple import config
from pyotp import TOTP
app = Flask(__name__)
api = Api(app)
def check_otp(name, realm, token):
data = {
"auth_name": config('AUTH_NAME', ''),
"auth_token": TOTP(config('AUTH_SEED', '')).now(),
"auth_realm": config('AUTH_REALM', ''),
"name": name,
"realm": realm,
"token": token
}
response = requests.post(
"https://{OTP_SERVER}{OTP_VERIFY_ENDPOINT}".format(
OTP_SERVER=config('OTP_SERVER', ''),
OTP_VERIFY_ENDPOINT=config('OTP_VERIFY_ENDPOINT', '/ungleichotp/verify/')
),
data=data
)
return response.status_code
class MainView(Resource):
def get(self):
return jsonify({'Detail': 'This view is open to users'})
class ProtectedView(Resource):
def post(self):
data = request.get_json()
if data is not None:
try:
user = data['name']
realm = data['realm']
token = data['token']
assert(realm == config('REALM_ALLOWED'))
code = check_otp(user, realm, token)
assert(code == 200)
except (KeyError, AssertionError) as e:
response = app.response_class(response=json.dumps({'Message': 'Invalid data'}),
status=400,
mimetype='application/json')
return response
response = app.response_class(response=json.dumps({'data sent': data}),
status=200,
mimetype='application/json')
return response
else:
return app.response_class(response=json.dumps({'Message': 'invalid request'}),
status=400,
mimetype='application/json')
api.add_resource(MainView, '/')
api.add_resource(ProtectedView, '/protected')
if __name__ == '__main__':
app.run(host='::')