Merge pull request #802 from dod-ccpo/accept-application-invite

Accept application invite
This commit is contained in:
dandds
2019-05-06 14:30:54 -04:00
committed by GitHub
13 changed files with 177 additions and 50 deletions

View File

@@ -1,5 +1,5 @@
from atst.database import db
from atst.models.application_role import ApplicationRole
from atst.models import ApplicationRole, ApplicationRoleStatus
from atst.domain.permission_sets import PermissionSets
@@ -21,3 +21,10 @@ class ApplicationRoles(object):
db.session.commit()
return application_role
@classmethod
def enable(cls, role):
role.status = ApplicationRoleStatus.ACTIVE
db.session.add(role)
db.session.commit()

View File

@@ -6,9 +6,7 @@ from atst.domain.application_roles import ApplicationRoles
from atst.domain.environments import Environments
from atst.domain.exceptions import NotFoundError
from atst.domain.users import Users
from atst.models.application import Application
from atst.models.environment import Environment
from atst.models.environment_role import EnvironmentRole
from atst.models import Application, ApplicationRole, ApplicationRoleStatus
class Applications(BaseDomainClass):
@@ -31,10 +29,11 @@ class Applications(BaseDomainClass):
def for_user(self, user, portfolio):
return (
db.session.query(Application)
.join(Environment)
.join(EnvironmentRole)
.join(ApplicationRole)
.filter(Application.portfolio_id == portfolio.id)
.filter(EnvironmentRole.user_id == user.id)
.filter(ApplicationRole.application_id == Application.id)
.filter(ApplicationRole.user_id == user.id)
.filter(ApplicationRole.status == ApplicationRoleStatus.ACTIVE)
.all()
)

View File

@@ -1,7 +1,6 @@
from atst.domain.authz import Authorization
from atst.models.permissions import Permissions
from atst.domain.applications import Applications
from atst.domain.environments import Environments
class ScopedResource(object):
@@ -35,31 +34,6 @@ class ScopedPortfolio(ScopedResource):
)
if can_view_all_applications:
applications = self.resource.applications
return self.resource.applications
else:
applications = Applications.for_user(self.user, self.resource)
return [
ScopedApplication(self.user, application) for application in applications
]
class ScopedApplication(ScopedResource):
"""
An object that obeys the same API as a Portfolio, but with the added
functionality that it only returns sub-resources (environments)
that the given user is allowed to see.
"""
@property
def environments(self):
can_view_all_environments = Authorization.has_portfolio_permission(
self.user, self.resource.portfolio, Permissions.VIEW_ENVIRONMENT
)
if can_view_all_environments:
environments = self.resource.environments
else:
environments = Environments.for_user(self.user, self.resource)
return environments
return Applications.for_user(self.user, self.resource)

View File

@@ -62,7 +62,13 @@ class ApplicationRole(
@property
def history(self):
return self.get_changes()
previous_state = self.get_changes()
change_set = {}
if "status" in previous_state:
from_status = previous_state["status"][0].value
to_status = self.status.value
change_set["status"] = [from_status, to_status]
return change_set
def has_permission_set(self, perm_set_name):
return first_or_none(

View File

@@ -6,6 +6,7 @@ from . import index
from . import new
from . import settings
from . import team
from . import invitations
from atst.domain.environment_roles import EnvironmentRoles
from atst.domain.exceptions import UnauthorizedError
from atst.domain.authz.decorator import user_can_access_decorator as user_can

View File

@@ -5,7 +5,21 @@ from atst.domain.authz.decorator import user_can_access_decorator as user_can
from atst.models.permissions import Permissions
def has_portfolio_applications(_user, portfolio=None, **_kwargs):
"""
If the portfolio exists and the user has access to applications
within the scoped portfolio, the user has access to the
portfolio landing page.
"""
if portfolio and portfolio.applications:
return True
@applications_bp.route("/portfolios/<portfolio_id>/applications")
@user_can(Permissions.VIEW_APPLICATION, message="view portfolio applications")
@user_can(
Permissions.VIEW_APPLICATION,
override=has_portfolio_applications,
message="view portfolio applications",
)
def portfolio_applications(portfolio_id):
return render_template("portfolios/applications/index.html")

View File

@@ -0,0 +1,16 @@
from flask import redirect, url_for, g
from . import applications_bp
from atst.domain.invitations import ApplicationInvitations
@applications_bp.route("/applications/invitations/<token>", methods=["GET"])
def accept_invitation(token):
invite = ApplicationInvitations.accept(g.current_user, token)
return redirect(
url_for(
"applications.portfolio_applications",
portfolio_id=invite.application.portfolio_id,
)
)