From 403b6fc56372b946441ae5980e625c39d5f93247 Mon Sep 17 00:00:00 2001
From: Bai <bugatti_it@163.com>
Date: Thu, 4 Jun 2020 17:02:43 +0800
Subject: [PATCH 1/3] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9=E7=94=A8?=
 =?UTF-8?q?=E6=88=B7=E6=9B=B4=E6=96=B0Public=5Fkey=E7=9A=84=E6=9D=A1?=
 =?UTF-8?q?=E4=BB=B6=E5=88=A4=E6=96=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 apps/users/api/profile.py | 5 -----
 apps/users/models/user.py | 7 ++++---
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/apps/users/api/profile.py b/apps/users/api/profile.py
index 321ef54e1..e9631b5b7 100644
--- a/apps/users/api/profile.py
+++ b/apps/users/api/profile.py
@@ -83,8 +83,3 @@ class UserPublicKeyApi(generics.RetrieveUpdateAPIView):
 
     def get_object(self):
         return self.request.user
-
-    def perform_update(self, serializer):
-        user = self.get_object()
-        user.public_key = serializer.validated_data['public_key']
-        user.save()
diff --git a/apps/users/models/user.py b/apps/users/models/user.py
index 431a9789b..3fb058396 100644
--- a/apps/users/models/user.py
+++ b/apps/users/models/user.py
@@ -48,8 +48,9 @@ class AuthMixin:
             super().set_password(raw_password)
 
     def set_public_key(self, public_key):
-        self.public_key = public_key
-        self.save()
+        if self.can_update_ssh_key():
+            self.public_key = public_key
+            self.save()
 
     def can_update_password(self):
         return self.is_local
@@ -58,7 +59,7 @@ class AuthMixin:
         return self.can_use_ssh_key_login()
 
     def can_use_ssh_key_login(self):
-        return settings.TERMINAL_PUBLIC_KEY_AUTH
+        return self.is_local and settings.TERMINAL_PUBLIC_KEY_AUTH
 
     def is_public_key_valid(self):
         """

From afc7f3bb9c17a2b25912934ab07abb6e6ee7324b Mon Sep 17 00:00:00 2001
From: Bai <bugatti_it@163.com>
Date: Thu, 4 Jun 2020 17:05:36 +0800
Subject: [PATCH 2/3] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9=E7=94=A8?=
 =?UTF-8?q?=E6=88=B7public=5Fkey=E7=94=9F=E6=88=90=E5=AF=86=E9=92=A5?=
 =?UTF-8?q?=E7=9A=84view?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 apps/users/views/profile/pubkey.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/apps/users/views/profile/pubkey.py b/apps/users/views/profile/pubkey.py
index 52c149084..4010fd996 100644
--- a/apps/users/views/profile/pubkey.py
+++ b/apps/users/views/profile/pubkey.py
@@ -46,8 +46,7 @@ class UserPublicKeyGenerateView(PermissionsMixin, View):
     def get(self, request, *args, **kwargs):
         username = request.user.username
         private, public = ssh_key_gen(username=username, hostname='jumpserver')
-        request.user.public_key = public
-        request.user.save()
+        request.user.set_public_key(public)
         response = HttpResponse(private, content_type='text/plain')
         filename = "{0}-jumpserver.pem".format(username)
         response['Content-Disposition'] = 'attachment; filename={}'.format(filename)

From 5730e60089e0d776e04663050d1273cb1563e020 Mon Sep 17 00:00:00 2001
From: Bai <bugatti_it@163.com>
Date: Thu, 4 Jun 2020 17:24:31 +0800
Subject: [PATCH 3/3] =?UTF-8?q?[Update]=20=E4=BF=AE=E6=94=B9=E7=94=A8?=
 =?UTF-8?q?=E6=88=B7profile=E5=BA=8F=E5=88=97=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 apps/users/serializers/user.py | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/apps/users/serializers/user.py b/apps/users/serializers/user.py
index fceeed5f3..019524cae 100644
--- a/apps/users/serializers/user.py
+++ b/apps/users/serializers/user.py
@@ -234,10 +234,6 @@ class UserProfileSerializer(UserSerializer):
             fields.remove('password')
             extra_kwargs.pop('password', None)
 
-        if 'public_key' in fields:
-            fields.remove('public_key')
-            extra_kwargs.pop('public_key', None)
-
     @staticmethod
     def get_guide_url(obj):
         return settings.USER_GUIDE_URL
@@ -247,6 +243,13 @@ class UserProfileSerializer(UserSerializer):
             return 2
         return mfa_level
 
+    def validate_public_key(self, public_key):
+        if self.instance and self.instance.can_update_ssh_key():
+            if not validate_ssh_public_key(public_key):
+                raise serializers.ValidationError(_('Not a valid ssh public key'))
+            return public_key
+        return None
+
 
 class UserUpdatePasswordSerializer(serializers.ModelSerializer):
     old_password = serializers.CharField(required=True, max_length=128, write_only=True)