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

⤴ Merge, resolving conflicts

This commit is contained in:
Stefano Pigozzi 2021-05-07 19:51:03 +02:00
commit 7a4e99c4f1
Signed by untrusted user who does not match committer: steffo
GPG key ID: 6965406171929D01
10 changed files with 318 additions and 2 deletions

View file

@ -36,6 +36,10 @@ class IntegerParameterSchema(Schema):
rid = fields.Integer(description="The target numeric id.") rid = fields.Integer(description="The target numeric id.")
class AlertParameterSchema(Schema):
rid = fields.Integer(description="The target numeric id.")
class CreateUser(Schema): class CreateUser(Schema):
email = fields.String(description="The new user's email.") email = fields.String(description="The new user's email.")
username = fields.String(description="The new user's username.") username = fields.String(description="The new user's username.")
@ -75,5 +79,38 @@ class CreateCondition(Schema):
content = fields.String(description="The condition content. Meaning may change according to type.") content = fields.String(description="The condition content. Meaning may change according to type.")
class CreateAlert(Schema):
name = fields.String(description="The name of the alert.")
limit = fields.Integer(description="The number of tweets in a time window.")
window_size = fields.Integer(description="The size of the time window.")
class Operations(Schema):
id = fields.Integer(description="The operation id.")
operation = fields.Integer(description="The type of the operation.")
is_root = fields.Boolean(description="If true, the operation is the root of the operation tree.")
node_1 = fields.Nested('self')
node_2 = fields.Nested('self')
condition = fields.Nested(ConditionSchema)
alert_id = fields.Integer(description="The id of the related alert.")
class Notification(Schema):
id = fields.Integer(description="The notification id.")
ora = fields.DateTime(description="Muda muda muda.")
repository_id = fields.Integer(description="The id of the related repository.")
class Alert(Schema):
id = fields.Integer(description="The alert id.")
name = fields.String(description="The name of the alert.")
limit = fields.Integer(description="The number of tweets in a time window.")
window_size = fields.Integer(description="The size of the time window.")
repository_id = fields.Integer(description="The id of the related repository.")
operations = fields.Nested(Operations, many=True)
root_operation = fields.Nested(Operations, many=False)
notifications = fields.Nested(Notification, many=True)
class ConditionParameterSchema(Schema): class ConditionParameterSchema(Schema):
cid = fields.Integer(description="The condition id.") cid = fields.Integer(description="The condition id.")

View file

@ -29,6 +29,9 @@ 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("ConditionParameter", schema=ConditionParameterSchema) spec.components.schema("ConditionParameter", schema=ConditionParameterSchema)
spec.components.schema("AlertParameter", schema=AlertParameterSchema)
spec.components.schema("Alert", schema=Alert)
spec.components.schema("CreateAlert", schema=CreateAlert)
spec.components.security_scheme("jwt", {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"}) spec.components.security_scheme("jwt", {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"})
# add swagger tags that are used for endpoint annotation # add swagger tags that are used for endpoint annotation
@ -42,6 +45,9 @@ tags = [
{'name': 'condition-related', {'name': 'condition-related',
'description': 'Condition related calls of the API.' 'description': 'Condition related calls of the API.'
}, },
{'name': 'alert-related',
'description': 'Alert related calls of the API.'
},
{'name': 'admin-only', {'name': 'admin-only',
'description': 'Admin only calls of the API.' 'description': 'Admin only calls of the API.'
}, },

View file

@ -62,6 +62,11 @@ app.add_url_rule(
view_func=routes.page_repository_conditions, view_func=routes.page_repository_conditions,
methods=["GET", "POST"], methods=["GET", "POST"],
) )
app.add_url_rule(
"/api/v1/repositories/<int:rid>/alerts",
view_func=routes.page_repository_alerts,
methods=["GET", "POST"]
)
app.add_url_rule( app.add_url_rule(
"/api/v1/conditions/<int:cid>", "/api/v1/conditions/<int:cid>",
view_func=routes.page_condition, view_func=routes.page_condition,

View file

@ -17,3 +17,16 @@ class Alert(ext.Model):
repository = ext.relationship("Repository", back_populates="alerts") repository = ext.relationship("Repository", back_populates="alerts")
notifications = ext.relationship("Notification", back_populates="alert", cascade="all, delete") notifications = ext.relationship("Notification", back_populates="alert", cascade="all, delete")
operations = ext.relationship("BoolOperation", back_populates="alert", cascade="all, delete") operations = ext.relationship("BoolOperation", back_populates="alert", cascade="all, delete")
def to_json(self):
return {
'id': self.id,
'name': self.name,
'window_size': self.window_size,
'limit': self.limit,
'repository_id': self.repository_id,
'notifications': [notification.to_json() for notification in self.notifications],
'operations': [operation.to_json() for operation in self.operations],
'root_operation': [operation.to_json() for operation in self.operations if operation.is_root == True][
0] if self.operations else None
}

View file

@ -9,6 +9,7 @@ from sqlalchemy.orm import backref
class BoolOperation(ext.Model): class BoolOperation(ext.Model):
__tablename__ = "bool_operation" __tablename__ = "bool_operation"
id = ext.Column(ext.Integer, primary_key=True) id = ext.Column(ext.Integer, primary_key=True)
operation = ext.Column(ext.Enum(OperationType), nullable=False) operation = ext.Column(ext.Enum(OperationType), nullable=False)
isRoot = ext.Column(ext.Boolean, default=False, nullable=False) isRoot = ext.Column(ext.Boolean, default=False, nullable=False)
@ -24,3 +25,13 @@ class BoolOperation(ext.Model):
node_2 = ext.relationship("BoolOperation", primaryjoin=("bool_operation.c.node_2_id==bool_operation.c.id"), node_2 = ext.relationship("BoolOperation", primaryjoin=("bool_operation.c.node_2_id==bool_operation.c.id"),
remote_side="BoolOperation.id", backref=backref("father_2", uselist=False)) remote_side="BoolOperation.id", backref=backref("father_2", uselist=False))
alert = ext.relationship("Alert", back_populates="operations") alert = ext.relationship("Alert", back_populates="operations")
def to_json(self):
return {"id": self.id,
"operation": self.operation,
"is_root": self.is_root,
"alert_id": self.alert_id,
"condition": self.condition.to_json() if self.condition else None,
"node_1": self.node_1.to_json() if self.node_1 else None,
"node_2": self.node_2.to_json() if self.node_2 else None
}

View file

@ -13,3 +13,10 @@ class Notification(ext.Model):
alert_id = ext.Column(ext.Integer, ext.ForeignKey("alert.id"), nullable=False) alert_id = ext.Column(ext.Integer, ext.ForeignKey("alert.id"), nullable=False)
# Relationships # Relationships
alert = ext.relationship("Alert", back_populates="notifications") alert = ext.relationship("Alert", back_populates="notifications")
def to_json(self):
return {
"id": self.id,
"ora": self.ora.isoformat(),
"alert_id": self.alert_id
}

View file

@ -2,3 +2,4 @@ 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 *
from .alerts import *

View file

@ -0,0 +1,2 @@
from .repository_alerts import page_repository_alerts
from .alert import page_alert

View file

@ -0,0 +1,142 @@
from flask import render_template, abort, jsonify, request
from nest_backend.database import *
from flask_jwt_extended import jwt_required
from nest_backend.gestione import *
from flask_cors import cross_origin
import datetime
@cross_origin()
@jwt_required()
@repository_auth
def page_alert(aid):
"""
---
get:
summary: Get details about an alert.
parameters:
- in: path
schema: AlertParameterSchema
security:
- jwt: []
responses:
'200':
description: The details about the requested alert. The schema is incapsulated in Success.
content:
application/json:
schema: Alert
'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
tags:
- alert-related
delete:
summary: Deletes an alert.
parameters:
- in: path
schema: AlertParameterSchema
security:
- jwt: []
responses:
'200':
description: The repository has been deleted successfully.
'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
'500':
description: Could not delete the repository.
content:
application/json:
schema: Error
tags:
- alert-related
patch:
summary: Updates an alert.
security:
- jwt: []
requestBody:
required: true
content:
application/json:
schema: CreateAlert
parameters:
- in: path
schema: AlertParameterSchema
responses:
'200':
description: The repository has been updated successfully.
content:
application/json:
schema: Alert
'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
tags:
- alert-related
"""
user = find_user(get_jwt_identity())
alert = Alert.query.filter_by(id=aid).first()
if not alert:
return json_error("Could not find alert."), 404
if alert.repository not in [a.repository for a in user.authorizations] + user.owner_of:
json_error("You are not authorized to proceed."), 403
if request.method == "GET":
return json_success(alert.to_json()), 200
if alert.repository not in user.owner_of:
json_error("You are not authorized to proceed."), 403
if request.method == "PATCH":
if 'name' in request.json:
alert.name = request.json['name']
if 'limit' in request.json:
alert.limit = request.json['limit']
if 'window_size' in request.json:
alert.window_size = request.json['window_size']
ext.session.commit()
return json_success(alert.to_json()), 200
elif request.method == "DELETE":
try:
ext.session.delete(alert)
ext.session.commit()
except Exception:
return json_error("Something went wrong while deleting alert."), 500
return json_success("Deletion completed."), 200
elif request.method == "PUT":
pass

View file

@ -0,0 +1,92 @@
from flask import render_template, abort, jsonify, request
from nest_backend.database import *
from flask_jwt_extended import jwt_required
from nest_backend.gestione import *
from flask_cors import cross_origin
@cross_origin()
@jwt_required()
@repository_auth
def page_repository_alerts(rid):
"""
---
get:
summary: Get a list of a repository alerts.
parameters:
- in: path
schema: IntegerParameterSchema
security:
- jwt: []
responses:
'200':
description: List of Alert schemas, incapsulated in Success.
'401':
description: The user is not logged in.
content:
application/json:
schema: Error
'403':
description: The user is not authorized.
content:
application/json:
schema: Error
'404':
description: The repository could not be found.
content:
application/json:
schema: Error
tags:
- repository-related
post:
summary: Creates an alert and attaches it to the repository.
security:
- jwt: []
requestBody:
required: true
content:
application/json:
schema: CreateAlert
responses:
'200':
description: The alert has been created successfully.
content:
application/json:
schema: Alert
'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
tags:
- alert-related
"""
repository = Repository.query.filter_by(id=rid).first()
if not repository:
return json_error("Could not find repository"), 404
user = find_user(get_jwt_identity())
if user.email != repository.owner_id:
return json_error("You are not authorized."), 403
if request.method == "GET":
return json_success([alert.to_json() for alert in repository.alerts])
if request.method == "POST":
if 'name' not in request.json:
json_error("Missing name."), 400
if 'limit' not in request.json:
json_error('Missing limit'), 400
if 'window_size' not in request.json:
json_error('Missing window size'), 400
alert = Alert(name=request.json['name'], limit=request.json['limit'], window_size=request.json['window_size'],
repository_id=rid)
ext.session.add(alert)
ext.session.commit()
return json_success(alert.to_json()), 200