-
-
Notifications
You must be signed in to change notification settings - Fork 81
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Association Object for Partner User relationship - May decide to do the same for the rest of the assoc. tables in the future * Add Members to Partner - `partners/:partner_id/members/add` endpoint created - When creating a Partner, the logged in user is automatically added as an admin * Add "Get All Members" - `/<int:partner_id>/members/` endpoint - Automatically create Timestamp for new Incident entries
- Loading branch information
Showing
9 changed files
with
496 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,16 @@ | ||
from backend.auth.jwt import min_role_required | ||
from backend.database.models.user import UserRole | ||
from backend.database.models.user import User, UserRole | ||
from flask import Blueprint, abort, current_app, request | ||
from flask_jwt_extended import get_jwt | ||
from flask_jwt_extended.view_decorators import jwt_required | ||
|
||
from ..database import Partner | ||
from ..database import Partner, PartnerMember, MemberRole, db | ||
from ..schemas import ( | ||
CreatePartnerSchema, | ||
AddMemberSchema, | ||
partner_orm_to_json, | ||
partner_member_orm_to_json, | ||
partner_member_to_orm, | ||
partner_to_orm, | ||
validate, | ||
) | ||
|
@@ -42,4 +46,140 @@ def create_partner(): | |
abort(400) | ||
|
||
created = partner.create() | ||
make_admin = PartnerMember( | ||
partner_id=created.id, | ||
user_id=User.get(get_jwt()["sub"]).id, | ||
role=MemberRole.ADMIN, | ||
) | ||
make_admin.create() | ||
|
||
return partner_orm_to_json(created) | ||
|
||
|
||
@bp.route("/", methods=["GET"]) | ||
@jwt_required() | ||
@min_role_required(UserRole.PUBLIC) | ||
@validate() | ||
def get_all_partners(): | ||
"""Get all partners. | ||
Accepts Query Parameters for pagination: | ||
per_page: number of results per page | ||
page: page number | ||
""" | ||
args = request.args | ||
q_page = args.get("page", 1, type=int) | ||
q_per_page = args.get("per_page", 20, type=int) | ||
|
||
all_partners = db.session.query(Partner) | ||
results = all_partners.paginate( | ||
page=q_page, per_page=q_per_page, max_per_page=100 | ||
) | ||
|
||
return { | ||
"results": [partner_orm_to_json(partner) for partner in results.items], | ||
"page": results.page, | ||
"totalPages": results.pages, | ||
"totalResults": results.total, | ||
} | ||
|
||
|
||
@bp.route("/<int:partner_id>/members/", methods=["GET"]) | ||
@jwt_required() | ||
@min_role_required(UserRole.PUBLIC) | ||
@validate() | ||
def get_partner_members(partner_id: int): | ||
"""Get all members of a partner. | ||
Accepts Query Parameters for pagination: | ||
per_page: number of results per page | ||
page: page number | ||
""" | ||
args = request.args | ||
q_page = args.get("page", 1, type=int) | ||
q_per_page = args.get("per_page", 20, type=int) | ||
|
||
# partner = Partner.get(partner_id) | ||
all_members = db.session.query(PartnerMember).filter( | ||
PartnerMember.partner_id == partner_id | ||
) | ||
results = all_members.paginate( | ||
page=q_page, per_page=q_per_page, max_per_page=100) | ||
|
||
return { | ||
"results": [ | ||
partner_member_orm_to_json(member) | ||
for member in results.items | ||
], | ||
"page": results.page, | ||
"totalPages": results.pages, | ||
"totalResults": results.total, | ||
} | ||
|
||
|
||
""" This class currently doesn't work with the `partner_member_to_orm` | ||
class AddMemberSchema(BaseModel): | ||
user_email: str | ||
role: Optional[MemberRole] = PartnerMember.get_default_role() | ||
is_active: Optional[bool] = True | ||
class Config: | ||
extra = "forbid" | ||
schema_extra = { | ||
"example": { | ||
"user_email": "[email protected]", | ||
"role": "ADMIN", | ||
} | ||
} """ | ||
|
||
|
||
@bp.route("/<int:partner_id>/members/add", methods=["POST"]) | ||
@jwt_required() | ||
@min_role_required(UserRole.PUBLIC) | ||
@validate(json=AddMemberSchema) | ||
def add_member_to_partner(partner_id: int): | ||
"""Add a member to a partner. | ||
TODO: Allow the API to accept a user email instad of a user id | ||
TODO: Use the partner ID from the API path instead of the request body | ||
The `partner_member_to_orm` function seems very picky about the input. | ||
I wasn't able to get it to accept a dict or a PartnerMember object. | ||
Cannot be called in production environments | ||
""" | ||
if current_app.env == "production": | ||
abort(418) | ||
|
||
# Ensure that the user has premission to add a member to this partner. | ||
jwt_decoded = get_jwt() | ||
|
||
current_user = User.get(jwt_decoded["sub"]) | ||
association = db.session.query(PartnerMember).filter( | ||
PartnerMember.user_id == current_user.id, | ||
PartnerMember.partner_id == partner_id, | ||
).first() | ||
|
||
if ( | ||
association is None | ||
or not association.is_administrator() | ||
or not association.partner_id == partner_id | ||
): | ||
abort(403) | ||
|
||
# TODO: Allow the API to accept a user email instad of a user id | ||
# user_obj = User.get_by_email(request.context.json.user_email) | ||
# if user_obj is None: | ||
# abort(400) | ||
|
||
# new_member = PartnerMember( | ||
# partner_id=partner_id, | ||
# user_id=user_obj.id, | ||
# role=request.context.json.role, | ||
# ) | ||
|
||
try: | ||
partner_member = partner_member_to_orm(request.context.json) | ||
except Exception: | ||
abort(400) | ||
|
||
created = partner_member.create() | ||
|
||
return partner_member_orm_to_json(created) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.