mirror of https://github.com/jumpserver/jumpserver
user-group delete implement
parent
4e2a41f4cf
commit
f00da20764
|
@ -0,0 +1,38 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django.db import models
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class NoDeleteQuerySet(models.query.QuerySet):
|
||||
|
||||
def delete(self):
|
||||
return self.update(is_discard=True, discard_time=now())
|
||||
|
||||
|
||||
class NoDeleteManager(models.Manager):
|
||||
|
||||
def get_all(self):
|
||||
return NoDeleteQuerySet(self.model, using=self._db)
|
||||
|
||||
def get_queryset(self):
|
||||
return NoDeleteQuerySet(self.model, using=self._db).filter(is_discard=False)
|
||||
|
||||
def get_deleted(self):
|
||||
return NoDeleteQuerySet(self.model, using=self._db).filter(is_discard=True)
|
||||
|
||||
|
||||
class NoDeleteModelMixin(models.Model):
|
||||
is_discard = models.BooleanField(verbose_name=_("is discard"), default=False)
|
||||
discard_time = models.DateTimeField(verbose_name=_("discard time"), null=True, blank=True)
|
||||
|
||||
objects = NoDeleteManager()
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def delete(self):
|
||||
self.is_discard = True
|
||||
self.discard_time = now()
|
||||
return self.save()
|
|
@ -6,7 +6,7 @@ import logging
|
|||
from rest_framework import generics
|
||||
|
||||
from .serializers import UserSerializer, UserGroupSerializer, UserAttributeSerializer, UserGroupEditSerializer, \
|
||||
UserPKUpdateSerializer
|
||||
GroupEditSerializer, UserPKUpdateSerializer
|
||||
from .models import User, UserGroup
|
||||
|
||||
|
||||
|
@ -87,3 +87,8 @@ class UserUpdatePKApi(generics.UpdateAPIView):
|
|||
user = self.get_object()
|
||||
user.private_key = serializer.validated_data['_public_key']
|
||||
user.save()
|
||||
|
||||
|
||||
class GroupDeleteApi(generics.DestroyAPIView):
|
||||
queryset = UserGroup.objects.all()
|
||||
serializer_class = GroupEditSerializer
|
||||
|
|
|
@ -4,19 +4,22 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.utils import timezone
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.core import signing
|
||||
from django.db import models, IntegrityError
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
from django.utils import timezone
|
||||
from django.db import IntegrityError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core import signing
|
||||
|
||||
from rest_framework.authtoken.models import Token
|
||||
|
||||
from common.utils import encrypt, decrypt, date_expired_default
|
||||
from common.mixins import NoDeleteModelMixin
|
||||
|
||||
|
||||
class UserGroup(models.Model):
|
||||
class UserGroup(NoDeleteModelMixin):
|
||||
name = models.CharField(max_length=100, unique=True, verbose_name=_('Name'))
|
||||
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||
date_created = models.DateTimeField(auto_now_add=True)
|
||||
|
@ -30,14 +33,20 @@ class UserGroup(models.Model):
|
|||
return True
|
||||
return False
|
||||
|
||||
def delete(self):
|
||||
if self.name != 'Default':
|
||||
self.users.clear()
|
||||
return super(UserGroup, self).delete()
|
||||
return True
|
||||
|
||||
class Meta:
|
||||
db_table = 'user_group'
|
||||
db_table = 'user-group'
|
||||
|
||||
@classmethod
|
||||
def initial(cls):
|
||||
group_or_create = cls.objects.get_or_create(name='Default', comment='Default user group for all user',
|
||||
created_by='System')
|
||||
return group_or_create[0]
|
||||
group, created = cls.objects.get_or_create(name='Default', comment='Default user group for all user',
|
||||
created_by='System')
|
||||
return group
|
||||
|
||||
@classmethod
|
||||
def generate_fake(cls, count=100):
|
||||
|
@ -48,8 +57,7 @@ class UserGroup(models.Model):
|
|||
for i in range(count):
|
||||
group = cls(name=forgery_py.name.full_name(),
|
||||
comment=forgery_py.lorem_ipsum.sentence(),
|
||||
created_by=choice(User.objects.all()).username
|
||||
)
|
||||
created_by=choice(User.objects.all()).username)
|
||||
try:
|
||||
group.save()
|
||||
except IntegrityError:
|
||||
|
@ -76,11 +84,10 @@ class User(AbstractUser):
|
|||
_private_key = models.CharField(max_length=5000, blank=True, verbose_name=_('ssh private key'))
|
||||
_public_key = models.CharField(max_length=1000, blank=True, verbose_name=_('ssh public key'))
|
||||
comment = models.TextField(max_length=200, blank=True, verbose_name=_('Comment'))
|
||||
is_first_login = models.BooleanField(default=True)
|
||||
is_first_login = models.BooleanField(default=False)
|
||||
date_expired = models.DateTimeField(default=date_expired_default, blank=True, null=True,
|
||||
verbose_name=_('Date expired'))
|
||||
created_by = models.CharField(max_length=30, default='', verbose_name=_('Created by'))
|
||||
is_public_key_valid = models.BooleanField(default=False)
|
||||
|
||||
@property
|
||||
def password_raw(self):
|
||||
|
@ -144,17 +151,13 @@ class User(AbstractUser):
|
|||
pass
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
# If user not set name, it's default equal username
|
||||
if not self.name:
|
||||
self.name = self.username
|
||||
|
||||
super(User, self).save(*args, **kwargs)
|
||||
# Set user default group 'All'
|
||||
# Todo: It's have bug
|
||||
# Add the current user to the default group.
|
||||
group = UserGroup.initial()
|
||||
if group not in self.groups.all():
|
||||
self.groups.add(group)
|
||||
# super(User, self).save(*args, **kwargs)
|
||||
self.groups.add(group)
|
||||
|
||||
@property
|
||||
def private_token(self):
|
||||
|
@ -227,8 +230,7 @@ class User(AbstractUser):
|
|||
role=choice(dict(User.ROLE_CHOICES).keys()),
|
||||
wechat=forgery_py.internet.user_name(True),
|
||||
comment=forgery_py.lorem_ipsum.sentence(),
|
||||
created_by=choice(cls.objects.all()).username,
|
||||
)
|
||||
created_by=choice(cls.objects.all()).username)
|
||||
try:
|
||||
user.save()
|
||||
except IntegrityError:
|
||||
|
@ -240,13 +242,13 @@ class User(AbstractUser):
|
|||
|
||||
def init_all_models():
|
||||
for model in (UserGroup, User):
|
||||
if hasattr(model, b'initial'):
|
||||
if hasattr(model, 'initial'):
|
||||
model.initial()
|
||||
|
||||
|
||||
def generate_fake():
|
||||
for model in (UserGroup, User):
|
||||
if hasattr(model, b'generate_fake'):
|
||||
if hasattr(model, 'generate_fake'):
|
||||
model.generate_fake()
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from rest_framework import serializers
|
||||
|
@ -27,6 +26,13 @@ class UserGroupSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
|
||||
class GroupEditSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = UserGroup
|
||||
fields = ['id', 'name', 'comment', 'date_created', 'created_by']
|
||||
|
||||
|
||||
class UserAttributeSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
{% extends '_list_base.html' %}
|
||||
{% load i18n %}
|
||||
{% load i18n static %}
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
|
||||
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content_left_head %}
|
||||
<a href="{% url 'users:user-group-create' %}" class="btn btn-sm btn-primary ">{% trans "Add User Group" %}</a>
|
||||
{% endblock %}
|
||||
|
@ -30,8 +35,9 @@
|
|||
<td class="text-center">999</td>
|
||||
<th class="text-center">{{ user_group.comment|truncatewords:8 }}</th>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'users:user-group-update' pk=user_group.id %}" class="btn btn-xs btn-info">编辑</a>
|
||||
<a href="{% url 'users:user-group-delete' pk=user_group.id %}" class="btn btn-xs btn-danger del">删除</a>
|
||||
<a href="{% url 'users:user-group-update' pk=user_group.id %}" class="btn btn-xs btn-info">{% trans "Edit" %}</a>
|
||||
<a href="javascript:void(0)" data-gid="{{ user_group.id }}"
|
||||
class="btn btn-xs btn-danger del {% ifequal user_group.name 'Default' %}disabled{% else %}btn_delete_user_group{% endifequal %}">{% trans "Delete" %}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
@ -52,3 +58,42 @@
|
|||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
$(document).on('click', '.btn_delete_user_group', function(){
|
||||
var $this = $(this);
|
||||
function doDelete() {
|
||||
var group_id = $this.data('gid');
|
||||
var the_url = "{% url 'users:user-group-delete-api' 99991937 %}".replace('99991937', group_id);
|
||||
var body = {};
|
||||
var success = function() {
|
||||
var msg = "{% trans 'Group Deleted.' %}";
|
||||
swal("{% trans 'Group Delete' %}", msg, "success");
|
||||
$this.closest('tr.gradeX').remove();
|
||||
};
|
||||
var fail = function() {
|
||||
var msg = "{% trans 'Group Deleting failed.' %}";
|
||||
swal("{% trans 'Group Delete' %}", msg, "error");
|
||||
}
|
||||
APIUpdateAttr({
|
||||
url: the_url,
|
||||
body: JSON.stringify(body),
|
||||
method: 'DELETE',
|
||||
success: success,
|
||||
error: fail
|
||||
});
|
||||
}
|
||||
swal({
|
||||
title: "{% trans 'Are you sure?' %}",
|
||||
text: "{% trans 'This will delete the selected group, but will not remove any user in this group.' %}",
|
||||
type: "warning",
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: "#DD6B55",
|
||||
confirmButtonText: "{% trans 'Confirm' %}",
|
||||
closeOnConfirm: false
|
||||
}, function() {
|
||||
doDelete();
|
||||
});
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
|
|
@ -22,8 +22,7 @@ urlpatterns = [
|
|||
name='user-asset-permission-create'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/granted-asset', views.UserGrantedAssetView.as_view(), name='user-granted-asset'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'),
|
||||
url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
|
||||
url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'), url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
|
||||
url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/delete$', views.UserDeleteView.as_view(), name='user-delete'),
|
||||
|
@ -31,7 +30,6 @@ urlpatterns = [
|
|||
url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'),
|
||||
url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'),
|
||||
url(r'^user-group/(?P<pk>[0-9]+)/update$', views.UserGroupUpdateView.as_view(), name='user-group-update'),
|
||||
url(r'^user-group/(?P<pk>[0-9]+)/delete$', views.UserGroupDeleteView.as_view(), name='user-group-delete'),
|
||||
]
|
||||
|
||||
|
||||
|
@ -49,4 +47,6 @@ urlpatterns += [
|
|||
api.UserGroupDetailDeleteUpdateApi.as_view(), name='user-group-detail-api'),
|
||||
url(r'^v1/user-groups/(?P<pk>[0-9]+)/edit$',
|
||||
api.UserGroupEditApi.as_view(), name='user-group-edit-api'),
|
||||
url(r'^v1/user-groups/(?P<pk>[0-9]+)/delete/$', api.GroupDeleteApi.as_view(),
|
||||
name='user-group-delete-api'),
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue