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
b4498f22
Unverified
Commit
b4498f22
authored
Dec 10, 2019
by
BaiJiangJie
Committed by
GitHub
Dec 10, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改 RemoteApp 前端 Form 渲染逻辑 (#3523)
* [Update] 修改 RemoteApp 前端 Form 渲染逻辑 * [Update] RemoteApp 表单添加默认值
parent
b2932803
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
208 additions
and
247 deletions
+208
-247
const.py
apps/applications/const.py
+8
-24
remote_app.py
apps/applications/forms/remote_app.py
+52
-55
remote_app.py
apps/applications/models/remote_app.py
+1
-1
remote_app.py
apps/applications/serializers/remote_app.py
+32
-5
remote_app_create_update.html
...ions/templates/applications/remote_app_create_update.html
+22
-109
remote_app_list.html
.../applications/templates/applications/remote_app_list.html
+10
-2
remote_app.py
apps/applications/views/remote_app.py
+45
-22
serializer.py
apps/common/fields/serializer.py
+26
-19
const.py
apps/terminal/const.py
+2
-2
storage.py
apps/terminal/serializers/storage.py
+10
-8
No files found.
apps/applications/const.py
View file @
b4498f22
...
@@ -12,29 +12,6 @@ REMOTE_APP_TYPE_MYSQL_WORKBENCH = 'mysql_workbench'
...
@@ -12,29 +12,6 @@ REMOTE_APP_TYPE_MYSQL_WORKBENCH = 'mysql_workbench'
REMOTE_APP_TYPE_VMWARE_CLIENT
=
'vmware_client'
REMOTE_APP_TYPE_VMWARE_CLIENT
=
'vmware_client'
REMOTE_APP_TYPE_CUSTOM
=
'custom'
REMOTE_APP_TYPE_CUSTOM
=
'custom'
REMOTE_APP_TYPE_CHOICES
=
(
(
_
(
'Browser'
),
(
(
REMOTE_APP_TYPE_CHROME
,
'Chrome'
),
)
),
(
_
(
'Database tools'
),
(
(
REMOTE_APP_TYPE_MYSQL_WORKBENCH
,
'MySQL Workbench'
),
)
),
(
_
(
'Virtualization tools'
),
(
(
REMOTE_APP_TYPE_VMWARE_CLIENT
,
'vSphere Client'
),
)
),
(
REMOTE_APP_TYPE_CUSTOM
,
_
(
'Custom'
)),
)
# Fields attribute write_only default => False
# Fields attribute write_only default => False
REMOTE_APP_TYPE_CHROME_FIELDS
=
[
REMOTE_APP_TYPE_CHROME_FIELDS
=
[
...
@@ -60,9 +37,16 @@ REMOTE_APP_TYPE_CUSTOM_FIELDS = [
...
@@ -60,9 +37,16 @@ REMOTE_APP_TYPE_CUSTOM_FIELDS = [
{
'name'
:
'custom_password'
,
'write_only'
:
True
}
{
'name'
:
'custom_password'
,
'write_only'
:
True
}
]
]
REMOTE_APP_TYPE_
MAP_FIELDS
=
{
REMOTE_APP_TYPE_
FIELDS_MAP
=
{
REMOTE_APP_TYPE_CHROME
:
REMOTE_APP_TYPE_CHROME_FIELDS
,
REMOTE_APP_TYPE_CHROME
:
REMOTE_APP_TYPE_CHROME_FIELDS
,
REMOTE_APP_TYPE_MYSQL_WORKBENCH
:
REMOTE_APP_TYPE_MYSQL_WORKBENCH_FIELDS
,
REMOTE_APP_TYPE_MYSQL_WORKBENCH
:
REMOTE_APP_TYPE_MYSQL_WORKBENCH_FIELDS
,
REMOTE_APP_TYPE_VMWARE_CLIENT
:
REMOTE_APP_TYPE_VMWARE_CLIENT_FIELDS
,
REMOTE_APP_TYPE_VMWARE_CLIENT
:
REMOTE_APP_TYPE_VMWARE_CLIENT_FIELDS
,
REMOTE_APP_TYPE_CUSTOM
:
REMOTE_APP_TYPE_CUSTOM_FIELDS
REMOTE_APP_TYPE_CUSTOM
:
REMOTE_APP_TYPE_CUSTOM_FIELDS
}
}
REMOTE_APP_TYPE_CHOICES
=
(
(
REMOTE_APP_TYPE_CHROME
,
'Chrome'
),
(
REMOTE_APP_TYPE_MYSQL_WORKBENCH
,
'MySQL Workbench'
),
(
REMOTE_APP_TYPE_VMWARE_CLIENT
,
'vSphere Client'
),
(
REMOTE_APP_TYPE_CUSTOM
,
_
(
'Custom'
)),
)
apps/applications/forms/remote_app.py
View file @
b4498f22
...
@@ -5,18 +5,52 @@ from django.utils.translation import ugettext as _
...
@@ -5,18 +5,52 @@ from django.utils.translation import ugettext as _
from
django
import
forms
from
django
import
forms
from
orgs.mixins.forms
import
OrgModelForm
from
orgs.mixins.forms
import
OrgModelForm
from
assets.models
import
SystemUser
from
..models
import
RemoteApp
from
..models
import
RemoteApp
from
..
import
const
__all__
=
[
__all__
=
[
'RemoteAppCreateUpdateForm'
,
'RemoteAppChromeForm'
,
'RemoteAppMySQLWorkbenchForm'
,
'RemoteAppVMwareForm'
,
'RemoteAppCustomForm'
]
]
class
RemoteAppTypeChromeForm
(
forms
.
ModelForm
):
class
BaseRemoteAppForm
(
OrgModelForm
):
default_initial_data
=
{}
def
__init__
(
self
,
*
args
,
**
kwargs
):
# 过滤RDP资产和系统用户
super
()
.
__init__
(
*
args
,
**
kwargs
)
field_asset
=
self
.
fields
[
'asset'
]
field_asset
.
queryset
=
field_asset
.
queryset
.
has_protocol
(
'rdp'
)
self
.
fields
[
'type'
]
.
widget
.
attrs
[
'disabled'
]
=
True
self
.
fields
.
move_to_end
(
'comment'
)
self
.
initial_default
()
def
initial_default
(
self
):
for
name
,
value
in
self
.
default_initial_data
.
items
():
field
=
self
.
fields
.
get
(
name
)
if
not
field
:
continue
field
.
initial
=
value
class
Meta
:
model
=
RemoteApp
fields
=
[
'name'
,
'asset'
,
'type'
,
'path'
,
'comment'
]
widgets
=
{
'asset'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Asset'
)
}),
}
class
RemoteAppChromeForm
(
BaseRemoteAppForm
):
default_initial_data
=
{
'path'
:
r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
}
chrome_target
=
forms
.
CharField
(
chrome_target
=
forms
.
CharField
(
max_length
=
128
,
label
=
_
(
'Target URL'
),
required
=
False
max_length
=
128
,
label
=
_
(
'Target URL'
),
required
=
False
)
)
...
@@ -29,7 +63,12 @@ class RemoteAppTypeChromeForm(forms.ModelForm):
...
@@ -29,7 +63,12 @@ class RemoteAppTypeChromeForm(forms.ModelForm):
)
)
class
RemoteAppTypeMySQLWorkbenchForm
(
forms
.
ModelForm
):
class
RemoteAppMySQLWorkbenchForm
(
BaseRemoteAppForm
):
default_initial_data
=
{
'path'
:
r'C:\Program Files\MySQL\MySQL Workbench 8.0 CE'
r'\MySQLWorkbench.exe'
}
mysql_workbench_ip
=
forms
.
CharField
(
mysql_workbench_ip
=
forms
.
CharField
(
max_length
=
128
,
label
=
_
(
'Database IP'
),
required
=
False
max_length
=
128
,
label
=
_
(
'Database IP'
),
required
=
False
)
)
...
@@ -45,7 +84,12 @@ class RemoteAppTypeMySQLWorkbenchForm(forms.ModelForm):
...
@@ -45,7 +84,12 @@ class RemoteAppTypeMySQLWorkbenchForm(forms.ModelForm):
)
)
class
RemoteAppTypeVMwareForm
(
forms
.
ModelForm
):
class
RemoteAppVMwareForm
(
BaseRemoteAppForm
):
default_initial_data
=
{
'path'
:
r'C:\Program Files (x86)\VMware\Infrastructure'
r'\Virtual Infrastructure Client\Launcher\VpxClient.exe'
}
vmware_target
=
forms
.
CharField
(
vmware_target
=
forms
.
CharField
(
max_length
=
128
,
label
=
_
(
'Target address'
),
required
=
False
max_length
=
128
,
label
=
_
(
'Target address'
),
required
=
False
)
)
...
@@ -58,7 +102,8 @@ class RemoteAppTypeVMwareForm(forms.ModelForm):
...
@@ -58,7 +102,8 @@ class RemoteAppTypeVMwareForm(forms.ModelForm):
)
)
class
RemoteAppTypeCustomForm
(
forms
.
ModelForm
):
class
RemoteAppCustomForm
(
BaseRemoteAppForm
):
custom_cmdline
=
forms
.
CharField
(
custom_cmdline
=
forms
.
CharField
(
max_length
=
128
,
label
=
_
(
'Operating parameter'
),
required
=
False
max_length
=
128
,
label
=
_
(
'Operating parameter'
),
required
=
False
)
)
...
@@ -73,51 +118,3 @@ class RemoteAppTypeCustomForm(forms.ModelForm):
...
@@ -73,51 +118,3 @@ class RemoteAppTypeCustomForm(forms.ModelForm):
max_length
=
128
,
label
=
_
(
'Login password'
),
required
=
False
max_length
=
128
,
label
=
_
(
'Login password'
),
required
=
False
)
)
class
RemoteAppTypeForms
(
RemoteAppTypeChromeForm
,
RemoteAppTypeMySQLWorkbenchForm
,
RemoteAppTypeVMwareForm
,
RemoteAppTypeCustomForm
):
pass
class
RemoteAppCreateUpdateForm
(
RemoteAppTypeForms
,
OrgModelForm
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
# 过滤RDP资产和系统用户
super
()
.
__init__
(
*
args
,
**
kwargs
)
field_asset
=
self
.
fields
[
'asset'
]
field_asset
.
queryset
=
field_asset
.
queryset
.
has_protocol
(
'rdp'
)
class
Meta
:
model
=
RemoteApp
fields
=
[
'name'
,
'asset'
,
'type'
,
'path'
,
'comment'
]
widgets
=
{
'asset'
:
forms
.
Select
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Asset'
)
}),
}
def
_clean_params
(
self
):
app_type
=
self
.
data
.
get
(
'type'
)
fields
=
const
.
REMOTE_APP_TYPE_MAP_FIELDS
.
get
(
app_type
,
[])
params
=
{}
for
field
in
fields
:
name
=
field
[
'name'
]
value
=
self
.
cleaned_data
[
name
]
params
.
update
({
name
:
value
})
return
params
def
_save_params
(
self
,
instance
):
params
=
self
.
_clean_params
()
instance
.
params
=
params
instance
.
save
()
return
instance
def
save
(
self
,
commit
=
True
):
instance
=
super
()
.
save
(
commit
=
commit
)
instance
=
self
.
_save_params
(
instance
)
return
instance
apps/applications/models/remote_app.py
View file @
b4498f22
...
@@ -62,7 +62,7 @@ class RemoteApp(OrgModelMixin):
...
@@ -62,7 +62,7 @@ class RemoteApp(OrgModelMixin):
_parameters
.
append
(
self
.
type
)
_parameters
.
append
(
self
.
type
)
path
=
'
\"
%
s
\"
'
%
self
.
path
path
=
'
\"
%
s
\"
'
%
self
.
path
_parameters
.
append
(
path
)
_parameters
.
append
(
path
)
for
field
in
const
.
REMOTE_APP_TYPE_
MAP_FIELDS
[
self
.
type
]:
for
field
in
const
.
REMOTE_APP_TYPE_
FIELDS_MAP
[
self
.
type
]:
value
=
self
.
params
.
get
(
field
[
'name'
])
value
=
self
.
params
.
get
(
field
[
'name'
])
if
value
is
None
:
if
value
is
None
:
continue
continue
...
...
apps/applications/serializers/remote_app.py
View file @
b4498f22
# coding: utf-8
# coding: utf-8
#
#
import
copy
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
common.serializers
import
AdaptedBulkListSerializer
from
common.serializers
import
AdaptedBulkListSerializer
...
@@ -18,26 +18,53 @@ __all__ = [
...
@@ -18,26 +18,53 @@ __all__ = [
class
RemoteAppParamsDictField
(
CustomMetaDictField
):
class
RemoteAppParamsDictField
(
CustomMetaDictField
):
type_
map_fields
=
const
.
REMOTE_APP_TYPE_MAP_FIELDS
type_
fields_map
=
const
.
REMOTE_APP_TYPE_FIELDS_MAP
default_type
=
const
.
REMOTE_APP_TYPE_CHROME
default_type
=
const
.
REMOTE_APP_TYPE_CHROME
convert_key_remove_type_prefix
=
False
convert_key_to_upper
=
False
class
RemoteAppSerializer
(
BulkOrgResourceModelSerializer
):
class
RemoteAppSerializer
(
BulkOrgResourceModelSerializer
):
params
=
RemoteAppParamsDictField
()
params
=
RemoteAppParamsDictField
()
type_fields_map
=
const
.
REMOTE_APP_TYPE_FIELDS_MAP
class
Meta
:
class
Meta
:
model
=
RemoteApp
model
=
RemoteApp
list_serializer_class
=
AdaptedBulkListSerializer
list_serializer_class
=
AdaptedBulkListSerializer
fields
=
[
fields
=
[
'id'
,
'name'
,
'asset'
,
'type'
,
'path'
,
'params'
,
'id'
,
'name'
,
'asset'
,
'asset_info'
,
'type'
,
'get_type_display'
,
'comment'
,
'created_by'
,
'date_created'
,
'asset_info'
,
'path'
,
'params'
,
'date_created'
,
'created_by'
,
'comment'
,
'get_type_display'
,
]
]
read_only_fields
=
[
read_only_fields
=
[
'created_by'
,
'date_created'
,
'asset_info'
,
'created_by'
,
'date_created'
,
'asset_info'
,
'get_type_display'
'get_type_display'
]
]
def
process_params
(
self
,
instance
,
validated_data
):
new_params
=
copy
.
deepcopy
(
validated_data
.
get
(
'params'
,
{}))
tp
=
validated_data
.
get
(
'type'
,
''
)
if
tp
!=
instance
.
type
:
return
new_params
old_params
=
instance
.
params
fields
=
self
.
type_fields_map
.
get
(
instance
.
type
,
[])
for
field
in
fields
:
if
not
field
.
get
(
'write_only'
,
False
):
continue
field_name
=
field
[
'name'
]
new_value
=
new_params
.
get
(
field_name
,
''
)
old_value
=
old_params
.
get
(
field_name
,
''
)
field_value
=
new_value
if
new_value
else
old_value
new_params
[
field_name
]
=
field_value
return
new_params
def
update
(
self
,
instance
,
validated_data
):
params
=
self
.
process_params
(
instance
,
validated_data
)
validated_data
[
'params'
]
=
params
return
super
()
.
update
(
instance
,
validated_data
)
class
RemoteAppConnectionInfoSerializer
(
serializers
.
ModelSerializer
):
class
RemoteAppConnectionInfoSerializer
(
serializers
.
ModelSerializer
):
parameter_remote_app
=
serializers
.
SerializerMethodField
()
parameter_remote_app
=
serializers
.
SerializerMethodField
()
...
...
apps/applications/templates/applications/remote_app_create_update.html
View file @
b4498f22
...
@@ -4,51 +4,8 @@
...
@@ -4,51 +4,8 @@
{% load i18n %}
{% load i18n %}
{% block form %}
{% block form %}
<form
id=
"appForm"
method=
"post"
class=
"form-horizontal"
>
<form
id=
"RemoteAppForm"
method=
"post"
class=
"form-horizontal"
>
{% if form.non_field_errors %}
{% bootstrap_form form layout="horizontal" %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.asset layout="horizontal" %}
{% bootstrap_field form.type layout="horizontal" %}
{% bootstrap_field form.path layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
{# chrome #}
<div
class=
"chrome-fields hidden"
>
{% bootstrap_field form.chrome_target layout="horizontal" %}
{% bootstrap_field form.chrome_username layout="horizontal" %}
{% bootstrap_field form.chrome_password layout="horizontal" %}
</div>
{# mysql workbench #}
<div
class=
"mysql_workbench-fields hidden"
>
{% bootstrap_field form.mysql_workbench_ip layout="horizontal" %}
{% bootstrap_field form.mysql_workbench_name layout="horizontal" %}
{% bootstrap_field form.mysql_workbench_username layout="horizontal" %}
{% bootstrap_field form.mysql_workbench_password layout="horizontal" %}
</div>
{# vmware #}
<div
class=
"vmware_client-fields hidden"
>
{% bootstrap_field form.vmware_target layout="horizontal" %}
{% bootstrap_field form.vmware_username layout="horizontal" %}
{% bootstrap_field form.vmware_password layout="horizontal" %}
</div>
{# custom #}
<div
class=
"custom-fields hidden"
>
{% bootstrap_field form.custom_cmdline layout="horizontal" %}
{% bootstrap_field form.custom_target layout="horizontal" %}
{% bootstrap_field form.custom_username layout="horizontal" %}
{% bootstrap_field form.custom_password layout="horizontal" %}
</div>
{% bootstrap_field form.comment layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
...
@@ -57,93 +14,49 @@
...
@@ -57,93 +14,49 @@
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
</div>
</form>
</form>
{% endblock %}
{% endblock %}
{% block custom_foot_js %}
{% block custom_foot_js %}
<script
type=
"text/javascript"
>
<script
type=
"text/javascript"
>
var
app_type_id
=
'#'
+
'{{ form.type.id_for_label }}'
;
var
app_type_id
=
'#'
+
'{{ form.type.id_for_label }}'
;
var
app_path_id
=
'#'
+
'{{ form.path.id_for_label }}'
;
var
all_type_fields
=
[
function
getFormDataType
(){
'.chrome-fields'
,
'.mysql_workbench-fields'
,
'.vmware_client-fields'
,
'.custom-fields'
];
var
app_type_map_default_fields_value
=
{
'chrome'
:
{
'app_path'
:
'C:
\\
Program Files (x86)
\\
Google
\\
Chrome
\\
Application
\\
chrome.exe'
},
'mysql_workbench'
:
{
'app_path'
:
'C:
\\
Program Files
\\
MySQL
\\
MySQL Workbench 8.0 CE
\\
MySQLWorkbench.exe'
},
'vmware_client'
:
{
'app_path'
:
'C:
\\
Program Files (x86)
\\
VMware
\\
Infrastructure
\\
Virtual Infrastructure Client
\\
Launcher
\\
VpxClient.exe'
},
'custom'
:
{
'app_path'
:
''
}
};
function
getAppType
(){
return
$
(
app_type_id
+
" option:selected"
).
val
();
return
$
(
app_type_id
+
" option:selected"
).
val
();
}
}
function
initialDefaultValue
(){
function
constructFormDataParams
(
data
){
var
app_type
=
getAppType
();
var
app_path
=
$
(
app_path_id
).
val
();
if
(
app_path
){
app_type_map_default_fields_value
[
app_type
][
'app_path'
]
=
app_path
}
}
function
setDefaultValue
(){
// 设置类型相关字段的默认值
var
app_type
=
getAppType
();
var
app_path
=
app_type_map_default_fields_value
[
app_type
][
'app_path'
];
$
(
app_path_id
).
val
(
app_path
)
}
function
hiddenFields
(){
var
app_type
=
getAppType
();
$
.
each
(
all_type_fields
,
function
(
index
,
value
){
$
(
value
).
addClass
(
'hidden'
)
});
$
(
'.'
+
app_type
+
'-fields'
).
removeClass
(
'hidden'
);
}
function
constructParams
(
data
)
{
var
typeList
=
[
'chrome'
,
'mysql_workbench'
,
'vmware_client'
,
'custom'
];
var
params
=
{};
var
params
=
{};
$
.
each
(
typeList
,
function
(
index
,
value
){
var
type
=
data
.
type
;
if
(
data
.
type
===
value
){
for
(
var
k
in
data
){
for
(
var
k
in
data
){
if
(
k
.
startsWith
(
type
)){
if
(
k
.
startsWith
(
value
)){
params
[
k
]
=
data
[
k
];
params
[
k
]
=
data
[
k
]
delete
data
[
k
]
}
}
}
}
});
}
return
params
;
return
params
}
function
getFormData
(
form
){
var
data
=
form
.
serializeObject
();
data
[
'type'
]
=
getFormDataType
();
data
[
'params'
]
=
constructFormDataParams
(
data
);
return
data
}
}
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
({
$
(
'.select2'
).
select2
({
closeOnSelect
:
true
closeOnSelect
:
true
});
});
initialDefaultValue
();
}).
on
(
"submit"
,
"form"
,
function
(
evt
)
{
hiddenFields
();
setDefaultValue
();
})
.
on
(
'change'
,
app_type_id
,
function
(){
hiddenFields
();
setDefaultValue
();
})
.
on
(
"submit"
,
"form"
,
function
(
evt
)
{
evt
.
preventDefault
();
evt
.
preventDefault
();
var
the_url
=
'{% url "api-applications:remote-app-list" %}'
;
var
the_url
=
'{% url "api-applications:remote-app-list" %}'
;
var
redirect_to
=
'{% url "applications:remote-app-list" %}'
;
var
redirect_to
=
'{% url "applications:remote-app-list" %}'
;
var
method
=
"POST"
;
var
method
=
"POST"
;
{
%
if
type
==
"update"
%
}
{
%
if
api_action
==
"update"
%
}
the_url
=
'{% url "api-applications:remote-app-detail" object.id %}'
;
the_url
=
'{% url "api-applications:remote-app-detail" object.id %}'
;
method
=
"PUT"
;
method
=
"PUT"
;
{
%
endif
%
}
{
%
endif
%
}
var
form
=
$
(
"form"
);
var
form
=
$
(
"form"
);
var
data
=
form
.
serializeObject
();
var
data
=
getFormData
(
form
);
data
[
"params"
]
=
constructParams
(
data
);
var
props
=
{
var
props
=
{
url
:
the_url
,
url
:
the_url
,
data
:
data
,
data
:
data
,
...
...
apps/applications/templates/applications/remote_app_list.html
View file @
b4498f22
...
@@ -6,8 +6,16 @@
...
@@ -6,8 +6,16 @@
{% endblock %}
{% endblock %}
{% block table_search %}{% endblock %}
{% block table_search %}{% endblock %}
{% block table_container %}
{% block table_container %}
<div
class=
"uc pull-left m-r-5"
>
<div
class=
"btn-group uc pull-left m-r-5"
>
<a
href=
"{% url 'applications:remote-app-create' %}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create RemoteApp" %}
</a>
<button
class=
"btn btn-sm btn-primary"
>
{% trans "Create RemoteApp" %}
</button>
<button
data-toggle=
"dropdown"
class=
"btn btn-primary btn-sm dropdown-toggle"
><span
class=
"caret"
></span></button>
<ul
class=
"dropdown-menu"
>
{% for key, value in type_choices %}
<li><a
class=
""
href=
"{% url 'applications:remote-app-create' %}?type={{ key }}"
>
{{ value }}
</a></li>
{% endfor %}
</ul>
</div>
</div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"remote_app_list_table"
>
<table
class=
"table table-striped table-bordered table-hover "
id=
"remote_app_list_table"
>
<thead>
<thead>
...
...
apps/applications/views/remote_app.py
View file @
b4498f22
# coding: utf-8
# coding: utf-8
#
#
from
django.http
import
Http404
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
from
django.views.generic
import
TemplateView
from
django.views.generic
import
TemplateView
from
django.views.generic.edit
import
CreateView
,
UpdateView
from
django.views.generic.edit
import
CreateView
,
UpdateView
from
django.views.generic.detail
import
DetailView
from
django.views.generic.detail
import
DetailView
from
django.contrib.messages.views
import
SuccessMessageMixin
from
django.urls
import
reverse_lazy
from
common.permissions
import
PermissionsMixin
,
IsOrgAdmin
,
IsValidUser
from
common.permissions
import
PermissionsMixin
,
IsOrgAdmin
,
IsValidUser
from
common.const
import
create_success_msg
,
update_success_msg
from
..models
import
RemoteApp
from
..models
import
RemoteApp
from
..
import
forms
from
..
import
forms
,
const
__all__
=
[
__all__
=
[
...
@@ -30,53 +27,79 @@ class RemoteAppListView(PermissionsMixin, TemplateView):
...
@@ -30,53 +27,79 @@ class RemoteAppListView(PermissionsMixin, TemplateView):
context
=
{
context
=
{
'app'
:
_
(
'Applications'
),
'app'
:
_
(
'Applications'
),
'action'
:
_
(
'RemoteApp list'
),
'action'
:
_
(
'RemoteApp list'
),
'type_choices'
:
const
.
REMOTE_APP_TYPE_CHOICES
,
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
RemoteAppCreateView
(
PermissionsMixin
,
SuccessMessageMixin
,
CreateView
)
:
class
BaseRemoteAppCreateUpdateView
:
template_name
=
'applications/remote_app_create_update.html'
template_name
=
'applications/remote_app_create_update.html'
model
=
RemoteApp
model
=
RemoteApp
form_class
=
forms
.
RemoteAppCreateUpdateForm
success_url
=
reverse_lazy
(
'applications:remote-app-list'
)
permission_classes
=
[
IsOrgAdmin
]
permission_classes
=
[
IsOrgAdmin
]
default_type
=
const
.
REMOTE_APP_TYPE_CHROME
form_class
=
forms
.
RemoteAppChromeForm
form_class_choices
=
{
const
.
REMOTE_APP_TYPE_CHROME
:
forms
.
RemoteAppChromeForm
,
const
.
REMOTE_APP_TYPE_MYSQL_WORKBENCH
:
forms
.
RemoteAppMySQLWorkbenchForm
,
const
.
REMOTE_APP_TYPE_VMWARE_CLIENT
:
forms
.
RemoteAppVMwareForm
,
const
.
REMOTE_APP_TYPE_CUSTOM
:
forms
.
RemoteAppCustomForm
}
def
get_initial
(
self
):
return
{
'type'
:
self
.
get_type
()}
def
get_type
(
self
):
return
self
.
default_type
def
get_form_class
(
self
):
tp
=
self
.
get_type
()
form_class
=
self
.
form_class_choices
.
get
(
tp
)
if
not
form_class
:
raise
Http404
()
return
form_class
class
RemoteAppCreateView
(
BaseRemoteAppCreateUpdateView
,
PermissionsMixin
,
CreateView
):
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
_
(
'Applications'
),
'app'
:
_
(
'Applications'
),
'action'
:
_
(
'Create RemoteApp'
),
'action'
:
_
(
'Create RemoteApp'
),
'
type
'
:
'create'
'
api_action
'
:
'create'
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
get_success_message
(
self
,
cleaned_data
):
def
get_type
(
self
):
return
create_success_msg
%
({
'name'
:
cleaned_data
[
'name'
]})
tp
=
self
.
request
.
GET
.
get
(
"type"
)
if
tp
:
return
tp
.
lower
()
return
super
()
.
get_type
()
class
RemoteAppUpdateView
(
PermissionsMixin
,
SuccessMessageMixin
,
UpdateView
):
class
RemoteAppUpdateView
(
BaseRemoteAppCreateUpdateView
,
template_name
=
'applications/remote_app_create_update.html'
PermissionsMixin
,
UpdateView
):
model
=
RemoteApp
form_class
=
forms
.
RemoteAppCreateUpdateForm
success_url
=
reverse_lazy
(
'applications:remote-app-list'
)
permission_classes
=
[
IsOrgAdmin
]
def
get_initial
(
self
):
def
get_initial
(
self
):
return
{
k
:
v
for
k
,
v
in
self
.
object
.
params
.
items
()}
initial_data
=
super
()
.
get_initial
()
params
=
{
k
:
v
for
k
,
v
in
self
.
object
.
params
.
items
()}
initial_data
.
update
(
params
)
return
initial_data
def
get_type
(
self
):
return
self
.
object
.
type
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
_
(
'Applications'
),
'app'
:
_
(
'Applications'
),
'action'
:
_
(
'Update RemoteApp'
),
'action'
:
_
(
'Update RemoteApp'
),
'
type
'
:
'update'
'
api_action
'
:
'update'
}
}
kwargs
.
update
(
context
)
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
get_success_message
(
self
,
cleaned_data
):
return
update_success_msg
%
({
'name'
:
cleaned_data
[
'name'
]})
class
RemoteAppDetailView
(
PermissionsMixin
,
DetailView
):
class
RemoteAppDetailView
(
PermissionsMixin
,
DetailView
):
template_name
=
'applications/remote_app_detail.html'
template_name
=
'applications/remote_app_detail.html'
...
...
apps/common/fields/serializer.py
View file @
b4498f22
...
@@ -51,12 +51,13 @@ class CustomMetaDictField(serializers.DictField):
...
@@ -51,12 +51,13 @@ class CustomMetaDictField(serializers.DictField):
CommandStorage meta field
CommandStorage meta field
ReplayStorage meta field
ReplayStorage meta field
"""
"""
type_
map_fields
=
{}
type_
fields_map
=
{}
default_type
=
None
default_type
=
None
need_convert_key
=
False
convert_key_remove_type_prefix
=
False
convert_key_to_upper
=
False
def
filter_attribute
(
self
,
attribute
,
instance
):
def
filter_attribute
(
self
,
attribute
,
instance
):
fields
=
self
.
type_
map_fields
.
get
(
instance
.
type
,
[])
fields
=
self
.
type_
fields_map
.
get
(
instance
.
type
,
[])
for
field
in
fields
:
for
field
in
fields
:
if
field
.
get
(
'write_only'
,
False
):
if
field
.
get
(
'write_only'
,
False
):
attribute
.
pop
(
field
[
'name'
],
None
)
attribute
.
pop
(
field
[
'name'
],
None
)
...
@@ -70,29 +71,35 @@ class CustomMetaDictField(serializers.DictField):
...
@@ -70,29 +71,35 @@ class CustomMetaDictField(serializers.DictField):
attribute
=
self
.
filter_attribute
(
attribute
,
instance
)
attribute
=
self
.
filter_attribute
(
attribute
,
instance
)
return
attribute
return
attribute
def
convert_value_key
(
self
,
dictionary
,
value
):
def
convert_value_key_remove_type_prefix
(
self
,
dictionary
,
value
):
if
not
self
.
need_convert_key
:
if
not
self
.
convert_key_remove_type_prefix
:
# remote app
return
value
return
value
tp
=
dictionary
.
get
(
'type'
)
tp
=
dictionary
.
get
(
'type'
)
_value
=
{}
prefix
=
'{}_'
.
format
(
tp
)
convert_value
=
{}
for
k
,
v
in
value
.
items
():
for
k
,
v
in
value
.
items
():
prefix
=
'{}_'
.
format
(
tp
)
_k
=
k
if
k
.
lower
()
.
startswith
(
prefix
):
if
k
.
lower
()
.
startswith
(
prefix
):
_k
=
k
.
lower
()
.
split
(
prefix
,
1
)[
1
]
k
=
k
.
lower
()
.
split
(
prefix
,
1
)[
1
]
_k
=
_k
.
upper
()
convert_value
[
k
]
=
v
_value
[
_k
]
=
value
[
k
]
return
convert_value
return
_value
def
convert_value_key_to_upper
(
self
,
value
):
if
not
self
.
convert_key_to_upper
:
return
value
convert_value
=
{
k
.
upper
():
v
for
k
,
v
in
value
.
items
()}
return
convert_value
def
convert_value_key
(
self
,
dictionary
,
value
):
value
=
self
.
convert_value_key_remove_type_prefix
(
dictionary
,
value
)
value
=
self
.
convert_value_key_to_upper
(
value
)
return
value
def
filter_value_key
(
self
,
dictionary
,
value
):
def
filter_value_key
(
self
,
dictionary
,
value
):
tp
=
dictionary
.
get
(
'type'
,
self
.
default_type
)
tp
=
dictionary
.
get
(
'type'
)
fields
=
self
.
type_
map_fields
.
get
(
tp
,
[])
fields
=
self
.
type_
fields_map
.
get
(
tp
,
[])
fields_names
=
[
field
[
'name'
]
for
field
in
fields
]
fields_names
=
[
field
[
'name'
]
for
field
in
fields
]
no_need_keys
=
[
k
for
k
in
value
.
keys
()
if
k
not
in
fields_names
]
filter_value
=
{
k
:
v
for
k
,
v
in
value
.
items
()
if
k
in
fields_names
}
for
k
in
no_need_keys
:
return
filter_value
value
.
pop
(
k
)
return
value
def
get_value
(
self
,
dictionary
):
def
get_value
(
self
,
dictionary
):
"""
"""
...
...
apps/terminal/const.py
View file @
b4498f22
...
@@ -49,7 +49,7 @@ REPLAY_STORAGE_TYPE_AZURE_FIELDS = [
...
@@ -49,7 +49,7 @@ REPLAY_STORAGE_TYPE_AZURE_FIELDS = [
{
'name'
:
'ENDPOINT_SUFFIX'
}
{
'name'
:
'ENDPOINT_SUFFIX'
}
]
]
REPLAY_STORAGE_TYPE_
MAP_FIELDS
=
{
REPLAY_STORAGE_TYPE_
FIELDS_MAP
=
{
REPLAY_STORAGE_TYPE_NULL
:
REPLAY_STORAGE_TYPE_EMPTY_FIELDS
,
REPLAY_STORAGE_TYPE_NULL
:
REPLAY_STORAGE_TYPE_EMPTY_FIELDS
,
REPLAY_STORAGE_TYPE_SERVER
:
REPLAY_STORAGE_TYPE_EMPTY_FIELDS
,
REPLAY_STORAGE_TYPE_SERVER
:
REPLAY_STORAGE_TYPE_EMPTY_FIELDS
,
REPLAY_STORAGE_TYPE_S3
:
REPLAY_STORAGE_TYPE_S3_FIELDS
,
REPLAY_STORAGE_TYPE_S3
:
REPLAY_STORAGE_TYPE_S3_FIELDS
,
...
@@ -89,7 +89,7 @@ COMMAND_STORAGE_TYPE_ES_FIELDS = [
...
@@ -89,7 +89,7 @@ COMMAND_STORAGE_TYPE_ES_FIELDS = [
{
'name'
:
'DOC_TYPE'
}
{
'name'
:
'DOC_TYPE'
}
]
]
COMMAND_STORAGE_TYPE_
MAP_FIELDS
=
{
COMMAND_STORAGE_TYPE_
FIELDS_MAP
=
{
COMMAND_STORAGE_TYPE_NULL
:
COMMAND_STORAGE_TYPE_EMPTY_FIELDS
,
COMMAND_STORAGE_TYPE_NULL
:
COMMAND_STORAGE_TYPE_EMPTY_FIELDS
,
COMMAND_STORAGE_TYPE_SERVER
:
COMMAND_STORAGE_TYPE_EMPTY_FIELDS
,
COMMAND_STORAGE_TYPE_SERVER
:
COMMAND_STORAGE_TYPE_EMPTY_FIELDS
,
COMMAND_STORAGE_TYPE_ES
:
COMMAND_STORAGE_TYPE_ES_FIELDS
,
COMMAND_STORAGE_TYPE_ES
:
COMMAND_STORAGE_TYPE_ES_FIELDS
,
...
...
apps/terminal/serializers/storage.py
View file @
b4498f22
...
@@ -9,13 +9,14 @@ from .. import const
...
@@ -9,13 +9,14 @@ from .. import const
class
ReplayStorageMetaDictField
(
CustomMetaDictField
):
class
ReplayStorageMetaDictField
(
CustomMetaDictField
):
type_
map_fields
=
const
.
REPLAY_STORAGE_TYPE_MAP_FIELDS
type_
fields_map
=
const
.
REPLAY_STORAGE_TYPE_FIELDS_MAP
default_type
=
const
.
REPLAY_STORAGE_TYPE_SERVER
default_type
=
const
.
REPLAY_STORAGE_TYPE_SERVER
need_convert_key
=
True
convert_key_remove_type_prefix
=
True
convert_key_to_upper
=
True
class
BaseStorageSerializerMixin
:
class
BaseStorageSerializerMixin
:
type_
map_fields
=
None
type_
fields_map
=
None
def
process_meta
(
self
,
instance
,
validated_data
):
def
process_meta
(
self
,
instance
,
validated_data
):
new_meta
=
copy
.
deepcopy
(
validated_data
.
get
(
'meta'
,
{}))
new_meta
=
copy
.
deepcopy
(
validated_data
.
get
(
'meta'
,
{}))
...
@@ -25,7 +26,7 @@ class BaseStorageSerializerMixin:
...
@@ -25,7 +26,7 @@ class BaseStorageSerializerMixin:
return
new_meta
return
new_meta
old_meta
=
instance
.
meta
old_meta
=
instance
.
meta
fields
=
self
.
type_
map_fields
.
get
(
instance
.
type
,
[])
fields
=
self
.
type_
fields_map
.
get
(
instance
.
type
,
[])
for
field
in
fields
:
for
field
in
fields
:
if
not
field
.
get
(
'write_only'
,
False
):
if
not
field
.
get
(
'write_only'
,
False
):
continue
continue
...
@@ -48,7 +49,7 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin,
...
@@ -48,7 +49,7 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin,
meta
=
ReplayStorageMetaDictField
()
meta
=
ReplayStorageMetaDictField
()
type_
map_fields
=
const
.
REPLAY_STORAGE_TYPE_MAP_FIELDS
type_
fields_map
=
const
.
REPLAY_STORAGE_TYPE_FIELDS_MAP
class
Meta
:
class
Meta
:
model
=
ReplayStorage
model
=
ReplayStorage
...
@@ -56,9 +57,10 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin,
...
@@ -56,9 +57,10 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin,
class
CommandStorageMetaDictField
(
CustomMetaDictField
):
class
CommandStorageMetaDictField
(
CustomMetaDictField
):
type_
map_fields
=
const
.
COMMAND_STORAGE_TYPE_MAP_FIELDS
type_
fields_map
=
const
.
COMMAND_STORAGE_TYPE_FIELDS_MAP
default_type
=
const
.
COMMAND_STORAGE_TYPE_SERVER
default_type
=
const
.
COMMAND_STORAGE_TYPE_SERVER
need_convert_key
=
True
convert_key_remove_type_prefix
=
True
convert_key_to_upper
=
True
class
CommandStorageSerializer
(
BaseStorageSerializerMixin
,
class
CommandStorageSerializer
(
BaseStorageSerializerMixin
,
...
@@ -66,7 +68,7 @@ class CommandStorageSerializer(BaseStorageSerializerMixin,
...
@@ -66,7 +68,7 @@ class CommandStorageSerializer(BaseStorageSerializerMixin,
meta
=
CommandStorageMetaDictField
()
meta
=
CommandStorageMetaDictField
()
type_
map_fields
=
const
.
COMMAND_STORAGE_TYPE_MAP_FIELDS
type_
fields_map
=
const
.
COMMAND_STORAGE_TYPE_FIELDS_MAP
class
Meta
:
class
Meta
:
model
=
CommandStorage
model
=
CommandStorage
...
...
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