mirror of https://github.com/jumpserver/jumpserver
[Update] 修改assets users api
parent
f10a7a75ae
commit
e8ebc94191
|
@ -40,9 +40,8 @@ class AssetUser(OrgModelMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def private_key_obj(self):
|
def private_key_obj(self):
|
||||||
if self._private_key:
|
if self.private_key:
|
||||||
key_str = signer.unsign(self._private_key)
|
return ssh_key_string_to_obj(self.private_key, password=self.password)
|
||||||
return ssh_key_string_to_obj(key_str, password=self.password)
|
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -52,8 +51,7 @@ class AssetUser(OrgModelMixin):
|
||||||
return None
|
return None
|
||||||
project_dir = settings.PROJECT_DIR
|
project_dir = settings.PROJECT_DIR
|
||||||
tmp_dir = os.path.join(project_dir, 'tmp')
|
tmp_dir = os.path.join(project_dir, 'tmp')
|
||||||
key_str = signer.unsign(self._private_key)
|
key_name = '.' + md5(self.private_key.encode('utf-8')).hexdigest()
|
||||||
key_name = '.' + md5(key_str.encode('utf-8')).hexdigest()
|
|
||||||
key_path = os.path.join(tmp_dir, key_name)
|
key_path = os.path.join(tmp_dir, key_name)
|
||||||
if not os.path.exists(key_path):
|
if not os.path.exists(key_path):
|
||||||
self.private_key_obj.write_private_key_file(key_path)
|
self.private_key_obj.write_private_key_file(key_path)
|
||||||
|
|
|
@ -15,20 +15,20 @@ class AdminUserSerializer(BulkOrgResourceModelSerializer):
|
||||||
"""
|
"""
|
||||||
管理用户
|
管理用户
|
||||||
"""
|
"""
|
||||||
password = serializers.CharField(
|
|
||||||
required=False, write_only=True, label=_('Password')
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
list_serializer_class = AdaptedBulkListSerializer
|
list_serializer_class = AdaptedBulkListSerializer
|
||||||
model = AdminUser
|
model = AdminUser
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'username', 'password', 'comment',
|
'id', 'name', 'username', 'password', 'private_key', 'public_key',
|
||||||
'connectivity_amount', 'assets_amount',
|
'comment', 'connectivity_amount', 'assets_amount',
|
||||||
'date_created', 'date_updated', 'created_by',
|
'date_created', 'date_updated', 'created_by',
|
||||||
]
|
]
|
||||||
|
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
|
'password': {"write_only": True},
|
||||||
|
'private_key': {"write_only": True},
|
||||||
|
'public_key': {"write_only": True},
|
||||||
'date_created': {'read_only': True},
|
'date_created': {'read_only': True},
|
||||||
'date_updated': {'read_only': True},
|
'date_updated': {'read_only': True},
|
||||||
'created_by': {'read_only': True},
|
'created_by': {'read_only': True},
|
||||||
|
|
|
@ -29,18 +29,6 @@ class AssetUserSerializer(BulkOrgResourceModelSerializer):
|
||||||
ip = serializers.CharField(read_only=True, label=_("IP"))
|
ip = serializers.CharField(read_only=True, label=_("IP"))
|
||||||
connectivity = ConnectivitySerializer(read_only=True, label=_("Connectivity"))
|
connectivity = ConnectivitySerializer(read_only=True, label=_("Connectivity"))
|
||||||
|
|
||||||
password = serializers.CharField(
|
|
||||||
max_length=256, allow_blank=True, allow_null=True, write_only=True,
|
|
||||||
required=False, label=_('Password')
|
|
||||||
)
|
|
||||||
public_key = serializers.CharField(
|
|
||||||
max_length=4096, allow_blank=True, allow_null=True, write_only=True,
|
|
||||||
required=False, label=_('Public key')
|
|
||||||
)
|
|
||||||
private_key = serializers.CharField(
|
|
||||||
max_length=4096, allow_blank=True, allow_null=True, write_only=True,
|
|
||||||
required=False, label=_('Private key')
|
|
||||||
)
|
|
||||||
backend = serializers.CharField(read_only=True, label=_("Backend"))
|
backend = serializers.CharField(read_only=True, label=_("Backend"))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -57,6 +45,9 @@ class AssetUserSerializer(BulkOrgResourceModelSerializer):
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'username': {'required': True},
|
'username': {'required': True},
|
||||||
|
'password': {'write_only': True},
|
||||||
|
'private_key': {'write_only': True},
|
||||||
|
'public_key': {'write_only': True},
|
||||||
}
|
}
|
||||||
|
|
||||||
def validate_private_key(self, key):
|
def validate_private_key(self, key):
|
||||||
|
@ -67,17 +58,9 @@ class AssetUserSerializer(BulkOrgResourceModelSerializer):
|
||||||
return key
|
return key
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
kwargs = {
|
if not validated_data.get("name") and validated_data.get("username"):
|
||||||
'name': validated_data.get('username'),
|
validated_data["name"] = validated_data["username"]
|
||||||
'username': validated_data.get('username'),
|
instance = AssetUserManager.create(**validated_data)
|
||||||
'asset': validated_data.get('asset'),
|
|
||||||
'comment': validated_data.get('comment', ''),
|
|
||||||
'org_id': validated_data.get('org_id', ''),
|
|
||||||
'password': validated_data.get('password'),
|
|
||||||
'public_key': validated_data.get('public_key'),
|
|
||||||
'private_key': validated_data.get('private_key')
|
|
||||||
}
|
|
||||||
instance = AssetUserManager.create(**kwargs)
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,20 @@ class SystemUserSerializer(BulkOrgResourceModelSerializer):
|
||||||
"""
|
"""
|
||||||
系统用户
|
系统用户
|
||||||
"""
|
"""
|
||||||
password = serializers.CharField(
|
|
||||||
required=False, write_only=True, label=_('Password')
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SystemUser
|
model = SystemUser
|
||||||
list_serializer_class = AdaptedBulkListSerializer
|
list_serializer_class = AdaptedBulkListSerializer
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'username', 'login_mode', 'login_mode_display',
|
'id', 'name', 'username', 'password', 'public_key', 'private_key',
|
||||||
'priority', 'protocol', 'auto_push', 'password',
|
'login_mode', 'login_mode_display', 'priority', 'protocol',
|
||||||
'cmd_filters', 'sudo', 'shell', 'comment', 'nodes', 'assets',
|
'auto_push', 'cmd_filters', 'sudo', 'shell', 'comment', 'nodes',
|
||||||
'assets_amount', 'connectivity_amount'
|
'assets', 'assets_amount', 'connectivity_amount'
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
|
'password': {"write_only": True},
|
||||||
|
'public_key': {"write_only": True},
|
||||||
|
'private_key': {"write_only": True},
|
||||||
'assets_amount': {'label': _('Asset')},
|
'assets_amount': {'label': _('Asset')},
|
||||||
'connectivity_amount': {'label': _('Connectivity')},
|
'connectivity_amount': {'label': _('Connectivity')},
|
||||||
'login_mode_display': {'label': _('Login mode display')},
|
'login_mode_display': {'label': _('Login mode display')},
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
from werkzeug.local import Local
|
||||||
|
|
||||||
|
thread_local = Local()
|
||||||
|
|
||||||
|
|
||||||
|
def _find(attr):
|
||||||
|
return getattr(thread_local, attr, None)
|
|
@ -3,12 +3,13 @@
|
||||||
import re
|
import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.dispatch import receiver
|
||||||
from django.core.signals import request_finished
|
from django.core.signals import request_finished
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
|
|
||||||
|
|
||||||
from .utils import get_logger
|
from .utils import get_logger
|
||||||
|
from .local import thread_local
|
||||||
|
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
pattern = re.compile(r'FROM `(\w+)`')
|
pattern = re.compile(r'FROM `(\w+)`')
|
||||||
|
@ -50,6 +51,11 @@ def on_request_finished_logging_db_query(sender, **kwargs):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(request_finished)
|
||||||
|
def on_request_finished_release_local(sender, **kwargs):
|
||||||
|
thread_local.__release_local__()
|
||||||
|
|
||||||
|
|
||||||
if settings.DEBUG:
|
if settings.DEBUG:
|
||||||
request_finished.connect(on_request_finished_logging_db_query)
|
request_finished.connect(on_request_finished_logging_db_query)
|
||||||
|
|
||||||
|
|
|
@ -176,125 +176,6 @@ def with_cache(func):
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class LocalProxy(object):
|
|
||||||
|
|
||||||
"""
|
|
||||||
Copy from werkzeug.local.LocalProxy
|
|
||||||
"""
|
|
||||||
__slots__ = ('__local', '__dict__', '__name__', '__wrapped__')
|
|
||||||
|
|
||||||
def __init__(self, local, name=None):
|
|
||||||
object.__setattr__(self, '_LocalProxy__local', local)
|
|
||||||
object.__setattr__(self, '__name__', name)
|
|
||||||
if callable(local) and not hasattr(local, '__release_local__'):
|
|
||||||
# "local" is a callable that is not an instance of Local or
|
|
||||||
# LocalManager: mark it as a wrapped function.
|
|
||||||
object.__setattr__(self, '__wrapped__', local)
|
|
||||||
|
|
||||||
def _get_current_object(self):
|
|
||||||
"""Return the current object. This is useful if you want the real
|
|
||||||
object behind the proxy at a time for performance reasons or because
|
|
||||||
you want to pass the object into a different context.
|
|
||||||
"""
|
|
||||||
if not hasattr(self.__local, '__release_local__'):
|
|
||||||
return self.__local()
|
|
||||||
try:
|
|
||||||
return getattr(self.__local, self.__name__)
|
|
||||||
except AttributeError:
|
|
||||||
raise RuntimeError('no object bound to %s' % self.__name__)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def __dict__(self):
|
|
||||||
try:
|
|
||||||
return self._get_current_object().__dict__
|
|
||||||
except RuntimeError:
|
|
||||||
raise AttributeError('__dict__')
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
try:
|
|
||||||
obj = self._get_current_object()
|
|
||||||
except RuntimeError:
|
|
||||||
return '<%s unbound>' % self.__class__.__name__
|
|
||||||
return repr(obj)
|
|
||||||
|
|
||||||
def __bool__(self):
|
|
||||||
try:
|
|
||||||
return bool(self._get_current_object())
|
|
||||||
except RuntimeError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __dir__(self):
|
|
||||||
try:
|
|
||||||
return dir(self._get_current_object())
|
|
||||||
except RuntimeError:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
if name == '__members__':
|
|
||||||
return dir(self._get_current_object())
|
|
||||||
return getattr(self._get_current_object(), name)
|
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
|
||||||
self._get_current_object()[key] = value
|
|
||||||
|
|
||||||
def __delitem__(self, key):
|
|
||||||
del self._get_current_object()[key]
|
|
||||||
|
|
||||||
__setattr__ = lambda x, n, v: setattr(x._get_current_object(), n, v)
|
|
||||||
__delattr__ = lambda x, n: delattr(x._get_current_object(), n)
|
|
||||||
__str__ = lambda x: str(x._get_current_object())
|
|
||||||
__lt__ = lambda x, o: x._get_current_object() < o
|
|
||||||
__le__ = lambda x, o: x._get_current_object() <= o
|
|
||||||
__eq__ = lambda x, o: x._get_current_object() == o
|
|
||||||
__ne__ = lambda x, o: x._get_current_object() != o
|
|
||||||
__gt__ = lambda x, o: x._get_current_object() > o
|
|
||||||
__ge__ = lambda x, o: x._get_current_object() >= o
|
|
||||||
__cmp__ = lambda x, o: cmp(x._get_current_object(), o) # noqa
|
|
||||||
__hash__ = lambda x: hash(x._get_current_object())
|
|
||||||
__call__ = lambda x, *a, **kw: x._get_current_object()(*a, **kw)
|
|
||||||
__len__ = lambda x: len(x._get_current_object())
|
|
||||||
__getitem__ = lambda x, i: x._get_current_object()[i]
|
|
||||||
__iter__ = lambda x: iter(x._get_current_object())
|
|
||||||
__contains__ = lambda x, i: i in x._get_current_object()
|
|
||||||
__add__ = lambda x, o: x._get_current_object() + o
|
|
||||||
__sub__ = lambda x, o: x._get_current_object() - o
|
|
||||||
__mul__ = lambda x, o: x._get_current_object() * o
|
|
||||||
__floordiv__ = lambda x, o: x._get_current_object() // o
|
|
||||||
__mod__ = lambda x, o: x._get_current_object() % o
|
|
||||||
__divmod__ = lambda x, o: x._get_current_object().__divmod__(o)
|
|
||||||
__pow__ = lambda x, o: x._get_current_object() ** o
|
|
||||||
__lshift__ = lambda x, o: x._get_current_object() << o
|
|
||||||
__rshift__ = lambda x, o: x._get_current_object() >> o
|
|
||||||
__and__ = lambda x, o: x._get_current_object() & o
|
|
||||||
__xor__ = lambda x, o: x._get_current_object() ^ o
|
|
||||||
__or__ = lambda x, o: x._get_current_object() | o
|
|
||||||
__div__ = lambda x, o: x._get_current_object().__div__(o)
|
|
||||||
__truediv__ = lambda x, o: x._get_current_object().__truediv__(o)
|
|
||||||
__neg__ = lambda x: -(x._get_current_object())
|
|
||||||
__pos__ = lambda x: +(x._get_current_object())
|
|
||||||
__abs__ = lambda x: abs(x._get_current_object())
|
|
||||||
__invert__ = lambda x: ~(x._get_current_object())
|
|
||||||
__complex__ = lambda x: complex(x._get_current_object())
|
|
||||||
__int__ = lambda x: int(x._get_current_object())
|
|
||||||
__float__ = lambda x: float(x._get_current_object())
|
|
||||||
__oct__ = lambda x: oct(x._get_current_object())
|
|
||||||
__hex__ = lambda x: hex(x._get_current_object())
|
|
||||||
__index__ = lambda x: x._get_current_object().__index__()
|
|
||||||
__coerce__ = lambda x, o: x._get_current_object().__coerce__(x, o)
|
|
||||||
__enter__ = lambda x: x._get_current_object().__enter__()
|
|
||||||
__exit__ = lambda x, *a, **kw: x._get_current_object().__exit__(*a, **kw)
|
|
||||||
__radd__ = lambda x, o: o + x._get_current_object()
|
|
||||||
__rsub__ = lambda x, o: o - x._get_current_object()
|
|
||||||
__rmul__ = lambda x, o: o * x._get_current_object()
|
|
||||||
__rdiv__ = lambda x, o: o / x._get_current_object()
|
|
||||||
__rtruediv__ = __rdiv__
|
|
||||||
__rfloordiv__ = lambda x, o: o // x._get_current_object()
|
|
||||||
__rmod__ = lambda x, o: o % x._get_current_object()
|
|
||||||
__rdivmod__ = lambda x, o: x._get_current_object().__rdivmod__(o)
|
|
||||||
__copy__ = lambda x: copy.copy(x._get_current_object())
|
|
||||||
__deepcopy__ = lambda x, memo: copy.deepcopy(x._get_current_object(), memo)
|
|
||||||
|
|
||||||
|
|
||||||
def random_string(length):
|
def random_string(length):
|
||||||
import string
|
import string
|
||||||
import random
|
import random
|
||||||
|
|
|
@ -1,24 +1,16 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
from werkzeug.local import LocalProxy
|
||||||
from common.utils import LocalProxy
|
from common.local import thread_local
|
||||||
|
|
||||||
try:
|
|
||||||
from threading import local
|
|
||||||
except ImportError:
|
|
||||||
from django.utils._threading_local import local
|
|
||||||
|
|
||||||
_thread_locals = local()
|
|
||||||
|
|
||||||
|
|
||||||
def set_current_request(request):
|
def set_current_request(request):
|
||||||
setattr(_thread_locals, 'current_request', request)
|
setattr(thread_local, 'current_request', request)
|
||||||
|
|
||||||
|
|
||||||
def _find(attr):
|
def _find(attr):
|
||||||
return getattr(_thread_locals, attr, None)
|
return getattr(thread_local, attr, None)
|
||||||
|
|
||||||
|
|
||||||
def get_current_request():
|
def get_current_request():
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
from functools import partial
|
from werkzeug.local import LocalProxy
|
||||||
from werkzeug.local import Local
|
|
||||||
|
|
||||||
from common.utils import LocalProxy
|
from common.local import thread_local
|
||||||
from .models import Organization
|
from .models import Organization
|
||||||
|
|
||||||
|
|
||||||
_thread_locals = Local()
|
|
||||||
|
|
||||||
|
|
||||||
def get_org_from_request(request):
|
def get_org_from_request(request):
|
||||||
oid = request.session.get("oid")
|
oid = request.session.get("oid")
|
||||||
if not oid:
|
if not oid:
|
||||||
|
@ -19,7 +15,7 @@ def get_org_from_request(request):
|
||||||
|
|
||||||
|
|
||||||
def set_current_org(org):
|
def set_current_org(org):
|
||||||
setattr(_thread_locals, 'current_org', org)
|
setattr(thread_local, 'current_org', org.id)
|
||||||
|
|
||||||
|
|
||||||
def set_to_default_org():
|
def set_to_default_org():
|
||||||
|
@ -31,17 +27,18 @@ def set_to_root_org():
|
||||||
|
|
||||||
|
|
||||||
def _find(attr):
|
def _find(attr):
|
||||||
return getattr(_thread_locals, attr, None)
|
return getattr(thread_local, attr, None)
|
||||||
|
|
||||||
|
|
||||||
def get_current_org():
|
def get_current_org():
|
||||||
return _find('current_org')
|
org_id = _find('current_org')
|
||||||
|
org = Organization.get_instance(org_id)
|
||||||
|
return org
|
||||||
|
|
||||||
|
|
||||||
def get_current_org_id():
|
def get_current_org_id():
|
||||||
org = get_current_org()
|
org_id = _find('current_org')
|
||||||
org_id = str(org.id) if org.is_real() else ''
|
|
||||||
return org_id
|
return org_id
|
||||||
|
|
||||||
|
|
||||||
current_org = LocalProxy(partial(_find, 'current_org'))
|
current_org = LocalProxy(get_current_org)
|
||||||
|
|
|
@ -48,9 +48,10 @@ class UserViewSet(IDInCacheFilterMixin, BulkModelViewSet):
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
users = serializer.save()
|
users = serializer.save()
|
||||||
for user in users:
|
if isinstance(users, User):
|
||||||
if current_org and current_org.is_real():
|
users = [users]
|
||||||
user.orgs.add(current_org.id)
|
if current_org and current_org.is_real():
|
||||||
|
current_org.users.add(*users)
|
||||||
self.send_created_signal(users)
|
self.send_created_signal(users)
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
@ -174,6 +175,7 @@ class UserResetPKApi(generics.UpdateAPIView):
|
||||||
send_reset_ssh_key_mail(user)
|
send_reset_ssh_key_mail(user)
|
||||||
|
|
||||||
|
|
||||||
|
# 废弃
|
||||||
class UserUpdatePKApi(generics.UpdateAPIView):
|
class UserUpdatePKApi(generics.UpdateAPIView):
|
||||||
queryset = User.objects.all()
|
queryset = User.objects.all()
|
||||||
serializer_class = UserPKUpdateSerializer
|
serializer_class = UserPKUpdateSerializer
|
||||||
|
@ -181,7 +183,7 @@ class UserUpdatePKApi(generics.UpdateAPIView):
|
||||||
|
|
||||||
def perform_update(self, serializer):
|
def perform_update(self, serializer):
|
||||||
user = self.get_object()
|
user = self.get_object()
|
||||||
user.public_key = serializer.validated_data['_public_key']
|
user.public_key = serializer.validated_data['public_key']
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,16 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
model = User
|
model = User
|
||||||
list_serializer_class = AdaptedBulkListSerializer
|
list_serializer_class = AdaptedBulkListSerializer
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'username', 'email', 'groups', 'groups_display',
|
'id', 'name', 'username', 'password', 'email', 'public_key',
|
||||||
|
'groups', 'groups_display',
|
||||||
'role', 'role_display', 'wechat', 'phone', 'otp_level',
|
'role', 'role_display', 'wechat', 'phone', 'otp_level',
|
||||||
'comment', 'source', 'source_display', 'is_valid', 'is_expired',
|
'comment', 'source', 'source_display', 'is_valid', 'is_expired',
|
||||||
'is_active', 'created_by', 'is_first_login',
|
'is_active', 'created_by', 'is_first_login',
|
||||||
'date_password_last_updated', 'date_expired', 'avatar_url',
|
'date_password_last_updated', 'date_expired', 'avatar_url',
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
|
'password': {'write_only': True},
|
||||||
|
'public_key': {'write_only': True},
|
||||||
'groups_display': {'label': _('Groups name')},
|
'groups_display': {'label': _('Groups name')},
|
||||||
'source_display': {'label': _('Source name')},
|
'source_display': {'label': _('Source name')},
|
||||||
'is_first_login': {'label': _('Is first login'), 'read_only': True},
|
'is_first_login': {'label': _('Is first login'), 'read_only': True},
|
||||||
|
@ -36,14 +39,37 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
|
||||||
'created_by': {'read_only': True}, 'source': {'read_only': True}
|
'created_by': {'read_only': True}, 'source': {'read_only': True}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate_password(value):
|
||||||
|
from ..utils import check_password_rules
|
||||||
|
if not check_password_rules(value):
|
||||||
|
msg = _('Password does not match security rules')
|
||||||
|
raise serializers.ValidationError(msg)
|
||||||
|
return value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def change_password_to_raw(validated_data):
|
||||||
|
password = validated_data.pop('password', None)
|
||||||
|
if password:
|
||||||
|
validated_data['password_raw'] = password
|
||||||
|
return validated_data
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
validated_data = self.change_password_to_raw(validated_data)
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
def update(self, instance, validated_data):
|
||||||
|
validated_data = self.change_password_to_raw(validated_data)
|
||||||
|
return super().update(instance, validated_data)
|
||||||
|
|
||||||
|
|
||||||
class UserPKUpdateSerializer(serializers.ModelSerializer):
|
class UserPKUpdateSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = User
|
model = User
|
||||||
fields = ['id', '_public_key']
|
fields = ['id', 'public_key']
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def validate__public_key(value):
|
def validate_public_key(value):
|
||||||
if not validate_ssh_public_key(value):
|
if not validate_ssh_public_key(value):
|
||||||
raise serializers.ValidationError(_('Not a valid ssh public key'))
|
raise serializers.ValidationError(_('Not a valid ssh public key'))
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -217,33 +217,9 @@
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block custom_foot_js %}
|
{% block custom_foot_js %}
|
||||||
<script>
|
<script>
|
||||||
$(document).on('click', '#btn_update_pk', function() {
|
$(document).ready(function () {
|
||||||
var $this = $(this);
|
})
|
||||||
var pk = $('#txt_pk').val();
|
.on('click', '.btn-reset-pubkey', function () {
|
||||||
var the_url = '{% url "api-users:user-public-key-update" pk=user.id %}';
|
|
||||||
var body = {'_public_key': pk};
|
|
||||||
var success = function() {
|
|
||||||
$('#txt_pk').val('');
|
|
||||||
var msg = "{% trans 'Successfully updated the SSH public key.' %}";
|
|
||||||
swal("{% trans 'User SSH public key update' %}", msg, "success");
|
|
||||||
};
|
|
||||||
var fail = function() {
|
|
||||||
var msg = "{% trans 'Failed to update SSH public key.' %}";
|
|
||||||
swal({
|
|
||||||
title: "{% trans 'User SSH public key update' %}",
|
|
||||||
text: msg,
|
|
||||||
type: "error",
|
|
||||||
showCancelButton: false,
|
|
||||||
confirmButtonColor: "#DD6B55",
|
|
||||||
confirmButtonText: "{% trans 'Confirm' %}",
|
|
||||||
closeOnConfirm: true
|
|
||||||
}, function () {
|
|
||||||
$('#txt_pk').focus();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
APIUpdateAttr({ url: the_url, body: JSON.stringify(body), success: success, error: fail});
|
|
||||||
}).on('click', '.btn-reset-pubkey', function () {
|
|
||||||
var the_url = '{% url "users:user-pubkey-generate" %}';
|
var the_url = '{% url "users:user-pubkey-generate" %}';
|
||||||
window.open(the_url, "_blank")
|
window.open(the_url, "_blank")
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue