def test_group_edge_roles_order_unchanged():
    # The order of the GROUP_EDGE_ROLES tuple matters:  new roles must be
    # appended.  This test attempts exposes that information to help prevent
    # that from happening accidentally.
    assert GROUP_EDGE_ROLES.index("member") == 0
    assert GROUP_EDGE_ROLES.index("manager") == 1
    assert GROUP_EDGE_ROLES.index("owner") == 2
    assert GROUP_EDGE_ROLES.index("np-owner") == 3
    def permission_grants_for_user(self, username):
        # type: (str) -> List[PermissionGrant]
        now = datetime.utcnow()
        user = User.get(self.session, name=username)
        if not user or user.role_user or user.is_service_account or not user.enabled:
            return []

        # Get the groups of which this user is a direct member.
        groups = (self.session.query(Group.id).join(
            GroupEdge, Group.id == GroupEdge.group_id).join(
                User, User.id == GroupEdge.member_pk).filter(
                    Group.enabled == True,
                    User.id == user.id,
                    GroupEdge.active == True,
                    GroupEdge.member_type == OBJ_TYPES["User"],
                    GroupEdge._role != GROUP_EDGE_ROLES.index("np-owner"),
                    or_(GroupEdge.expiration > now,
                        GroupEdge.expiration == None),
                ).distinct())
        group_ids = [g.id for g in groups]

        # If the user was not a member of any group, we can return early.
        if not group_ids:
            return []

        # Now, get the parent groups of those groups and so forth until we run out of levels of the
        # tree.  Use a set of seen group_ids to avoid querying the same group twice if a user is a
        # member of it via multiple paths.
        seen_group_ids = set(group_ids)
        while group_ids:
            parent_groups = (self.session.query(Group.id).join(
                GroupEdge, Group.id == GroupEdge.group_id).filter(
                    GroupEdge.member_pk.in_(group_ids),
                    Group.enabled == True,
                    GroupEdge.active == True,
                    GroupEdge.member_type == OBJ_TYPES["Group"],
                    GroupEdge._role != GROUP_EDGE_ROLES.index("np-owner"),
                    or_(GroupEdge.expiration > now,
                        GroupEdge.expiration == None),
                ).distinct())
            group_ids = [
                g.id for g in parent_groups if g.id not in seen_group_ids
            ]
            seen_group_ids.update(group_ids)

        # Return the permission grants.
        group_permission_grants = (self.session.query(
            Permission.name, PermissionMap.argument).filter(
                Permission.id == PermissionMap.permission_id,
                PermissionMap.group_id.in_(seen_group_ids),
            ).all())
        return [
            PermissionGrant(g.name, g.argument)
            for g in group_permission_grants
        ]
Exemple #3
0
def user_role_index(user, members):
    if user_is_group_admin(user.session, user):
        return GROUP_EDGE_ROLES.index("owner")
    member = members.get(("User", user.name))
    if not member:
        return None
    return member.role
Exemple #4
0
def user_role_index(user, members):
    if user_is_group_admin(user.session, user):
        return GROUP_EDGE_ROLES.index("owner")
    member = members.get(("User", user.name))
    if not member:
        return None
    return member.role
Exemple #5
0
def _create_edge(session, group, member, role):
    edge, new = GroupEdge.get_or_create(session,
                                        group_id=group.id,
                                        member_type=member.member_type,
                                        member_pk=member.id)

    if new:
        # TODO(herb): this means all requests by this user to this group will
        # have the same role. we should probably record the role specifically
        # on the request and use that as the source on the UI
        edge._role = GROUP_EDGE_ROLES.index(role)

    session.flush()

    return edge
Exemple #6
0
 def add_user_to_group(self, user, group, role="member"):
     # type: (str, str, str) -> None
     self.create_user(user)
     self.create_group(group)
     user_obj = User.get(self.session, name=user)
     assert user_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     edge = GroupEdge(
         group_id=group_obj.id,
         member_type=OBJ_TYPES["User"],
         member_pk=user_obj.id,
         active=True,
         _role=GROUP_EDGE_ROLES.index(role),
     )
     edge.add(self.session)
Exemple #7
0
 def add_group_to_group(self, member, group):
     # type: (str, str) -> None
     self.create_group(member)
     self.create_group(group)
     member_obj = Group.get(self.session, name=member)
     assert member_obj
     group_obj = Group.get(self.session, name=group)
     assert group_obj
     edge = GroupEdge(
         group_id=group_obj.id,
         member_type=OBJ_TYPES["Group"],
         member_pk=member_obj.id,
         active=True,
         _role=GROUP_EDGE_ROLES.index("member"),
     )
     edge.add(self.session)
Exemple #8
0
def _create_edge(session, group, member, role):
    edge, new = GroupEdge.get_or_create(
        session,
        group_id=group.id,
        member_type=member.member_type,
        member_pk=member.id
    )

    if new:
        # TODO(herb): this means all requests by this user to this group will
        # have the same role. we should probably record the role specifically
        # on the request and use that as the source on the UI
        edge._role = GROUP_EDGE_ROLES.index(role)

    session.flush()

    return edge
    def will_update_group_membership(self, session, group, member, **updates):
        if member.member_type != OBJ_TYPES["User"]:
            return

        check_permanent_owners = False

        if "role" in updates:
            role_idx = GROUP_EDGE_ROLES.index(updates["role"])
            if role_idx not in OWNER_ROLE_INDICES:
                check_permanent_owners = True

        if updates.get("expiration"):
            check_permanent_owners = True

        if "active" in updates and not updates["active"]:
            check_permanent_owners = True

        if check_permanent_owners and _is_last_permanent_owner(session, group, member):
            raise PluginRejectedGroupMembershipUpdate(EXCEPTION_MESSAGE)
    def will_update_group_membership(self, session, group, member, **updates):
        if member.member_type != OBJ_TYPES["User"]:
            return

        check_permanent_owners = False

        if "role" in updates:
            role_idx = GROUP_EDGE_ROLES.index(updates["role"])
            if role_idx not in OWNER_ROLE_INDICES:
                check_permanent_owners = True

        if updates.get("expiration"):
            check_permanent_owners = True

        if "active" in updates and not updates["active"]:
            check_permanent_owners = True

        if check_permanent_owners and _is_last_permanent_owner(session, group, member):
            raise PluginRejectedGroupMembershipUpdate(EXCEPTION_MESSAGE)
Exemple #11
0
 def groups_of_user(self, username):
     # type: (str) -> List[str]
     now = datetime.utcnow()
     user = User.get(self.session, name=username)
     if not user or user.role_user or user.is_service_account or not user.enabled:
         return []
     groups = (
         self.session.query(Group.groupname)
         .join(GroupEdge, Group.id == GroupEdge.group_id)
         .join(User, User.id == GroupEdge.member_pk)
         .filter(
             Group.enabled == True,
             User.id == user.id,
             GroupEdge.active == True,
             GroupEdge.member_type == OBJ_TYPES["User"],
             GroupEdge._role != GROUP_EDGE_ROLES.index("np-owner"),
             or_(GroupEdge.expiration > now, GroupEdge.expiration == None),
         )
         .distinct()
     )
     return [g.groupname for g in groups]