diff --git a/apps/static/css/jumpserver.css b/apps/static/css/jumpserver.css
index ecbde4cc4..a7a6d0af4 100644
--- a/apps/static/css/jumpserver.css
+++ b/apps/static/css/jumpserver.css
@@ -225,6 +225,7 @@ table.dataTable tbody td.selected td i.text-navy
background: #f1f1f1;
margin-right: 2px;
}
+
.form-asset-on{
border: 1px solid #e5e6e7;
padding-top:5px;
@@ -263,4 +264,16 @@ div.dataTables_wrapper div.dataTables_filter,
div.dataTables_wrapper div.dataTables_filter {
margin-left: 15px;
-}
\ No newline at end of file
+}
+
+.simple-tag {
+ background-color: #f3f3f4;
+ border: 1px solid #e7eaec;
+ border-radius: 2px;
+ color: inherit;
+ display: inline-block;
+ font-size: 10px;
+ margin-right: 5px;
+ margin-top: 5px;
+ padding: 5px 12px;
+}
diff --git a/apps/users/templates/users/user_profile.html b/apps/users/templates/users/user_profile.html
new file mode 100644
index 000000000..11b5b55fb
--- /dev/null
+++ b/apps/users/templates/users/user_profile.html
@@ -0,0 +1,114 @@
+{% extends 'base.html' %}
+{% load common_tags %}
+{% load users_tags %}
+{% load static %}
+{% load i18n %}
+
+{% block custom_head_css_js %}
+
+
+{% endblock %}
+{% block content %}
+
+
+
+
+
+
+
+
+
+
+ 用户名 |
+ {{ user.username }} |
+
+
+ 姓名 |
+ {{ user.name }} |
+
+
+ 权限 |
+ {{ user.get_role_display }} |
+
+
+ Email |
+ {{ user.email }} |
+
+
+ 激活 |
+ {{ user.is_active }} |
+
+
+ 添加日期 |
+ {{ user.date_joined|date:"Y-m-d H:i:s" }} |
+
+
+ 最后登录 |
+ {{ user.last_login|date:"Y-m-d H:i:s" }} |
+
+
+ 所在用户组 |
+
+ {% for group in user.groups.all %}
+
+ {{ group.name }}
+
+ {% endfor %}
+ |
+
+
+ 授权主机数量 |
+ {{ assets | length }} |
+
+
+ 授权主机组 |
+
+ {% for group in asset_groups %}
+
+ {{ group.name }}
+
+ {% endfor %}
+ |
+
+
+ 授权规则 |
+
+ {% for perm in permissions %}
+
+ {{ perm.name }}
+
+ {% endfor %}
+ |
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
+{% block custom_foot_js %}
+{% endblock %}
diff --git a/apps/users/urls/views_urls.py b/apps/users/urls/views_urls.py
index 58c531765..9ec2fecf6 100644
--- a/apps/users/urls/views_urls.py
+++ b/apps/users/urls/views_urls.py
@@ -1,6 +1,7 @@
from __future__ import absolute_import
from django.conf.urls import url
+
from .. import views
app_name = 'users'
@@ -20,6 +21,11 @@ urlpatterns = [
views.UserResetPasswordSuccessView.as_view(),
name='reset-password-success'),
+ # Profile
+ url(r'^profile/$',
+ views.UserProfileView.as_view(),
+ name='user-profile'),
+
# User view
url(r'^user$', views.UserListView.as_view(), name='user-list'),
url(r'^user/(?P[0-9]+)$', views.UserDetailView.as_view(),
diff --git a/apps/users/views/user.py b/apps/users/views/user.py
index 8a2df396e..e5e0579cd 100644
--- a/apps/users/views/user.py
+++ b/apps/users/views/user.py
@@ -1,17 +1,19 @@
# ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals
-import uuid
-import json
-from django.shortcuts import redirect
+import json
+import uuid
+
+from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.writer.excel import save_virtual_workbook
-from openpyxl import load_workbook
-from django import forms
+
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib.messages.views import SuccessMessageMixin
from django.core.cache import cache
from django.http import HttpResponse, JsonResponse
-from django.contrib.messages.views import SuccessMessageMixin
+from django.shortcuts import redirect
from django.urls import reverse_lazy, reverse
from django.utils import timezone
from django.utils.translation import ugettext as _
@@ -19,22 +21,23 @@ from django.utils.decorators import method_decorator
from django.views import View
from django.views.generic import ListView
from django.views.generic.base import TemplateView
-from django.views.generic.edit import CreateView, UpdateView, FormMixin, \
- FormView
+from django.views.generic.edit import (CreateView, UpdateView, FormMixin,
+ FormView)
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.views.decorators.csrf import csrf_exempt
+from .. import forms
+from ..models import User, UserGroup
+from ..utils import AdminUserRequiredMixin, user_add_success_next
from common.mixins import JSONResponseMixin
from common.utils import get_logger
from perms.models import AssetPermission
-from ..models import User, UserGroup
-from ..utils import AdminUserRequiredMixin, user_add_success_next
-from .. import forms
__all__ = ['UserListView', 'UserCreateView', 'UserDetailView',
'UserUpdateView', 'UserAssetPermissionCreateView',
'UserAssetPermissionView', 'UserGrantedAssetView',
- 'UserExportView', 'UserBulkImportView']
+ 'UserExportView', 'UserBulkImportView', 'UserProfileView']
+
logger = get_logger(__name__)
@@ -118,6 +121,7 @@ class UserDetailView(AdminUserRequiredMixin, DetailView):
@method_decorator(csrf_exempt, name='dispatch')
class UserExportView(View):
+
def get(self, request, *args, **kwargs):
spm = request.GET.get('spm', '')
users_id = cache.get(spm)
@@ -135,13 +139,14 @@ class UserExportView(View):
for user in users:
ws.append([user.name, user.username, user.email,
','.join([group.name for group in user.groups.all()]),
- user.role, user.phone, user.wechat, user.comment])
+ user.role, user.phone, user.wechat, user.comment])
filename = 'users-{}.xlsx'.format(
timezone.localtime(timezone.now()).strftime('%Y-%m-%d_%H-%M-%S'))
response = HttpResponse(save_virtual_workbook(wb),
content_type='applications/vnd.ms-excel')
- response['Content-Disposition'] = 'attachment; filename="%s"' % filename
+ response[
+ 'Content-Disposition'] = 'attachment; filename="%s"' % filename
return response
def post(self, request, *args, **kwargs):
@@ -180,11 +185,13 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
return self.render_json_response(data)
rows = ws.rows
- header_need = ["name", 'username', 'email', 'groups', "role", "phone", "wechat", "comment"]
+ header_need = ["name", 'username', 'email',
+ 'groups', "role", "phone", "wechat", "comment"]
header = [col.value for col in next(rows)]
print(header)
if header != header_need:
- data = {'valid': False, 'msg': 'Must be same format as template or export file'}
+ data = {
+ 'valid': False, 'msg': 'Must be same format as template or export file'}
return self.render_json_response(data)
created = []
@@ -297,4 +304,28 @@ class UserGrantedAssetView(AdminUserRequiredMixin, DetailView):
'action': 'User granted asset',
}
kwargs.update(context)
- return super(UserGrantedAssetView, self).get_context_data(**kwargs)
\ No newline at end of file
+ return super(UserGrantedAssetView, self).get_context_data(**kwargs)
+
+
+class UserProfileView(LoginRequiredMixin, TemplateView):
+ template_name = 'users/user_profile.html'
+
+ def get_context_data(self, **kwargs):
+ from perms.utils import (get_user_granted_assets,
+ get_user_granted_asset_groups,
+ get_user_asset_permissions)
+ assets = get_user_granted_assets(self.request.user)
+ asset_groups = get_user_granted_asset_groups(self.request.user)
+ permissions = get_user_asset_permissions(self.request.user)
+ context = {
+ 'app': 'User',
+ 'action': 'User Profile',
+ 'assets': assets,
+ 'asset_groups': asset_groups,
+ 'permissions': permissions
+ }
+ print assets
+ print asset_groups
+ print permissions
+ kwargs.update(context)
+ return super(UserProfileView, self).get_context_data(**kwargs)