mirror of https://github.com/jumpserver/jumpserver
user-profile page
parent
31bded8953
commit
f3647ea46d
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load common_tags %}
|
||||
{% load users_tags %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/sweetalert/sweetalert.css" %}" rel="stylesheet">
|
||||
<script src="{% static "js/plugins/sweetalert/sweetalert.min.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span class="label label-primary"><b>{{ user.name }}</b></span>
|
||||
<div class="ibox-tools">
|
||||
<a class="collapse-link">
|
||||
<i class="fa fa-chevron-up"></i>
|
||||
</a>
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<div>
|
||||
<div class="text-left">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<td class="text-navy">用户名</td>
|
||||
<td>{{ user.username }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">姓名</td>
|
||||
<td>{{ user.name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">权限</td>
|
||||
<td>{{ user.get_role_display }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">Email</td>
|
||||
<td>{{ user.email }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">激活</td>
|
||||
<td>{{ user.is_active }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">添加日期</td>
|
||||
<td>{{ user.date_joined|date:"Y-m-d H:i:s" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">最后登录</td>
|
||||
<td>{{ user.last_login|date:"Y-m-d H:i:s" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">所在用户组</td>
|
||||
<td>
|
||||
{% for group in user.groups.all %}
|
||||
<span class="simple-tag with-link">
|
||||
<a href="{% url 'users:user-group-detail' group.id %}">{{ group.name }}</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">授权主机数量</td>
|
||||
<td>{{ assets | length }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">授权主机组</td>
|
||||
<td>
|
||||
{% for group in asset_groups %}
|
||||
<span class="simple-tag with-link">
|
||||
<a href="#">{{ group.name }}</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-navy">授权规则</td>
|
||||
<td>
|
||||
{% for perm in permissions %}
|
||||
<span class="simple-tag with-link">
|
||||
<a href="#">{{ perm.name }}</a>
|
||||
</span>
|
||||
{% endfor %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-4"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
{% endblock %}
|
|
@ -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<pk>[0-9]+)$', views.UserDetailView.as_view(),
|
||||
|
|
|
@ -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)
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue