Skip to content

Commit

Permalink
codeforboston#284 - Added a check for the contributor having a source…
Browse files Browse the repository at this point in the history
… before continuing. Will now update unit tests.
  • Loading branch information
mnuzzose committed Jul 25, 2023
1 parent c51f066 commit 5fc0d81
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 30 deletions.
24 changes: 24 additions & 0 deletions backend/auth/jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ def verify_roles_or_abort(min_role):
return True


def verify_contributor_has_source_or_abort():
verify_jwt_in_request()
jwt_decoded = get_jwt()
current_user = User.get(jwt_decoded["sub"])
if (
current_user is None
or not current_user.member_of
):
abort(403)
return False
return True


def blueprint_role_required(*roles):
def decorator():
verify_roles_or_abort(roles)
Expand All @@ -45,3 +58,14 @@ def decorator(*args, **kwargs):
return decorator

return wrapper

def contributor_has_source():
def wrapper(fn):
@wraps(fn)
def decorator(*args, **kwargs):
if verify_contributor_has_source_or_abort():
return fn(*args, **kwargs)

return decorator

return wrapper
25 changes: 22 additions & 3 deletions backend/database/models/_assoc_tables.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
from .. import db
from backend.database.models.officer import Rank
# from backend.database.models.source import MemberRole
from enum import Enum

""" source_user = db.Table(

class MemberRole(Enum):
ADMIN = "Administrator"
PUBLISHER = "Publisher"
MEMBER = "Member"
SUBSCRIBER = "Subscriber"

def get_value(self):
if self == MemberRole.ADMIN:
return 1
elif self == MemberRole.PUBLISHER:
return 2
elif self == MemberRole.MEMBER:
return 3
elif self == MemberRole.SUBSCRIBER:
return 4
else:
return 5


source_user = db.Table(
'source_user',
db.Column('source_id', db.String, db.ForeignKey('source.id'),
primary_key=True),
Expand All @@ -13,7 +33,6 @@
db.Column('is_active', db.Boolean),
db.Column('is_admin', db.Boolean)
)
"""

incident_agency = db.Table(
'incident_agency',
Expand Down
28 changes: 4 additions & 24 deletions backend/database/models/source.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,5 @@
from ..core import db, CrudMixin
# from backend.database.models._assoc_tables import source_user
from enum import Enum


class MemberRole(Enum):
ADMIN = "Administrator"
PUBLISHER = "Publisher"
MEMBER = "Member"
SUBSCRIBER = "Subscriber"

def get_value(self):
if self == MemberRole.ADMIN:
return 1
elif self == MemberRole.PUBLISHER:
return 2
elif self == MemberRole.MEMBER:
return 3
elif self == MemberRole.SUBSCRIBER:
return 4
else:
return 5
from backend.database.models._assoc_tables import source_user


class Source(db.Model, CrudMixin):
Expand All @@ -29,6 +9,6 @@ class Source(db.Model, CrudMixin):
contact_email = db.Column(db.Text)
reported_incidents = db.relationship(
'Incident', backref='source', lazy="select")
# members = db.relationship(
# 'User', backref='contributor_orgs',
# secondary=source_user, lazy="select")
members = db.relationship(
'User', backref='contributor_orgs',
secondary=source_user, lazy="select")
3 changes: 3 additions & 0 deletions backend/database/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,8 @@ class User(db.Model, UserMixin, CrudMixin):

phone_number = db.Column(db.Text)

member_of = db.relationship(
'Source', backref='source', secondary='source_user', lazy="select")

def verify_password(self, pw):
return bcrypt.checkpw(pw.encode("utf8"), self.password.encode("utf8"))
4 changes: 2 additions & 2 deletions backend/routes/incidents.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime
from typing import Optional

from backend.auth.jwt import min_role_required
from backend.auth.jwt import min_role_required, contributor_has_source
from backend.database.models.user import UserRole
from flask import Blueprint, abort, current_app, request
from flask_jwt_extended.view_decorators import jwt_required
Expand Down Expand Up @@ -30,8 +30,8 @@ def get_incidents(incident_id: int):

@bp.route("/create", methods=["POST"])
@jwt_required()
# TODO: Require CONTRIBUTOR role
@min_role_required(UserRole.CONTRIBUTOR)
@contributor_has_source()
@validate(json=CreateIncidentSchema)
def create_incident():
"""Create a single incident.
Expand Down
5 changes: 5 additions & 0 deletions backend/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def example_user(db_session):
db_session.commit()
return user


@pytest.fixture
def admin_user(db_session):
user = User(
Expand All @@ -78,6 +79,7 @@ def admin_user(db_session):

return user


@pytest.fixture
def contributor_user(db_session):
user = User(
Expand All @@ -92,6 +94,7 @@ def contributor_user(db_session):

return user


@pytest.fixture
def access_token(client, example_user):
res = client.post(
Expand All @@ -104,6 +107,7 @@ def access_token(client, example_user):
assert res.status_code == 200
return res.json["access_token"]


@pytest.fixture
def contributor_access_token(client, contributor_user):
res = client.post(
Expand All @@ -116,6 +120,7 @@ def contributor_access_token(client, contributor_user):
assert res.status_code == 200
return res.json["access_token"]


@pytest.fixture
def cli_runner(app):
return app.test_cli_runner()
Expand Down
3 changes: 2 additions & 1 deletion backend/tests/test_incidents.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ def example_incidents(db_session, client, contributor_access_token):
res = client.post(
"/api/v1/incidents/create",
json=mock,
headers={"Authorization": "Bearer {0}".format(contributor_access_token)},
headers={"Authorization":
"Bearer {0}".format(contributor_access_token)},
)
assert res.status_code == 200
created[name] = res.json
Expand Down

0 comments on commit 5fc0d81

Please sign in to comment.