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
58c4a46f
Commit
58c4a46f
authored
Mar 05, 2019
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 用户权限增加cache
parent
dfd26d88
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
265 additions
and
72 deletions
+265
-72
node.py
apps/assets/models/node.py
+1
-0
signals.py
apps/assets/signals.py
+0
-5
user_asset_list.html
apps/assets/templates/assets/user_asset_list.html
+11
-5
error_views.py
apps/jumpserver/error_views.py
+20
-0
urls.py
apps/jumpserver/urls.py
+4
-1
command_execution_create.html
apps/ops/templates/ops/command_execution_create.html
+2
-2
user_permission.py
apps/perms/api/user_permission.py
+88
-16
signals_handler.py
apps/perms/signals_handler.py
+12
-1
utils.py
apps/perms/utils.py
+65
-29
forms.py
apps/settings/forms.py
+2
-1
jumpserver.css
apps/static/css/jumpserver.css
+5
-0
jumpserver.js
apps/static/js/jumpserver.js
+14
-0
404.html
apps/templates/404.html
+11
-0
500.html
apps/templates/500.html
+11
-0
user.py
apps/users/models/user.py
+10
-9
user_granted_asset.html
apps/users/templates/users/user_granted_asset.html
+9
-3
No files found.
apps/assets/models/node.py
View file @
58c4a46f
...
...
@@ -29,6 +29,7 @@ class Node(OrgModelMixin):
class
Meta
:
verbose_name
=
_
(
"Node"
)
ordering
=
[
'key'
]
def
__str__
(
self
):
return
self
.
full_value
...
...
apps/assets/signals.py
deleted
100644 → 0
View file @
dfd26d88
# -*- coding: utf-8 -*-
#
from
django.dispatch
import
Signal
on_app_ready
=
Signal
()
apps/assets/templates/assets/user_asset_list.html
View file @
58c4a46f
...
...
@@ -17,7 +17,6 @@
<div
class=
"file-manager "
>
<div
id=
"assetTree"
class=
"ztree"
>
</div>
<div
class=
"clearfix"
></div>
</div>
</div>
...
...
@@ -62,16 +61,19 @@
{% block custom_foot_js %}
<script>
var
treeUrl
=
"{% url 'api-perms:my-nodes-assets-as-tree' %}?show_assets=0&cache_policy=1"
;
var
zTree
,
asset_table
,
show
=
0
;
var
inited
=
false
;
var
url
;
function
initTable
()
{
if
(
inited
){
return
}
else
{
inited
=
true
;
}
url
=
"{% url 'api-perms:my-assets' %}"
;
url
=
"{% url 'api-perms:my-assets' %}
?cache_policy=1
"
;
var
options
=
{
ele
:
$
(
'#user_assets_table'
),
columnDefs
:
[
...
...
@@ -106,7 +108,7 @@ function initTable() {
}
function
onSelected
(
event
,
treeNode
)
{
url
=
'{% url "api-perms:my-node-assets" node_id=DEFAULT_PK %}'
;
url
=
'{% url "api-perms:my-node-assets" node_id=DEFAULT_PK %}
?cache_policy=1
'
;
var
node_id
=
treeNode
.
meta
.
node
.
id
;
url
=
url
.
replace
(
"{{ DEFAULT_PK }}"
,
node_id
);
setCookie
(
'node_selected'
,
treeNode
.
id
);
...
...
@@ -118,7 +120,7 @@ function initTree() {
var
setting
=
{
view
:
{
dblClickExpand
:
false
,
showLine
:
true
showLine
:
true
,
},
data
:
{
simpleData
:
{
...
...
@@ -131,10 +133,14 @@ function initTree() {
};
var
zNodes
=
[];
$
.
get
(
"{% url 'api-perms:my-nodes-assets-as-tree' %}?show_assets=0"
,
function
(
data
,
status
){
$
.
get
(
treeUrl
,
function
(
data
,
status
){
zNodes
=
data
;
$
.
fn
.
zTree
.
init
(
$
(
"#assetTree"
),
setting
,
zNodes
);
zTree
=
$
.
fn
.
zTree
.
getZTreeObj
(
"assetTree"
);
rootNodeAddDom
(
zTree
,
function
()
{
treeUrl
=
treeUrl
.
replace
(
'cache_policy=1'
,
'cache_policy=2'
);
initTree
();
});
});
}
...
...
apps/jumpserver/error_views.py
0 → 100644
View file @
58c4a46f
# -*- coding: utf-8 -*-
#
from
django.shortcuts
import
render
from
django.http
import
JsonResponse
def
handler404
(
request
,
*
args
,
**
argv
):
if
request
.
content_type
.
find
(
'application/json'
)
>
-
1
:
response
=
JsonResponse
({
'error'
:
'Not found'
},
status
=
404
)
else
:
response
=
render
(
request
,
'404.html'
,
status
=
404
)
return
response
def
handler500
(
request
,
*
args
,
**
argv
):
if
request
.
content_type
.
find
(
'application/json'
)
>
-
1
:
response
=
JsonResponse
({
'error'
:
'Server internal error'
},
status
=
500
)
else
:
response
=
render
(
request
,
'500.html'
,
status
=
500
)
return
response
apps/jumpserver/urls.py
View file @
58c4a46f
...
...
@@ -21,7 +21,7 @@ api_v1_patterns = [
path
(
'audits/v1/'
,
include
(
'audits.urls.api_urls'
,
namespace
=
'api-audits'
)),
path
(
'orgs/v1/'
,
include
(
'orgs.urls.api_urls'
,
namespace
=
'api-orgs'
)),
path
(
'settings/v1/'
,
include
(
'settings.urls.api_urls'
,
namespace
=
'api-settings'
)),
path
(
'authentication/v1/'
,
include
(
'authentication.urls.api_urls'
,
namespace
=
'api-auth'
)),
path
(
'authentication/v1/'
,
include
(
'authentication.urls.api_urls'
,
namespace
=
'api-auth'
)),
]))
]
...
...
@@ -68,6 +68,9 @@ urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \
+
static
(
settings
.
STATIC_URL
,
document_root
=
settings
.
STATIC_ROOT
)
urlpatterns
+=
js_i18n_patterns
handler404
=
'jumpserver.error_views.handler404'
handler500
=
'jumpserver.error_views.handler500'
if
settings
.
DEBUG
:
urlpatterns
+=
[
re_path
(
'^swagger(?P<format>
\
.json|
\
.yaml)$'
,
...
...
apps/ops/templates/ops/command_execution_create.html
View file @
58c4a46f
...
...
@@ -110,9 +110,9 @@ function initTree() {
onCheck
:
onCheck
}
};
var
url
=
"{% url 'api-perms:my-nodes-assets-as-tree' %}"
;
var
url
=
"{% url 'api-perms:my-nodes-assets-as-tree' %}
?cache_policy=1
"
;
if
(
systemUserId
)
{
url
+=
'
?
system_user='
+
systemUserId
url
+=
'
&
system_user='
+
systemUserId
}
$
.
get
(
url
,
function
(
data
,
status
){
...
...
apps/perms/api/user_permission.py
View file @
58c4a46f
# -*- coding: utf-8 -*-
#
from
hashlib
import
md5
from
django.core.cache
import
cache
from
django.conf
import
settings
from
django.shortcuts
import
get_object_or_404
from
rest_framework.views
import
APIView
,
Response
from
rest_framework.generics
import
(
...
...
@@ -10,6 +13,7 @@ from rest_framework.pagination import LimitOffsetPagination
from
common.permissions
import
IsValidUser
,
IsOrgAdminOrAppUser
from
common.tree
import
TreeNodeSerializer
from
common.utils
import
get_logger
from
orgs.utils
import
set_to_root_org
from
..utils
import
(
AssetPermissionUtil
,
parse_asset_to_tree_node
,
parse_node_to_tree_node
...
...
@@ -21,6 +25,7 @@ from ..hands import (
from
..
import
serializers
from
..mixins
import
AssetsFilterMixin
logger
=
get_logger
(
__name__
)
__all__
=
[
'UserGrantedAssetsApi'
,
'UserGrantedNodesApi'
,
...
...
@@ -32,18 +37,61 @@ __all__ = [
class
UserPermissionMixin
:
cache_policy
=
'0'
RESP_CACHE_KEY
=
'_PERMISSION_RESPONSE_CACHE_{}'
CACHE_TIME
=
settings
.
ASSETS_PERM_CACHE_TIME
@staticmethod
def
change_org_if_need
(
request
,
kwargs
):
if
request
.
user
.
is_superuser
or
\
if
request
.
user
.
is_authenticated
and
\
request
.
user
.
is_superuser
or
\
request
.
user
.
is_app
or
\
kwargs
.
get
(
'pk'
)
is
None
:
set_to_root_org
()
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
def
get_response_from_cache
(
self
,
request
):
if
self
.
cache_policy
in
[
'1'
,
'using'
]:
path_md5
=
md5
(
request
.
get_full_path
()
.
encode
())
.
hexdigest
()
obj
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
obj
,
cache_policy
=
self
.
cache_policy
)
cache_id
=
'{}_{}'
.
format
(
path_md5
,
util
.
cache_meta
.
get
(
'id'
))
response
=
self
.
get_cache_response
(
cache_id
)
return
response
return
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
change_org_if_need
(
request
,
kwargs
)
self
.
cache_policy
=
request
.
GET
.
get
(
'cache_policy'
,
'0'
)
return
super
()
.
dispatch
(
request
,
*
args
,
**
kwargs
)
path_md5
=
md5
(
request
.
get_full_path
()
.
encode
())
.
hexdigest
()
path_cache_key
=
'{}_{}'
.
format
(
path_md5
,
'*'
)
if
self
.
cache_policy
in
AssetPermissionUtil
.
CACHE_POLICY_MAP
[
0
]:
return
super
()
.
get
(
request
,
*
args
,
**
kwargs
)
elif
self
.
cache_policy
in
AssetPermissionUtil
.
CACHE_POLICY_MAP
[
2
]:
self
.
expire_cache_response
(
path_cache_key
)
obj
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
obj
,
cache_policy
=
self
.
cache_policy
)
cache_id
=
'{}_{}'
.
format
(
path_md5
,
util
.
cache_meta
.
get
(
'id'
))
response
=
self
.
get_cache_response
(
cache_id
)
if
not
response
:
response
=
super
()
.
get
(
request
,
*
args
,
**
kwargs
)
self
.
set_cache_response
(
cache_id
,
response
)
return
response
def
get_cache_response
(
self
,
_id
):
if
not
_id
:
return
None
key
=
self
.
RESP_CACHE_KEY
.
format
(
_id
)
data
=
cache
.
get
(
key
)
if
not
data
:
return
None
return
Response
(
data
)
def
expire_cache_response
(
self
,
_id
):
key
=
self
.
RESP_CACHE_KEY
.
format
(
_id
)
cache
.
delete
(
key
)
def
set_cache_response
(
self
,
_id
,
response
):
key
=
self
.
RESP_CACHE_KEY
.
format
(
_id
)
cache
.
set
(
key
,
response
.
data
,
self
.
CACHE_TIME
)
class
UserGrantedAssetsApi
(
UserPermissionMixin
,
AssetsFilterMixin
,
ListAPIView
):
...
...
@@ -54,15 +102,18 @@ class UserGrantedAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIView):
serializer_class
=
AssetGrantedSerializer
pagination_class
=
LimitOffsetPagination
def
get_
queryse
t
(
self
):
def
get_
objec
t
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
queryset
=
[]
if
user_id
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
return
user
def
get_queryset
(
self
):
queryset
=
[]
user
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
assets
=
util
.
get_assets
()
for
k
,
v
in
assets
.
items
():
...
...
@@ -84,12 +135,16 @@ class UserGrantedNodesApi(UserPermissionMixin, ListAPIView):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
serializer_class
=
NodeSerializer
def
get_
queryse
t
(
self
):
def
get_
objec
t
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
if
user_id
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
return
user
def
get_queryset
(
self
):
user
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
nodes
=
util
.
get_nodes_with_assets
()
return
nodes
.
keys
()
...
...
@@ -107,14 +162,17 @@ class UserGrantedNodesWithAssetsApi(UserPermissionMixin, AssetsFilterMixin, List
permission_classes
=
(
IsOrgAdminOrAppUser
,)
serializer_class
=
serializers
.
NodeGrantedSerializer
def
get_
queryse
t
(
self
):
def
get_
objec
t
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
queryset
=
[]
if
not
user_id
:
user
=
self
.
request
.
user
else
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
return
user
def
get_queryset
(
self
):
queryset
=
[]
user
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
nodes
=
util
.
get_nodes_with_assets
()
for
node
,
_assets
in
nodes
.
items
():
...
...
@@ -154,17 +212,22 @@ class UserGrantedNodesWithAssetsAsTreeApi(UserPermissionMixin, ListAPIView):
self
.
permission_classes
=
(
IsValidUser
,)
return
super
()
.
get_permissions
()
def
get_
queryse
t
(
self
):
def
get_
objec
t
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
queryset
=
[]
if
not
user_id
:
user
=
self
.
request
.
user
else
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
return
user
def
get_queryset
(
self
):
queryset
=
[]
user
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
if
self
.
system_user_id
:
util
.
filter_permission_with_system_user
(
system_user
=
self
.
system_user_id
)
system_user
=
self
.
system_user_id
)
nodes
=
util
.
get_nodes_with_assets
()
for
node
,
assets
in
nodes
.
items
():
data
=
parse_node_to_tree_node
(
node
)
...
...
@@ -186,14 +249,18 @@ class UserGrantedNodeAssetsApi(UserPermissionMixin, AssetsFilterMixin, ListAPIVi
serializer_class
=
AssetGrantedSerializer
pagination_class
=
LimitOffsetPagination
def
get_
queryse
t
(
self
):
def
get_
objec
t
(
self
):
user_id
=
self
.
kwargs
.
get
(
'pk'
,
''
)
node_id
=
self
.
kwargs
.
get
(
'node_id'
)
if
user_id
:
user
=
get_object_or_404
(
User
,
id
=
user_id
)
else
:
user
=
self
.
request
.
user
return
user
def
get_queryset
(
self
):
user
=
self
.
get_object
()
node_id
=
self
.
kwargs
.
get
(
'node_id'
)
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
node
=
get_object_or_404
(
Node
,
id
=
node_id
)
nodes
=
util
.
get_nodes_with_assets
()
...
...
@@ -217,8 +284,12 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView):
permission_classes
=
(
IsValidUser
,)
serializer_class
=
serializers
.
AssetPermissionNodeSerializer
def
get_object
(
self
):
return
self
.
request
.
user
def
get_children_queryset
(
self
):
util
=
AssetPermissionUtil
(
self
.
request
.
user
,
cache_policy
=
self
.
cache_policy
)
user
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
node_id
=
self
.
request
.
query_params
.
get
(
'id'
)
nodes_granted
=
util
.
get_nodes_with_assets
()
if
not
nodes_granted
:
...
...
@@ -258,7 +329,8 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView):
return
queryset
def
get_search_queryset
(
self
,
keyword
):
util
=
AssetPermissionUtil
(
self
.
request
.
user
,
cache_policy
=
self
.
cache_policy
)
user
=
self
.
get_object
()
util
=
AssetPermissionUtil
(
user
,
cache_policy
=
self
.
cache_policy
)
nodes_granted
=
util
.
get_nodes_with_assets
()
queryset
=
[]
for
node
,
assets
in
nodes_granted
.
items
():
...
...
@@ -294,7 +366,7 @@ class UserGrantedNodeChildrenApi(UserPermissionMixin, ListAPIView):
class
ValidateUserAssetPermissionApi
(
UserPermissionMixin
,
APIView
):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
def
get
(
self
,
request
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
user_id
=
request
.
query_params
.
get
(
'user_id'
,
''
)
asset_id
=
request
.
query_params
.
get
(
'asset_id'
,
''
)
system_id
=
request
.
query_params
.
get
(
'system_user_id'
,
''
)
...
...
apps/perms/signals_handler.py
View file @
58c4a46f
# -*- coding: utf-8 -*-
#
from
django.db.models.signals
import
m2m_changed
from
django.db.models.signals
import
m2m_changed
,
post_save
,
post_delete
from
django.dispatch
import
receiver
from
common.utils
import
get_logger
from
.utils
import
AssetPermissionUtil
from
.models
import
AssetPermission
logger
=
get_logger
(
__file__
)
@receiver
(
post_save
)
def
on_permission_update
(
sender
,
**
kwargs
):
AssetPermissionUtil
.
expire_all_cache
()
@receiver
(
post_delete
)
def
on_permission_delete
(
sender
,
**
kwargs
):
AssetPermissionUtil
.
expire_all_cache
()
@receiver
(
m2m_changed
,
sender
=
AssetPermission
.
nodes
.
through
)
def
on_permission_nodes_changed
(
sender
,
instance
=
None
,
**
kwargs
):
if
isinstance
(
instance
,
AssetPermission
)
and
kwargs
[
'action'
]
==
'post_add'
:
...
...
apps/perms/utils.py
View file @
58c4a46f
# coding: utf-8
from
__future__
import
absolute_import
,
unicode_literals
import
uuid
from
collections
import
defaultdict
from
django.utils
import
timezone
from
django.db.models
import
Q
from
django.core.cache
import
cache
from
django.conf
import
settings
...
...
@@ -100,14 +102,19 @@ class AssetPermissionUtil:
}
CACHE_KEY
=
'_ASSET_PERM_CACHE_{}_{}'
CACHE_META_KEY
=
'_ASSET_PERM_META_KEY_{}'
CACHE_TIME
=
settings
.
ASSETS_PERM_CACHE_TIME
CACHE_POLICY_MAP
=
((
'0'
,
'never'
),
(
'1'
,
'using'
),
(
'2'
,
'refresh'
))
def
__init__
(
self
,
obj
,
cache_policy
=
'0'
):
self
.
object
=
obj
self
.
obj_id
=
str
(
obj
.
id
)
self
.
_permissions
=
None
self
.
_assets
=
None
self
.
cache_policy
=
cache_policy
self
.
node_key
=
self
.
CACHE_KEY
.
format
(
self
.
obj_id
,
'NODES_WITH_ASSETS'
)
self
.
asset_key
=
self
.
CACHE_KEY
.
format
(
self
.
obj_id
,
'ASSETS'
)
self
.
system_key
=
self
.
CACHE_KEY
.
format
(
self
.
obj_id
,
'SYSTEM_USER'
)
@property
def
permissions
(
self
):
...
...
@@ -163,14 +170,11 @@ class AssetPermissionUtil:
return
self
.
_assets
def
get_assets_from_cache
(
self
):
cache_key
=
self
.
CACHE_KEY
.
format
(
str
(
self
.
object
.
id
),
'ASSETS'
)
cached
=
cache
.
get
(
cache_key
)
if
cached
:
return
cached
assets
=
self
.
get_assets_without_cache
()
self
.
expire_cache
()
cache
.
set
(
cache_key
,
assets
,
self
.
CACHE_TIME
)
return
assets
cached
=
cache
.
get
(
self
.
asset_key
)
if
not
cached
:
self
.
update_cache
()
cached
=
cache
.
get
(
self
.
asset_key
)
return
cached
def
get_assets
(
self
):
if
self
.
cache_policy
in
self
.
CACHE_POLICY_MAP
[
1
]:
...
...
@@ -179,6 +183,7 @@ class AssetPermissionUtil:
self
.
expire_cache
()
return
self
.
get_assets_from_cache
()
else
:
self
.
expire_cache
()
return
self
.
get_assets_without_cache
()
def
get_nodes_with_assets_without_cache
(
self
):
...
...
@@ -187,21 +192,18 @@ class AssetPermissionUtil:
{"node": {"assets": set("system_user")}}
:return:
"""
assets
=
self
.
get_assets
()
assets
=
self
.
get_assets
_without_cache
()
tree
=
GenerateTree
()
for
asset
,
system_users
in
assets
.
items
():
tree
.
add_asset
(
asset
,
system_users
)
return
tree
.
get_nodes
()
def
get_nodes_with_assets_from_cache
(
self
):
cache_key
=
self
.
CACHE_KEY
.
format
(
str
(
self
.
object
.
id
),
'NODES_WITH_ASSETS'
)
cached
=
cache
.
get
(
cache_key
)
if
cached
:
return
cached
nodes
=
self
.
get_nodes_with_assets_without_cache
()
self
.
expire_cache
()
cache
.
set
(
cache_key
,
nodes
,
self
.
CACHE_TIME
)
return
nodes
cached
=
cache
.
get
(
self
.
node_key
)
if
not
cached
:
self
.
update_cache
()
cached
=
cache
.
get
(
self
.
node_key
)
return
cached
def
get_nodes_with_assets
(
self
):
if
self
.
cache_policy
in
self
.
CACHE_POLICY_MAP
[
1
]:
...
...
@@ -220,14 +222,11 @@ class AssetPermissionUtil:
return
system_users
def
get_system_user_from_cache
(
self
):
cache_key
=
self
.
CACHE_KEY
.
format
(
str
(
self
.
object
.
id
),
'SYSTEM_USER'
)
cached
=
cache
.
get
(
cache_key
)
if
cached
:
return
cached
self
.
expire_cache
()
system_users
=
self
.
get_system_user_without_cache
()
cache
.
set
(
cache_key
,
system_users
,
self
.
CACHE_TIME
)
return
system_users
cached
=
cache
.
get
(
self
.
system_key
)
if
not
cached
:
self
.
update_cache
()
cached
=
cache
.
get
(
self
.
system_key
)
return
cached
def
get_system_users
(
self
):
if
self
.
cache_policy
in
self
.
CACHE_POLICY_MAP
[
1
]:
...
...
@@ -238,14 +237,51 @@ class AssetPermissionUtil:
else
:
return
self
.
get_system_user_without_cache
()
@property
def
cache_meta
(
self
):
key
=
self
.
CACHE_META_KEY
.
format
(
str
(
self
.
object
.
id
))
return
cache
.
get
(
key
)
or
{}
def
set_cache_meta
(
self
):
key
=
self
.
CACHE_META_KEY
.
format
(
str
(
self
.
object
.
id
))
meta
=
{
'id'
:
str
(
uuid
.
uuid4
()),
'datetime'
:
timezone
.
now
(),
'object'
:
str
(
self
.
object
)
}
cache
.
set
(
key
,
meta
,
self
.
CACHE_TIME
)
def
expire_cache_meta
(
self
):
key
=
self
.
CACHE_META_KEY
.
format
(
str
(
self
.
object
.
id
))
cache
.
delete
(
key
)
def
update_cache
(
self
):
assets
=
self
.
get_assets_without_cache
()
nodes
=
self
.
get_nodes_with_assets_without_cache
()
system_users
=
self
.
get_system_user_without_cache
()
cache
.
set
(
self
.
asset_key
,
assets
,
self
.
CACHE_TIME
)
cache
.
set
(
self
.
node_key
,
nodes
,
self
.
CACHE_TIME
)
cache
.
set
(
self
.
system_key
,
system_users
,
self
.
CACHE_TIME
)
self
.
set_cache_meta
()
def
expire_cache
(
self
):
cache_key
=
self
.
CACHE_KEY
.
format
(
str
(
self
.
object
.
id
),
'*'
)
cache
.
delete_pattern
(
cache_key
)
"""
因为 获取用户的节点,资产,系统用户等都能会缓存,这里会清理所有与该对象有关的
缓存,以免造成不统一的情况
:return:
"""
key
=
self
.
CACHE_KEY
.
format
(
str
(
self
.
object
.
id
),
'*'
)
cache
.
delete_pattern
(
key
)
self
.
expire_cache_meta
()
def
expire_all_cache_meta
(
self
):
key
=
self
.
CACHE_META_KEY
.
format
(
'*'
)
cache
.
delete_pattern
(
key
)
@classmethod
def
expire_all_cache
(
cls
):
cache_
key
=
cls
.
CACHE_KEY
.
format
(
'*'
,
'*'
)
cache
.
delete_pattern
(
cache_
key
)
key
=
cls
.
CACHE_KEY
.
format
(
'*'
,
'*'
)
cache
.
delete_pattern
(
key
)
def
is_obj_attr_has
(
obj
,
val
,
attrs
=
(
"hostname"
,
"ip"
,
"comment"
)):
...
...
apps/settings/forms.py
View file @
58c4a46f
...
...
@@ -105,7 +105,8 @@ class LDAPSettingForm(BaseForm):
)
AUTH_LDAP_SEARCH_OU
=
forms
.
CharField
(
label
=
_
(
"User OU"
),
help_text
=
_
(
"Use | split User OUs"
)
help_text
=
_
(
"Use | split User OUs"
),
required
=
False
,
)
AUTH_LDAP_SEARCH_FILTER
=
forms
.
CharField
(
label
=
_
(
"User search filter"
),
...
...
apps/static/css/jumpserver.css
View file @
58c4a46f
...
...
@@ -450,3 +450,7 @@ div.dataTables_wrapper div.dataTables_filter {
content
:
"*"
;
color
:
red
;
}
#tree-refresh
.fa-refresh
{
font
:
normal
normal
normal
14px
/
1
FontAwesome
!important
;
}
\ No newline at end of file
apps/static/js/jumpserver.js
View file @
58c4a46f
...
...
@@ -922,3 +922,16 @@ function initSelectedAssets2Table(){
});
}
}
function
rootNodeAddDom
(
ztree
,
callback
)
{
var
refreshIcon
=
"<a id='tree-refresh'><i class='fa fa-refresh'></i></a>"
;
var
rootNode
=
ztree
.
getNodes
()[
0
];
var
$rootNodeRef
=
$
(
"#"
+
rootNode
.
tId
+
"_a"
);
$rootNodeRef
.
after
(
refreshIcon
);
var
refreshIconRef
=
$
(
'#tree-refresh'
);
refreshIconRef
.
bind
(
'click'
,
function
()
{
ztree
.
destroy
();
callback
()
})
}
\ No newline at end of file
apps/templates/404.html
0 → 100644
View file @
58c4a46f
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Not found
</title>
</head>
<body>
<h1>
Not found
</h1>
</body>
</html>
\ No newline at end of file
apps/templates/500.html
0 → 100644
View file @
58c4a46f
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Server error
</title>
</head>
<body>
<h1>
Server error occur, contact administrator
</h1>
</body>
</html>
\ No newline at end of file
apps/users/models/user.py
View file @
58c4a46f
...
...
@@ -286,20 +286,21 @@ class User(AbstractUser):
@property
def
private_token
(
self
):
return
self
.
create_private_token
()
def
create_private_token
(
self
):
from
.authentication
import
PrivateToken
from
authentication.models
import
PrivateToken
try
:
token
=
PrivateToken
.
objects
.
get
(
user
=
self
)
except
PrivateToken
.
DoesNotExist
:
token
=
PrivateToken
.
objects
.
create
(
user
=
self
)
return
token
.
key
token
=
self
.
create_private_token
()
return
token
def
create_private_token
(
self
):
from
authentication.models
import
PrivateToken
token
=
PrivateToken
.
objects
.
create
(
user
=
self
)
return
token
def
refresh_private_token
(
self
):
from
.authentication
import
PrivateToken
PrivateToken
.
objects
.
filter
(
user
=
self
)
.
delete
()
return
PrivateToken
.
objects
.
create
(
user
=
self
)
self
.
private_token
.
delete
()
return
self
.
create_private_token
()
def
create_bearer_token
(
self
,
request
=
None
):
expiration
=
settings
.
TOKEN_EXPIRATION
or
3600
...
...
apps/users/templates/users/user_granted_asset.html
View file @
58c4a46f
...
...
@@ -64,6 +64,7 @@ var zTree;
var
inited
=
false
;
var
url
;
var
asset_table
;
var
treeUrl
=
"{% url 'api-perms:user-nodes-assets-as-tree' pk=object.id %}?show_assets=0&cache_policy=1"
;
function
initTable
()
{
if
(
inited
){
...
...
@@ -71,7 +72,7 @@ function initTable() {
}
else
{
inited
=
true
;
}
url
=
"{% url 'api-perms:user-assets' pk=object.id %}"
;
url
=
"{% url 'api-perms:user-assets' pk=object.id %}
?cache_policy=1
"
;
var
options
=
{
ele
:
$
(
'#user_assets_table'
),
columnDefs
:
[
...
...
@@ -106,13 +107,14 @@ function initTable() {
}
function
onSelected
(
event
,
treeNode
)
{
url
=
'{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}'
;
url
=
'{% url "api-perms:user-node-assets" pk=object.id node_id=DEFAULT_PK %}
?cache_policy=1
'
;
var
node_id
=
treeNode
.
meta
.
node
.
id
;
url
=
url
.
replace
(
"{{ DEFAULT_PK }}"
,
node_id
);
asset_table
.
ajax
.
url
(
url
);
asset_table
.
ajax
.
reload
();
}
function
initTree
()
{
var
setting
=
{
view
:
{
...
...
@@ -129,9 +131,13 @@ function initTree() {
}
};
$
.
get
(
"{% url 'api-perms:user-nodes-assets-as-tree' pk=object.id %}?show_assets=0"
,
function
(
data
,
status
)
{
$
.
get
(
treeUrl
,
function
(
data
,
status
)
{
$
.
fn
.
zTree
.
init
(
$
(
"#assetTree"
),
setting
,
data
);
zTree
=
$
.
fn
.
zTree
.
getZTreeObj
(
"assetTree"
);
rootNodeAddDom
(
zTree
,
function
()
{
treeUrl
=
treeUrl
.
replace
(
'cache_policy=1'
,
'cache_policy=2'
);
initTree
();
});
});
}
...
...
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