Skip to content

Commit

Permalink
new: [API] Added an endpoint to let the user regenerate the API key.
Browse files Browse the repository at this point in the history
  • Loading branch information
cedricbonhomme committed Jul 31, 2024
1 parent 4772acb commit 06c78af
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 9 deletions.
4 changes: 2 additions & 2 deletions website/web/api/v1/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from website.validators import validate_json
from website.web.api.v1.common import auth_func
from website.web.api.v1.common import metada_params_model
from website.web.api.v1.common import user_params_model
from website.web.api.v1.common import user_light_params_model
from website.web.api.v1.common import uuid_type
from website.web.api.v1.types import ResultType
from website.models import Bundle
Expand Down Expand Up @@ -67,7 +67,7 @@
metadata = bundle_ns.model("metadata", metada_params_model)

bundle["author"] = fields.Nested(
bundle_ns.model("User", user_params_model), readonly=True
bundle_ns.model("User", user_light_params_model), readonly=True
)

bundle_list_fields = bundle_ns.model(
Expand Down
4 changes: 2 additions & 2 deletions website/web/api/v1/comment.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from website.validators import validate_json
from website.web.api.v1.common import auth_func
from website.web.api.v1.common import metada_params_model
from website.web.api.v1.common import user_params_model
from website.web.api.v1.common import user_light_params_model
from website.web.api.v1.common import uuid_type
from website.web.api.v1.types import ResultType
from website.models import Comment
Expand Down Expand Up @@ -74,7 +74,7 @@
metadata = comment_ns.model("metadata", metada_params_model)

comment["author"] = fields.Nested(
comment_ns.model("User", user_params_model), readonly=True
comment_ns.model("User", user_light_params_model), readonly=True
)

comment_list_fields = comment_ns.model(
Expand Down
2 changes: 1 addition & 1 deletion website/web/api/v1/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def uuid_type(value: str) -> uuid.UUID:
"limit": fields.Integer(readonly=True, description="Requested limit data."),
}

user_params_model = {
user_light_params_model = {
"login": fields.String(readonly=True, description="Login of the user."),
"name": fields.String(readonly=True, description="Name of the user."),
}
46 changes: 42 additions & 4 deletions website/web/api/v1/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
description="Last seen time of the user.", readonly=True
),
}
user = user_ns.model("User", user_params_model)
user_model = user_ns.model("UserFull", user_params_model)
metadata = user_ns.model("metadata", metada_params_model)

user_list_fields = user_ns.model(
Expand All @@ -70,7 +70,7 @@
metadata, description="Metada related to the result."
),
"data": fields.List(
fields.Nested(user, skip_none=True), description="List of users."
fields.Nested(user_model, skip_none=True), description="List of users."
),
},
)
Expand All @@ -82,9 +82,10 @@ class UserSelf(Resource): # type: ignore[misc]
@user_ns.doc(
responses={
200: "Success.",
404: "User not found.",
}
) # type: ignore[misc]
@user_ns.marshal_with(user, skip_none=True) # type: ignore[misc]
@user_ns.marshal_with(user_model, skip_none=True) # type: ignore[misc]
@auth_func
def get(self) -> Tuple[dict[Any, Any], int]:
"Get information about the currently authenticated user."
Expand All @@ -98,6 +99,43 @@ def get(self) -> Tuple[dict[Any, Any], int]:
return me, 200


@user_ns.route("/user/api_key")
class UserNewAPIKey(Resource): # type: ignore[misc]
@user_ns.doc(description="Regenerating the API key of the authenticated user with the current API key.") # type: ignore[misc]
@user_ns.doc(
responses={
200: "Success.",
403: "Wrong API key submitted.",
404: "User not found.",
}
) # type: ignore[misc]
@user_ns.expect(
user_ns.model("API Key", {"apikey": fields.String(description="The current API key of the user.")}, location="json")
) # type: ignore[misc]
@user_ns.marshal_with(user_model, skip_none=True) # type: ignore[misc]
@auth_func
def post(self) -> Tuple[dict[Any, Any], int]:
"Regenerating the API key of the authenticated user with the current API key."
user_obj = User.query.filter(
User.id == current_user.id,
User.is_active == True,
User.is_confirmed == True,
).first()

if not user_obj:
return {"message": "User not found."}, 404

data = user_ns.payload

if user_obj.apikey != data.get("apikey", ""):
return {"message": "Wrong API key submitted."}, 403

user_obj.generate_apikey()
db.session.commit()

return user_obj, 200


@user_ns.route("/user/<string:user_id>")
class UserItem(Resource): # type: ignore[misc]
@user_ns.doc(description="Delete a user.") # type: ignore[misc]
Expand Down Expand Up @@ -182,7 +220,7 @@ def get(self) -> Tuple[ResultType, int]:
}
) # type: ignore[misc]
@user_ns.expect(parser) # type: ignore[misc]
@user_ns.marshal_list_with(user, code=201) # type: ignore[misc]
@user_ns.marshal_with(user_model) # type: ignore[misc]
def post(self) -> Tuple[Dict[Any, Any], int]:
"""Create a non-admin user.
The user will be active but must have to confirm the account with the email sent by the instance.
Expand Down

0 comments on commit 06c78af

Please sign in to comment.