-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
139 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}) | ||
|
||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |