Esempio n. 1
0
    def put(self):
        dc = self.dc
        request = self.request

        ser = self.serializer(request, dc, data=self.data, partial=True)

        if not ser.is_valid():
            return FailureTaskResponse(request, ser.errors, obj=dc)

        ser.save()
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  obj=dc,
                                  detail_dict=ser.detail_dict(),
                                  msg=LOG_DC_UPDATE)
        task_id = res.data.get('task_id')
        # Changing DC groups affects the group.dc_bound flag
        if ser.groups_changed:
            # The groups that are removed or added should not be DC-bound anymore
            for group in ser.groups_changed:
                connection.on_commit(lambda: group_relationship_changed.send(
                    dc_name=dc.name, group_name=group.name))
                if group.dc_bound:
                    remove_dc_binding_virt_object(task_id,
                                                  LOG_GROUP_UPDATE,
                                                  group,
                                                  user=request.user)

        # After changing the DC owner or changing DC groups we have to invalidate the list of admins for this DC
        if ser.owner_changed or ser.groups_changed:
            connection.on_commit(
                lambda: dc_relationship_changed.send(dc_name=dc.name))
            User.clear_dc_admin_ids(dc)
            # Remove user.dc_bound flag for new DC owner
            # Remove user.dc_bound flag for users in new dc.groups, which are DC-bound, but not to this datacenter
            self._remove_user_dc_binding(task_id,
                                         owner=dc.owner,
                                         groups=ser.groups_added)

        # When a user is removed as owner from non-default DC or groups are changed on a non-default DC
        # we have to update the current_dc on every affected user, because he could remain access to this DC
        # (this is because get_dc() uses current_dc as a shortcut)
        if not dc.is_default():
            if ser.owner_changed and not ser.owner_changed.is_staff:
                ser.owner_changed.reset_current_dc()

            if ser.removed_users:
                for user in ser.removed_users.select_related(
                        'default_dc').exclude(is_staff=True):
                    user.reset_current_dc()

        return res
Esempio n. 2
0
    def delete(self):
        group = self.group
        dd = {
            'permissions':
            list(group.permissions.all().values_list('name', flat=True))
        }
        group.delete()
        connection.on_commit(
            lambda: group_relationship_changed.send(group_name=group.name))

        return SuccessTaskResponse(self.request,
                                   None,
                                   obj=group,
                                   msg=LOG_GROUP_DELETE,
                                   detail_dict=dd,
                                   dc_bound=False)
Esempio n. 3
0
    def delete(self):
        dc, group = self.dc, self.role

        if not group.dc_set.filter(id=dc.id).exists():
            raise ObjectNotFound(model=Role)

        ser = self.serializer(self.request, group)
        group.dc_set.remove(self.request.dc)
        connection.on_commit(lambda: group_relationship_changed.send(
            group_name=group.name, dc_name=dc.name))
        res = SuccessTaskResponse(self.request,
                                  None,
                                  obj=group,
                                  detail_dict=ser.detail_dict(),
                                  msg=LOG_GROUP_DETACH)
        self._remove_dc_binding(res)
        self._update_affected_users(detach=True)

        return res
Esempio n. 4
0
    def post(self):
        dc, group = self.dc, self.role

        if group.dc_set.filter(id=dc.id).exists():
            raise ObjectAlreadyExists(model=Role)

        ser = self.serializer(self.request, group)
        group.dc_set.add(dc)

        connection.on_commit(lambda: group_relationship_changed.send(
            group_name=group.name, dc_name=dc.name))
        res = SuccessTaskResponse(self.request,
                                  ser.data,
                                  obj=group,
                                  status=status.HTTP_201_CREATED,
                                  detail_dict=ser.detail_dict(),
                                  msg=LOG_GROUP_ATTACH)
        self._remove_dc_binding(res)
        self._remove_user_dc_binding(res)
        self._update_affected_users()

        return res
Esempio n. 5
0
    def group_modify(self, update=False):
        group = self.group
        request = self.request

        if update:
            # We are deleting users that are not assigned to group any more, so we have to store all of them before
            # deleting because we have to update task log for user so he can see he was removed from group
            original_group_users = set(
                group.user_set.select_related('dc_bound', 'default_dc').all())
        else:
            group.alias = group.name  # just a default
            original_group_users = set()

        ser = self.serializer(request, group, data=self.data, partial=update)

        if not ser.is_valid():
            return FailureTaskResponse(request,
                                       ser.errors,
                                       obj=group,
                                       dc_bound=False)

        ser.save()
        if update:
            msg = LOG_GROUP_UPDATE
            status = HTTP_200_OK
        else:
            msg = LOG_GROUP_CREATE
            status = HTTP_201_CREATED

        connection.on_commit(lambda: group_relationship_changed.send(
            group_name=ser.object.name))
        res = SuccessTaskResponse(request,
                                  ser.data,
                                  status=status,
                                  obj=group,
                                  msg=msg,
                                  detail_dict=ser.detail_dict(),
                                  dc_bound=False)

        # let's get the task_id so we use the same one for each log message
        task_id = res.data.get('task_id')
        removed_users = None

        if group.dc_bound and not update:
            attach_dc_virt_object(res.data.get('task_id'),
                                  LOG_GROUP_ATTACH,
                                  group,
                                  group.dc_bound,
                                  user=request.user)

        if ser.object._users_to_save is not None:
            # Update Users log that are attached to group
            current_users = set(ser.object._users_to_save)
            added_users = current_users - original_group_users
            removed_users = original_group_users - current_users
            affected_users = current_users.symmetric_difference(
                original_group_users)

            # Remove user.dc_bound flag for newly added users if group is attached to multiple DCs or
            #                                                          to one DC that is different from user.dc_bound
            if added_users:
                group_dcs_count = group.dc_set.count()

                if group_dcs_count >= 1:
                    if group_dcs_count == 1:
                        dc = group.dc_set.get()
                    else:
                        dc = None

                    for user in added_users:
                        remove_user_dc_binding(task_id, user, dc=dc)

            # Update Users that were removed from group or added to group
            for user in affected_users:
                detail = "groups='%s'" % ','.join(user.roles.all().values_list(
                    'name', flat=True))
                task_log_success(task_id,
                                 LOG_USER_UPDATE,
                                 obj=user,
                                 owner=user,
                                 update_user_tasks=False,
                                 detail=detail)

        # Permission or users for this group were changed, which may affect the cached list of DC admins for DCs which
        # are attached to this group. So we need to clear the list of admins cached for each affected DC
        if ser.object._permissions_to_save is not None or ser.object._users_to_save is not None:
            for dc in group.dc_set.all():
                User.clear_dc_admin_ids(dc)

            # Users were removed from this group and may loose access to DCs which are attached to this group
            # So we better set all users current_dc to default_dc
            if removed_users:
                for user in removed_users:
                    if not user.is_staff:
                        user.reset_current_dc()

        return res