mirror of https://github.com/jumpserver/jumpserver
Update terminal api
parent
30c4fc9514
commit
034f0a02b1
|
@ -3,12 +3,10 @@
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import copy
|
import copy
|
||||||
from rest_framework.generics import ListCreateAPIView
|
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from rest_framework.views import APIView, Response
|
from rest_framework.views import APIView, Response
|
||||||
from rest_framework.permissions import AllowAny
|
from rest_framework.permissions import AllowAny
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from rest_framework.decorators import api_view
|
|
||||||
|
|
||||||
from .models import Terminal, TerminalHeatbeat
|
from .models import Terminal, TerminalHeatbeat
|
||||||
from .serializers import TerminalSerializer, TerminalHeatbeatSerializer
|
from .serializers import TerminalSerializer, TerminalHeatbeatSerializer
|
||||||
|
@ -17,21 +15,25 @@ from .hands import IsSuperUserOrAppUser, IsAppUser, ProxyLog, \
|
||||||
from common.utils import get_object_or_none
|
from common.utils import get_object_or_none
|
||||||
|
|
||||||
|
|
||||||
class TerminalRegisterView(ListCreateAPIView):
|
class TerminalViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Terminal.objects.all()
|
queryset = Terminal.objects.all()
|
||||||
serializer_class = TerminalSerializer
|
serializer_class = TerminalSerializer
|
||||||
permission_classes = (AllowAny,)
|
permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
def create(self, request, *args, **kwargs):
|
||||||
name = request.data.get('name', '')
|
name = request.data.get('name')
|
||||||
remote_addr = request.META.get('X-Real-IP') or \
|
remote_ip = request.META.get('REMOTE_ADDR')
|
||||||
request.META.get('REMOTE_ADDR')
|
x_real_ip = request.META.get('X-Real-IP')
|
||||||
serializer = self.serializer_class(
|
remote_addr = x_real_ip or remote_ip
|
||||||
data={'name': name, 'remote_addr': remote_addr})
|
|
||||||
|
|
||||||
if get_object_or_none(Terminal, name=name):
|
terminal = get_object_or_none(Terminal, name=name)
|
||||||
return Response({'msg': 'Already register, Need '
|
if terminal:
|
||||||
'administrator active it'}, status=200)
|
msg = 'Terminal name %s already used' % name
|
||||||
|
return Response({'msg': msg}, status=409)
|
||||||
|
|
||||||
|
serializer = self.serializer_class(data={
|
||||||
|
'name': name, 'remote_addr': remote_addr
|
||||||
|
})
|
||||||
|
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
terminal = serializer.save()
|
terminal = serializer.save()
|
||||||
|
@ -39,30 +41,19 @@ class TerminalRegisterView(ListCreateAPIView):
|
||||||
data = OrderedDict()
|
data = OrderedDict()
|
||||||
data['terminal'] = copy.deepcopy(serializer.data)
|
data['terminal'] = copy.deepcopy(serializer.data)
|
||||||
data['user'] = app_user.to_json()
|
data['user'] = app_user.to_json()
|
||||||
data['access_key_id'] = access_key.id
|
data['access_key'] = {'id': access_key.id,
|
||||||
data['access_key_secret'] = access_key.secret
|
'secret': access_key.secret}
|
||||||
return Response(data, status=201)
|
return Response(data, status=201)
|
||||||
else:
|
else:
|
||||||
data = {'msg': 'Not valid', 'detail': ';'.join(serializer.errors)}
|
data = serializer.errors
|
||||||
return Response(data, status=400)
|
return Response(data, status=400)
|
||||||
|
|
||||||
def list(self, request, *args, **kwargs):
|
def get_permissions(self):
|
||||||
return Response('', status=404)
|
if self.action == "create":
|
||||||
|
self.permission_classes = (AllowAny,)
|
||||||
|
|
||||||
|
return super().get_permissions()
|
||||||
|
|
||||||
class TerminalViewSet(viewsets.ModelViewSet):
|
|
||||||
queryset = Terminal.objects.all()
|
|
||||||
serializer_class = TerminalSerializer
|
|
||||||
permission_classes = (IsSuperUserOrAppUserOrUserReadonly,)
|
|
||||||
|
|
||||||
def create(self, request, *args, **kwargs):
|
|
||||||
return Response({'msg': 'Use register view except that'}, status=404)
|
|
||||||
|
|
||||||
# def destroy(self, request, *args, **kwargs):
|
|
||||||
# instance = self.get_object()
|
|
||||||
# if instance.user is not None:
|
|
||||||
# instance.user.delete()
|
|
||||||
# return super(TerminalViewSet, self).destroy(request, *args, **kwargs)
|
|
||||||
|
|
||||||
tasks = OrderedDict()
|
tasks = OrderedDict()
|
||||||
# tasks = {1: [{'name': 'kill_proxy', 'proxy_log_id': 23}]}
|
# tasks = {1: [{'name': 'kill_proxy', 'proxy_log_id': 23}]}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .models import Terminal
|
from .models import Terminal
|
||||||
|
|
||||||
|
@ -9,9 +10,11 @@ from .models import Terminal
|
||||||
class TerminalForm(forms.ModelForm):
|
class TerminalForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Terminal
|
model = Terminal
|
||||||
fields = ['name', 'remote_addr', 'type', 'url', 'comment']
|
fields = ['name', 'remote_addr', 'ssh_port', 'http_port', 'comment']
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'url': 'Example: ssh://192.168.1.1:22 or http://jms.jumpserver.org, that user login'
|
'remote_addr': _('A unique addr of every terminal, user browser can arrive it'),
|
||||||
|
'ssh_port': _("Coco ssh listen port"),
|
||||||
|
'http_port': _("Coco http/ws listen port"),
|
||||||
}
|
}
|
||||||
widgets = {
|
widgets = {
|
||||||
'name': forms.TextInput(attrs={'readonly': 'readonly'})
|
'name': forms.TextInput(attrs={'readonly': 'readonly'})
|
||||||
|
|
|
@ -7,16 +7,11 @@ from users.models import User
|
||||||
|
|
||||||
|
|
||||||
class Terminal(models.Model):
|
class Terminal(models.Model):
|
||||||
TYPE_CHOICES = (
|
name = models.CharField(max_length=32, unique=True, verbose_name=_('Name'))
|
||||||
('SSH', 'SSH Terminal'),
|
remote_addr = models.CharField(max_length=128, verbose_name=_('Remote Address'))
|
||||||
('Web', 'Web Terminal')
|
ssh_port = models.IntegerField(verbose_name=_('SSH Port'), default=2222)
|
||||||
)
|
http_port = models.IntegerField(verbose_name=_('HTTP Port'), default=5000)
|
||||||
name = models.CharField(max_length=30, unique=True, verbose_name=_('Name'))
|
user = models.OneToOneField(User, related_name='terminal', verbose_name='Application User', null=True, on_delete=models.CASCADE)
|
||||||
remote_addr = models.GenericIPAddressField(verbose_name=_('Remote address'), blank=True, null=True)
|
|
||||||
type = models.CharField(choices=TYPE_CHOICES, max_length=3, blank=True, verbose_name=_('Terminal type'))
|
|
||||||
user = models.OneToOneField(User, related_name='terminal', verbose_name='Application user',
|
|
||||||
null=True, on_delete=models.CASCADE)
|
|
||||||
url = models.CharField(max_length=100, blank=True, verbose_name=_('URL to login'))
|
|
||||||
is_accepted = models.BooleanField(default=False, verbose_name='Is Accepted')
|
is_accepted = models.BooleanField(default=False, verbose_name='Is Accepted')
|
||||||
date_created = models.DateTimeField(auto_now_add=True)
|
date_created = models.DateTimeField(auto_now_add=True)
|
||||||
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
comment = models.TextField(blank=True, verbose_name=_('Comment'))
|
||||||
|
@ -44,12 +39,10 @@ class Terminal(models.Model):
|
||||||
self.user.delete()
|
self.user.delete()
|
||||||
return super(Terminal, self).delete(using=using, keep_parents=keep_parents)
|
return super(Terminal, self).delete(using=using, keep_parents=keep_parents)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
active = 'Active' if self.user and self.user.is_active else 'Disabled'
|
active = 'Active' if self.user and self.user.is_active else 'Disabled'
|
||||||
return '%s: %s' % (self.name, active)
|
return '%s: %s' % (self.name, active)
|
||||||
|
|
||||||
__str__ = __unicode__
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('is_accepted',)
|
ordering = ('is_accepted',)
|
||||||
|
|
||||||
|
|
|
@ -9,17 +9,17 @@ from .hands import ProxyLog
|
||||||
|
|
||||||
|
|
||||||
class TerminalSerializer(serializers.ModelSerializer):
|
class TerminalSerializer(serializers.ModelSerializer):
|
||||||
proxy_online = serializers.SerializerMethodField()
|
session_connected = serializers.SerializerMethodField()
|
||||||
is_alive = serializers.SerializerMethodField()
|
is_alive = serializers.SerializerMethodField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Terminal
|
model = Terminal
|
||||||
fields = ['id', 'name', 'remote_addr', 'type', 'url', 'comment',
|
fields = ['id', 'name', 'remote_addr', 'http_port', 'ssh_port',
|
||||||
'is_accepted', 'is_active', 'get_type_display',
|
'comment', 'is_accepted',
|
||||||
'proxy_online', 'is_alive']
|
'session_connected', 'is_alive']
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_proxy_online(obj):
|
def get_session_connected(obj):
|
||||||
return ProxyLog.objects.filter(terminal=obj.name, is_finished=False).count()
|
return ProxyLog.objects.filter(terminal=obj.name, is_finished=False).count()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -33,9 +33,10 @@ class TerminalSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class TerminalHeatbeatSerializer(serializers.ModelSerializer):
|
class TerminalHeatbeatSerializer(serializers.ModelSerializer):
|
||||||
date_start = serializers.DateTimeField
|
date_start = serializers.DateTimeField
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = TerminalHeatbeat
|
model = TerminalHeatbeat
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
pass
|
|
||||||
|
|
|
@ -27,9 +27,10 @@
|
||||||
</div>
|
</div>
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">{% trans 'Name' %}</th>
|
<th class="text-center">{% trans 'Name' %}</th>
|
||||||
<th class="text-center">{% trans 'IP' %}</th>
|
<th class="text-center">{% trans 'Addr' %}</th>
|
||||||
<th class="text-center">{% trans 'Type' %}</th>
|
<th class="text-center">{% trans 'SSH Port' %}</th>
|
||||||
<th class="text-center">{% trans 'Session online' %}</th>
|
<th class="text-center">{% trans 'Http Port' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Connected' %}</th>
|
||||||
<th class="text-center">{% trans 'Active' %}</th>
|
<th class="text-center">{% trans 'Active' %}</th>
|
||||||
<th class="text-center">{% trans 'Alive' %}</th>
|
<th class="text-center">{% trans 'Alive' %}</th>
|
||||||
<th class="text-center">{% trans 'Action' %}</th>
|
<th class="text-center">{% trans 'Action' %}</th>
|
||||||
|
@ -53,21 +54,21 @@ $(document).ready(function(){
|
||||||
var detail_btn = '<a href="{% url "applications:terminal-detail" pk=99991937 %}">' + cellData + '</a>';
|
var detail_btn = '<a href="{% url "applications:terminal-detail" pk=99991937 %}">' + cellData + '</a>';
|
||||||
$(td).html(detail_btn.replace('99991937', rowData.id));
|
$(td).html(detail_btn.replace('99991937', rowData.id));
|
||||||
}},
|
}},
|
||||||
{targets: 5, createdCell: function (td, cellData) {
|
{targets: 6, createdCell: function (td, cellData) {
|
||||||
if (!cellData) {
|
if (!cellData) {
|
||||||
$(td).html('<i class="fa fa-times text-danger"></i>')
|
$(td).html('<i class="fa fa-times text-danger"></i>')
|
||||||
} else {
|
} else {
|
||||||
$(td).html('<i class="fa fa-check text-navy"></i>')
|
$(td).html('<i class="fa fa-check text-navy"></i>')
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 6, createdCell: function (td, cellData) {
|
{targets: 7, createdCell: function (td, cellData) {
|
||||||
if (!cellData) {
|
if (!cellData) {
|
||||||
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
$(td).html('<i class="fa fa-circle text-danger"></i>')
|
||||||
} else {
|
} else {
|
||||||
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
$(td).html('<i class="fa fa-circle text-navy"></i>')
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{targets: 7, createdCell: function (td, cellData, rowData) {
|
{targets: 8, createdCell: function (td, cellData, rowData) {
|
||||||
var update_btn = '<a href="{% url "applications:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
|
var update_btn = '<a href="{% url "applications:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
|
||||||
.replace('99991937', cellData);
|
.replace('99991937', cellData);
|
||||||
var delete_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Delete" %}</a>'
|
var delete_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-del" data-id="99991937" data-name="99991938">{% trans "Delete" %}</a>'
|
||||||
|
@ -94,8 +95,8 @@ $(document).ready(function(){
|
||||||
}}
|
}}
|
||||||
],
|
],
|
||||||
ajax_url: '{% url "api-applications:terminal-list" %}',
|
ajax_url: '{% url "api-applications:terminal-list" %}',
|
||||||
columns: [{data: function(){return ""}}, {data: "name" }, {data: "remote_addr" }, {data: "get_type_display" },
|
columns: [{data: function(){return ""}}, {data: "name" }, {data: "remote_addr" }, {data: "ssh_port"}, {data: "http_port"},
|
||||||
{data: "proxy_online"}, {data: "is_active" }, {data: 'is_active'}, {data: "id"}],
|
{data: "session_connected"}, {data: "is_alive" }, {data: 'is_alive'}, {data: "id"}],
|
||||||
op_html: $('#actions').html()
|
op_html: $('#actions').html()
|
||||||
};
|
};
|
||||||
jumpserver.initDataTable(options);
|
jumpserver.initDataTable(options);
|
||||||
|
@ -131,7 +132,6 @@ $(document).ready(function(){
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
$('#id_name').val(data.name);
|
$('#id_name').val(data.name);
|
||||||
$('#id_remote_addr').val(data.remote_addr);
|
$('#id_remote_addr').val(data.remote_addr);
|
||||||
$('#id_type').val(data.type);
|
|
||||||
$('#id_url').val(data.url);
|
$('#id_url').val(data.url);
|
||||||
$('#id_comment').val(data.comment);
|
$('#id_comment').val(data.comment);
|
||||||
$('#form_terminal_accept').attr('action', post_url)
|
$('#form_terminal_accept').attr('action', post_url)
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
<p class="alert alert-danger" id="modal-error" style="display: none"></p>
|
<p class="alert alert-danger" id="modal-error" style="display: none"></p>
|
||||||
{% bootstrap_field form.name layout="horizontal" %}
|
{% bootstrap_field form.name layout="horizontal" %}
|
||||||
{% bootstrap_field form.remote_addr layout="horizontal" %}
|
{% bootstrap_field form.remote_addr layout="horizontal" %}
|
||||||
{% bootstrap_field form.type layout="horizontal" %}
|
{% bootstrap_field form.ssh_port layout="horizontal" %}
|
||||||
{% bootstrap_field form.url layout="horizontal" %}
|
{% bootstrap_field form.http_port layout="horizontal" %}
|
||||||
{% bootstrap_field form.comment layout="horizontal" %}
|
{% bootstrap_field form.comment layout="horizontal" %}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,8 @@ router.register(r'v1/terminal/heatbeat', api.TerminalHeatbeatViewSet, 'terminal-
|
||||||
router.register(r'v1/terminal', api.TerminalViewSet, 'terminal')
|
router.register(r'v1/terminal', api.TerminalViewSet, 'terminal')
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^v1/terminal/register/$', api.TerminalRegisterView.as_view(),
|
|
||||||
name='terminal-register'),
|
|
||||||
url(r'^v1/terminate/connection/$', api.TerminateConnectionView.as_view(),
|
url(r'^v1/terminate/connection/$', api.TerminateConnectionView.as_view(),
|
||||||
name='terminate-connection')
|
name='terminate-connection')
|
||||||
# url(r'^v1/terminal/heatbeat/$', api.TestHeatbeat.as_view())
|
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns += router.urls
|
urlpatterns += router.urls
|
||||||
|
|
|
@ -66,7 +66,6 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView)
|
||||||
template_name = 'applications/terminal_modal_test.html'
|
template_name = 'applications/terminal_modal_test.html'
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
print(request.POST)
|
|
||||||
return super(TerminalModelAccept, self).post(request, *args, **kwargs)
|
return super(TerminalModelAccept, self).post(request, *args, **kwargs)
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
@ -81,7 +80,7 @@ class TerminalModelAccept(AdminUserRequiredMixin, JSONResponseMixin, UpdateView)
|
||||||
return self.render_json_response(data)
|
return self.render_json_response(data)
|
||||||
|
|
||||||
def form_invalid(self, form):
|
def form_invalid(self, form):
|
||||||
print('form.data')
|
print(form.data)
|
||||||
data = {
|
data = {
|
||||||
'success': False,
|
'success': False,
|
||||||
'msg': str(form.errors),
|
'msg': str(form.errors),
|
||||||
|
|
|
@ -274,8 +274,10 @@ def content_md5(data):
|
||||||
|
|
||||||
返回值可以直接作为HTTP Content-Type头部的值
|
返回值可以直接作为HTTP Content-Type头部的值
|
||||||
"""
|
"""
|
||||||
m = hashlib.md5(to_bytes(data))
|
if isinstance(data, str):
|
||||||
return to_string(base64.b64encode(m.digest()))
|
data = hashlib.md5(data.encode('utf-8'))
|
||||||
|
value = base64.b64encode(data.digest())
|
||||||
|
return value.decode('utf-8')
|
||||||
|
|
||||||
_STRPTIME_LOCK = threading.Lock()
|
_STRPTIME_LOCK = threading.Lock()
|
||||||
|
|
||||||
|
@ -330,8 +332,6 @@ def encrypt_password(password):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def capacity_convert(size, expect='auto', rate=1000):
|
def capacity_convert(size, expect='auto', rate=1000):
|
||||||
"""
|
"""
|
||||||
:param size: '100MB', '1G'
|
:param size: '100MB', '1G'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import url("https://fonts.css.network/css?family=Open+Sans:300,400,600,700");
|
/*@import url("https://fonts.css.network/css?family=Open+Sans:300,400,600,700");*/
|
||||||
@import url("https://fonts.css.network/css?family=Roboto:400,300,500,700");
|
/*@import url("https://fonts.css.network/css?family=Roboto:400,300,500,700");*/
|
||||||
/** {*/
|
/** {*/
|
||||||
/*box-sizing: border-box;*/
|
/*box-sizing: border-box;*/
|
||||||
/*}*/
|
/*}*/
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
@import url("https://fonts.css.network/css?family=Open+Sans:300,400,600,700");
|
/*@import url("https://fonts.css.network/css?family=Open+Sans:300,400,600,700");*/
|
||||||
@import url("https://fonts.css.network/css?family=Roboto:400,300,500,700");
|
/*@import url("https://fonts.css.network/css?family=Roboto:400,300,500,700");*/
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* INSPINIA - Responsive Admin Theme
|
* INSPINIA - Responsive Admin Theme
|
||||||
|
|
|
@ -49,7 +49,6 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
|
||||||
|
|
||||||
def authenticate(self, request):
|
def authenticate(self, request):
|
||||||
auth = authentication.get_authorization_header(request).split()
|
auth = authentication.get_authorization_header(request).split()
|
||||||
|
|
||||||
if not auth or auth[0].lower() != self.keyword.lower().encode():
|
if not auth or auth[0].lower() != self.keyword.lower().encode():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -80,7 +79,8 @@ class AccessKeyAuthentication(authentication.BaseAuthentication):
|
||||||
request_signature = sign[1]
|
request_signature = sign[1]
|
||||||
|
|
||||||
return self.authenticate_credentials(
|
return self.authenticate_credentials(
|
||||||
request, access_key_id, request_signature)
|
request, access_key_id, request_signature
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def authenticate_credentials(request, access_key_id, request_signature):
|
def authenticate_credentials(request, access_key_id, request_signature):
|
||||||
|
|
|
@ -25,11 +25,9 @@ class AccessKey(models.Model):
|
||||||
def get_secret(self):
|
def get_secret(self):
|
||||||
return str(self.secret)
|
return str(self.secret)
|
||||||
|
|
||||||
def __unicode__(self):
|
def __str__(self):
|
||||||
return str(self.id)
|
return str(self.id)
|
||||||
|
|
||||||
__str__ = __unicode__
|
|
||||||
|
|
||||||
|
|
||||||
class PrivateToken(Token):
|
class PrivateToken(Token):
|
||||||
"""Inherit from auth token, otherwise migration is boring"""
|
"""Inherit from auth token, otherwise migration is boring"""
|
||||||
|
|
|
@ -23,9 +23,9 @@ __all__ = ['User']
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
ROLE_CHOICES = (
|
ROLE_CHOICES = (
|
||||||
('Admin', _('Administrator')),
|
('Admin', 'Administrator'),
|
||||||
('User', _('User')),
|
('User', 'User'),
|
||||||
('App', _('Application'))
|
('App', 'Application')
|
||||||
)
|
)
|
||||||
|
|
||||||
username = models.CharField(max_length=20, unique=True, verbose_name=_('Username'))
|
username = models.CharField(max_length=20, unique=True, verbose_name=_('Username'))
|
||||||
|
|
|
@ -36,8 +36,6 @@ class UserPKUpdateSerializer(serializers.ModelSerializer):
|
||||||
@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):
|
||||||
print('Not a valid key')
|
|
||||||
print(value)
|
|
||||||
raise serializers.ValidationError(_('Not a valid ssh public key'))
|
raise serializers.ValidationError(_('Not a valid ssh public key'))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue