Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""LICENSE
2Copyright 2020 Hermann Krumrey <hermann@krumreyh.com>
4This file is part of jerrycan.
6jerrycan is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
11jerrycan is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
16You should have received a copy of the GNU General Public License
17along with jerrycan. If not, see <http://www.gnu.org/licenses/>.
18LICENSE"""
20from typing import Dict, Any
21from flask import Blueprint, request
22from flask_login import login_required
23from puffotter.crypto import generate_random, generate_hash
24from jerrycan.base import db
25from jerrycan.Config import Config
26from jerrycan.db.User import User
27from jerrycan.db.ApiKey import ApiKey
28from jerrycan.exceptions import ApiException
29from jerrycan.routes.decorators import api, api_login_required
32def define_blueprint(blueprint_name: str) -> Blueprint:
33 """
34 Defines the blueprint for this route
35 :param blueprint_name: The name of the blueprint
36 :return: The blueprint
37 """
38 blueprint = Blueprint(blueprint_name, __name__)
39 api_base = f"/api/v{Config.API_VERSION}"
41 @blueprint.route(f"{api_base}/key", methods=["POST", "DELETE"])
42 @api
43 def api_key() -> Dict[str, Any]:
44 """
45 Allows users to request a new API key or revoke an existing API key
46 :return: The JSON response
47 """
48 data = request.get_json()
49 assert data is not None
50 if request.method == "POST":
51 username = data["username"]
52 password = data["password"]
53 user = User.query.filter_by(username=username).first()
55 if user is None:
56 raise ApiException("user does not exist", 401)
57 elif not user.confirmed:
58 raise ApiException("user is not confirmed", 401)
59 elif not user.verify_password(password):
60 raise ApiException("password is incorrect", 401)
61 else:
62 key = generate_random(32)
63 hashed = generate_hash(key)
64 _api_key = ApiKey(user=user, key_hash=hashed)
65 db.session.add(_api_key)
66 db.session.commit()
68 return {
69 "api_key": "{}:{}".format(_api_key.id, key),
70 "expiration": (
71 int(_api_key.creation_time)
72 + Config.MAX_API_KEY_AGE
73 ),
74 "user": user.__json__(False)
75 }
77 else: # request.method == "DELETE"
78 key = data["api_key"]
79 _api_key = ApiKey.query.get(key.split(":", 1)[0])
81 if _api_key is None:
82 raise ApiException("api key does not exist", 401)
83 elif not _api_key.verify_key(key):
84 raise ApiException("api key not valid", 401)
85 else:
86 db.session.delete(_api_key)
87 db.session.commit()
88 return {}
90 @blueprint.route(f"{api_base}/authorize", methods=["GET"])
91 @api_login_required
92 @login_required
93 @api
94 def api_authorize() -> Dict[str, Any]:
95 """
96 Allows a user to check if an API key is authorized or not
97 :return: None
98 """
99 return {} # Checks done by @login_required
101 return blueprint