Skip to content

Commit

Permalink
Merge branch 'master' into enhancement/view-edit-search-filter
Browse files Browse the repository at this point in the history
  • Loading branch information
whitdog47 authored Oct 6, 2023
2 parents 97af3c1 + 0327461 commit 406c6e5
Show file tree
Hide file tree
Showing 31 changed files with 1,212 additions and 63 deletions.
12 changes: 8 additions & 4 deletions docs/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 19 additions & 6 deletions requirements-base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,14 @@ click==8.1.7
# schemathesis
# typer
# uvicorn
cloudpathlib==0.15.1
# via weasel
colorama==0.4.6
# via schemathesis
confection==0.1.1
# via thinc
# via
# thinc
# weasel
cryptography==39.0.2
# via
# -r requirements-base.in
Expand Down Expand Up @@ -128,7 +132,7 @@ frozenlist==1.4.0
# aiosignal
google-api-core==2.11.1
# via google-api-python-client
google-api-python-client==2.101.0
google-api-python-client==2.102.0
# via -r requirements-base.in
google-auth==2.22.0
# via
Expand Down Expand Up @@ -255,6 +259,7 @@ packaging==23.1
# spacy
# statsmodels
# thinc
# weasel
pandas==2.1.1
# via
# -r requirements-base.in
Expand All @@ -277,12 +282,12 @@ preshed==3.0.8
# via
# spacy
# thinc
protobuf==4.24.3
protobuf==4.24.4
# via
# -r requirements-base.in
# google-api-core
# googleapis-common-protos
psycopg2-binary==2.9.8
psycopg2-binary==2.9.9
# via -r requirements-base.in
pyasn1==0.5.0
# via
Expand All @@ -304,6 +309,7 @@ pydantic==1.10.13
# fastapi
# spacy
# thinc
# weasel
pyjwt[crypto]==2.8.0
# via
# msal
Expand Down Expand Up @@ -357,6 +363,7 @@ requests==2.31.0
# schemathesis
# spacy
# starlette-testclient
# weasel
requests-oauthlib==1.3.1
# via
# atlassian-python-api
Expand Down Expand Up @@ -411,14 +418,15 @@ smart-open==6.3.0
# via
# pathy
# spacy
# weasel
sniffio==1.3.0
# via
# anyio
# httpcore
# httpx
sortedcontainers==2.4.0
# via hypothesis
spacy==3.6.1
spacy==3.7.1
# via -r requirements-base.in
spacy-legacy==3.0.12
# via spacy
Expand All @@ -439,6 +447,7 @@ srsly==2.4.7
# confection
# spacy
# thinc
# weasel
starlette==0.27.0
# via
# fastapi
Expand Down Expand Up @@ -468,6 +477,7 @@ typer==0.9.0
# via
# pathy
# spacy
# weasel
typing-extensions==4.7.1
# via
# alembic
Expand All @@ -480,7 +490,7 @@ tzdata==2023.3
# via pandas
uritemplate==4.1.1
# via google-api-python-client
urllib3==1.26.16
urllib3==1.26.17
# via
# botocore
# google-auth
Expand All @@ -497,6 +507,9 @@ wasabi==1.1.2
# via
# spacy
# thinc
# weasel
weasel==0.3.2
# via spacy
werkzeug==2.3.7
# via schemathesis
wrapt==1.15.0
Expand Down
33 changes: 33 additions & 0 deletions src/dispatch/auth/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from dispatch.models import PrimaryKeyModel
from dispatch.organization import service as organization_service
from dispatch.organization.models import OrganizationRead
from dispatch.participant_role.enums import ParticipantRoleType

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -315,6 +316,8 @@ def has_required_permissions(
if current_incident.reporter.individual.email == current_user.email:
return True

return False


class IncidentCommanderPermission(BasePermission):
def has_required_permissions(
Expand All @@ -331,6 +334,36 @@ def has_required_permissions(
if current_incident.commander.individual.email == current_user.email:
return True

return False


class IncidentCommanderOrScribePermission(BasePermission):
def has_required_permissions(
self,
request: Request,
) -> bool:
current_user = get_current_user(request=request)
pk = PrimaryKeyModel(id=request.path_params["incident_id"])
current_incident = incident_service.get(db_session=request.state.db, incident_id=pk.id)
if not current_incident:
return False

if (
current_incident.commander
and current_incident.commander.individual.email == current_user.email
):
return True

scribes = [
participant.individual.email
for participant in current_incident.participants
if ParticipantRoleType.scribe in [role.role for role in participant.participant_roles]
]
if current_user.email in scribes:
return True

return False


class IncidentParticipantPermission(BasePermission):
def has_required_permissions(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Adds type to events
Revision ID: 3538650dc471
Revises: e875e9544048
Create Date: 2023-09-12 13:43:42.539336
"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = "3538650dc471"
down_revision = "e875e9544048"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("event", sa.Column("type", sa.String(), nullable=True))
op.add_column("event", sa.Column("owner", sa.String(), nullable=True))
op.add_column("event", sa.Column("pinned", sa.Boolean(), nullable=True))
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column("event", "type")
op.drop_column("event", "pinned")
op.drop_column("event", "owner")
# ### end Alembic commands ###
9 changes: 9 additions & 0 deletions src/dispatch/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,12 @@ class DocumentResourceTemplateTypes(DispatchEnum):
incident = "dispatch-incident-document-template"
review = "dispatch-incident-review-document-template"
tracking = "dispatch-incident-sheet-template"


class EventType(DispatchEnum):
other = "Other" # default and catch-all (x resource created/updated, etc.)
field_updated = "Field updated" # for fields like title, description, tags, type, etc.
assessment_updated = "Assessment updated" # for priority, status, or severity changes
participant_updated = "Participant updated" # for added/removed users and role changes
imported_message = "Imported message" # for stopwatch-reacted messages from Slack
custom_event = "Custom event" # for user-added events (new feature)
55 changes: 55 additions & 0 deletions src/dispatch/event/flows.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import logging

from dispatch.decorators import background_task
from dispatch.event import service as event_service
from dispatch.incident import service as incident_service
from dispatch.individual import service as individual_service
from dispatch.event.models import EventUpdate, EventCreateMinimal

log = logging.getLogger(__name__)


@background_task
def log_incident_event(
user_email: str,
incident_id: int,
event_in: EventCreateMinimal,
db_session=None,
organization_slug: str = None,
):
incident = incident_service.get(db_session=db_session, incident_id=incident_id)
individual = individual_service.get_by_email_and_project(
db_session=db_session, email=user_email, project_id=incident.project.id
)
event_in.source = f"Custom event created by {individual.name}"
event_in.owner = individual.name

event_service.log_incident_event(
db_session=db_session,
incident_id=incident_id,
**event_in.__dict__,
)


@background_task
def update_incident_event(
event_in: EventUpdate,
db_session=None,
organization_slug: str = None,
):
event_service.update_incident_event(
db_session=db_session,
event_in=event_in,
)


@background_task
def delete_incident_event(
event_uuid: str,
db_session=None,
organization_slug: str = None,
):
event_service.delete_incident_event(
db_session=db_session,
uuid=event_uuid,
)
18 changes: 17 additions & 1 deletion src/dispatch/event/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@

from typing import Optional

from sqlalchemy import Column, DateTime, ForeignKey, Integer, String
from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Boolean
from sqlalchemy.dialects.postgresql import UUID as SQLAlchemyUUID
from sqlalchemy_utils import TSVectorType, JSONType

from dispatch.database.core import Base
from dispatch.models import DispatchBase, TimeStampMixin
from dispatch.enums import EventType


# SQLAlchemy Model
Expand All @@ -21,6 +22,9 @@ class Event(Base, TimeStampMixin):
source = Column(String, nullable=False)
description = Column(String, nullable=False)
details = Column(JSONType, nullable=True)
type = Column(String, default=EventType.other, nullable=True)
owner = Column(String, nullable=True)
pinned = Column(Boolean, default=False)

# relationships
individual_id = Column(Integer, ForeignKey("individual_contact.id", ondelete="CASCADE"))
Expand All @@ -45,6 +49,9 @@ class EventBase(DispatchBase):
source: str
description: str
details: Optional[dict]
type: Optional[str]
owner: Optional[str]
pinned: Optional[bool]


class EventCreate(EventBase):
Expand All @@ -57,3 +64,12 @@ class EventUpdate(EventBase):

class EventRead(EventBase):
pass


class EventCreateMinimal(DispatchBase):
started_at: datetime
source: str
description: str
details: dict
type: Optional[str]
owner: Optional[str]
Loading

0 comments on commit 406c6e5

Please sign in to comment.