diff --git a/server/app/apis/auth.py b/server/app/apis/auth.py index 09419d9246069bf2dc12d7c203ea8aead2851057..dd31c561964445e93452b4e0235c99211200db3a 100644 --- a/server/app/apis/auth.py +++ b/server/app/apis/auth.py @@ -10,14 +10,15 @@ import marshmallow as ma from app.core.codes import verify_code from app.core.schemas import UserSchema from app.core.sockets import is_active_competition +from app.database.controller.delete import whitelist_to_blacklist from app.database.models import User, Whitelist from flask import current_app, has_app_context from flask.views import MethodView from flask_jwt_extended import create_access_token, get_jti -from flask_jwt_extended.utils import get_jti -from flask_smorest import Blueprint, abort +from flask_jwt_extended.utils import get_jti, get_jwt +from flask_smorest import Blueprint, abort, arguments -from . import http_codes +from . import http_codes, protect_route blp = Blueprint("auth", "auth", url_prefix="/api/auth", description="Operations related to authorization") @@ -32,13 +33,6 @@ class UserLoginResponseSchema(ma.Schema): access_token = ma.fields.String() -# create_user_parser = login_parser.copy() -# create_user_parser.add_argument("city_id", type=int, required=True, location="json") -# create_user_parser.add_argument("role_id", type=int, required=True, location="json") - -# login_code_parser = reqparse.RequestParser() -# login_code_parser.add_argument("code", type=str, required=True, location="json") - if has_app_context(): USER_LOGIN_LOCKED_ATTEMPTS = current_app.config["USER_LOGIN_LOCKED_ATTEMPTS"] USER_LOGIN_LOCKED_EXPIRES = current_app.config["USER_LOGIN_LOCKED_EXPIRES"] @@ -124,69 +118,56 @@ class AuthLogin(MethodView): return {"id": item_user.id, "access_token": access_token} -# @api.route("/login/code") -# class AuthLoginCode(Resource): -# def post(self): -# """ Logs in using the provided competition code. """ - -# args = login_code_parser.parse_args() -# code = args["code"] - -# # Check so the code string is valid -# if not verify_code(code): -# api.abort(codes.UNAUTHORIZED, "Invalid code") - -# item_code = dbc.get.code_by_code(code) +@blp.route("/logout") +class AuthLogout(MethodView): + @protect_route(allowed_roles=["*"], allowed_views=["*"]) + @blp.response(http_codes.NO_CONTENT, None) + def post(self): + """ Logs out. """ + whitelist_to_blacklist(Whitelist.jti == get_jwt()["jti"]) + return None -# if item_code.view_type_id != 4: -# if not is_active_competition(item_code.competition_id): -# api.abort(codes.UNAUTHORIZED, "Competition not active") -# # Create jwt that is only valid for 8 hours -# access_token = create_access_token( -# item_code.id, user_claims=get_code_claims(item_code), expires_delta=timedelta(hours=8) -# ) +class CodeArgsSchema(ma.Schema): + code = ma.fields.String(required=True) -# # Whitelist the created jwt -# dbc.add.whitelist(get_jti(access_token), competition_id=item_code.competition_id) -# response = { -# "competition_id": item_code.competition_id, -# "view": item_code.view_type.name, -# "team_id": item_code.team_id, -# "access_token": access_token, -# } -# return response +class CodeResponseSchema(ma.Schema): + competition_id = ma.fields.Int() + view = ma.fields.String() + team_id = ma.fields.Int() + access_token = ma.fields.String() -# @api.route("/logout") -# class AuthLogout(Resource): -# @protect_route(allowed_roles=["*"], allowed_views=["*"]) -# def post(self): -# """ Logs out. """ -# jti = get_raw_jwt()["jti"] +@blp.route("/code") +class AuthLoginCode(MethodView): + @blp.arguments(CodeArgsSchema) + @blp.response(http_codes.OK, CodeResponseSchema) + @blp.alt_response(http_codes.UNAUTHORIZED, None, description="Incorrect code or competition is not active") + @blp.alt_response(http_codes.NOT_FOUND, None, description="The code doesn't exist") + def post(self, args): + """ Logs in using the provided competition code. """ -# # Blacklist the token so the user cannot access the api anymore -# dbc.add.blacklist(jti) + code = args["code"] -# # Remove the the token from the whitelist since it's blacklisted now -# Whitelist.query.filter(Whitelist.jti == jti).delete() + if not verify_code(code): # Check that code string is valid + abort(http_codes.UNAUTHORIZED, message="Felaktigt kod") -# dbc.utils.commit() -# return text_response("Logout") + item_code = dbc.get.code_by_code(code) + # If joining client is not operator and competition is not active + if item_code.view_type_id != 4 and not is_active_competition(item_code.competition_id): + abort(http_codes.UNAUTHORIZED, message="Tävlingen är ej aktiv") -""" -@api.route("/refresh") -class AuthRefresh(Resource): - @protect_route(allowed_roles=["*"]) - @jwt_refresh_token_required - def post(self): - old_jti = get_raw_jwt()["jti"] + # Create jwt that is only valid for 8 hours + access_token = create_access_token( + item_code.id, additional_claims=get_code_claims(item_code), expires_delta=timedelta(hours=8) + ) + dbc.add.whitelist(get_jti(access_token), competition_id=item_code.competition_id) # Whitelist the created jwt - item_user = dbc.get.user(get_jwt_identity()) - access_token = create_access_token(item_user.id, user_claims=get_user_claims(item_user)) - dbc.add.blacklist(old_jti) - response = {"access_token": access_token} - return response -""" + return { + "competition_id": item_code.competition_id, + "view": item_code.view_type.name, + "team_id": item_code.team_id, + "access_token": access_token, + }