Exemplo n.º 1
0
    def _announce_task(event, event_status):
        task_id = event['uuid']
        user_id, owner_id, dc_id = user_owner_dc_ids_from_task_id(task_id)

        if owner_id == internal_id:
            return  # probably beat task

        if event.get('queue', None) == 'mgmt':
            return  # sent task on mgmt

        if event.get('direct', None):
            # Send signal to ObjectOwner only
            users = (int(owner_id), )
        else:
            # Send signal to all affected users
            users = User.get_super_admin_ids()  # SuperAdmins
            users.update(User.get_dc_admin_ids(dc_id=dc_id))  # DcAdmins
            users.add(int(user_id))  # TaskCreator
            users.add(int(owner_id))  # ObjectOwner

        debug('Sending signal for %s task %s to %s', event_status, task_id,
              users)

        # Signal!
        for i in users:
            new_task = signal('task-for-%s' % i)
            new_task.send(event, task_id=task_id, event_status=event_status)
Exemplo n.º 2
0
    def delete(self):
        user = self.user
        # Predefined users can not be deleted
        if user.id in (settings.ADMIN_USER, settings.SYSTEM_USER, self.request.user.id):
            raise PermissionDenied

        relations = user.get_relations()
        if relations:
            message = {
                'detail': _('Cannot delete user, because he has relations to some objects.'),
                'relations': relations
            }
            return FailureTaskResponse(self.request, message, obj=user, dc_bound=False)

        dd = {'email': user.email, 'date_joined': user.date_joined}
        was_staff = user.is_staff
        old_roles = list(user.roles.all())
        ser = self.serializer(self.request, user)
        ser.object.delete()

        res = SuccessTaskResponse(self.request, None, obj=user, msg=LOG_USER_DELETE, detail_dict=dd, dc_bound=False)

        # User was removed, which may affect the cached list of DC admins for DCs which are attached to user's groups
        # So we need to clear the list of admins cached for each affected DC
        affected_dcs = Dc.objects.distinct().filter(roles__in=old_roles, roles__permissions__id=AdminPermission.id)
        for dc in affected_dcs:
            User.clear_dc_admin_ids(dc)

        if was_staff:
            User.clear_super_admin_ids()

        return res
Exemplo n.º 3
0
    def _announce_task(event, event_status):
        task_id = event['uuid']
        user_id, owner_id, dc_id = user_owner_dc_ids_from_task_id(task_id)

        if owner_id == internal_id:
            return  # probably beat task

        if event.get('queue', None) == 'mgmt':
            return  # sent task on mgmt

        if event.get('direct', None):
            # Send signal to ObjectOwner only
            users = (int(owner_id),)
        elif event.get('broadcast', None):
            # Send signal to all active socket.io sessions
            from sio.namespaces import ACTIVE_USERS
            users = set(session[0] for session in itervalues(ACTIVE_USERS))
        else:
            # Send signal to all affected users
            users = User.get_super_admin_ids()  # SuperAdmins
            users.update(User.get_dc_admin_ids(dc_id=dc_id))  # DcAdmins
            users.add(int(user_id))  # TaskCreator
            users.add(int(owner_id))  # ObjectOwner

        debug('Sending signal for %s task %s to %s', event_status, task_id, users)

        # Signal!
        for i in users:
            new_task = signal('task-for-%s' % i)
            new_task.send(event, task_id=task_id, event_status=event_status)
Exemplo n.º 4
0
    def user_modify(self, update=False, serializer=None):
        affected_groups = ()

        if not serializer:
            serializer = self.serializer

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

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

        ser.save()
        if update:
            msg = LOG_USER_UPDATE
            status = HTTP_200_OK
        else:
            msg = LOG_USER_CREATE
            status = HTTP_201_CREATED

        res = SuccessTaskResponse(self.request,
                                  ser.data,
                                  status=status,
                                  obj=user,
                                  msg=msg,
                                  owner=ser.object,
                                  detail_dict=ser.detail_dict(),
                                  dc_bound=False)

        if serializer == UserSerializer:
            # User's is_staff attribute was changed -> Clear the cached list of super admins
            if ser.is_staff_changed:
                User.clear_super_admin_ids()

            # User's groups were changed, which may affect the cached list of DC admins for DCs which are attached
            # to these groups. So we need to clear the list of admins cached for each affected DC
            # noinspection PyProtectedMember
            if user._roles_to_save is not None:
                # noinspection PyProtectedMember
                affected_groups = set(user._roles_to_save)
                affected_groups.update(ser.old_roles)
                affected_dcs = Dc.objects.distinct().filter(
                    roles__in=affected_groups,
                    roles__permissions__id=AdminPermission.id)
                for dc in affected_dcs:
                    User.clear_dc_admin_ids(dc)

            # User was removed from some groups and may loose access to DCs which are attached to this group
            # So we better set his current_dc to default_dc
            if ser.old_roles and not user.is_staff:
                user.reset_current_dc()

        connection.on_commit(lambda: user_relationship_changed.send(
            user_name=ser.object.username,
            affected_groups=tuple(group.id for group in affected_groups)))
        return res
Exemplo n.º 5
0
 def _update_affected_users(self, detach=False):
     # DC groups have changed -> invalidate the list of admins for this DC
     User.clear_dc_admin_ids(self.dc)
     # DC groups have changed on a non-default DC -> update the current_dc on every affected user
     # This is only required when the group is being removed from a DC and does not make sense when attaching
     if detach and not self.dc.is_default():
         for user in self.role.user_set.select_related('default_dc').filter(default_dc=self.dc)\
                                                                    .exclude(is_staff=True):
             user.reset_current_dc()
Exemplo n.º 6
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
Exemplo n.º 7
0
    def save(self, **kwargs):
        user = self.object
        new_flag = (not user.pk or getattr(user, 'new', False))
        user.save()

        if user._roles_to_save is not None:
            self.old_roles = set(user.roles.all())
            user.roles = user._roles_to_save

        # Newly created user via API is automatically marked as verified
        # Creator has to provide correct email, or in user profile set email as not verified (since email is required)!

        # Email change by user will trigger email with verification code so he can finish profile!
        # If admin doesnt set phone user is force to set it and when phone is changed sms verification is send
        if new_flag:
            user.userprofile.email_verified = True
            user.userprofile.phone_verified = True
            user.userprofile.save()

        # Changing a user email makes the email not verified
        # (unless request.user is not part of the staff or registration is disabled)
        if self.old_email and not self.request.user.is_staff and User.must_email_be_verified():
            user.userprofile.email_verified = False
            user.userprofile.email_token = user.userprofile.generate_token(6)
            user.userprofile.save()
            self.send_email_verification(user)
Exemplo n.º 8
0
def get_owners(request, dc=None, all=False, order_by=('username', )):
    """
    Return QuerySet of all active users. WARNING: Use with care!
    """
    dc = dc or request.dc
    qs = User.objects.exclude(id=settings.SYSTEM_USER).filter(
        is_active=True).order_by(*order_by).distinct()

    if all or dc.access == dc.PUBLIC:
        # Public DC is available for all active users
        return qs

    # Private DC is available to only staff, DC owner and DC admins ...
    admins = User.get_super_admin_ids()
    admins.update(User.get_dc_admin_ids(dc))

    # ... and users who have access to DC:
    return qs.filter(Q(id__in=admins) | Q(roles__in=dc.roles.all()))
Exemplo n.º 9
0
    def _announce_task(event, event_status):
        task_id = event['uuid']
        task_prefix = task_prefix_from_task_id(task_id)

        if task_prefix[2] == internal_id:  # owner_id
            return  # probably beat task

        if event.get('queue', None) == 'mgmt':
            return  # sent task on mgmt

        users = User.get_super_admin_ids()  # SuperAdmins
        users.update(User.get_dc_admin_ids(dc_id=task_prefix[4]))  # DcAdmins
        users.add(int(task_prefix[0]))  # TaskCreator
        users.add(int(task_prefix[2]))  # ObjectOwner
        debug('Sending signal for %s task %s to %s', event_status, task_id,
              users)

        # Signal!
        for i in users:
            new_task = signal('task-for-%s' % i)
            new_task.send(event, task_id=task_id, event_status=event_status)
Exemplo n.º 10
0
def log(msgdict):
    """
    Save msgdict into DB and cache.
    """
    # This dictionary can be store more than once
    dct = msgdict.copy()

    # DB
    TaskLogEntry.add(**msgdict)

    # Do not store PKs in cache
    dc_id = dct.pop('dc_id')
    owner_id = dct.pop('owner_id')
    del dct['user_id']
    del dct['object_pk']
    del dct['content_type']
    dct['time'] = dct['time'].isoformat()

    # Always store everything in staff cached task log
    _cache_log(_cache_log_key(settings.TASK_LOG_STAFF_ID, dc_id), dct)

    # Store owner relevant actions in owners cached task log
    if owner_id not in User.get_super_admin_ids():
        _cache_log(_cache_log_key(owner_id, dc_id), dct)
Exemplo n.º 11
0
 def _create_db_user():
     user = User()
     user.first_name = get_random_string(10)
     user.last_name = get_random_string(10)
     user.api_access = True
     user.is_active = True
     user.is_super_admin = False
     user.callback_key = '***'
     user.password = get_random_string(10)
     user.email = get_random_string(10) + '@' + get_random_string(
         10) + '.com'
     user.api_key = get_random_string(30)
     user.username = '******' + get_random_string(10)
     user.password = get_random_string(10)
     user.save()
     return user
Exemplo n.º 12
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
Exemplo n.º 13
0
 def _create_db_user(self):
     user = User()
     user.first_name = get_random_string(10)
     user.last_name = get_random_string(10)
     user.api_access = True
     user.is_active = True
     user.is_staff = False
     user.password = get_random_string(10)
     user.email = get_random_string(10) + '@' + get_random_string(10) + '.com'
     user.username = '******' + get_random_string(10)
     user.password = get_random_string(10)
     user.save()
     user.userprofile.alerting_email = user.email
     user.userprofile.alerting_phone = get_random_string(10)
     user.userprofile.alerting_jabber = 'jabber_' + user.email
     user.userprofile.save()
     return user