Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
c31b56dd
Commit
c31b56dd
authored
Nov 11, 2019
by
BaiJiangJie
Browse files
Options
Browse Files
Download
Plain Diff
[Update] Merge local branch dev to dev_ldap2
parents
0a08ba3b
0d2fc27a
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
153 additions
and
89 deletions
+153
-89
node.py
apps/assets/models/node.py
+1
-1
_asset_list_modal.html
apps/assets/templates/assets/_asset_list_modal.html
+1
-1
_node_tree.html
apps/assets/templates/assets/_node_tree.html
+2
-2
asset_list.html
apps/assets/templates/assets/asset_list.html
+12
-9
conf.py
apps/jumpserver/conf.py
+1
-0
signals_handler.py
apps/perms/signals_handler.py
+0
-7
api.py
apps/settings/api.py
+25
-5
serializers.py
apps/settings/serializers.py
+3
-0
api_urls.py
apps/settings/urls/api_urls.py
+1
-0
forms.py
apps/users/forms.py
+21
-1
__init__.py
apps/users/serializers/__init__.py
+2
-2
group.py
apps/users/serializers/group.py
+69
-0
user.py
apps/users/serializers/user.py
+1
-59
signals_handler.py
apps/users/signals_handler.py
+13
-2
_user.html
apps/users/templates/users/_user.html
+1
-0
No files found.
apps/assets/models/node.py
View file @
c31b56dd
...
@@ -68,7 +68,7 @@ class TreeMixin:
...
@@ -68,7 +68,7 @@ class TreeMixin:
@classmethod
@classmethod
def
refresh_node_assets
(
cls
,
t
=
None
):
def
refresh_node_assets
(
cls
,
t
=
None
):
logger
.
debug
(
"Refresh node
tree
assets"
)
logger
.
debug
(
"Refresh node assets"
)
key
=
cls
.
tree_assets_cache_key
key
=
cls
.
tree_assets_cache_key
ttl
=
cls
.
tree_cache_time
ttl
=
cls
.
tree_cache_time
if
not
t
:
if
not
t
:
...
...
apps/assets/templates/assets/_asset_list_modal.html
View file @
c31b56dd
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
<div
class=
"wrapper wrapper-content"
>
<div
class=
"wrapper wrapper-content"
>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-lg-3"
id=
"split-left"
style=
"padding-left: 3px"
>
<div
class=
"col-lg-3"
id=
"split-left"
style=
"padding-left: 3px
;overflow: auto;max-height: 500px
"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-content mailbox-content"
style=
"padding-top: 0;padding-left: 1px"
>
<div
class=
"ibox-content mailbox-content"
style=
"padding-top: 0;padding-left: 1px"
>
<div
class=
"file-manager "
>
<div
class=
"file-manager "
>
...
...
apps/assets/templates/assets/_node_tree.html
View file @
c31b56dd
...
@@ -32,8 +32,7 @@
...
@@ -32,8 +32,7 @@
}
}
</style>
</style>
<div
class=
"ibox treebox float-e-margins"
style=
"overflow:auto;"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-content mailbox-content"
style=
"padding-top: 0;padding-left: 1px"
>
<div
class=
"ibox-content mailbox-content"
style=
"padding-top: 0;padding-left: 1px"
>
<div
class=
"file-manager"
id=
"tree-node-id"
>
<div
class=
"file-manager"
id=
"tree-node-id"
>
<div
id=
"{% block treeID %}nodeTree{% endblock %}"
class=
"ztree"
>
<div
id=
"{% block treeID %}nodeTree{% endblock %}"
class=
"ztree"
>
...
@@ -306,6 +305,7 @@ function defaultCallback(action) {
...
@@ -306,6 +305,7 @@ function defaultCallback(action) {
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
$
(
'.treebox'
).
css
(
'height'
,
window
.
innerHeight
-
180
);
})
})
.
on
(
'click'
,
'.btn-show-current-asset'
,
function
(){
.
on
(
'click'
,
'.btn-show-current-asset'
,
function
(){
hideRMenu
();
hideRMenu
();
...
...
apps/assets/templates/assets/asset_list.html
View file @
c31b56dd
...
@@ -426,13 +426,15 @@ $(document).ready(function(){
...
@@ -426,13 +426,15 @@ $(document).ready(function(){
function
success
(
data
)
{
function
success
(
data
)
{
url
=
setUrlParam
(
the_url
,
'spm'
,
data
.
spm
);
url
=
setUrlParam
(
the_url
,
'spm'
,
data
.
spm
);
requestApi
({
requestApi
({
url
:
url
,
url
:
url
,
method
:
'DELETE'
,
method
:
'DELETE'
,
success
:
refreshPage
,
success
:
function
()
{
flash_message
:
false
,
});
var
msg
=
"{% trans 'Asset Deleted.' %}"
;
var
msg
=
"{% trans 'Asset Deleted.' %}"
;
swal
(
"{% trans 'Asset Delete' %}"
,
msg
,
"success"
);
swal
(
"{% trans 'Asset Delete' %}"
,
msg
,
"success"
);
refreshPage
();
},
flash_message
:
false
,
});
}
}
function
fail
()
{
function
fail
()
{
var
msg
=
"{% trans 'Asset Deleting failed.' %}"
;
var
msg
=
"{% trans 'Asset Deleting failed.' %}"
;
...
@@ -440,10 +442,11 @@ $(document).ready(function(){
...
@@ -440,10 +442,11 @@ $(document).ready(function(){
}
}
requestApi
({
requestApi
({
url
:
"{% url 'api-common:resources-cache' %}"
,
url
:
"{% url 'api-common:resources-cache' %}"
,
method
:
'POST'
,
method
:
'POST'
,
body
:
JSON
.
stringify
(
data
),
body
:
JSON
.
stringify
(
data
),
success
:
success
,
success
:
success
,
error
:
fail
error
:
fail
,
flash_message
:
false
})
})
})
})
}
}
...
...
apps/jumpserver/conf.py
View file @
c31b56dd
...
@@ -395,6 +395,7 @@ defaults = {
...
@@ -395,6 +395,7 @@ defaults = {
'FLOWER_URL'
:
"127.0.0.1:5555"
,
'FLOWER_URL'
:
"127.0.0.1:5555"
,
'DEFAULT_ORG_SHOW_ALL_USERS'
:
True
,
'DEFAULT_ORG_SHOW_ALL_USERS'
:
True
,
'PERIOD_TASK_ENABLED'
:
True
,
'PERIOD_TASK_ENABLED'
:
True
,
'WINDOWS_SKIP_ALL_MANUAL_PASSWORD'
:
False
,
}
}
...
...
apps/perms/signals_handler.py
View file @
c31b56dd
...
@@ -11,13 +11,6 @@ from .utils.asset_permission import AssetPermissionUtilV2
...
@@ -11,13 +11,6 @@ from .utils.asset_permission import AssetPermissionUtilV2
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
permission_m2m_senders
=
(
AssetPermission
.
nodes
.
through
,
AssetPermission
.
assets
.
through
,
AssetPermission
.
users
.
through
,
AssetPermission
.
user_groups
.
through
,
)
@receiver
([
post_save
,
post_delete
],
sender
=
AssetPermission
)
@receiver
([
post_save
,
post_delete
],
sender
=
AssetPermission
)
@on_transaction_commit
@on_transaction_commit
...
...
apps/settings/api.py
View file @
c31b56dd
...
@@ -21,7 +21,10 @@ from .utils import (
...
@@ -21,7 +21,10 @@ from .utils import (
from
.tasks
import
sync_ldap_user_task
from
.tasks
import
sync_ldap_user_task
from
common.permissions
import
IsOrgAdmin
,
IsSuperUser
from
common.permissions
import
IsOrgAdmin
,
IsSuperUser
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
.serializers
import
MailTestSerializer
,
LDAPTestSerializer
,
LDAPUserSerializer
from
.serializers
import
(
MailTestSerializer
,
LDAPTestSerializer
,
LDAPUserSerializer
,
PublicSettingSerializer
,
)
from
users.models
import
User
from
users.models
import
User
...
@@ -29,7 +32,7 @@ logger = get_logger(__file__)
...
@@ -29,7 +32,7 @@ logger = get_logger(__file__)
class
MailTestingAPI
(
APIView
):
class
MailTestingAPI
(
APIView
):
permission_classes
=
(
Is
OrgAdmin
,)
permission_classes
=
(
Is
SuperUser
,)
serializer_class
=
MailTestSerializer
serializer_class
=
MailTestSerializer
success_message
=
_
(
"Test mail sent to {}, please check"
)
success_message
=
_
(
"Test mail sent to {}, please check"
)
...
@@ -68,7 +71,7 @@ class MailTestingAPI(APIView):
...
@@ -68,7 +71,7 @@ class MailTestingAPI(APIView):
class
LDAPTestingAPI
(
APIView
):
class
LDAPTestingAPI
(
APIView
):
permission_classes
=
(
Is
OrgAdmin
,)
permission_classes
=
(
Is
SuperUser
,)
serializer_class
=
LDAPTestSerializer
serializer_class
=
LDAPTestSerializer
success_message
=
_
(
"Test ldap success"
)
success_message
=
_
(
"Test ldap success"
)
...
@@ -114,7 +117,7 @@ class LDAPTestingAPI(APIView):
...
@@ -114,7 +117,7 @@ class LDAPTestingAPI(APIView):
class
LDAPUserListApi
(
generics
.
ListAPIView
):
class
LDAPUserListApi
(
generics
.
ListAPIView
):
permission_classes
=
(
Is
OrgAdmin
,)
permission_classes
=
(
Is
SuperUser
,)
serializer_class
=
LDAPUserSerializer
serializer_class
=
LDAPUserSerializer
def
get_queryset_from_cache
(
self
):
def
get_queryset_from_cache
(
self
):
...
@@ -200,7 +203,7 @@ class LDAPUserListApi(generics.ListAPIView):
...
@@ -200,7 +203,7 @@ class LDAPUserListApi(generics.ListAPIView):
class
LDAPUserImportAPI
(
APIView
):
class
LDAPUserImportAPI
(
APIView
):
permission_classes
=
(
Is
OrgAdmin
,)
permission_classes
=
(
Is
SuperUser
,)
def
get_ldap_users
(
self
):
def
get_ldap_users
(
self
):
username_list
=
self
.
request
.
data
.
get
(
'username_list'
,
[])
username_list
=
self
.
request
.
data
.
get
(
'username_list'
,
[])
...
@@ -229,6 +232,7 @@ class LDAPUserImportAPI(APIView):
...
@@ -229,6 +232,7 @@ class LDAPUserImportAPI(APIView):
class
LDAPCacheRefreshAPI
(
generics
.
RetrieveAPIView
):
class
LDAPCacheRefreshAPI
(
generics
.
RetrieveAPIView
):
permission_classes
=
(
IsSuperUser
,)
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
def
retrieve
(
self
,
request
,
*
args
,
**
kwargs
):
try
:
try
:
...
@@ -318,3 +322,19 @@ class CommandStorageDeleteAPI(APIView):
...
@@ -318,3 +322,19 @@ class CommandStorageDeleteAPI(APIView):
storage_name
=
str
(
request
.
data
.
get
(
'name'
))
storage_name
=
str
(
request
.
data
.
get
(
'name'
))
Setting
.
delete_storage
(
'TERMINAL_COMMAND_STORAGE'
,
storage_name
)
Setting
.
delete_storage
(
'TERMINAL_COMMAND_STORAGE'
,
storage_name
)
return
Response
({
"msg"
:
_
(
'Delete succeed'
)},
status
=
200
)
return
Response
({
"msg"
:
_
(
'Delete succeed'
)},
status
=
200
)
class
PublicSettingApi
(
generics
.
RetrieveAPIView
):
permission_classes
=
()
serializer_class
=
PublicSettingSerializer
def
get_object
(
self
):
c
=
settings
.
CONFIG
instance
=
{
"data"
:
{
"WINDOWS_SKIP_ALL_MANUAL_PASSWORD"
:
c
.
WINDOWS_SKIP_ALL_MANUAL_PASSWORD
}
}
return
instance
apps/settings/serializers.py
View file @
c31b56dd
...
@@ -29,3 +29,6 @@ class LDAPUserSerializer(serializers.Serializer):
...
@@ -29,3 +29,6 @@ class LDAPUserSerializer(serializers.Serializer):
email
=
serializers
.
CharField
()
email
=
serializers
.
CharField
()
existing
=
serializers
.
BooleanField
(
read_only
=
True
)
existing
=
serializers
.
BooleanField
(
read_only
=
True
)
class
PublicSettingSerializer
(
serializers
.
Serializer
):
data
=
serializers
.
DictField
(
read_only
=
True
)
apps/settings/urls/api_urls.py
View file @
c31b56dd
...
@@ -16,4 +16,5 @@ urlpatterns = [
...
@@ -16,4 +16,5 @@ urlpatterns = [
path
(
'terminal/replay-storage/delete/'
,
api
.
ReplayStorageDeleteAPI
.
as_view
(),
name
=
'replay-storage-delete'
),
path
(
'terminal/replay-storage/delete/'
,
api
.
ReplayStorageDeleteAPI
.
as_view
(),
name
=
'replay-storage-delete'
),
path
(
'terminal/command-storage/create/'
,
api
.
CommandStorageCreateAPI
.
as_view
(),
name
=
'command-storage-create'
),
path
(
'terminal/command-storage/create/'
,
api
.
CommandStorageCreateAPI
.
as_view
(),
name
=
'command-storage-create'
),
path
(
'terminal/command-storage/delete/'
,
api
.
CommandStorageDeleteAPI
.
as_view
(),
name
=
'command-storage-delete'
),
path
(
'terminal/command-storage/delete/'
,
api
.
CommandStorageDeleteAPI
.
as_view
(),
name
=
'command-storage-delete'
),
path
(
'public/'
,
api
.
PublicSettingApi
.
as_view
(),
name
=
'public-setting'
),
]
]
apps/users/forms.py
View file @
c31b56dd
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
from
django
import
forms
from
django
import
forms
from
django.utils.translation
import
gettext_lazy
as
_
from
django.utils.translation
import
gettext_lazy
as
_
from
django.conf
import
settings
from
common.utils
import
validate_ssh_public_key
from
common.utils
import
validate_ssh_public_key
from
orgs.mixins.forms
import
OrgModelForm
from
orgs.mixins.forms
import
OrgModelForm
...
@@ -21,6 +22,20 @@ class UserCheckOtpCodeForm(forms.Form):
...
@@ -21,6 +22,20 @@ class UserCheckOtpCodeForm(forms.Form):
otp_code
=
forms
.
CharField
(
label
=
_
(
'MFA code'
),
max_length
=
6
)
otp_code
=
forms
.
CharField
(
label
=
_
(
'MFA code'
),
max_length
=
6
)
def
get_source_choices
():
choices_all
=
dict
(
User
.
SOURCE_CHOICES
)
choices
=
[
(
User
.
SOURCE_LOCAL
,
choices_all
[
User
.
SOURCE_LOCAL
]),
]
if
settings
.
AUTH_LDAP
:
choices
.
append
((
User
.
SOURCE_LDAP
,
choices_all
[
User
.
SOURCE_LDAP
]))
if
settings
.
AUTH_OPENID
:
choices
.
append
((
User
.
SOURCE_OPENID
,
choices_all
[
User
.
SOURCE_OPENID
]))
if
settings
.
AUTH_RADIUS
:
choices
.
append
((
User
.
SOURCE_RADIUS
,
choices_all
[
User
.
SOURCE_RADIUS
]))
return
choices
class
UserCreateUpdateFormMixin
(
OrgModelForm
):
class
UserCreateUpdateFormMixin
(
OrgModelForm
):
role_choices
=
((
i
,
n
)
for
i
,
n
in
User
.
ROLE_CHOICES
if
i
!=
User
.
ROLE_APP
)
role_choices
=
((
i
,
n
)
for
i
,
n
in
User
.
ROLE_CHOICES
if
i
!=
User
.
ROLE_APP
)
password
=
forms
.
CharField
(
password
=
forms
.
CharField
(
...
@@ -31,6 +46,10 @@ class UserCreateUpdateFormMixin(OrgModelForm):
...
@@ -31,6 +46,10 @@ class UserCreateUpdateFormMixin(OrgModelForm):
choices
=
role_choices
,
required
=
True
,
choices
=
role_choices
,
required
=
True
,
initial
=
User
.
ROLE_USER
,
label
=
_
(
"Role"
)
initial
=
User
.
ROLE_USER
,
label
=
_
(
"Role"
)
)
)
source
=
forms
.
ChoiceField
(
choices
=
get_source_choices
,
required
=
True
,
initial
=
User
.
SOURCE_LOCAL
,
label
=
_
(
"Source"
)
)
public_key
=
forms
.
CharField
(
public_key
=
forms
.
CharField
(
label
=
_
(
'ssh public key'
),
max_length
=
5000
,
required
=
False
,
label
=
_
(
'ssh public key'
),
max_length
=
5000
,
required
=
False
,
widget
=
forms
.
Textarea
(
attrs
=
{
'placeholder'
:
_
(
'ssh-rsa AAAA...'
)}),
widget
=
forms
.
Textarea
(
attrs
=
{
'placeholder'
:
_
(
'ssh-rsa AAAA...'
)}),
...
@@ -41,7 +60,8 @@ class UserCreateUpdateFormMixin(OrgModelForm):
...
@@ -41,7 +60,8 @@ class UserCreateUpdateFormMixin(OrgModelForm):
model
=
User
model
=
User
fields
=
[
fields
=
[
'username'
,
'name'
,
'email'
,
'groups'
,
'wechat'
,
'username'
,
'name'
,
'email'
,
'groups'
,
'wechat'
,
'phone'
,
'role'
,
'date_expired'
,
'comment'
,
'otp_level'
'source'
,
'phone'
,
'role'
,
'date_expired'
,
'comment'
,
'otp_level'
]
]
widgets
=
{
widgets
=
{
'otp_level'
:
forms
.
RadioSelect
(),
'otp_level'
:
forms
.
RadioSelect
(),
...
...
apps/users/serializers/__init__.py
View file @
c31b56dd
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
from
.v1
import
*
from
.user
import
*
\ No newline at end of file
from
.group
import
*
apps/users/serializers/group.py
0 → 100644
View file @
c31b56dd
# -*- coding: utf-8 -*-
#
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework
import
serializers
from
common.fields
import
StringManyToManyField
from
common.serializers
import
AdaptedBulkListSerializer
from
orgs.mixins.serializers
import
BulkOrgResourceModelSerializer
from
..models
import
User
,
UserGroup
from
..
import
utils
__all__
=
[
'UserGroupSerializer'
,
'UserGroupListSerializer'
,
'UserGroupUpdateMemberSerializer'
]
class
UserGroupSerializer
(
BulkOrgResourceModelSerializer
):
users
=
serializers
.
PrimaryKeyRelatedField
(
required
=
False
,
many
=
True
,
queryset
=
User
.
objects
,
label
=
_
(
'User'
)
)
class
Meta
:
model
=
UserGroup
list_serializer_class
=
AdaptedBulkListSerializer
fields
=
[
'id'
,
'name'
,
'users'
,
'comment'
,
'date_created'
,
'created_by'
,
]
extra_kwargs
=
{
'created_by'
:
{
'label'
:
_
(
'Created by'
),
'read_only'
:
True
}
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
self
.
set_fields_queryset
()
def
set_fields_queryset
(
self
):
users_field
=
self
.
fields
[
'users'
]
users_field
.
child_relation
.
queryset
=
utils
.
get_current_org_members
()
def
validate_users
(
self
,
users
):
for
user
in
users
:
if
user
.
is_super_auditor
:
msg
=
_
(
'Auditors cannot be join in the user group'
)
raise
serializers
.
ValidationError
(
msg
)
return
users
class
UserGroupListSerializer
(
UserGroupSerializer
):
users
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
class
UserGroupUpdateMemberSerializer
(
serializers
.
ModelSerializer
):
users
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
User
.
objects
)
class
Meta
:
model
=
UserGroup
fields
=
[
'id'
,
'users'
]
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
self
.
set_fields_queryset
()
def
set_fields_queryset
(
self
):
users_field
=
self
.
fields
[
'users'
]
users_field
.
child_relation
.
queryset
=
utils
.
get_current_org_members
()
apps/users/serializers/
v1
.py
→
apps/users/serializers/
user
.py
View file @
c31b56dd
...
@@ -6,19 +6,14 @@ from rest_framework import serializers
...
@@ -6,19 +6,14 @@ from rest_framework import serializers
from
common.utils
import
validate_ssh_public_key
from
common.utils
import
validate_ssh_public_key
from
common.mixins
import
BulkSerializerMixin
from
common.mixins
import
BulkSerializerMixin
from
common.fields
import
StringManyToManyField
from
common.serializers
import
AdaptedBulkListSerializer
from
common.serializers
import
AdaptedBulkListSerializer
from
common.permissions
import
CanUpdateDeleteUser
from
common.permissions
import
CanUpdateDeleteUser
from
orgs.mixins.serializers
import
BulkOrgResourceModelSerializer
from
..models
import
User
,
UserGroup
from
..models
import
User
,
UserGroup
from
..
import
utils
__all__
=
[
__all__
=
[
'UserSerializer'
,
'UserPKUpdateSerializer'
,
'UserUpdateGroupSerializer'
,
'UserSerializer'
,
'UserPKUpdateSerializer'
,
'UserUpdateGroupSerializer'
,
'UserGroupSerializer'
,
'UserGroupListSerializer'
,
'ChangeUserPasswordSerializer'
,
'ResetOTPSerializer'
,
'UserGroupUpdateMemberSerializer'
,
'ChangeUserPasswordSerializer'
,
'ResetOTPSerializer'
,
]
]
...
@@ -49,7 +44,6 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
...
@@ -49,7 +44,6 @@ class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
'is_valid'
:
{
'label'
:
_
(
'Is valid'
)},
'is_valid'
:
{
'label'
:
_
(
'Is valid'
)},
'is_expired'
:
{
'label'
:
_
(
'Is expired'
)},
'is_expired'
:
{
'label'
:
_
(
'Is expired'
)},
'avatar_url'
:
{
'label'
:
_
(
'Avatar url'
)},
'avatar_url'
:
{
'label'
:
_
(
'Avatar url'
)},
'source'
:
{
'read_only'
:
True
},
'created_by'
:
{
'read_only'
:
True
,
'allow_blank'
:
True
},
'created_by'
:
{
'read_only'
:
True
,
'allow_blank'
:
True
},
'can_update'
:
{
'read_only'
:
True
},
'can_update'
:
{
'read_only'
:
True
},
'can_delete'
:
{
'read_only'
:
True
},
'can_delete'
:
{
'read_only'
:
True
},
...
@@ -127,58 +121,6 @@ class UserUpdateGroupSerializer(serializers.ModelSerializer):
...
@@ -127,58 +121,6 @@ class UserUpdateGroupSerializer(serializers.ModelSerializer):
fields
=
[
'id'
,
'groups'
]
fields
=
[
'id'
,
'groups'
]
class
UserGroupSerializer
(
BulkOrgResourceModelSerializer
):
users
=
serializers
.
PrimaryKeyRelatedField
(
required
=
False
,
many
=
True
,
queryset
=
User
.
objects
,
label
=
_
(
'User'
)
)
class
Meta
:
model
=
UserGroup
list_serializer_class
=
AdaptedBulkListSerializer
fields
=
[
'id'
,
'name'
,
'users'
,
'comment'
,
'date_created'
,
'created_by'
,
]
extra_kwargs
=
{
'created_by'
:
{
'label'
:
_
(
'Created by'
),
'read_only'
:
True
}
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
self
.
set_fields_queryset
()
def
set_fields_queryset
(
self
):
users_field
=
self
.
fields
[
'users'
]
users_field
.
child_relation
.
queryset
=
utils
.
get_current_org_members
()
def
validate_users
(
self
,
users
):
for
user
in
users
:
if
user
.
is_super_auditor
:
msg
=
_
(
'Auditors cannot be join in the user group'
)
raise
serializers
.
ValidationError
(
msg
)
return
users
class
UserGroupListSerializer
(
UserGroupSerializer
):
users
=
StringManyToManyField
(
many
=
True
,
read_only
=
True
)
class
UserGroupUpdateMemberSerializer
(
serializers
.
ModelSerializer
):
users
=
serializers
.
PrimaryKeyRelatedField
(
many
=
True
,
queryset
=
User
.
objects
)
class
Meta
:
model
=
UserGroup
fields
=
[
'id'
,
'users'
]
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
self
.
set_fields_queryset
()
def
set_fields_queryset
(
self
):
users_field
=
self
.
fields
[
'users'
]
users_field
.
child_relation
.
queryset
=
utils
.
get_current_org_members
()
class
ChangeUserPasswordSerializer
(
serializers
.
ModelSerializer
):
class
ChangeUserPasswordSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
class
Meta
:
...
...
apps/users/signals_handler.py
View file @
c31b56dd
...
@@ -2,11 +2,11 @@
...
@@ -2,11 +2,11 @@
#
#
from
django.dispatch
import
receiver
from
django.dispatch
import
receiver
# from django.db.models.signals import post_save
from
django.db.models.signals
import
post_save
,
m2m_changed
from
common.utils
import
get_logger
from
common.utils
import
get_logger
from
.signals
import
post_user_create
from
.signals
import
post_user_create
#
from .models import User
from
.models
import
User
logger
=
get_logger
(
__file__
)
logger
=
get_logger
(
__file__
)
...
@@ -28,3 +28,14 @@ def on_user_create(sender, user=None, **kwargs):
...
@@ -28,3 +28,14 @@ def on_user_create(sender, user=None, **kwargs):
logger
.
info
(
" - Sending welcome mail ..."
.
format
(
user
.
name
))
logger
.
info
(
" - Sending welcome mail ..."
.
format
(
user
.
name
))
if
user
.
email
:
if
user
.
email
:
send_user_created_mail
(
user
)
send_user_created_mail
(
user
)
@receiver
(
m2m_changed
,
sender
=
User
.
groups
.
through
)
def
on_user_groups_change
(
sender
,
instance
=
None
,
action
=
''
,
**
kwargs
):
"""
资产节点发生变化时,刷新节点
"""
if
action
.
startswith
(
'post'
):
logger
.
debug
(
"User group member change signal recv: {}"
.
format
(
instance
))
from
perms.utils
import
AssetPermissionUtilV2
AssetPermissionUtilV2
.
expire_all_user_tree_cache
()
apps/users/templates/users/_user.html
View file @
c31b56dd
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
<h3>
{% trans 'Auth' %}
</h3>
<h3>
{% trans 'Auth' %}
</h3>
{% block password %}{% endblock %}
{% block password %}{% endblock %}
{% bootstrap_field form.otp_level layout="horizontal" %}
{% bootstrap_field form.otp_level layout="horizontal" %}
{% bootstrap_field form.source layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Security and Role' %}
</h3>
<h3>
{% trans 'Security and Role' %}
</h3>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment