Skip to content

Commit

Permalink
added initial apikey endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
brngylni committed Jul 12, 2024
1 parent ba14c64 commit 46b596f
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
Empty file.
105 changes: 105 additions & 0 deletions webhook_to_fedora_messaging/endpoints/apikey.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
from flask import Blueprint, Flask, request, Response, Request
from ..database import db
from ..models.apikey import APIKey
from ..models.user import User
from datetime import datetime
from sqlalchemy_helpers import get_or_create
from .util import not_found, success, bad_request, created, conflict, validate_request, unprocessable_entity


app = Flask(__name__)
apikey_endpoint = Blueprint("apikey_endpoint", __name__)


@apikey_endpoint.route("/apikey", methods=["POST"])
def create_apikey():
"""Used for creating a new service by sending a post request to /service/ path.
Request body:
username: Username of the user that api key belongs to
valid_till: Time the api key will be valid until
name: Name of the api key.
"""
session = db.Session()
body = request.json
if not validate_request(request, fields=['username', 'valid_till', 'name',]):
return unprocessable_entity()

user = session.query(User).filter(User.username == body['username']).first()
if user is None:
return not_found()
# Can be different parsing here.
valid_till = datetime.strptime(body['valid_till'], "%Y-%m-%d")
apikey, is_created = get_or_create(session, APIKey, user_id=user.id, name=body['name'], expiry_date=valid_till)

if not is_created:
return conflict({'message': 'Key Already Exists'})
else:
return created({'message': 'Created', 'uuid': apikey.id, 'code': apikey.token})


@apikey_endpoint.route("/apikey/search", methods=["GET"])
def list_apikey():
"""Used for listing all api keys by sending a get request to /apikey/search path.
Request body:
username: Username of the user
"""
if not validate_request(request):
return unprocessable_entity()

session = db.Session()
user = session.query(User).filter(User.username.like(request.json['username'])).first()
if user is None:
return not_found()

apikeys = session.query(APIKey).filter(APIKey.user_id == user.id).all()

return success({'apikey_list': apikeys})


@apikey_endpoint.route("/apikey", methods=["GET"])
def lookup_apikey():
"""Used for searching api keys by sending a get request to /apikey path
Request body:
uuid: UUID of the apikey
"""
if not validate_request(request, fields=['uuid']):
return unprocessable_entity

session = db.Session()
apikey = session.query(APIKey).filter(APIKey.id == request.json['apikey_uuid']).first()

if apikey is None:
return not_found()
else:
valid_till = datetime.strftime(apikey.expiry_date, "%Y-%m-%d")
return success({'uuid': apikey.id, 'name': apikey.name, 'valid_till': valid_till, 'valid': not apikey.disabled})


@apikey_endpoint.route("/apikey/revoke", methods=["PUT"])
def revoke_service():
"""Used for revoking an api key by sending a PUT request to /apikey/revoke path.
Request body:
username: Username of the user that the api key belongs to.
apikey_uuid: UUID of the api key.
"""
if not validate_request(request):
return unprocessable_entity()

session = db.Session()
user = session.query(User).filter(User.username == request.json['username']).first()
apikey = session.query(APIKey).filter(APIKey.user_id == user.id and APIKey.id == request.json['apikey_uuid']).first()
if apikey is None:
return not_found()
else:
apikey.disabled = True
session.commit()
return success({'uuid': apikey.id, 'is_valid': not apikey.disabled})





34 changes: 34 additions & 0 deletions webhook_to_fedora_messaging/endpoints/util.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from flask import Response, Request


def not_found() -> Response:
return Response({'message': 'Not Found'}, status=404, mimetype='application/json')


def success(data: dict) ->Response:
return Response(data, status=200, mimetype='application/json')


def bad_request() -> Response:
return Response("{'message': 'Bad Request'}", status=400, mimetype='application/json')


def created(data: dict) -> Response:
return Response(data, status=201, mimetype='application/json')


def conflict(data: dict) -> Response:
return Response(data, status=409, mimetype='application/json')


def validate_request(request: Request, fields=['username']):
return all(field in request for field in fields)


def unprocessable_entity() -> Response:
return Response("{'message: 'Unprocessable Entity'}", status=429, mimetype="application/json")


def exclude_from_val(func):
func._exclude_from_validation = True
return func

0 comments on commit 46b596f

Please sign in to comment.