From 290872dcade674ec8f87da579b22e552bc7fe52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=AE=A1=E5=AE=9C=E5=B0=A7?= Date: Sun, 24 Sep 2017 08:40:59 +0800 Subject: [PATCH 1/4] =?UTF-8?q?bugfix:=20=E8=A7=A3=E5=86=B3=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=A4=B1=E6=95=88=E6=97=B6=E9=97=B4=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E6=97=A0=E6=B3=95=E4=BD=BF=E7=94=A8=E5=AF=86?= =?UTF-8?q?=E7=A0=81=E8=BF=9B=E8=A1=8Cssh=E7=99=BB=E5=BD=95=E8=B7=B3?= =?UTF-8?q?=E6=9D=BF=E6=9C=BA=E7=9A=84=E9=97=AE=E9=A2=98=20(#659)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bugfix: 解决用户失效时间为空时,无法使用密码进行ssh登录跳板机的问题 bugfix: 解决用户失效时间为空时,无法使用密码进行ssh登录跳板机的问题。 ``` AttributeError at /api/users/v1/auth/ 'NoneType' object has no attribute 'strftime' Request Method: POST Request URL: http://127.0.0.1:8080/api/users/v1/auth/ Django Version: 1.11.4 Python Executable: /opt/py3/bin/python Python Version: 3.6.1 Python Path: ['/data/deployment/jumpserver/apps', '/usr/local/lib/python36.zip', '/usr/local/lib/python3.6', '/usr/local/lib/python3.6/lib-dynload', '/opt/py3/lib/python3.6/site-packages', '/data/deployment/jumpserver', '/data/deployment/jumpserver/apps'] Server time: Wed, 30 Aug 2017 23:18:47 +0800 Installed Applications: ['users.apps.UsersConfig', 'assets.apps.AssetsConfig', 'perms.apps.PermsConfig', 'ops.apps.OpsConfig', 'audits.apps.AuditsConfig', 'common.apps.CommonConfig', 'applications.apps.ApplicationsConfig', 'rest_framework', 'rest_framework_swagger', 'django_filters', 'bootstrap3', 'captcha', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles'] Installed Middleware: ['django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'jumpserver.middleware.TimezoneMiddleware', 'jumpserver.middleware.DemoMiddleware'] Traceback: File "/opt/py3/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 41. response = get_response(request) File "/opt/py3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 187. response = self.process_exception_by_middleware(e, request) File "/opt/py3/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 185. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/usr/local/lib/python3.6/contextlib.py" in inner 53. return func(*args, **kwds) File "/opt/py3/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view 58. return view_func(*args, **kwargs) File "/opt/py3/lib/python3.6/site-packages/django/views/generic/base.py" in view 68. return self.dispatch(request, *args, **kwargs) File "/opt/py3/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 489. response = self.handle_exception(exc) File "/opt/py3/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception 449. self.raise_uncaught_exception(exc) File "/opt/py3/lib/python3.6/site-packages/rest_framework/views.py" in dispatch 486. response = handler(request, *args, **kwargs) File "/data/deployment/jumpserver/apps/users/api.py" in post 166. return Response({'token': token, 'user': user.to_json()}) File "/data/deployment/jumpserver/apps/users/models/user.py" in to_json 207. 'date_expired': self.date_expired.strftime('%Y-%m-%d %H:%M:%S') Exception Type: AttributeError at /api/users/v1/auth/ Exception Value: 'NoneType' object has no attribute 'strftime' Request information: USER: AnonymousUser GET: No GET data POST: No POST data FILES: No FILES data COOKIES: No cookie data ``` * bugfix: 个人信息页面个人信息pannel错位 bugfix: 个人信息页面个人信息pannel错位 --- apps/users/models/user.py | 2 +- apps/users/templates/users/user_profile.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/users/models/user.py b/apps/users/models/user.py index fc40ee87a..660b5f350 100644 --- a/apps/users/models/user.py +++ b/apps/users/models/user.py @@ -204,7 +204,7 @@ class User(AbstractUser): 'wechat': self.wechat, 'phone': self.phone, 'comment': self.comment, - 'date_expired': self.date_expired.strftime('%Y-%m-%d %H:%M:%S') + 'date_expired': self.date_expired.strftime('%Y-%m-%d %H:%M:%S') if self.date_expired is not None else None }) @classmethod diff --git a/apps/users/templates/users/user_profile.html b/apps/users/templates/users/user_profile.html index 93a14ef86..c57eeb611 100644 --- a/apps/users/templates/users/user_profile.html +++ b/apps/users/templates/users/user_profile.html @@ -22,7 +22,7 @@
-
+
{{ user.name }} From 48ef5c421b4ce7c3a75f1e2af5d5d2209e1337b9 Mon Sep 17 00:00:00 2001 From: crisewng Date: Sun, 24 Sep 2017 08:41:42 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E6=9B=B4=E6=96=B0Mac=E5=AE=89=E8=A3=85ldap?= =?UTF-8?q?=E5=A4=B1=E8=B4=A5=E8=A7=A3=E5=86=B3=E6=96=B9=E6=B3=95=20(#613)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/install.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/install.md b/docs/install.md index 587b012b9..e6b240ab1 100644 --- a/docs/install.md +++ b/docs/install.md @@ -36,6 +36,10 @@ $ sudo yum -y install `cat rpm_requirements.txt` $ pip install -r requirements.txt -i https://pypi.doubanio.com/simple + // 解决Mac安装ldap提示 Modules/LDAPObject.c:18:10: fatal error: 'sasl.h' file not found + pip install python-ldap \ + --global-option=build_ext \ + --global-option="-I$(xcrun --show-sdk-path)/usr/include/sasl" ##### 2.3 准备配置文件 From 8342ba68c03596cfcb792c4266ebcffc74cf1901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=81=E5=B9=BF?= Date: Sun, 24 Sep 2017 08:57:20 +0800 Subject: [PATCH 3/4] Update requirements.txt --- requirements/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements/requirements.txt b/requirements/requirements.txt index e89c13f26..82ea60990 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -5,8 +5,8 @@ djangorestframework>=3.6.2 ForgeryPy #openpyxl>=2.4.0 celery>=4.0.2 -paramiko>=2.1.2 -ansible>=2.2.2.0 +paramiko==2.1.2 +ansible==2.2.2.0 django-simple-captcha>=0.5.5 django-formtools>=2.0 sshpubkeys>=2.2.0 From 43a0c4fe51d0d51bd67a218d0826cfdeb6d6d13e Mon Sep 17 00:00:00 2001 From: Caijun Date: Sun, 24 Sep 2017 09:16:47 +0800 Subject: [PATCH 4/4] Fix importing csv bugs (#717) * Fix exporting csv bugs 1. auto detect the encoding of csv 2. if id in csv is empty, let it equal 0 3. if hostname exists, give up this asset * Add chardet to requirements.txt --- apps/assets/views/asset.py | 22 +++++++++++++++++----- requirements/requirements.txt | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/apps/assets/views/asset.py b/apps/assets/views/asset.py index 935ec5964..a5411499b 100644 --- a/apps/assets/views/asset.py +++ b/apps/assets/views/asset.py @@ -5,6 +5,7 @@ import csv import json import uuid import codecs +import chardet from io import StringIO from collections import defaultdict @@ -242,10 +243,11 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): form_class = forms.FileForm def form_valid(self, form): - file = form.cleaned_data['file'] - data = file.read().decode('utf-8').strip( - codecs.BOM_UTF8.decode('utf-8')) - csv_file = StringIO(data) + f = form.cleaned_data['file'] + det_result = chardet.detect(f.read()) + f.seek(0) # reset file seek index + file_data = f.read().decode(det_result['encoding']).strip(codecs.BOM_UTF8.decode()) + csv_file = StringIO(file_data) reader = csv.reader(csv_file) csv_data = [row for row in reader] fields = [ @@ -269,8 +271,15 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): for row in csv_data[1:]: if set(row) == {''}: continue + asset_dict = dict(zip(attr, row)) id_ = asset_dict.pop('id', 0) + + try: + id_ = int(id_) + except ValueError: + id_ = 0 + asset = get_object_or_none(Asset, id=id_) for k, v in asset_dict.items(): if k == 'idc': @@ -294,11 +303,13 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): if not asset: try: groups = asset_dict.pop('groups') + if len(Asset.objects.filter(hostname=asset_dict.get('hostname'))): + raise Exception(_('already exists')) asset = Asset.objects.create(**asset_dict) asset.groups.set(groups) created.append(asset_dict['hostname']) assets.append(asset) - except IndexError as e: + except Exception as e: failed.append('%s: %s' % (asset_dict['hostname'], str(e))) else: for k, v in asset_dict.items(): @@ -316,6 +327,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): if assets: update_assets_hardware_info.delay([asset._to_secret_json() for asset in assets]) + data = { 'created': created, 'created_info': 'Created {}'.format(len(created)), diff --git a/requirements/requirements.txt b/requirements/requirements.txt index 82ea60990..952b041d6 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -21,3 +21,4 @@ gssapi django-rest-swagger django-auth-ldap ldap3 +chardet>=3.0.4