Merge branch 'master' into require-personal-info

This commit is contained in:
patricksmithdds
2018-10-31 14:12:55 -04:00
committed by GitHub
27 changed files with 661 additions and 85 deletions

View File

@@ -6,8 +6,7 @@ from atst.domain.exceptions import UnauthorizedError
class Authorization(object):
@classmethod
def has_workspace_permission(cls, user, workspace, permission):
workspace_user = WorkspaceUsers.get(workspace.id, user.id)
return permission in workspace_user.permissions()
return permission in WorkspaceUsers.workspace_user_permissions(workspace, user)
@classmethod
def has_atat_permission(cls, user, permission):

View File

@@ -0,0 +1,70 @@
import datetime
from sqlalchemy.orm.exc import NoResultFound
from atst.database import db
from atst.models.invitation import Invitation, Status as InvitationStatus
from atst.domain.workspace_users import WorkspaceUsers
from .exceptions import NotFoundError
class InvitationError(Exception):
def __init__(self, invite):
self.invite = invite
@property
def message(self):
return "{} has a status of {}".format(self.invite.id, self.invite.status.value)
class Invitations(object):
# number of minutes a given invitation is considered valid
EXPIRATION_LIMIT_MINUTES = 360
@classmethod
def _get(cls, token):
try:
invite = db.session.query(Invitation).filter_by(token=token).one()
except NoResultFound:
raise NotFoundError("invite")
return invite
@classmethod
def create(cls, workspace_role, inviter, user):
invite = Invitation(
workspace_role=workspace_role,
inviter=inviter,
user=user,
status=InvitationStatus.PENDING,
expiration_time=Invitations.current_expiration_time(),
)
db.session.add(invite)
db.session.commit()
return invite
@classmethod
def accept(cls, token):
invite = Invitations._get(token)
if invite.is_expired:
invite.status = InvitationStatus.REJECTED
elif invite.is_pending:
invite.status = InvitationStatus.ACCEPTED
db.session.add(invite)
db.session.commit()
if invite.is_revoked or invite.is_rejected:
raise InvitationError(invite)
WorkspaceUsers.enable(invite.workspace_role)
return invite
@classmethod
def current_expiration_time(cls):
return datetime.datetime.now() + datetime.timedelta(
minutes=Invitations.EXPIRATION_LIMIT_MINUTES
)

View File

@@ -89,3 +89,12 @@ class Users(object):
db.session.commit()
return user
@classmethod
def finalize(cls, user):
user.provisional = False
db.session.add(user)
db.session.commit()
return user

View File

@@ -1,7 +1,7 @@
from sqlalchemy.orm.exc import NoResultFound
from atst.database import db
from atst.models.workspace_role import WorkspaceRole
from atst.models.workspace_role import WorkspaceRole, Status as WorkspaceRoleStatus
from atst.models.workspace_user import WorkspaceUser
from atst.models.user import User
@@ -30,6 +30,30 @@ class WorkspaceUsers(object):
return WorkspaceUser(user, workspace_role)
@classmethod
def _get_active_workspace_role(cls, workspace_id, user_id):
try:
return (
db.session.query(WorkspaceRole)
.join(User)
.filter(User.id == user_id, WorkspaceRole.workspace_id == workspace_id)
.filter(WorkspaceRole.status == WorkspaceRoleStatus.ACTIVE)
.one()
)
except NoResultFound:
return None
@classmethod
def workspace_user_permissions(cls, workspace, user):
workspace_role = WorkspaceUsers._get_active_workspace_role(
workspace.id, user.id
)
atat_permissions = set(user.atat_role.permissions)
workspace_permissions = (
[] if workspace_role is None else workspace_role.role.permissions
)
return set(workspace_permissions).union(atat_permissions)
@classmethod
def _get_workspace_role(cls, user, workspace_id):
try:
@@ -123,3 +147,10 @@ class WorkspaceUsers(object):
db.session.commit()
return workspace_users
@classmethod
def enable(cls, workspace_role):
workspace_role.status = WorkspaceRoleStatus.ACTIVE
db.session.add(workspace_role)
db.session.commit()

View File

@@ -4,7 +4,7 @@ from atst.database import db
from atst.domain.common import Query
from atst.domain.exceptions import NotFoundError
from atst.models.workspace import Workspace
from atst.models.workspace_role import WorkspaceRole
from atst.models.workspace_role import WorkspaceRole, Status as WorkspaceRoleStatus
class WorkspacesQuery(Query):
@@ -25,9 +25,10 @@ class WorkspacesQuery(Query):
db.session.query(Workspace)
.join(WorkspaceRole)
.filter(WorkspaceRole.user == user)
.filter(WorkspaceRole.status == WorkspaceRoleStatus.ACTIVE)
.all()
)
@classmethod
def create_workspace_role(cls, user, role, workspace):
return WorkspaceRole(user=user, role=role, workspace=workspace)
def create_workspace_role(cls, user, role, workspace, **kwargs):
return WorkspaceRole(user=user, role=role, workspace=workspace, **kwargs)

View File

@@ -3,6 +3,7 @@ from atst.domain.authz import Authorization
from atst.models.permissions import Permissions
from atst.domain.users import Users
from atst.domain.workspace_users import WorkspaceUsers
from atst.models.workspace_role import Status as WorkspaceRoleStatus
from .query import WorkspacesQuery
from .scopes import ScopedWorkspace
@@ -13,7 +14,9 @@ class Workspaces(object):
def create(cls, request, name=None):
name = name or request.displayname
workspace = WorkspacesQuery.create(request=request, name=name)
Workspaces._create_workspace_role(request.creator, workspace, "owner")
Workspaces._create_workspace_role(
request.creator, workspace, "owner", status=WorkspaceRoleStatus.ACTIVE
)
WorkspacesQuery.add_and_commit(workspace)
return workspace
@@ -86,6 +89,7 @@ class Workspaces(object):
last_name=data["last_name"],
email=data["email"],
atat_role_name="default",
provisional=True,
)
return Workspaces.add_member(workspace, new_user, data["workspace_role"])
@@ -106,9 +110,13 @@ class Workspaces(object):
return WorkspaceUsers.update_role(member, workspace.id, role_name)
@classmethod
def _create_workspace_role(cls, user, workspace, role_name):
def _create_workspace_role(
cls, user, workspace, role_name, status=WorkspaceRoleStatus.PENDING
):
role = Roles.get(role_name)
workspace_role = WorkspacesQuery.create_workspace_role(user, role, workspace)
workspace_role = WorkspacesQuery.create_workspace_role(
user, role, workspace, status=status
)
WorkspacesQuery.add_and_commit(workspace_role)
return workspace_role