143 lines
4.5 KiB
Python
143 lines
4.5 KiB
Python
from itertools import groupby
|
|
from typing import List
|
|
from uuid import UUID
|
|
|
|
from sqlalchemy.orm.exc import NoResultFound
|
|
from sqlalchemy import func, and_, or_
|
|
|
|
from atat.database import db
|
|
from atat.domain.environment_roles import EnvironmentRoles
|
|
from atat.models import Application, ApplicationRole, ApplicationRoleStatus, Portfolio
|
|
from .permission_sets import PermissionSets
|
|
from .exceptions import NotFoundError
|
|
|
|
|
|
class ApplicationRoles(object):
|
|
@classmethod
|
|
def _permission_sets_for_names(cls, set_names):
|
|
set_names = set(set_names).union({PermissionSets.VIEW_APPLICATION})
|
|
return PermissionSets.get_many(set_names)
|
|
|
|
@classmethod
|
|
def create(cls, user, application, permission_set_names):
|
|
application_role = ApplicationRole(
|
|
user=user, application_id=application.id, application=application
|
|
)
|
|
|
|
application_role.permission_sets = ApplicationRoles._permission_sets_for_names(
|
|
permission_set_names
|
|
)
|
|
|
|
db.session.add(application_role)
|
|
db.session.commit()
|
|
|
|
return application_role
|
|
|
|
@classmethod
|
|
def enable(cls, role, user):
|
|
role.status = ApplicationRoleStatus.ACTIVE
|
|
role.user = user
|
|
|
|
db.session.add(role)
|
|
db.session.commit()
|
|
|
|
@classmethod
|
|
def get(cls, user_id, application_id):
|
|
try:
|
|
app_role = (
|
|
db.session.query(ApplicationRole)
|
|
.filter_by(user_id=user_id, application_id=application_id)
|
|
.one()
|
|
)
|
|
except NoResultFound:
|
|
raise NotFoundError("application_role")
|
|
|
|
return app_role
|
|
|
|
@classmethod
|
|
def get_by_id(cls, id_):
|
|
try:
|
|
return (
|
|
db.session.query(ApplicationRole)
|
|
.filter(ApplicationRole.id == id_)
|
|
.filter(ApplicationRole.status != ApplicationRoleStatus.DISABLED)
|
|
.one()
|
|
)
|
|
except NoResultFound:
|
|
raise NotFoundError("application_role")
|
|
|
|
@classmethod
|
|
def get_many(cls, ids):
|
|
return (
|
|
db.session.query(ApplicationRole)
|
|
.filter(ApplicationRole.id.in_(ids))
|
|
.filter(ApplicationRole.status != ApplicationRoleStatus.DISABLED)
|
|
.all()
|
|
)
|
|
|
|
@classmethod
|
|
def update_permission_sets(cls, application_role, new_perm_sets_names):
|
|
application_role.permission_sets = ApplicationRoles._permission_sets_for_names(
|
|
new_perm_sets_names
|
|
)
|
|
|
|
db.session.add(application_role)
|
|
db.session.commit()
|
|
|
|
return application_role
|
|
|
|
@classmethod
|
|
def _update_status(cls, application_role, new_status):
|
|
application_role.status = new_status
|
|
db.session.add(application_role)
|
|
db.session.commit()
|
|
|
|
return application_role
|
|
|
|
@classmethod
|
|
def disable(cls, application_role):
|
|
cls._update_status(application_role, ApplicationRoleStatus.DISABLED)
|
|
application_role.deleted = True
|
|
|
|
for env in application_role.application.environments:
|
|
EnvironmentRoles.delete(
|
|
application_role_id=application_role.id, environment_id=env.id
|
|
)
|
|
|
|
db.session.add(application_role)
|
|
db.session.commit()
|
|
|
|
@classmethod
|
|
def get_pending_creation(cls) -> List[List[UUID]]:
|
|
"""
|
|
Returns a list of lists of ApplicationRole IDs. The IDs
|
|
should be grouped by user and portfolio.
|
|
"""
|
|
results = (
|
|
db.session.query(ApplicationRole.id, ApplicationRole.user_id, Portfolio.id)
|
|
.join(Application, Application.id == ApplicationRole.application_id)
|
|
.join(Portfolio, Portfolio.id == Application.portfolio_id)
|
|
.filter(
|
|
and_(
|
|
Application.cloud_id.isnot(None),
|
|
ApplicationRole.deleted == False,
|
|
ApplicationRole.cloud_id.is_(None),
|
|
ApplicationRole.user_id.isnot(None),
|
|
ApplicationRole.status == ApplicationRoleStatus.ACTIVE,
|
|
or_(
|
|
ApplicationRole.claimed_until.is_(None),
|
|
ApplicationRole.claimed_until <= func.now(),
|
|
),
|
|
)
|
|
)
|
|
).all()
|
|
|
|
groups = []
|
|
keyfunc = lambda pair: (pair[1], pair[2])
|
|
sorted_results = sorted(results, key=keyfunc)
|
|
for _, g in groupby(sorted_results, keyfunc):
|
|
group = [pair[0] for pair in list(g)]
|
|
groups.append(group)
|
|
|
|
return groups
|