workspace -> portfolio everywhere

This commit is contained in:
dandds
2019-01-11 09:58:00 -05:00
parent 3fc323d785
commit d3d36822df
122 changed files with 2156 additions and 2129 deletions

View File

@@ -7,10 +7,10 @@ from .request_status_event import RequestStatusEvent
from .permissions import Permissions
from .role import Role
from .user import User
from .workspace_role import WorkspaceRole
from .portfolio_role import PortfolioRole
from .pe_number import PENumber
from .legacy_task_order import LegacyTaskOrder
from .workspace import Workspace
from .portfolio import Portfolio
from .application import Application
from .environment import Environment
from .attachment import Attachment

View File

@@ -14,7 +14,7 @@ class Application(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
description = Column(String, nullable=False)
workspace_id = Column(ForeignKey("workspaces.id"), nullable=False)
workspace = relationship("Workspace")
portfolio = relationship("Portfolio")
environments = relationship("Environment", back_populates="application")
@property
@@ -22,6 +22,6 @@ class Application(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
return self.name
def __repr__(self): # pragma: no cover
return "<Application(name='{}', description='{}', workspace='{}', id='{}')>".format(
self.name, self.description, self.workspace.name, self.id
return "<Application(name='{}', description='{}', portfolio='{}', id='{}')>".format(
self.name, self.description, self.portfolio.name, self.id
)

View File

@@ -15,7 +15,7 @@ class AuditEvent(Base, TimestampsMixin):
user = relationship("User", backref="audit_events")
workspace_id = Column(UUID(as_uuid=True), ForeignKey("workspaces.id"), index=True)
workspace = relationship("Workspace", backref="audit_events")
portfolio = relationship("Portfolio", backref="audit_events")
request_id = Column(UUID(as_uuid=True), ForeignKey("requests.id"), index=True)
request = relationship("Request", backref="audit_events")

View File

@@ -30,17 +30,17 @@ class Environment(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
return self.name
@property
def workspace(self):
return self.application.workspace
def portfolio(self):
return self.application.portfolio
def auditable_workspace_id(self):
def auditable_portfolio_id(self):
return self.application.workspace_id
def __repr__(self):
return "<Environment(name='{}', num_users='{}', application='{}', workspace='{}', id='{}')>".format(
return "<Environment(name='{}', num_users='{}', application='{}', portfolio='{}', id='{}')>".format(
self.name,
self.num_users,
self.application.name,
self.application.workspace.name,
self.application.portfolio.name,
self.id,
)

View File

@@ -47,8 +47,8 @@ class EnvironmentRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
"environment_id": str(self.environment_id),
"application": self.environment.application.name,
"application_id": str(self.environment.project_id),
"workspace": self.environment.application.workspace.name,
"workspace_id": str(self.environment.application.workspace.id),
"portfolio": self.environment.application.portfolio.name,
"portfolio_id": str(self.environment.application.portfolio.id),
}

View File

@@ -30,8 +30,8 @@ class Invitation(Base, TimestampsMixin, AuditableMixin):
workspace_role_id = Column(
UUID(as_uuid=True), ForeignKey("workspace_roles.id"), index=True
)
workspace_role = relationship(
"WorkspaceRole",
portfolio_role = relationship(
"PortfolioRole",
backref=backref("invitations", order_by="Invitation.time_created"),
)
@@ -47,8 +47,8 @@ class Invitation(Base, TimestampsMixin, AuditableMixin):
email = Column(String, nullable=False)
def __repr__(self):
return "<Invitation(user='{}', workspace_role='{}', id='{}', email='{}')>".format(
self.user_id, self.workspace_role_id, self.id, self.email
return "<Invitation(user='{}', portfolio_role='{}', id='{}', email='{}')>".format(
self.user_id, self.portfolio_role_id, self.id, self.email
)
@property
@@ -91,13 +91,13 @@ class Invitation(Base, TimestampsMixin, AuditableMixin):
]
@property
def workspace(self):
if self.workspace_role: # pragma: no branch
return self.workspace_role.workspace
def portfolio(self):
if self.portfolio_role: # pragma: no branch
return self.portfolio_role.portfolio
@property
def user_name(self):
return self.workspace_role.user.full_name
return self.portfolio_role.user.full_name
@property
def is_revokable(self):
@@ -122,5 +122,5 @@ class Invitation(Base, TimestampsMixin, AuditableMixin):
return change_set
@property
def workspace_id(self):
return self.workspace_role.workspace_id
def portfolio_id(self):
return self.portfolio_role.workspace_id

View File

@@ -13,7 +13,7 @@ class AuditableMixin(object):
@staticmethod
def create_audit_event(connection, resource, action):
user_id = getattr_path(g, "current_user.id")
workspace_id = resource.workspace_id
portfolio_id = resource.workspace_id
request_id = resource.request_id
resource_type = resource.resource_type
display_name = resource.displayname
@@ -23,7 +23,7 @@ class AuditableMixin(object):
audit_event = AuditEvent(
user_id=user_id,
workspace_id=workspace_id,
workspace_id=portfolio_id,
request_id=request_id,
resource_type=resource_type,
resource_id=resource.id,

View File

@@ -1,10 +1,10 @@
class Permissions(object):
VIEW_AUDIT_LOG = "view_audit_log"
VIEW_WORKSPACE_AUDIT_LOG = "view_workspace_audit_log"
REQUEST_JEDI_WORKSPACE = "request_jedi_workspace"
VIEW_WORKSPACE_AUDIT_LOG = "view_portfolio_audit_log"
REQUEST_JEDI_WORKSPACE = "request_jedi_portfolio"
VIEW_ORIGINAL_JEDI_REQEUST = "view_original_jedi_request"
REVIEW_AND_APPROVE_JEDI_WORKSPACE_REQUEST = (
"review_and_approve_jedi_workspace_request"
"review_and_approve_jedi_portfolio_request"
)
MODIFY_ATAT_ROLE_PERMISSIONS = "modify_atat_role_permissions"
CREATE_CSP_ROLE = "create_csp_role"
@@ -22,18 +22,18 @@ class Permissions(object):
VIEW_ASSIGNED_ATAT_ROLE_CONFIGURATIONS = "view_assigned_atat_role_configurations"
VIEW_ASSIGNED_CSP_ROLE_CONFIGURATIONS = "view_assigned_csp_role_configurations"
EDIT_WORKSPACE_INFORMATION = "edit_workspace_information"
DEACTIVATE_WORKSPACE = "deactivate_workspace"
EDIT_WORKSPACE_INFORMATION = "edit_portfolio_information"
DEACTIVATE_WORKSPACE = "deactivate_portfolio"
VIEW_ATAT_PERMISSIONS = "view_atat_permissions"
TRANSFER_OWNERSHIP_OF_WORKSPACE = "transfer_ownership_of_workspace"
VIEW_WORKSPACE_MEMBERS = "view_workspace_members"
VIEW_WORKSPACE = "view_workspace"
TRANSFER_OWNERSHIP_OF_WORKSPACE = "transfer_ownership_of_portfolio"
VIEW_WORKSPACE_MEMBERS = "view_portfolio_members"
VIEW_WORKSPACE = "view_portfolio"
ADD_APPLICATION_IN_WORKSPACE = "add_application_in_workspace"
DELETE_APPLICATION_IN_WORKSPACE = "delete_application_in_workspace"
DEACTIVATE_APPLICATION_IN_WORKSPACE = "deactivate_application_in_workspace"
VIEW_APPLICATION_IN_WORKSPACE = "view_application_in_workspace"
RENAME_APPLICATION_IN_WORKSPACE = "rename_application_in_workspace"
ADD_APPLICATION_IN_WORKSPACE = "add_application_in_portfolio"
DELETE_APPLICATION_IN_WORKSPACE = "delete_application_in_portfolio"
DEACTIVATE_APPLICATION_IN_WORKSPACE = "deactivate_application_in_portfolio"
VIEW_APPLICATION_IN_WORKSPACE = "view_application_in_portfolio"
RENAME_APPLICATION_IN_WORKSPACE = "rename_application_in_portfolio"
ADD_ENVIRONMENT_IN_APPLICATION = "add_environment_in_application"
DELETE_ENVIRONMENT_IN_APPLICATION = "delete_environment_in_application"
@@ -41,8 +41,8 @@ class Permissions(object):
VIEW_ENVIRONMENT_IN_APPLICATION = "view_environment_in_application"
RENAME_ENVIRONMENT_IN_APPLICATION = "rename_environment_in_application"
ADD_TAG_TO_WORKSPACE = "add_tag_to_workspace"
REMOVE_TAG_FROM_WORKSPACE = "remove_tag_from_workspace"
ADD_TAG_TO_WORKSPACE = "add_tag_to_portfolio"
REMOVE_TAG_FROM_WORKSPACE = "remove_tag_from_portfolio"
VIEW_TASK_ORDER = "view_task_order"
UPDATE_TASK_ORDER = "update_task_order"

View File

@@ -3,28 +3,28 @@ from sqlalchemy.orm import relationship
from itertools import chain
from atst.models import Base, mixins, types
from atst.models.workspace_role import WorkspaceRole, Status as WorkspaceRoleStatus
from atst.models.portfolio_role import PortfolioRole, Status as PortfolioRoleStatus
from atst.utils import first_or_none
from atst.database import db
class Workspace(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
class Portfolio(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
__tablename__ = "workspaces"
id = types.Id()
name = Column(String)
request_id = Column(ForeignKey("requests.id"), nullable=True)
applications = relationship("Application", back_populates="workspace")
roles = relationship("WorkspaceRole")
applications = relationship("Application", back_populates="portfolio")
roles = relationship("PortfolioRole")
task_orders = relationship("TaskOrder")
@property
def owner(self):
def _is_workspace_owner(workspace_role):
return workspace_role.role.name == "owner"
def _is_portfolio_owner(portfolio_role):
return portfolio_role.role.name == "owner"
owner = first_or_none(_is_workspace_owner, self.roles)
owner = first_or_none(_is_portfolio_owner, self.roles)
return owner.user if owner else None
@property
@@ -42,9 +42,9 @@ class Workspace(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
@property
def members(self):
return (
db.session.query(WorkspaceRole)
.filter(WorkspaceRole.workspace_id == self.id)
.filter(WorkspaceRole.status != WorkspaceRoleStatus.DISABLED)
db.session.query(PortfolioRole)
.filter(PortfolioRole.portfolio_id == self.id)
.filter(PortfolioRole.status != PortfolioRoleStatus.DISABLED)
.all()
)
@@ -56,10 +56,10 @@ class Workspace(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
def all_environments(self):
return list(chain.from_iterable(p.environments for p in self.applications))
def auditable_workspace_id(self):
def auditable_portfolio_id(self):
return self.id
def __repr__(self):
return "<Workspace(name='{}', request='{}', user_count='{}', id='{}')>".format(
return "<Portfolio(name='{}', request='{}', user_count='{}', id='{}')>".format(
self.name, self.request_id, self.user_count, self.id
)

View File

@@ -30,14 +30,14 @@ class Status(Enum):
PENDING = "pending"
class WorkspaceRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
class PortfolioRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
__tablename__ = "workspace_roles"
id = Id()
workspace_id = Column(
UUID(as_uuid=True), ForeignKey("workspaces.id"), index=True, nullable=False
)
workspace = relationship("Workspace", back_populates="roles")
portfolio = relationship("Portfolio", back_populates="roles")
role_id = Column(UUID(as_uuid=True), ForeignKey("roles.id"), nullable=False)
role = relationship("Role")
@@ -49,8 +49,8 @@ class WorkspaceRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
status = Column(SQLAEnum(Status, native_enum=False), default=Status.PENDING)
def __repr__(self):
return "<WorkspaceRole(role='{}', workspace='{}', user_id='{}', id='{}')>".format(
self.role.name, self.workspace.name, self.user_id, self.id
return "<PortfolioRole(role='{}', portfolio='{}', user_id='{}', id='{}')>".format(
self.role.name, self.portfolio.name, self.user_id, self.id
)
@property
@@ -127,8 +127,8 @@ class WorkspaceRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
db.session.query(EnvironmentRole)
.join(EnvironmentRole.environment)
.join(Environment.application)
.join(Application.workspace)
.filter(Application.workspace_id == self.workspace_id)
.join(Application.portfolio)
.filter(Application.portfolio_id == self.portfolio_id)
.filter(EnvironmentRole.user_id == self.user_id)
.count()
)
@@ -139,8 +139,8 @@ class WorkspaceRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
db.session.query(EnvironmentRole)
.join(EnvironmentRole.environment)
.join(Environment.application)
.join(Application.workspace)
.filter(Application.workspace_id == self.workspace_id)
.join(Application.portfolio)
.filter(Application.portfolio_id == self.portfolio_id)
.filter(EnvironmentRole.user_id == self.user_id)
.all()
)
@@ -157,8 +157,8 @@ class WorkspaceRole(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
Index(
"workspace_role_user_workspace",
WorkspaceRole.user_id,
WorkspaceRole.workspace_id,
"portfolio_role_user_portfolio",
PortfolioRole.user_id,
PortfolioRole.workspace_id,
unique=True,
)

View File

@@ -34,7 +34,7 @@ class Request(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
"RequestStatusEvent", backref="request", order_by="RequestStatusEvent.sequence"
)
workspace = relationship("Workspace", uselist=False, backref="request")
portfolio = relationship("Portfolio", uselist=False, backref="request")
user_id = Column(ForeignKey("users.id"), nullable=False)
creator = relationship("User", backref="owned_requests")

View File

@@ -25,7 +25,7 @@ class TaskOrder(Base, mixins.TimestampsMixin):
id = types.Id()
workspace_id = Column(ForeignKey("workspaces.id"))
workspace = relationship("Workspace")
portfolio = relationship("Portfolio")
user_id = Column(ForeignKey("users.id"))
creator = relationship("User", foreign_keys="TaskOrder.user_id")
@@ -92,7 +92,7 @@ class TaskOrder(Base, mixins.TimestampsMixin):
@property
def portfolio_name(self):
return self.workspace.name
return self.portfolio.name
@property
def is_pending(self):

View File

@@ -14,7 +14,7 @@ class User(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
atat_role_id = Column(UUID(as_uuid=True), ForeignKey("roles.id"))
atat_role = relationship("Role")
workspace_roles = relationship("WorkspaceRole", backref="user")
portfolio_roles = relationship("PortfolioRole", backref="user")
email = Column(String, unique=True)
dod_id = Column(String, unique=True, nullable=False)
@@ -65,22 +65,22 @@ class User(Base, mixins.TimestampsMixin, mixins.AuditableMixin):
return "{} {}".format(self.first_name, self.last_name)
@property
def has_workspaces(self):
def has_portfolios(self):
return (
Permissions.VIEW_WORKSPACE in self.atat_role.permissions
) or self.workspace_roles
) or self.portfolio_roles
@property
def displayname(self):
return self.full_name
def __repr__(self):
return "<User(name='{}', dod_id='{}', email='{}', role='{}', has_workspaces='{}', id='{}')>".format(
return "<User(name='{}', dod_id='{}', email='{}', role='{}', has_portfolios='{}', id='{}')>".format(
self.full_name,
self.dod_id,
self.email,
self.atat_role_name,
self.has_workspaces,
self.has_portfolios,
self.id,
)