mirror of https://github.com/jumpserver/jumpserver
Finish user asset form
parent
e232962649
commit
ab2eeb0da3
|
@ -358,7 +358,7 @@ class SystemUserCreateView(AdminUserRequiredMixin, SuccessMessageMixin, CreateVi
|
|||
self.object.name,
|
||||
))
|
||||
|
||||
return self.success_message
|
||||
return success_message
|
||||
|
||||
|
||||
class SystemUserUpdateView(AdminUserRequiredMixin, UpdateView):
|
||||
|
|
|
@ -11,12 +11,18 @@ from common.utils import date_expired_default, combine_seq
|
|||
|
||||
|
||||
class AssetPermission(models.Model):
|
||||
name = models.CharField(max_length=128, verbose_name=_('Name'))
|
||||
PRIVATE_FOR_CHOICE = (
|
||||
('N', 'None'),
|
||||
('U', 'user'),
|
||||
('G', 'user group'),
|
||||
)
|
||||
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
|
||||
users = models.ManyToManyField(User, related_name='asset_permissions', blank=True)
|
||||
user_groups = models.ManyToManyField(UserGroup, related_name='asset_permissions', blank=True)
|
||||
assets = models.ManyToManyField(Asset, related_name='granted_by_permissions', blank=True)
|
||||
asset_groups = models.ManyToManyField(AssetGroup, related_name='granted_by_permissions', blank=True)
|
||||
system_users = models.ManyToManyField(SystemUser, related_name='granted_by_permissions')
|
||||
private_for = models.CharField(choices=PRIVATE_FOR_CHOICE, max_length=1, default='N', verbose_name=_('Private for'))
|
||||
is_active = models.BooleanField(default=True, verbose_name=_('Active'))
|
||||
date_expired = models.DateTimeField(default=date_expired_default, verbose_name=_('Date expired'))
|
||||
created_by = models.CharField(max_length=128, blank=True, verbose_name=_('Created by'))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
@import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700");
|
||||
@import url("https://fonts.googleapis.com/css?family=Roboto:400,300,500,700");
|
||||
@import url("https://fonts.useso.com/css?family=Open+Sans:300,400,600,700");
|
||||
@import url("https://fonts.useso.com/css?family=Roboto:400,300,500,700");
|
||||
/*
|
||||
*
|
||||
* INSPINIA - Responsive Admin Theme
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
from django import forms
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from captcha.fields import CaptchaField
|
||||
|
||||
from .models import User, UserGroup
|
||||
from .hands import AssetPermission
|
||||
|
||||
|
||||
class UserLoginForm(AuthenticationForm):
|
||||
|
@ -25,12 +25,10 @@ class UserCreateForm(forms.ModelForm):
|
|||
'username', 'name', 'email', 'groups', 'wechat',
|
||||
'phone', 'enable_otp', 'role', 'date_expired', 'comment',
|
||||
]
|
||||
|
||||
help_texts = {
|
||||
'username': '* required',
|
||||
'email': '* required',
|
||||
}
|
||||
|
||||
widgets = {
|
||||
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join user groups')}),
|
||||
}
|
||||
|
@ -44,13 +42,11 @@ class UserUpdateForm(forms.ModelForm):
|
|||
'name', 'email', 'groups', 'wechat',
|
||||
'phone', 'enable_otp', 'role', 'date_expired', 'comment',
|
||||
]
|
||||
|
||||
help_texts = {
|
||||
'username': '* required',
|
||||
'email': '* required',
|
||||
'groups': '* required'
|
||||
}
|
||||
|
||||
widgets = {
|
||||
'groups': forms.SelectMultiple(attrs={'class': 'select2', 'data-placeholder': _('Join user groups')}),
|
||||
}
|
||||
|
@ -60,11 +56,9 @@ class UserGroupForm(forms.ModelForm):
|
|||
|
||||
class Meta:
|
||||
model = UserGroup
|
||||
|
||||
fields = [
|
||||
'name', 'comment',
|
||||
]
|
||||
|
||||
help_texts = {
|
||||
'name': '* required'
|
||||
}
|
||||
|
@ -88,3 +82,33 @@ class UserKeyForm(forms.Form):
|
|||
if not checked:
|
||||
raise forms.ValidationError(_('Not a valid ssh private key.'))
|
||||
return ssh_pk
|
||||
|
||||
|
||||
class UserPrivateAssetPermissionForm(forms.ModelForm):
|
||||
|
||||
def save(self, commit=True):
|
||||
self.instance = super(UserPrivateAssetPermissionForm, self).save(commit=commit)
|
||||
self.instance.users = [self.user]
|
||||
self.instance.name = '_Private for %s %s' % (self.user.username, )
|
||||
self.instance.save()
|
||||
return self.instance
|
||||
|
||||
def clean_private_for(self):
|
||||
return 'U'
|
||||
|
||||
class Meta:
|
||||
model = AssetPermission
|
||||
fields = [
|
||||
'assets', 'asset_groups', 'system_users', 'private_for', 'name',
|
||||
]
|
||||
widgets = {
|
||||
'assets': forms.SelectMultiple(attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select assets')}),
|
||||
'asset_groups': forms.SelectMultiple(attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select asset groups')}),
|
||||
'system_users': forms.SelectMultiple(attrs={'class': 'select2',
|
||||
'data-placeholder': _('Select system users')}),
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -10,5 +10,7 @@
|
|||
:license: GPL v2, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
from perms.models import AssetPermission
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
{% extends 'base.html' %}
|
||||
{% load common_tags %}
|
||||
{% load users_tags %}
|
||||
{% load bootstrap %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block custom_head_css_js %}
|
||||
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
|
||||
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="wrapper wrapper-content animated fadeInRight">
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{% url 'users:user-detail' pk=user_object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="{% url 'users:user-asset-permission' pk=user_object.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission list' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-granted-asset' pk=user_object.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-login-history' pk=user_object.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a>
|
||||
</li>
|
||||
<form id="search_form" method="get" action="" class="pull-right mail-search">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
|
||||
<div class="input-group-btn">
|
||||
<button id="search_btn" type="submit" class="btn btn-sm btn-primary">
|
||||
搜索
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
<div class="col-sm-7" style="padding-left: 0;">
|
||||
<div class="ibox float-e-margins">
|
||||
<div class="ibox-title">
|
||||
<span style="float: left">{% trans 'Asset permission of ' %} <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">
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ibox-content">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center"><a href="{% url 'perms:asset-permission-list' %}?sort=name">{% trans 'Name' %}</a></th>
|
||||
<th class="text-center">{% trans 'User ' %}</th>
|
||||
<th class="text-center">{% trans 'User group ' %}</th>
|
||||
<th class="text-center">{% trans 'Asset ' %}</th>
|
||||
<th class="text-center">{% trans 'Asset group ' %}</th>
|
||||
<th class="text-center">{% trans 'System user ' %}</th>
|
||||
<th class="text-center">
|
||||
<a href="#">{% trans 'Is valid' %}</a>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for asset_permission in object_list %}
|
||||
<tr class="gradeX">
|
||||
<td class="text-center">
|
||||
<a href="{% url 'perms:asset-permission-detail' pk=asset_permission.id %}">
|
||||
{{ asset_permission.name }}
|
||||
</a>
|
||||
</td>
|
||||
<td class="text-center">{{ asset_permission.users.count}}</td>
|
||||
<td class="text-center">{{ asset_permission.user_groups.count}}</td>
|
||||
<td class="text-center">{{ asset_permission.assets.count }}</td>
|
||||
<td class="text-center">{{ asset_permission.asset_groups.count }}</td>
|
||||
<td class="text-center">{{ asset_permission.system_users.count }}</td>
|
||||
<td class="text-center">
|
||||
{% if asset_permission.is_valid %}
|
||||
<i class="fa fa-check text-navy"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-times text-danger"></i>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<button class="btn btn-danger btn-xs btn_delete_user_group {% if asset_permission.is_inherit_from_user_groups %} disabled {% endif %}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="row">
|
||||
{% include '_pagination.html' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
|
||||
<div class="panel panel-primary">
|
||||
<div class="panel-heading">
|
||||
<i class="fa fa-info-circle"></i> {% trans 'Quick create permission for user' %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
{% csrf_token %}
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{{ form.assets|bootstrap }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{{ form.asset_groups|bootstrap }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td colspan="1" style="padding-top: 0">
|
||||
{{ form.system_users|bootstrap }}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="no-borders-tr">
|
||||
<td>
|
||||
<button type="button"
|
||||
class="btn btn-primary btn-sm">{% trans 'Submit' %}</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block custom_foot_js %}
|
||||
<script>
|
||||
{# function switch_user_status(obj) {#}
|
||||
{# var status = $(obj).prop('checked');#}
|
||||
{##}
|
||||
{# $.ajax({#}
|
||||
{# url: "{% url 'users:user-active-api' pk=user_object.id %}",#}
|
||||
{# type: "PUT",#}
|
||||
{# data: {#}
|
||||
{# 'is_active': status#}
|
||||
{# },#}
|
||||
{# success: function (data, status) {#}
|
||||
{# console.log(data)#}
|
||||
{# },#}
|
||||
{# error: function () {#}
|
||||
{# console.log('error')#}
|
||||
{# }#}
|
||||
{# })#}
|
||||
{# }#}
|
||||
$(document).ready(function () {
|
||||
$('.select2').select2();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -18,11 +18,13 @@
|
|||
<div class="panel-options">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active">
|
||||
<a href="" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
<a href="{% url 'users:user-detail' pk=user_object.id %}" class="text-center"><i class="fa fa-laptop"></i> {% trans 'User detail' %} </a>
|
||||
</li>
|
||||
<li><a href="" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission list' %}</a></li>
|
||||
<li><a href="" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a></li>
|
||||
<li><a href="" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a></li>
|
||||
<li>
|
||||
<a href="{% url 'users:user-asset-permission' pk=user_object.id %}" class="text-center"><i class="fa fa-bar-chart-o"></i> {% trans 'Asset permission list' %}</a>
|
||||
</li>
|
||||
<li><a href="{% url 'users:user-granted-asset' pk=user_object.id %}" class="text-center"><i class="fa fa-cubes"></i> {% trans 'Asset granted' %}</a></li>
|
||||
<li><a href="{% url 'users:user-login-history' pk=user_object.id %}" class="text-center"><i class="fa fa-calculator-o"></i> {% trans 'Login history' %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
|
|
|
@ -16,6 +16,10 @@ urlpatterns = [
|
|||
name='reset-password-success'),
|
||||
url(r'^user$', views.UserListView.as_view(), name='user-list'),
|
||||
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(),
|
||||
name='user-asset-permission'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/asset-granted', views.UserDetailView.as_view(), name='user-granted-asset'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/login-history', views.UserDetailView.as_view(), name='user-login-history'),
|
||||
url(r'^first-login/$', views.UserFirstLoginView.as_view(), name='user-first-login'),
|
||||
url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
|
||||
url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import login as auth_login, logout as auth_logout
|
||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
|
@ -20,7 +18,7 @@ from django.views.decorators.csrf import csrf_protect
|
|||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
from django.views.generic.base import TemplateView
|
||||
from django.views.generic.list import ListView
|
||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView, FormView
|
||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView, FormView, SingleObjectMixin, FormMixin
|
||||
from django.views.generic.detail import DetailView
|
||||
|
||||
from formtools.wizard.views import SessionWizardView
|
||||
|
@ -28,10 +26,12 @@ from formtools.wizard.views import SessionWizardView
|
|||
from common.utils import get_object_or_none, get_logger
|
||||
|
||||
from .models import User, UserGroup
|
||||
from .forms import UserCreateForm, UserUpdateForm, UserGroupForm, UserLoginForm, UserInfoForm, UserKeyForm
|
||||
from .forms import UserCreateForm, UserUpdateForm, UserGroupForm, UserLoginForm, UserInfoForm, UserKeyForm, \
|
||||
UserPrivateAssetPermissionForm
|
||||
from .utils import AdminUserRequiredMixin, user_add_success_next, send_reset_password_mail
|
||||
|
||||
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
|
@ -355,3 +355,43 @@ class UserFirstLoginView(LoginRequiredMixin, SessionWizardView):
|
|||
'phone': user.phone or ''
|
||||
}
|
||||
return super(UserFirstLoginView, self).get_form_initial(step)
|
||||
|
||||
|
||||
class UserAssetPermissionView(AdminUserRequiredMixin, FormMixin, SingleObjectMixin, ListView):
|
||||
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
|
||||
template_name = 'users/user_asset_permission.html'
|
||||
context_object_name = 'user_object'
|
||||
form_class = UserPrivateAssetPermissionForm
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.object = self.get_object(queryset=User.objects.all())
|
||||
return super(UserAssetPermissionView, self).get(request, *args, **kwargs)
|
||||
|
||||
def get_asset_permission_inherit_from_user_group(self):
|
||||
asset_permissions = set()
|
||||
user_groups = self.object.groups.all()
|
||||
|
||||
for user_group in user_groups:
|
||||
for asset_permission in user_group.asset_permissions.all():
|
||||
setattr(asset_permission, 'is_inherit_from_user_groups', True)
|
||||
setattr(asset_permission, 'inherit_from_user_groups',
|
||||
getattr(asset_permission, b'inherit_from_user_groups', set()).add(user_group))
|
||||
asset_permissions.add(asset_permission)
|
||||
return asset_permissions
|
||||
|
||||
def get_queryset(self):
|
||||
asset_permissions = set(self.object.asset_permissions.all()) \
|
||||
| self.get_asset_permission_inherit_from_user_group()
|
||||
return list(asset_permissions)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = {
|
||||
'app': 'Users',
|
||||
'action': 'User asset permissions',
|
||||
}
|
||||
kwargs.update(context)
|
||||
return super(UserAssetPermissionView, self).get_context_data(**kwargs)
|
||||
|
||||
|
||||
class UserAssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
|
||||
pass
|
||||
|
|
Loading…
Reference in New Issue