Add application_id column to AuditEvent
Use application_id and portfolio_id if the resource is a portfolio in AuditableMixin Clean up some residual references to workspace
This commit is contained in:
parent
42900a20a6
commit
b3ecd1658c
@ -0,0 +1,32 @@
|
||||
"""add_appliction_id_to_auditevent
|
||||
|
||||
Revision ID: c5deba1826be
|
||||
Revises: 404bb5bb3a0e
|
||||
Create Date: 2019-05-15 16:30:27.981456
|
||||
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import postgresql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = 'c5deba1826be'
|
||||
down_revision = '404bb5bb3a0e'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('audit_events', sa.Column('application_id', postgresql.UUID(as_uuid=True), nullable=True))
|
||||
op.create_index(op.f('ix_audit_events_application_id'), 'audit_events', ['application_id'], unique=False)
|
||||
op.create_foreign_key('audit_events_application_application_id', 'audit_events', 'applications', ['application_id'], ['id'])
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_constraint('audit_events_application_application_id', 'audit_events', type_='foreignkey')
|
||||
op.drop_index(op.f('ix_audit_events_application_id'), table_name='audit_events')
|
||||
op.drop_column('audit_events', 'application_id')
|
||||
# ### end Alembic commands ###
|
@ -14,15 +14,10 @@ class AuditEventQuery(Query):
|
||||
return cls.paginate(query, pagination_opts)
|
||||
|
||||
@classmethod
|
||||
def get_ws_events(cls, portfolio_id, pagination_opts):
|
||||
def get_portfolio_events(cls, portfolio_id, pagination_opts):
|
||||
query = (
|
||||
db.session.query(cls.model)
|
||||
.filter(
|
||||
or_(
|
||||
cls.model.portfolio_id == portfolio_id,
|
||||
cls.model.resource_id == portfolio_id,
|
||||
)
|
||||
)
|
||||
.filter(cls.model.portfolio_id == portfolio_id)
|
||||
.order_by(cls.model.time_created.desc())
|
||||
)
|
||||
return cls.paginate(query, pagination_opts)
|
||||
@ -39,7 +34,8 @@ class AuditLog(object):
|
||||
|
||||
@classmethod
|
||||
def get_portfolio_events(cls, portfolio, pagination_opts=None):
|
||||
return AuditEventQuery.get_ws_events(portfolio.id, pagination_opts)
|
||||
return AuditEventQuery.get_portfolio_events(portfolio.id, pagination_opts)
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_by_resource(cls, resource_id):
|
||||
|
@ -17,11 +17,17 @@ class AuditEvent(Base, TimestampsMixin):
|
||||
portfolio_id = Column(UUID(as_uuid=True), ForeignKey("portfolios.id"), index=True)
|
||||
portfolio = relationship("Portfolio", backref="audit_events")
|
||||
|
||||
application_id = Column(
|
||||
UUID(as_uuid=True), ForeignKey("applications.id"), index=True
|
||||
)
|
||||
application = relationship("Application", backref="audit_events")
|
||||
|
||||
changed_state = Column(JSONB())
|
||||
event_details = Column(JSONB())
|
||||
|
||||
resource_type = Column(String(), nullable=False)
|
||||
resource_id = Column(UUID(as_uuid=True), index=True, nullable=False)
|
||||
|
||||
display_name = Column(String())
|
||||
action = Column(String(), nullable=False)
|
||||
|
||||
@ -29,6 +35,7 @@ class AuditEvent(Base, TimestampsMixin):
|
||||
def log(self):
|
||||
return {
|
||||
"portfolio_id": str(self.portfolio_id),
|
||||
"application_id": str(self.application_id),
|
||||
"changed_state": self.changed_state,
|
||||
"event_details": self.event_details,
|
||||
"resource_type": self.resource_type,
|
||||
|
@ -13,17 +13,27 @@ class AuditableMixin(object):
|
||||
@staticmethod
|
||||
def create_audit_event(connection, resource, action, changed_state=None):
|
||||
user_id = getattr_path(g, "current_user.id")
|
||||
portfolio_id = resource.portfolio_id
|
||||
resource_type = resource.resource_type
|
||||
display_name = resource.displayname
|
||||
event_details = resource.event_details
|
||||
|
||||
if resource_type == "portfolio":
|
||||
portfolio_id = resource.id
|
||||
else:
|
||||
portfolio_id = resource.portfolio_id
|
||||
|
||||
if resource_type == "application":
|
||||
application_id = resource.id
|
||||
else:
|
||||
application_id = resource.application_id
|
||||
|
||||
if changed_state is None:
|
||||
changed_state = resource.history if action == ACTION_UPDATE else None
|
||||
|
||||
audit_event = AuditEvent(
|
||||
user_id=user_id,
|
||||
portfolio_id=portfolio_id,
|
||||
application_id=application_id,
|
||||
resource_type=resource_type,
|
||||
resource_id=resource.id,
|
||||
display_name=display_name,
|
||||
@ -95,6 +105,10 @@ class AuditableMixin(object):
|
||||
def portfolio_id(self):
|
||||
return None
|
||||
|
||||
@property
|
||||
def application_id(self):
|
||||
return None
|
||||
|
||||
@property
|
||||
def displayname(self):
|
||||
return None
|
||||
|
@ -1,5 +1,6 @@
|
||||
import pytest
|
||||
|
||||
from atst.domain.applications import Applications
|
||||
from atst.domain.audit_log import AuditLog
|
||||
from atst.domain.exceptions import UnauthorizedError
|
||||
from atst.domain.permission_sets import PermissionSets
|
||||
@ -45,7 +46,7 @@ def test_paginate_ws_audit_log():
|
||||
assert len(events) == 25
|
||||
|
||||
|
||||
def test_ws_audit_log_only_includes_current_ws_events():
|
||||
def test_portfolio_audit_log_only_includes_current_portfolio_events():
|
||||
owner = UserFactory.create()
|
||||
portfolio = PortfolioFactory.create(owner=owner)
|
||||
other_portfolio = PortfolioFactory.create(owner=owner)
|
||||
@ -55,8 +56,30 @@ def test_ws_audit_log_only_includes_current_ws_events():
|
||||
|
||||
events = AuditLog.get_portfolio_events(portfolio)
|
||||
for event in events:
|
||||
assert event.portfolio_id == portfolio.id or event.resource_id == portfolio.id
|
||||
assert event.portfolio_id == portfolio.id
|
||||
assert (
|
||||
not event.portfolio_id == other_portfolio.id
|
||||
or event.resource_id == other_portfolio.id
|
||||
)
|
||||
|
||||
|
||||
def test_portfolio_audit_log_includes_app_and_env_events():
|
||||
# TODO: add in events for
|
||||
# creating/updating/deleting env_role and app_role
|
||||
# creating an app_invitation
|
||||
owner = UserFactory.create()
|
||||
portfolio = PortfolioFactory.create(owner=owner)
|
||||
application = ApplicationFactory.create(portfolio=portfolio)
|
||||
Applications.update(application, {"name": "Star Cruiser"})
|
||||
|
||||
events = AuditLog.get_portfolio_events(portfolio)
|
||||
|
||||
for event in events:
|
||||
assert event.portfolio_id == portfolio.id
|
||||
if event.resource_type == 'application':
|
||||
assert event.application_id == application.id
|
||||
pass
|
||||
|
||||
|
||||
def test_application_audit_log_does_not_include_portfolio_events():
|
||||
pass
|
||||
|
Loading…
x
Reference in New Issue
Block a user