mirror of
https://github.com/pds-nest/nest.git
synced 2024-11-25 06:24:19 +00:00
Add authorization creation/deletion API calls
This commit is contained in:
parent
8d8e396ebf
commit
3368f2d2d3
12 changed files with 204 additions and 6 deletions
|
@ -24,6 +24,20 @@ class ErrorSchema(Schema):
|
|||
code = fields.String(description="Error code")
|
||||
|
||||
|
||||
class AuthorizationSchema(Schema):
|
||||
rid = fields.Integer(description="The repository id.")
|
||||
email = fields.String(description="The user's email.")
|
||||
|
||||
|
||||
class AuthorizationParameterSchema(Schema):
|
||||
rid = fields.Integer(description="The repository id.")
|
||||
email = fields.String(description="The user's email.")
|
||||
|
||||
|
||||
class CreateAuthorizationSchema(Schema):
|
||||
email = fields.String(description="The user's email")
|
||||
|
||||
|
||||
class SuccesSchema(Schema):
|
||||
result = fields.String(description="Contains a string that informs if the procedure was successful.")
|
||||
data = fields.String(description="The content of the response.")
|
||||
|
|
|
@ -33,6 +33,8 @@ spec.components.schema("AlertParameter", schema=AlertParameterSchema)
|
|||
spec.components.schema("Alert", schema=Alert)
|
||||
spec.components.schema("Tweet", schema=TweetSchema)
|
||||
spec.components.schema("CreateAlert", schema=CreateAlert)
|
||||
spec.components.schema("CreateAuthorization", schema=CreateAuthorizationSchema)
|
||||
spec.components.schema("Authorization", schema=AuthorizationSchema)
|
||||
spec.components.security_scheme("jwt", {"type": "http", "scheme": "bearer", "bearerFormat": "JWT"})
|
||||
|
||||
# add swagger tags that are used for endpoint annotation
|
||||
|
|
|
@ -66,11 +66,21 @@ app.add_url_rule(
|
|||
view_func=routes.page_repository_alerts,
|
||||
methods=["GET", "POST"]
|
||||
)
|
||||
app.add_url_rule(
|
||||
"/api/v1/repositories/<int:rid>/authorizations/",
|
||||
view_func=routes.page_repository_authorizations,
|
||||
methods=["GET", "POST"],
|
||||
)
|
||||
app.add_url_rule(
|
||||
"/api/v1/repositories/<int:rid>/tweets/",
|
||||
view_func=routes.page_repository_tweets,
|
||||
methods=["GET"]
|
||||
)
|
||||
app.add_url_rule(
|
||||
"/api/v1/authorization/<int:rid>/<string:email>",
|
||||
view_func=routes.page_authorization,
|
||||
methods=["DELETE"]
|
||||
)
|
||||
app.add_url_rule(
|
||||
"/api/v1/alert/<int:aid>",
|
||||
view_func=routes.page_alert,
|
||||
|
|
|
@ -10,4 +10,10 @@ class Authorization(ext.Model):
|
|||
email = ext.Column(ext.String, ext.ForeignKey("user.email", ondelete="CASCADE"), primary_key=True)
|
||||
# Relationships
|
||||
repository = ext.relationship("Repository", back_populates="authorizations")
|
||||
user = ext.relationship("User", back_populates="authorizations")
|
||||
user = ext.relationship("User", back_populates="authorizations")
|
||||
|
||||
def to_json(self):
|
||||
return {
|
||||
"rid": self.rid,
|
||||
"email": self.email,
|
||||
}
|
|
@ -25,3 +25,5 @@ ALERT_NO_LIMIT = "errorAlertNoLimit" # Missing limit entry
|
|||
ALERT_NO_WINDOW = "errorAlertNoWindow" # Missing window entry
|
||||
ALERT_NO_EVALUATION = "errorAlertNoEvaluation" # Missing evalmode entry
|
||||
ALERT_DELETION_FAILURE = "errorAlertDeletionFailure" # Error while deleting alerts
|
||||
# Authorization
|
||||
AUTHORIZATION_NOT_FOUND = "errorAuthorizationNotFound" # Authorization not found
|
||||
|
|
|
@ -8,7 +8,7 @@ import functools
|
|||
from flask_jwt_extended import get_jwt_identity
|
||||
from flask import jsonify
|
||||
from re import sub
|
||||
from .errors import GENERIC_UFO
|
||||
from .errors import GENERIC_UFO, REPOSITORY_NOT_FOUND, USER_NOT_AUTHORIZED
|
||||
|
||||
__all__ = ["authenticate", "identity", "gen_password", "find_user", "admin_or_403",
|
||||
"repository_auth", "json_request_authorizer", "json_error",
|
||||
|
@ -76,10 +76,10 @@ def repository_auth(f):
|
|||
return json_error("Missing one or more parameters."), 400
|
||||
repository = Repository.query.filter_by(id=repository_id).first()
|
||||
if not repository:
|
||||
return json_error("Cant't find the repository."), 404
|
||||
return json_error("Cant't find the repository.", REPOSITORY_NOT_FOUND), 404
|
||||
if repository.owner_id != user.email and user.email not in [a.email for a in
|
||||
repository.authorizations] and not user.isAdmin:
|
||||
return json_error("Stop right there, criminal scum! Nobody accesses protected data under MY watch!"), 403
|
||||
return json_error("Stop right there, criminal scum! Nobody accesses protected data under MY watch!", USER_NOT_AUTHORIZED), 403
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return func
|
||||
|
|
|
@ -5,6 +5,8 @@ This module imports all the routes that return something to the frontend.
|
|||
from .doa import page_doa
|
||||
from .users import *
|
||||
from .repository import *
|
||||
|
||||
__all__ = ["page_alert", "page_repository_alerts", "page_repository", "page_doa",
|
||||
"page_condition", "page_repository_conditions", "page_repositories",
|
||||
"page_login", "page_user", "page_users"]
|
||||
"page_login", "page_user", "page_users", "page_authorization", "page_repository_authorizations",
|
||||
"page_repository_tweets"]
|
||||
|
|
|
@ -4,6 +4,8 @@ from .repositories import page_repositories
|
|||
from .conditions import *
|
||||
from .alerts import *
|
||||
from .tweets import *
|
||||
from .authorizations import *
|
||||
|
||||
__all__ = ["page_condition", "page_repository_conditions", "page_repositories",
|
||||
"page_alert", "page_repository", "page_repository_alerts", "page_repository_tweets"]
|
||||
"page_alert", "page_repository", "page_repository_alerts", "page_repository_tweets",
|
||||
"page_authorization", "page_repository_authorizations"]
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
from .authorization import page_authorization
|
||||
from .repository_authorizations import page_repository_authorizations
|
||||
|
||||
__all__ = ["page_authorization", "page_repository_authorizations"]
|
|
@ -0,0 +1,54 @@
|
|||
from flask import render_template, abort, jsonify, request
|
||||
from nest_backend.database import *
|
||||
from flask_jwt_extended import jwt_required, get_jwt_identity
|
||||
from nest_backend.gestione import *
|
||||
from flask_cors import cross_origin
|
||||
from nest_backend.errors import *
|
||||
|
||||
|
||||
@cross_origin()
|
||||
@jwt_required()
|
||||
def page_authorization(rid, email):
|
||||
"""
|
||||
---
|
||||
delete:
|
||||
summary: Delete an authorization.
|
||||
parameters:
|
||||
- in: path
|
||||
schema: AuthorizationParameterSchema
|
||||
security:
|
||||
- jwt: []
|
||||
responses:
|
||||
'204':
|
||||
description: The deletion was successful.
|
||||
'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: Something could not be found.
|
||||
content:
|
||||
application/json:
|
||||
schema: Error
|
||||
tags:
|
||||
- repository-related
|
||||
"""
|
||||
repository = Repository.query.filter_by(id=rid).first()
|
||||
user = find_user(get_jwt_identity())
|
||||
if not repository:
|
||||
return json_error("Could not find the repository.", REPOSITORY_NOT_FOUND), 404
|
||||
if user != repository.owner:
|
||||
return json_error("You are not authorized.", USER_NOT_AUTHORIZED), 403
|
||||
authorization = Authorization.query.filter_by(rid=rid, email=email).first()
|
||||
if not authorization:
|
||||
return json_error("Could not find the authorization", AUTHORIZATION_NOT_FOUND), 404
|
||||
if request.method == "DELETE":
|
||||
ext.session.delete(authorization)
|
||||
ext.session.commit()
|
||||
return json_success("Deleted."), 204
|
|
@ -0,0 +1,101 @@
|
|||
from flask import request
|
||||
from flask_jwt_extended import jwt_required
|
||||
from nest_backend.gestione import repository_auth, json_error, json_success, find_user, get_jwt_identity
|
||||
from nest_backend.database import ext, User, Authorization, Repository
|
||||
from flask_cors import cross_origin
|
||||
from nest_backend.gestione import hashtag_validator
|
||||
from nest_backend.errors import *
|
||||
|
||||
|
||||
@cross_origin()
|
||||
@jwt_required()
|
||||
@repository_auth
|
||||
def page_repository_authorizations(rid):
|
||||
"""
|
||||
---
|
||||
get:
|
||||
summary: Get a list of a repository authorizations.
|
||||
parameters:
|
||||
- in: path
|
||||
schema: IntegerParameterSchema
|
||||
security:
|
||||
- jwt: []
|
||||
responses:
|
||||
'200':
|
||||
description: List of Authorization 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 a condition and attaches it to the repository.
|
||||
security:
|
||||
- jwt: []
|
||||
parameters:
|
||||
- in: path
|
||||
schema: IntegerParameterSchema
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: CreateAuthorization
|
||||
responses:
|
||||
'201':
|
||||
description: The authorization has been created successfully.
|
||||
content:
|
||||
application/json:
|
||||
schema: Authorization
|
||||
'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:
|
||||
- repository-related
|
||||
"""
|
||||
|
||||
repository = Repository.query.filter_by(id=rid).first()
|
||||
if not repository:
|
||||
return json_error("Could not find repository", REPOSITORY_NOT_FOUND), 404
|
||||
user = find_user(get_jwt_identity())
|
||||
if user.email != repository.owner_id:
|
||||
return json_error("You are not authorized.", REPOSITORY_NOT_OWNER), 403
|
||||
if request.method == "GET":
|
||||
try:
|
||||
return json_success([a.to_json() for a in repository.authorizations])
|
||||
except Exception as e:
|
||||
return json_error("Unknown error:" + str(e), GENERIC_UFO), 400
|
||||
if request.method == "POST":
|
||||
if request.json is None:
|
||||
return json_error("Missing json content.", GENERIC_NO_JSON), 400
|
||||
if not request.json.get("email"):
|
||||
return json_error("Missing user email.", GENERIC_MISSING_FIELDS), 400
|
||||
target = User.query.filter_by(email=request.json.get('email')).first()
|
||||
if not target:
|
||||
return json_error("User could not be located", USER_NOT_FOUND), 400
|
||||
if target == user:
|
||||
return json_error("Owner cannot be a spectator", GENERIC_ALREADY_EXISTS), 406
|
||||
|
||||
authorization = Authorization(email=request.json.get('email'), rid=repository.id)
|
||||
ext.session.add(authorization)
|
||||
ext.session.commit()
|
||||
|
||||
return json_success(authorization.to_json()), 201
|
|
@ -198,6 +198,7 @@ def page_repository(rid):
|
|||
repository.evaluation_mode = evaluation_mode
|
||||
repository.name = request.json['name']
|
||||
repository.is_active = request.json['is_active']
|
||||
ext.session.commit()
|
||||
ids = [c['id'] for c in request.json['conditions'] if c['id']]
|
||||
# Delete no longer needed conditions.
|
||||
for c in repository.conditions:
|
||||
|
|
Loading…
Reference in a new issue