1
Fork 0
mirror of https://github.com/pds-nest/nest.git synced 2024-11-25 14:34:19 +00:00

Add PUT method to repository api call.

This commit is contained in:
Lorenzo Balugani 2021-05-06 17:20:07 +02:00
parent 44f4b97ddf
commit a6bf0fc87f
9 changed files with 112 additions and 21 deletions

View file

@ -26,7 +26,7 @@ app.add_url_rule("/api/v1/login", view_func=page_login, methods=["POST"])
app.add_url_rule("/api/v1/users", view_func=page_users, methods=["GET", "POST"]) app.add_url_rule("/api/v1/users", view_func=page_users, methods=["GET", "POST"])
app.add_url_rule("/api/v1/users/<string:email>", view_func=page_user, methods=["GET", "PATCH", "DELETE"]) app.add_url_rule("/api/v1/users/<string:email>", view_func=page_user, methods=["GET", "PATCH", "DELETE"])
app.add_url_rule("/api/v1/repositories/", view_func=page_repositories, methods=["GET", "POST"]) app.add_url_rule("/api/v1/repositories/", view_func=page_repositories, methods=["GET", "POST"])
app.add_url_rule("/api/v1/repositories/<int:rid>", view_func=page_repository, methods=["GET", "PATCH", "DELETE"]) app.add_url_rule("/api/v1/repositories/<int:rid>", view_func=page_repository, methods=["GET", "PATCH", "DELETE", "PUT"])
app.add_url_rule("/api/v1/repositories/<int:rid>/conditions", view_func=page_repository_conditions, app.add_url_rule("/api/v1/repositories/<int:rid>/conditions", view_func=page_repository_conditions,
methods=["GET", "POST"]) methods=["GET", "POST"])
app.add_url_rule("/api/v1/conditions/<int:cid>", view_func=page_condition, methods=["GET", "PATCH", "DELETE"]) app.add_url_rule("/api/v1/conditions/<int:cid>", view_func=page_condition, methods=["GET", "PATCH", "DELETE"])

View file

@ -42,13 +42,21 @@ class CreateUser(Schema):
password = fields.String(description="The new user's password.") password = fields.String(description="The new user's password.")
class ConditionSchema(Schema):
id = fields.Integer(description="The condition id.")
type = fields.Integer(description="The condition type.")
content = fields.String(description="The condition content. Meaning may change according to type.")
class RepositorySchema(Schema): class RepositorySchema(Schema):
id = fields.Integer(description="The repository id.") id = fields.Integer(description="The repository id.")
name = fields.String(description="The repository name.") name = fields.String(description="The repository name.")
start = fields.DateTime(description="The start date of the repository.") start = fields.DateTime(description="The start date of the repository.")
isActive = fields.Boolean(description="True if the repository is active.") is_active = fields.Boolean(description="True if the repository is active.")
end = fields.DateTime(description="The end date of the repository") end = fields.DateTime(description="The end date of the repository")
owner = fields.Nested(UserSchema) owner = fields.Nested(UserSchema)
conditions = fields.Nested(ConditionSchema, many=True)
evaluation_mode = fields.Integer(description="The mode with which conditions are evaluated.")
class CreateRepository(Schema): class CreateRepository(Schema):
@ -59,12 +67,7 @@ class RepositoryUpdate(Schema):
name = fields.String(description="If present, it changes the name of the repository.") name = fields.String(description="If present, it changes the name of the repository.")
close = fields.String(description="If present, it closes the repository.") close = fields.String(description="If present, it closes the repository.")
open = fields.String(description="If present, it opens the repository.") open = fields.String(description="If present, it opens the repository.")
evaluation_mode = fields.Integer(description="If present, it alters the Condition evaluation mode.")
class ConditionSchema(Schema):
id = fields.Integer(description="The condition id.")
type = fields.Integer(description="The condition type.")
content = fields.String(description="The condition content. Meaning may change according to type.")
class CreateCondition(Schema): class CreateCondition(Schema):

View file

@ -28,7 +28,6 @@ spec.components.schema("IntegerParameter", schema=IntegerParameterSchema)
spec.components.schema("RepositoryUpdate", schema=RepositoryUpdate) spec.components.schema("RepositoryUpdate", schema=RepositoryUpdate)
spec.components.schema("CreateRepository", schema=CreateRepository) spec.components.schema("CreateRepository", schema=CreateRepository)
spec.components.schema("CreateCondition", schema=CreateCondition) spec.components.schema("CreateCondition", schema=CreateCondition)
spec.components.schema("Condition", schema=ConditionSchema)
spec.components.schema("ConditionParameter", schema=ConditionParameterSchema) spec.components.schema("ConditionParameter", schema=ConditionParameterSchema)
spec.components.security_scheme("jwt", {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}) spec.components.security_scheme("jwt", {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"})

View file

@ -23,3 +23,8 @@ class OperationType(enum.Enum):
_or = 1 _or = 1
_not = 2 _not = 2
assign = 3 assign = 3
class ConditionMode(enum.Enum):
all_or = 0
all_and = 1

View file

@ -3,6 +3,7 @@ This module defines the :class:`.Repository` database class.
""" """
from ..base import Base from ..base import Base
from .Enums import ConditionMode
class Repository(Base.Model): class Repository(Base.Model):
@ -13,7 +14,8 @@ class Repository(Base.Model):
name = Base.Column(Base.String, nullable=False) name = Base.Column(Base.String, nullable=False)
start = Base.Column(Base.DateTime, nullable=True) start = Base.Column(Base.DateTime, nullable=True)
end = Base.Column(Base.DateTime, nullable=True) end = Base.Column(Base.DateTime, nullable=True)
isActive = Base.Column(Base.Boolean, nullable=False, default=False) is_active = Base.Column(Base.Boolean, nullable=False, default=False)
evaluation_mode = Base.Column(Base.Enum(ConditionMode), default=ConditionMode.all_or.value)
# Foreign Keys # Foreign Keys
owner_id = Base.Column(Base.String, Base.ForeignKey("user.email", ondelete="CASCADE"), nullable=False) owner_id = Base.Column(Base.String, Base.ForeignKey("user.email", ondelete="CASCADE"), nullable=False)
@ -30,7 +32,9 @@ class Repository(Base.Model):
"id": self.id, "id": self.id,
"name": self.name, "name": self.name,
"start": self.start.isoformat() if self.start else None, "start": self.start.isoformat() if self.start else None,
"isActive": self.isActive, "is_active": self.is_active,
"end": self.end.isoformat() if self.end else None, "end": self.end.isoformat() if self.end else None,
"owner": self.owner.to_json() "owner": self.owner.to_json(),
"evaluation_mode": self.evaluation_mode,
"conditions": [c.to_json() for c in self.conditions]
} }

View file

@ -107,3 +107,9 @@ def error_handler(e):
except Exception: except Exception:
print(e) print(e)
return json_error(f"{e.__repr__()}"), 500 return json_error(f"{e.__repr__()}"), 500
def json_request_authorizer(json, serializable):
json_keys = json.keys()
serializable_keys = serializable.to_json().keys()
return all(key in json_keys for key in serializable_keys)

View file

@ -1,4 +1,4 @@
from routes.repository.conditions.repository_conditions import page_repository_conditions from .conditions import page_repository_conditions
from .repository import page_repository from .repository import page_repository
from .repositories import page_repositories from .repositories import page_repositories
from .conditions import * from .conditions import *

View file

@ -64,10 +64,10 @@ def page_repositories():
spectator = Authorization.query.filter_by(email=user.email).join(Repository) spectator = Authorization.query.filter_by(email=user.email).join(Repository)
if request.args.get("onlyActive"): if request.args.get("onlyActive"):
owner = owner.filter_by(isActive=True) owner = owner.filter_by(isActive=True)
spectator = spectator.filter(Repository.isActive) spectator = spectator.filter(Repository.is_active)
elif request.args.get("onlyDead"): elif request.args.get("onlyDead"):
owner = owner.filter_by(isActive=False) owner = owner.filter_by(isActive=False)
spectator = spectator.filter(not Repository.isActive) spectator = spectator.filter(not Repository.is_active)
owner = owner.all() owner = owner.all()
spectator = spectator.all() spectator = spectator.all()
return json_success({"owner": [r.to_json() for r in owner], return json_success({"owner": [r.to_json() for r in owner],

View file

@ -110,6 +110,47 @@ def page_repository(rid):
schema: Error schema: Error
tags: tags:
- repository-related - repository-related
put:
summary: Overwrites a repository.
security:
- jwt: []
requestBody:
required: true
content:
application/json:
schema: Repository
parameters:
- in: path
schema: IntegerParameterSchema
responses:
'200':
description: The repository has been updated successfully.
content:
application/json:
schema: Repository
'404':
description: Could not find the requested repository.
content:
application/json:
schema: Error
'403':
description: The user is not authorized.
content:
application/json:
schema: Error
'401':
description: The user is not logged in.
content:
application/json:
schema: Error
'400':
description: The request was malformed.
content:
application/json:
schema: Error
tags:
- repository-related
""" """
user = find_user(get_jwt_identity()) user = find_user(get_jwt_identity())
repository = Repository.query.filter_by(id=rid).first() repository = Repository.query.filter_by(id=rid).first()
@ -122,11 +163,17 @@ def page_repository(rid):
return json_error("You are not the owner of this repository."), 403 return json_error("You are not the owner of this repository."), 403
if 'name' in request.json: if 'name' in request.json:
repository.name = request.json['name'] repository.name = request.json['name']
if 'close' in request.json and not repository.end and repository.isActive: if 'close' in request.json and not repository.end and repository.is_active:
repository.end = datetime.datetime.now() repository.end = datetime.datetime.now()
repository.isActive = False repository.is_active = False
if 'open' in request.json and not repository.isActive and not repository.end: if 'open' in request.json and not repository.is_active and not repository.end:
repository.isActive = True repository.is_active = True
if 'evaluation_mode' in request.json:
try:
evaluation_mode = ConditionType(request.json['evaluation_mode'])
except KeyError:
return json_error("Unknown `type` specified."), 400
repository.evaluation_mode = evaluation_mode
Base.session.commit() Base.session.commit()
return json_success(repository.to_json()), 200 return json_success(repository.to_json()), 200
elif request.method == "DELETE": elif request.method == "DELETE":
@ -139,3 +186,30 @@ def page_repository(rid):
Base.session.rollback() Base.session.rollback()
return json_error("Cant delete repository because of dependencies."), 500 return json_error("Cant delete repository because of dependencies."), 500
return json_success("Success"), 200 return json_success("Success"), 200
elif request.method == "PUT":
if not json_request_authorizer(request.json, repository):
return json_error("Missing one or more parameters in repository json."), 400
# Users will be tolerated if they change parameters they're not supposed to touch. We'll ignore them for now.
try:
repository.evaluation_mode = request.json['evaluation_mode']
except KeyError:
return json_error("Unknown `type` specified."), 400
repository.name = request.json['name']
repository.is_active = request.json['is_active']
ids = [c['id'] for c in request.json['conditions'] if c['id']]
# Delete no longer needed conditions.
for c in repository.conditions:
if c.id not in ids:
Base.session.delete(c)
Base.session.commit()
# Create brand new conditions
for c in request.json['conditions']:
if not c['id']:
if (type_ := c['type']) is not None:
try:
type_ = ConditionType(type_)
except KeyError:
return json_error("Unknown `type` specified."), 400
Base.session.add(Condition(type=type_, content=c['content'], repository_id=rid))
Base.session.commit()
return json_success(repository.to_json()), 200