Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gjl2004yn
jumpserver
提交
775cd523
J
jumpserver
项目概览
gjl2004yn
/
jumpserver
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jumpserver
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
775cd523
编写于
12月 25, 2016
作者:
baltery
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update app terminal name to applications
上级
a8fa4d2f
变更
47
展开全部
隐藏空白更改
内联
并排
Showing
47 changed file
with
151 addition
and
140 deletion
+151
-140
apps/applications/__init__.py
apps/applications/__init__.py
+0
-0
apps/applications/admin.py
apps/applications/admin.py
+0
-0
apps/applications/api.py
apps/applications/api.py
+1
-1
apps/applications/apps.py
apps/applications/apps.py
+2
-2
apps/applications/forms.py
apps/applications/forms.py
+0
-0
apps/applications/hands.py
apps/applications/hands.py
+0
-0
apps/applications/models.py
apps/applications/models.py
+2
-14
apps/applications/serializers.py
apps/applications/serializers.py
+1
-1
apps/applications/tasks.py
apps/applications/tasks.py
+0
-0
apps/applications/templates/applications/terminal_list.html
apps/applications/templates/applications/terminal_list.html
+12
-5
apps/applications/templates/applications/terminal_update.html
.../applications/templates/applications/terminal_update.html
+0
-0
apps/applications/tests.py
apps/applications/tests.py
+0
-0
apps/applications/urls/__init__.py
apps/applications/urls/__init__.py
+0
-0
apps/applications/urls/api_urls.py
apps/applications/urls/api_urls.py
+3
-3
apps/applications/urls/views_urls.py
apps/applications/urls/views_urls.py
+1
-1
apps/applications/views.py
apps/applications/views.py
+5
-5
apps/assets/views.py
apps/assets/views.py
+1
-1
apps/audits/api.py
apps/audits/api.py
+1
-1
apps/audits/hands.py
apps/audits/hands.py
+1
-1
apps/audits/serializers.py
apps/audits/serializers.py
+1
-1
apps/jumpserver/settings.py
apps/jumpserver/settings.py
+5
-5
apps/jumpserver/urls.py
apps/jumpserver/urls.py
+4
-3
apps/static/js/angular.min.js
apps/static/js/angular.min.js
+2
-2
apps/static/js/jquery-2.1.1.js
apps/static/js/jquery-2.1.1.js
+1
-1
apps/static/js/jumpserver.js
apps/static/js/jumpserver.js
+1
-1
apps/static/js/plugins/dataTables/datatables.min.js
apps/static/js/plugins/dataTables/datatables.min.js
+10
-10
apps/static/js/plugins/dropzone/dropzone.js
apps/static/js/plugins/dropzone/dropzone.js
+2
-2
apps/static/js/plugins/highcharts/highcharts-all.js
apps/static/js/plugins/highcharts/highcharts-all.js
+1
-1
apps/static/js/plugins/highcharts/highcharts.src.js
apps/static/js/plugins/highcharts/highcharts.src.js
+1
-1
apps/static/js/plugins/highcharts/modules/exporting.js
apps/static/js/plugins/highcharts/modules/exporting.js
+1
-1
apps/static/js/plugins/highcharts/modules/exporting.src.js
apps/static/js/plugins/highcharts/modules/exporting.src.js
+1
-1
apps/static/js/plugins/steps/jquery.steps.min.js
apps/static/js/plugins/steps/jquery.steps.min.js
+1
-1
apps/static/js/record.js
apps/static/js/record.js
+2
-2
apps/static/js/term.js
apps/static/js/term.js
+26
-26
apps/static/js/webterminal.js
apps/static/js/webterminal.js
+7
-7
apps/static/js/wssh.js
apps/static/js/wssh.js
+1
-1
apps/templates/_nav.html
apps/templates/_nav.html
+7
-4
apps/terminal/migrations/__init__.py
apps/terminal/migrations/__init__.py
+0
-0
apps/users/api.py
apps/users/api.py
+4
-4
apps/users/authentication.py
apps/users/authentication.py
+11
-9
apps/users/hands.py
apps/users/hands.py
+1
-1
apps/users/models/authentication.py
apps/users/models/authentication.py
+1
-4
apps/users/models/user.py
apps/users/models/user.py
+13
-12
apps/users/utils.py
apps/users/utils.py
+11
-3
apps/users/views.py
apps/users/views.py
+1
-1
utils/clean_migrations.sh
utils/clean_migrations.sh
+1
-1
utils/generate_fake.sh
utils/generate_fake.sh
+4
-0
未找到文件。
apps/
terminal
/__init__.py
→
apps/
applications
/__init__.py
浏览文件 @
775cd523
文件已移动
apps/
terminal
/admin.py
→
apps/
applications
/admin.py
浏览文件 @
775cd523
文件已移动
apps/
terminal
/api.py
→
apps/
applications
/api.py
浏览文件 @
775cd523
...
...
@@ -33,7 +33,7 @@ class TerminalRegisterView(ListCreateAPIView):
terminal
=
serializer
.
save
()
app_user
,
access_key
=
terminal
.
create_related_app_user
()
data
=
{}
data
[
'
terminal
'
]
=
copy
.
deepcopy
(
serializer
.
data
)
data
[
'
applications
'
]
=
copy
.
deepcopy
(
serializer
.
data
)
data
[
'user'
]
=
app_user
.
to_json
()
data
[
'access_key_id'
]
=
access_key
.
id
data
[
'access_key_secret'
]
=
access_key
.
secret
...
...
apps/
terminal
/apps.py
→
apps/
applications
/apps.py
浏览文件 @
775cd523
...
...
@@ -3,5 +3,5 @@ from __future__ import unicode_literals
from
django.apps
import
AppConfig
class
Terminal
Config
(
AppConfig
):
name
=
'
terminal
'
class
Applications
Config
(
AppConfig
):
name
=
'
applications
'
apps/
terminal
/forms.py
→
apps/
applications
/forms.py
浏览文件 @
775cd523
文件已移动
apps/
terminal
/hands.py
→
apps/
applications
/hands.py
浏览文件 @
775cd523
文件已移动
apps/
terminal
/models.py
→
apps/
applications
/models.py
浏览文件 @
775cd523
...
...
@@ -16,6 +16,7 @@ class Terminal(models.Model):
type
=
models
.
CharField
(
choices
=
TYPE_CHOICES
,
max_length
=
2
,
blank
=
True
,
verbose_name
=
_
(
'Terminal type'
))
user
=
models
.
OneToOneField
(
User
,
verbose_name
=
'Application user'
,
null
=
True
)
url
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
,
verbose_name
=
_
(
'URL to login'
))
is_accepted
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'Is Accepted'
)
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
...
...
@@ -31,19 +32,6 @@ class Terminal(models.Model):
self
.
user
.
is_active
=
active
self
.
user
.
save
()
@
property
def
is_accepted
(
self
):
if
self
.
user
:
return
True
else
:
return
False
@
is_accepted
.
setter
def
is_accepted
(
self
,
active
):
if
active
is
True
and
self
.
user
:
self
.
user
.
is_active
=
True
self
.
user
.
save
()
def
create_related_app_user
(
self
):
user
,
access_key
=
User
.
create_app_user
(
name
=
self
.
name
,
comment
=
self
.
comment
)
self
.
user
=
user
...
...
@@ -65,7 +53,7 @@ class Terminal(models.Model):
__str__
=
__unicode__
class
Meta
:
db_table
=
'
terminal
'
db_table
=
'
applications
'
class
TerminalHeatbeat
(
models
.
Model
):
...
...
apps/
terminal
/serializers.py
→
apps/
applications
/serializers.py
浏览文件 @
775cd523
...
...
@@ -14,7 +14,7 @@ class TerminalSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
Terminal
fields
=
[
'id'
,
'name'
,
'remote_addr'
,
'type'
,
'url'
,
'comment'
,
fields
=
[
'id'
,
'name'
,
'remote_addr'
,
'type'
,
'url'
,
'comment'
,
'is_accepted'
,
'is_active'
,
'get_type_display'
,
'proxy_online'
,
'is_alive'
]
@
staticmethod
...
...
apps/
terminal
/tasks.py
→
apps/
applications
/tasks.py
浏览文件 @
775cd523
文件已移动
apps/
terminal/templates/terminal
/terminal_list.html
→
apps/
applications/templates/applications
/terminal_list.html
浏览文件 @
775cd523
...
...
@@ -65,16 +65,23 @@ $(document).ready(function(){
}},
{
targets
:
7
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
console
.
log
(
rowData
.
name
);
var
update_btn
=
'
<a href="{% url "
terminal
:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>
'
var
update_btn
=
'
<a href="{% url "
applications
:terminal-update" pk=99991937 %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>
'
.
replace
(
'
99991937
'
,
cellData
);
var
delete_btn
=
'
<a class="btn btn-xs btn-danger m-l-xs btn_delete" data-uid="99991937" data-name="99991938">{% trans "Delete" %}</a>
'
.
replace
(
'
99991937
'
,
cellData
)
.
replace
(
'
99991938
'
,
rowData
.
name
);
$
(
td
).
html
(
update_btn
+
delete_btn
)
var
accept_btn
=
'
<a href="" class="btn btn-xs btn-primary">{% trans "Accept" %}</a>
'
.
replace
(
'
99991937
'
,
cellData
);
var
reject_btn
=
'
<a href="" class="btn btn-xs btn-danger">{% trans "Reject" %}</a>
'
if
(
rowData
.
is_accepted
)
{
$
(
td
).
html
(
update_btn
+
delete_btn
)
}
else
{
$
(
td
).
html
(
accept_btn
+
reject_btn
)
}
}}
],
ajax_url
:
'
{% url "api-
terminal
:terminal-list" %}
'
,
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"
name
"
},
{
data
:
"
ip
"
},
{
data
:
"
get_type_display
"
},
ajax_url
:
'
{% url "api-
applications
:terminal-list" %}
'
,
columns
:
[{
data
:
function
(){
return
""
}},
{
data
:
"
name
"
},
{
data
:
"
remote_addr
"
},
{
data
:
"
get_type_display
"
},
{
data
:
"
proxy_online
"
},
{
data
:
"
is_active
"
},
{
data
:
'
is_active
'
},
{
data
:
"
id
"
}],
op_html
:
$
(
'
#actions
'
).
html
()
};
...
...
@@ -83,7 +90,7 @@ $(document).ready(function(){
var
$this
=
$
(
this
);
var
uid
=
$this
.
data
(
'
uid
'
);
var
name
=
$
(
this
).
data
(
'
name
'
);
var
the_url
=
'
{% url "api-
terminal
:terminal-detail" pk=99991937 %}
'
.
replace
(
'
99991937
'
,
uid
);
var
the_url
=
'
{% url "api-
applications
:terminal-detail" pk=99991937 %}
'
.
replace
(
'
99991937
'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
)
})
</script>
...
...
apps/
terminal/templates/terminal
/terminal_update.html
→
apps/
applications/templates/applications
/terminal_update.html
浏览文件 @
775cd523
文件已移动
apps/
terminal
/tests.py
→
apps/
applications
/tests.py
浏览文件 @
775cd523
文件已移动
apps/
terminal
/urls/__init__.py
→
apps/
applications
/urls/__init__.py
浏览文件 @
775cd523
文件已移动
apps/
terminal
/urls/api_urls.py
→
apps/
applications
/urls/api_urls.py
浏览文件 @
775cd523
...
...
@@ -7,14 +7,14 @@ from rest_framework import routers
from
..
import
api
app_name
=
'
terminal
'
app_name
=
'
applications
'
router
=
routers
.
DefaultRouter
()
router
.
register
(
r
'v1/terminal/heatbeat'
,
api
.
TerminalHeatbeatViewSet
,
'terminal-heatbeat'
)
router
.
register
(
r
'v1/terminal'
,
api
.
TerminalViewSet
,
'terminal'
)
router
.
register
(
r
'v1/terminal/heatbeat'
,
api
.
TerminalHeatbeatViewSet
,
'terminal-heatbeat'
)
urlpatterns
=
[
url
(
r
'v1/
register$'
,
api
.
TerminalRegisterView
.
as_view
(),
name
=
'api-
terminal-register'
)
url
(
r
'v1/
terminal/register$'
,
api
.
TerminalRegisterView
.
as_view
(),
name
=
'
terminal-register'
)
]
urlpatterns
+=
router
.
urls
\ No newline at end of file
apps/
terminal
/urls/views_urls.py
→
apps/
applications
/urls/views_urls.py
浏览文件 @
775cd523
...
...
@@ -6,7 +6,7 @@ from django.conf.urls import url
from
..
import
views
app_name
=
'
terminal
'
app_name
=
'
applications
'
urlpatterns
=
[
url
(
r
'^terminal$'
,
views
.
TerminalListView
.
as_view
(),
name
=
'terminal-list'
),
...
...
apps/
terminal
/views.py
→
apps/
applications
/views.py
浏览文件 @
775cd523
...
...
@@ -11,7 +11,7 @@ from .forms import TerminalForm
class
TerminalListView
(
ListView
):
model
=
Terminal
template_name
=
'
terminal
/terminal_list.html'
template_name
=
'
applications
/terminal_list.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
TerminalListView
,
self
).
get_context_data
(
**
kwargs
)
...
...
@@ -22,16 +22,16 @@ class TerminalListView(ListView):
class
TerminalUpdateView
(
UpdateView
):
model
=
Terminal
form_class
=
TerminalForm
template_name
=
'
terminal
/terminal_update.html'
success_url
=
reverse_lazy
(
'
terminal:terminal
-list'
)
template_name
=
'
applications
/terminal_update.html'
success_url
=
reverse_lazy
(
'
applications:applications
-list'
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
(
TerminalUpdateView
,
self
).
get_context_data
(
**
kwargs
)
context
.
update
({
'app'
:
_
(
'Terminal'
),
'action'
:
_
(
'Update
terminal
'
)})
context
.
update
({
'app'
:
_
(
'Terminal'
),
'action'
:
_
(
'Update
applications
'
)})
return
context
class
TerminalDeleteView
(
DeleteView
):
model
=
Terminal
template_name
=
'assets/delete_confirm.html'
success_url
=
reverse_lazy
(
'terminal:terminal-list'
)
\ No newline at end of file
success_url
=
reverse_lazy
(
'applications:applications-list'
)
\ No newline at end of file
apps/assets/views.py
浏览文件 @
775cd523
...
...
@@ -738,7 +738,7 @@ class AssetExportView(View):
ws
.
append
([
self
.
get_asset_attr
(
asset
,
attr
)
for
attr
in
header
])
filename
=
'assets-{}.xlsx'
.
format
(
timezone
.
localtime
(
timezone
.
now
()).
strftime
(
'%Y-%m-%d_%H-%M-%S'
))
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'application/vnd.ms-excel'
)
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'application
s
/vnd.ms-excel'
)
response
[
'Content-Disposition'
]
=
'attachment; filename="%s"'
%
filename
return
response
...
...
apps/audits/api.py
浏览文件 @
775cd523
...
...
@@ -18,7 +18,7 @@ class ProxyLogViewSet(viewsets.ModelViewSet):
"name": "",
"hostname": "",
"ip": "",
"
terminal
", "",
"
applications
", "",
"login_type": "",
"system_user": "",
"was_failed": "",
...
...
apps/audits/hands.py
浏览文件 @
775cd523
...
...
@@ -5,4 +5,4 @@ from users.utils import AdminUserRequiredMixin
from
users.models
import
User
from
assets.models
import
Asset
,
SystemUser
from
users.permissions
import
IsSuperUserOrAppUser
from
terminal
.models
import
Terminal
from
applications
.models
import
Terminal
apps/audits/serializers.py
浏览文件 @
775cd523
...
...
@@ -13,7 +13,7 @@ class ProxyLogSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
models
.
ProxyLog
fields
=
[
'id'
,
'name'
,
'username'
,
'hostname'
,
'ip'
,
'system_user'
,
'login_type'
,
'
terminal
'
,
fields
=
[
'id'
,
'name'
,
'username'
,
'hostname'
,
'ip'
,
'system_user'
,
'login_type'
,
'
applications
'
,
'log_file'
,
'was_failed'
,
'is_finished'
,
'date_start'
,
'date_finished'
,
'time'
,
'command_length'
,
"commands_dict"
]
...
...
apps/jumpserver/settings.py
浏览文件 @
775cd523
...
...
@@ -58,7 +58,7 @@ INSTALLED_APPS = [
'ops.apps.OpsConfig'
,
'audits.apps.AuditsConfig'
,
'common.apps.CommonConfig'
,
'
terminal.apps.Terminal
Config'
,
'
applications.apps.Applications
Config'
,
'rest_framework'
,
'bootstrapform'
,
'captcha'
,
...
...
@@ -103,7 +103,7 @@ TEMPLATES = [
},
]
# WSGI_APPLICATION = 'jumpserver.wsgi.application'
# WSGI_APPLICATION = 'jumpserver.wsgi.application
s
'
LOGIN_REDIRECT_URL
=
reverse_lazy
(
'index'
)
LOGIN_URL
=
reverse_lazy
(
'users:login'
)
...
...
@@ -277,7 +277,7 @@ REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'
:
(
'users.authentication.AccessKeyAuthentication'
,
'users.authentication.AccessTokenAuthentication'
,
'
rest_framework.authentication.
TokenAuthentication'
,
'
users.authentication.Private
TokenAuthentication'
,
'rest_framework.authentication.SessionAuthentication'
,
),
'DEFAULT_FILTER_BACKENDS'
:
(
'django_filters.rest_framework.DjangoFilterBackend'
,),
...
...
@@ -298,9 +298,9 @@ CELERY_RESULT_BACKEND = BROKER_URL
# crontab job
# CELERYBEAT_SCHEDULE = {
# Check
terminal
is alive every 10m
# Check
applications
is alive every 10m
# 'check_terminal_alive': {
# 'task': '
terminal
.tasks.check_terminal_alive',
# 'task': '
applications
.tasks.check_terminal_alive',
# 'schedule': timedelta(seconds=TERMINAL_HEATBEAT_INTERVAL),
# 'args': (),
# },
...
...
apps/jumpserver/urls.py
浏览文件 @
775cd523
...
...
@@ -29,14 +29,15 @@ urlpatterns = [
url
(
r
'^assets/'
,
include
(
'assets.urls.views_urls'
,
namespace
=
'assets'
)),
url
(
r
'^perms/'
,
include
(
'perms.urls.views_urls'
,
namespace
=
'perms'
)),
url
(
r
'^audits/'
,
include
(
'audits.urls.views_urls'
,
namespace
=
'audits'
)),
url
(
r
'^
terminal/'
,
include
(
'terminal.urls.views_urls'
,
namespace
=
'terminal
'
)),
url
(
'^ops/'
,
include
(
'ops.urls.view_urls'
,
namespace
=
'ops'
)),
url
(
r
'^
applications/'
,
include
(
'applications.urls.views_urls'
,
namespace
=
'applications
'
)),
url
(
r
'^ops/'
,
include
(
'ops.urls.view_urls'
,
namespace
=
'ops'
)),
# Api url view map
url
(
r
'^api/users/'
,
include
(
'users.urls.api_urls'
,
namespace
=
'api-users'
)),
url
(
r
'^api/assets/'
,
include
(
'assets.urls.api_urls'
,
namespace
=
'api-assets'
)),
url
(
r
'^api/perms/'
,
include
(
'perms.urls.api_urls'
,
namespace
=
'api-perms'
)),
url
(
r
'^api/audits/'
,
include
(
'audits.urls.api_urls'
,
namespace
=
'api-audits'
)),
url
(
r
'^api/
terminal/'
,
include
(
'terminal.urls.api_urls'
,
namespace
=
'api-terminal
'
)),
url
(
r
'^api/
applications/'
,
include
(
'applications.urls.api_urls'
,
namespace
=
'api-applications
'
)),
url
(
r
'^api/ops/'
,
include
(
'ops.urls.api_urls'
,
namespace
=
'api-ops'
)),
]
...
...
apps/static/js/angular.min.js
浏览文件 @
775cd523
...
...
@@ -75,7 +75,7 @@ b)}:E;D.$$addScopeClass=k?function(a,b){I(a,b?"ng-isolate-scope":"ng-scope")}:E;
"
controller
"
);
J
(
a
)?
w
(
b
,
a
):
b
[
a
]
=
c
};
this
.
allowGlobals
=
function
(){
a
=!
0
};
this
.
$get
=
[
"
$injector
"
,
"
$window
"
,
function
(
d
,
e
){
function
f
(
a
,
b
,
c
,
d
){
if
(
!
a
||!
J
(
a
.
$scope
))
throw
R
(
"
$controller
"
)(
"
noscp
"
,
d
,
b
);
a
.
$scope
[
b
]
=
c
}
return
function
(
g
,
h
,
l
,
k
){
var
n
,
p
,
q
;
l
=!
0
===
l
;
k
&&
C
(
k
)
&&
(
q
=
k
);
if
(
C
(
g
)){
k
=
g
.
match
(
c
);
if
(
!
k
)
throw
rf
(
"
ctrlfmt
"
,
g
);
p
=
k
[
1
];
q
=
q
||
k
[
3
];
g
=
b
.
hasOwnProperty
(
p
)?
b
[
p
]:
xc
(
h
.
$scope
,
p
,
!
0
)
||
(
a
?
xc
(
e
,
p
,
!
0
):
t
);
sb
(
g
,
p
,
!
0
)}
if
(
l
)
return
l
=
(
H
(
g
)?
g
[
g
.
length
-
1
]:
g
).
prototype
,
n
=
Object
.
create
(
l
||
null
),
q
&&
f
(
h
,
q
,
n
,
p
||
g
.
name
),
w
(
function
(){
d
.
invoke
(
g
,
n
,
h
,
p
);
return
n
},{
instance
:
n
,
identifier
:
q
});
n
=
d
.
instantiate
(
g
,
h
,
p
);
q
&&
f
(
h
,
q
,
n
,
p
||
g
.
name
);
return
n
}}]}
function
Ge
(){
this
.
$get
=
[
"
$window
"
,
function
(
b
){
return
A
(
b
.
document
)}]}
function
He
(){
this
.
$get
=
[
"
$log
"
,
function
(
b
){
return
function
(
a
,
c
){
b
.
error
.
apply
(
b
,
arguments
)}}]}
function
Zb
(
b
,
a
){
if
(
C
(
b
)){
var
c
=
b
.
replace
(
sf
,
""
).
trim
();
if
(
c
){
var
d
=
a
(
"
Content-Type
"
);(
d
=
d
&&
0
===
d
.
indexOf
(
Wc
))
||
(
d
=
(
d
=
c
.
match
(
tf
))
&&
uf
[
d
[
0
]].
test
(
c
));
d
&&
(
b
=
qc
(
c
))}}
return
b
}
function
Xc
(
b
){
var
a
=
ia
(),
c
,
d
,
e
;
if
(
!
b
)
return
a
;
r
(
b
.
split
(
"
\n
"
),
function
(
b
){
e
=
b
.
indexOf
(
"
:
"
);
c
=
z
(
N
(
b
.
substr
(
0
,
e
)));
d
=
N
(
b
.
substr
(
e
+
1
));
c
&&
(
a
[
c
]
=
a
[
c
]?
a
[
c
]
+
"
,
"
+
d
:
d
)});
return
a
}
function
Yc
(
b
){
var
a
=
J
(
b
)?
b
:
t
;
return
function
(
c
){
a
||
(
a
=
Xc
(
b
));
return
c
?(
c
=
a
[
z
(
c
)],
void
0
===
c
&&
(
c
=
null
),
c
):
a
}}
function
Zc
(
b
,
a
,
c
,
d
){
if
(
G
(
d
))
return
d
(
b
,
a
,
c
);
r
(
d
,
function
(
d
){
b
=
d
(
b
,
a
,
c
)});
return
b
}
function
Ke
(){
var
b
=
this
.
defaults
=
{
transformResponse
:[
Zb
],
transformRequest
:[
function
(
a
){
return
J
(
a
)
&&
"
[object File]
"
!==
Ca
.
call
(
a
)
&&
"
[object Blob]
"
!==
Ca
.
call
(
a
)
&&
"
[object FormData]
"
!==
Ca
.
call
(
a
)?
$a
(
a
):
a
}],
headers
:{
common
:{
Accept
:
"
application/json, text/plain, */*
"
},
post
:
sa
(
$b
),
put
:
sa
(
$b
),
patch
:
sa
(
$b
)},
xsrfCookieName
:
"
XSRF-TOKEN
"
,
xsrfHeaderName
:
"
X-XSRF-TOKEN
"
},
a
=!
1
;
this
.
useApplyAsync
=
function
(
b
){
return
y
(
b
)?(
a
=!!
b
,
this
):
a
};
var
c
=
this
.
interceptors
=
[];
this
.
$get
=
[
"
$httpBackend
"
,
"
$browser
"
,
"
$cacheFactory
"
,
"
$rootScope
"
,
"
$q
"
,
"
$injector
"
,
function
(
d
,
e
,
f
,
g
,
h
,
l
){
function
k
(
a
){
function
c
(
a
){
var
b
=
w
({},
a
);
b
.
data
=
a
.
data
?
Zc
(
a
.
data
,
a
.
headers
,
a
.
status
,
e
.
transformResponse
):
a
.
data
;
a
=
a
.
status
;
return
200
<=
a
&&
300
>
a
?
a
}],
headers
:{
common
:{
Accept
:
"
application
s
/json, text/plain, */*
"
},
post
:
sa
(
$b
),
put
:
sa
(
$b
),
patch
:
sa
(
$b
)},
xsrfCookieName
:
"
XSRF-TOKEN
"
,
xsrfHeaderName
:
"
X-XSRF-TOKEN
"
},
a
=!
1
;
this
.
useApplyAsync
=
function
(
b
){
return
y
(
b
)?(
a
=!!
b
,
this
):
a
};
var
c
=
this
.
interceptors
=
[];
this
.
$get
=
[
"
$httpBackend
"
,
"
$browser
"
,
"
$cacheFactory
"
,
"
$rootScope
"
,
"
$q
"
,
"
$injector
"
,
function
(
d
,
e
,
f
,
g
,
h
,
l
){
function
k
(
a
){
function
c
(
a
){
var
b
=
w
({},
a
);
b
.
data
=
a
.
data
?
Zc
(
a
.
data
,
a
.
headers
,
a
.
status
,
e
.
transformResponse
):
a
.
data
;
a
=
a
.
status
;
return
200
<=
a
&&
300
>
a
?
b
:
h
.
reject
(
b
)}
function
d
(
a
){
var
b
,
c
=
{};
r
(
a
,
function
(
a
,
d
){
G
(
a
)?(
b
=
a
(),
null
!=
b
&&
(
c
[
d
]
=
b
)):
c
[
d
]
=
a
});
return
c
}
if
(
!
ca
.
isObject
(
a
))
throw
R
(
"
$http
"
)(
"
badreq
"
,
a
);
var
e
=
w
({
method
:
"
get
"
,
transformRequest
:
b
.
transformRequest
,
transformResponse
:
b
.
transformResponse
},
a
);
e
.
headers
=
function
(
a
){
var
c
=
b
.
headers
,
e
=
w
({},
a
.
headers
),
f
,
g
,
c
=
w
({},
c
.
common
,
c
[
z
(
a
.
method
)]);
a
:
for
(
f
in
c
){
a
=
z
(
f
);
for
(
g
in
e
)
if
(
z
(
g
)
===
a
)
continue
a
;
e
[
f
]
=
c
[
f
]}
return
d
(
e
)}(
a
);
e
.
method
=
ub
(
e
.
method
);
var
f
=
[
function
(
a
){
var
d
=
a
.
headers
,
e
=
Zc
(
a
.
data
,
Yc
(
d
),
t
,
a
.
transformRequest
);
x
(
e
)
&&
r
(
d
,
function
(
a
,
b
){
"
content-type
"
===
z
(
b
)
&&
delete
d
[
b
]});
x
(
a
.
withCredentials
)
&&!
x
(
b
.
withCredentials
)
&&
(
a
.
withCredentials
=
b
.
withCredentials
);
return
n
(
a
,
e
).
then
(
c
,
c
)},
t
],
g
=
h
.
when
(
e
);
for
(
r
(
u
,
function
(
a
){(
a
.
request
||
a
.
requestError
)
&&
f
.
unshift
(
a
.
request
,
a
.
requestError
);(
a
.
response
||
a
.
responseError
)
&&
f
.
push
(
a
.
response
,
a
.
responseError
)});
f
.
length
;){
a
=
f
.
shift
();
var
k
=
f
.
shift
(),
g
=
g
.
then
(
a
,
k
)}
g
.
success
=
function
(
a
){
g
.
then
(
function
(
b
){
a
(
b
.
data
,
b
.
status
,
b
.
headers
,
e
)});
return
g
};
g
.
error
=
function
(
a
){
g
.
then
(
null
,
function
(
b
){
a
(
b
.
data
,
b
.
status
,
b
.
headers
,
e
)});
return
g
};
return
g
}
function
n
(
c
,
f
){
function
l
(
b
,
c
,
d
,
e
){
function
f
(){
m
(
c
,
b
,
d
,
e
)}
I
&&
(
200
<=
b
&&
300
>
b
?
I
.
put
(
P
,[
b
,
c
,
Xc
(
d
),
e
]):
I
.
remove
(
P
));
a
?
g
.
$applyAsync
(
f
):(
f
(),
g
.
$$phase
||
g
.
$apply
())}
function
m
(
a
,
b
,
d
,
e
){
b
=
Math
.
max
(
b
,
0
);(
200
<=
b
&&
300
>
b
?
L
.
resolve
:
L
.
reject
)({
data
:
a
,
status
:
b
,
headers
:
Yc
(
d
),
config
:
c
,
statusText
:
e
})}
function
n
(
a
){
m
(
a
.
data
,
a
.
status
,
sa
(
a
.
headers
()),
a
.
statusText
)}
function
u
(){
var
a
=
k
.
pendingRequests
.
indexOf
(
c
);
-
1
!==
a
&&
k
.
pendingRequests
.
splice
(
a
,
...
...
@@ -176,7 +176,7 @@ d){var e=c+"-animation";if(c&&"."!=c.charAt(0))throw Tf("notcsel",c);this.$$sele
r
((
a
.
attr
(
"
class
"
)
||
""
).
split
(
/
\s
+/
),
function
(
a
){
f
[
a
]
=!
0
});
r
(
c
,
function
(
a
,
c
){
var
g
=
f
[
c
];
!
1
===
a
&&
g
?
e
.
push
(
c
):
!
0
!==
a
||
g
||
d
.
push
(
c
)});
return
0
<
d
.
length
+
e
.
length
&&
[
d
.
length
?
d
:
null
,
e
.
length
?
e
:
null
]}
function
h
(
a
,
c
,
d
){
for
(
var
e
=
0
,
f
=
c
.
length
;
e
<
f
;
++
e
)
a
[
c
[
e
]]
=
d
}
function
l
(){
n
||
(
n
=
a
.
defer
(),
d
(
function
(){
n
.
resolve
();
n
=
null
}));
return
n
.
promise
}
function
k
(
a
,
c
){
if
(
ca
.
isObject
(
c
)){
var
d
=
w
(
c
.
from
||
{},
c
.
to
||
{});
a
.
css
(
d
)}}
var
n
;
return
{
animate
:
function
(
a
,
c
,
d
){
k
(
a
,{
from
:
c
,
to
:
d
});
return
l
()},
enter
:
function
(
a
,
c
,
d
,
e
){
k
(
a
,
e
);
d
?
d
.
after
(
a
):
c
.
prepend
(
a
);
return
l
()},
leave
:
function
(
a
,
c
){
k
(
a
,
c
);
a
.
remove
();
return
l
()},
move
:
function
(
a
,
c
,
d
,
e
){
return
this
.
enter
(
a
,
c
,
d
,
e
)},
addClass
:
function
(
a
,
c
,
d
){
return
this
.
setClass
(
a
,
c
,[],
d
)},
$
$addClassImmediately
:
function
(
a
,
c
,
d
){
a
=
A
(
a
);
c
=
C
(
c
)?
c
:
H
(
c
)?
c
.
join
(
"
"
):
""
;
r
(
a
,
function
(
a
){
Cb
(
a
,
c
)});
k
(
a
,
d
);
return
l
()},
removeClass
:
function
(
a
,
c
,
d
){
return
this
.
setClass
(
a
,[],
c
,
d
)},
$
$removeClassImmediately
:
function
(
a
,
c
,
d
){
a
=
A
(
a
);
c
=
C
(
c
)?
c
:
H
(
c
)?
c
.
join
(
"
"
):
""
;
r
(
a
,
function
(
a
){
Bb
(
a
,
c
)});
k
(
a
,
d
);
return
l
()},
setClass
:
function
(
a
,
c
,
d
,
e
){
var
k
=
this
,
l
=!
1
;
a
=
A
(
a
);
var
m
=
a
.
data
(
"
$$animateClasses
"
);
m
?
e
&&
m
.
options
&&
(
m
.
options
=
ca
.
extend
(
m
.
options
||
{},
e
)):(
m
=
{
classes
:{},
options
:
e
},
l
=!
0
);
e
=
m
.
classes
;
c
=
H
(
c
)?
c
:
c
.
split
(
"
"
);
d
=
H
(
d
)?
d
:
d
.
split
(
"
"
);
h
(
e
,
c
,
!
0
);
h
(
e
,
d
,
!
1
);
l
&&
(
m
.
promise
=
f
(
function
(
c
){
var
d
=
a
.
data
(
"
$$animateClasses
"
);
a
.
removeData
(
"
$$animateClasses
"
);
if
(
d
){
var
e
=
g
(
a
,
d
.
classes
);
e
&&
k
.
$$setClassImmediately
(
a
,
e
[
0
],
e
[
1
],
d
.
options
)}
c
()}),
a
.
data
(
"
$$animateClasses
"
,
m
));
return
m
.
promise
},
$
$setClassImmediately
:
function
(
a
,
c
,
d
,
e
){
c
&&
this
.
$$addClassImmediately
(
a
,
c
);
d
&&
this
.
$$removeClassImmediately
(
a
,
d
);
k
(
a
,
e
);
return
l
()},
enabled
:
E
,
cancel
:
E
}}]}],
la
=
R
(
"
$compile
"
);
yc
.
$inject
=
[
"
$provide
"
,
"
$$sanitizeUriProvider
"
];
var
Sc
=
/^
((?:
x|data
)[\:\-
_
])
/i
,
rf
=
R
(
"
$controller
"
),
Wc
=
"
application/json
"
,
$b
=
{
"
Content-Type
"
:
Wc
+
"
;charset=utf-8
"
},
tf
=
/^
\[
|^
\{(?!\{)
/
,
uf
=
{
"
[
"
:
/
]
$
/
,
"
{
"
:
/
}
$
/
},
sf
=
/^
\)\]\}
',
?\n
/
,
ac
=
R
(
"
$interpolate
"
),
Uf
=
/^
([^\?
#
]
*
)(\?([^
#
]
*
))?(
#
(
.*
))?
$/
,
xf
=
{
http
:
80
,
https
:
443
,
ftp
:
21
},
Gb
=
R
(
"
$location
"
),
Vf
=
{
$
$html5
:
!
1
,
$
$replace
:
!
1
,
absUrl
:
Hb
(
"
$$absUrl
"
),
url
:
function
(
a
){
if
(
x
(
a
))
return
this
.
$$url
;
c
);
d
&&
this
.
$$removeClassImmediately
(
a
,
d
);
k
(
a
,
e
);
return
l
()},
enabled
:
E
,
cancel
:
E
}}]}],
la
=
R
(
"
$compile
"
);
yc
.
$inject
=
[
"
$provide
"
,
"
$$sanitizeUriProvider
"
];
var
Sc
=
/^
((?:
x|data
)[\:\-
_
])
/i
,
rf
=
R
(
"
$controller
"
),
Wc
=
"
application
s
/json
"
,
$b
=
{
"
Content-Type
"
:
Wc
+
"
;charset=utf-8
"
},
tf
=
/^
\[
|^
\{(?!\{)
/
,
uf
=
{
"
[
"
:
/
]
$
/
,
"
{
"
:
/
}
$
/
},
sf
=
/^
\)\]\}
',
?\n
/
,
ac
=
R
(
"
$interpolate
"
),
Uf
=
/^
([^\?
#
]
*
)(\?([^
#
]
*
))?(
#
(
.*
))?
$/
,
xf
=
{
http
:
80
,
https
:
443
,
ftp
:
21
},
Gb
=
R
(
"
$location
"
),
Vf
=
{
$
$html5
:
!
1
,
$
$replace
:
!
1
,
absUrl
:
Hb
(
"
$$absUrl
"
),
url
:
function
(
a
){
if
(
x
(
a
))
return
this
.
$$url
;
var
c
=
Uf
.
exec
(
a
);(
c
[
1
]
||
""
===
a
)
&&
this
.
path
(
decodeURIComponent
(
c
[
1
]));(
c
[
2
]
||
c
[
1
]
||
""
===
a
)
&&
this
.
search
(
c
[
3
]
||
""
);
this
.
hash
(
c
[
5
]
||
""
);
return
this
},
protocol
:
Hb
(
"
$$protocol
"
),
host
:
Hb
(
"
$$host
"
),
port
:
Hb
(
"
$$port
"
),
path
:
dd
(
"
$$path
"
,
function
(
a
){
a
=
null
!==
a
?
a
.
toString
():
""
;
return
"
/
"
==
a
.
charAt
(
0
)?
a
:
"
/
"
+
a
}),
search
:
function
(
a
,
c
){
switch
(
arguments
.
length
){
case
0
:
return
this
.
$$search
;
case
1
:
if
(
C
(
a
)
||
Y
(
a
))
a
=
a
.
toString
(),
this
.
$$search
=
sc
(
a
);
else
if
(
J
(
a
))
a
=
Da
(
a
,{}),
r
(
a
,
function
(
c
,
e
){
null
==
c
&&
delete
a
[
e
]}),
this
.
$$search
=
a
;
else
throw
Gb
(
"
isrcharg
"
);
break
;
default
:
x
(
c
)
||
null
===
c
?
delete
this
.
$$search
[
a
]:
this
.
$$search
[
a
]
=
c
}
this
.
$$compose
();
return
this
},
hash
:
dd
(
"
$$hash
"
,
function
(
a
){
return
null
!==
a
?
a
.
toString
():
""
}),
replace
:
function
(){
this
.
$$replace
=!
0
;
return
this
}};
r
([
cd
,
ec
,
dc
],
function
(
a
){
a
.
prototype
=
Object
.
create
(
Vf
);
a
.
prototype
.
state
=
function
(
c
){
if
(
!
arguments
.
length
)
return
this
.
$$state
;
if
(
a
!==
dc
||!
this
.
$$html5
)
throw
Gb
(
"
nostate
"
);
this
.
$$state
=
x
(
c
)?
null
:
c
;
return
this
}});
var
na
=
R
(
"
$parse
"
),
Wf
=
Function
.
prototype
.
call
,
Xf
=
Function
.
prototype
.
apply
,
Yf
=
Function
.
prototype
.
bind
,
mb
=
ia
();
r
({
"
null
"
:
function
(){
return
null
},
"
true
"
:
function
(){
return
!
0
},
"
false
"
:
function
(){
return
!
1
},
undefined
:
function
(){}},
function
(
a
,
c
){
a
.
constant
=
a
.
literal
=
a
.
sharedGetter
=!
0
;
mb
[
c
]
=
a
});
mb
[
"
this
"
]
=
function
(
a
){
return
a
};
mb
[
"
this
"
].
sharedGetter
=!
0
;
var
nb
=
w
(
ia
(),{
"
+
"
:
function
(
a
,
c
,
d
,
e
){
d
=
d
(
a
,
c
);
e
=
e
(
a
,
c
);
return
y
(
d
)?
y
(
e
)?
d
+
e
:
d
:
y
(
e
)?
e
:
t
},
"
-
"
:
function
(
a
,
c
,
d
,
e
){
d
=
d
(
a
,
c
);
e
=
e
(
a
,
c
);
return
(
y
(
d
)?
d
:
0
)
-
(
y
(
e
)?
e
:
0
)},
"
*
"
:
function
(
a
,
c
,
d
,
e
){
return
d
(
a
,
c
)
*
e
(
a
,
c
)},
...
...
apps/static/js/jquery-2.1.1.js
浏览文件 @
775cd523
此差异已折叠。
点击以展开。
apps/static/js/jumpserver.js
浏览文件 @
775cd523
...
...
@@ -195,7 +195,7 @@ function APIUpdateAttr(props) {
url
:
props
.
url
,
type
:
props
.
method
||
"
PATCH
"
,
data
:
props
.
body
,
contentType
:
props
.
content_type
||
"
application/json; charset=utf-8
"
,
contentType
:
props
.
content_type
||
"
application
s
/json; charset=utf-8
"
,
dataType
:
props
.
data_type
||
"
json
"
}).
done
(
function
(
data
,
textStatue
,
jqXHR
)
{
toastr
.
success
(
success_message
);
...
...
apps/static/js/plugins/dataTables/datatables.min.js
浏览文件 @
775cd523
此差异已折叠。
点击以展开。
apps/static/js/plugins/dropzone/dropzone.js
浏览文件 @
775cd523
...
...
@@ -1370,7 +1370,7 @@
return
;
}
response
=
xhr
.
responseText
;
if
(
xhr
.
getResponseHeader
(
"
content-type
"
)
&&
~
xhr
.
getResponseHeader
(
"
content-type
"
).
indexOf
(
"
application/json
"
))
{
if
(
xhr
.
getResponseHeader
(
"
content-type
"
)
&&
~
xhr
.
getResponseHeader
(
"
content-type
"
).
indexOf
(
"
application
s
/json
"
))
{
try
{
response
=
JSON
.
parse
(
response
);
}
catch
(
_error
)
{
...
...
@@ -1397,7 +1397,7 @@
progressObj
=
(
_ref
=
xhr
.
upload
)
!=
null
?
_ref
:
xhr
;
progressObj
.
onprogress
=
updateProgress
;
headers
=
{
"
Accept
"
:
"
application/json
"
,
"
Accept
"
:
"
application
s
/json
"
,
"
Cache-Control
"
:
"
no-cache
"
,
"
X-Requested-With
"
:
"
XMLHttpRequest
"
};
...
...
apps/static/js/plugins/highcharts/highcharts-all.js
浏览文件 @
775cd523
...
...
@@ -423,7 +423,7 @@ c.setTooltipPoints(),c.render()},c.wrap(c.Axis.prototype,"render",function(c){c.
*/
(
function
(
f
){
var
A
=
f
.
Chart
,
t
=
f
.
addEvent
,
B
=
f
.
removeEvent
,
l
=
f
.
createElement
,
o
=
f
.
discardElement
,
v
=
f
.
css
,
k
=
f
.
merge
,
r
=
f
.
each
,
p
=
f
.
extend
,
D
=
Math
.
max
,
j
=
document
,
C
=
window
,
E
=
f
.
isTouchDevice
,
F
=
f
.
Renderer
.
prototype
.
symbols
,
s
=
f
.
getOptions
(),
y
;
p
(
s
.
lang
,{
printChart
:
"
Print chart
"
,
downloadPNG
:
"
Download PNG image
"
,
downloadJPEG
:
"
Download JPEG image
"
,
downloadPDF
:
"
Download PDF document
"
,
downloadSVG
:
"
Download SVG vector image
"
,
contextButtonTitle
:
"
Chart context menu
"
});
s
.
navigation
=
{
menuStyle
:{
border
:
"
1px solid #A0A0A0
"
,
background
:
"
#FFFFFF
"
,
padding
:
"
5px 0
"
},
menuItemStyle
:{
padding
:
"
0 10px
"
,
background
:
"
none
"
,
color
:
"
#303030
"
,
fontSize
:
E
?
"
14px
"
:
"
11px
"
},
menuItemHoverStyle
:{
background
:
"
#4572A5
"
,
color
:
"
#FFFFFF
"
},
buttonOptions
:{
symbolFill
:
"
#E0E0E0
"
,
symbolSize
:
14
,
symbolStroke
:
"
#666
"
,
symbolStrokeWidth
:
3
,
symbolX
:
12.5
,
symbolY
:
10.5
,
align
:
"
right
"
,
buttonSpacing
:
3
,
height
:
22
,
theme
:{
fill
:
"
white
"
,
stroke
:
"
none
"
},
verticalAlign
:
"
top
"
,
width
:
24
}};
s
.
exporting
=
{
type
:
"
image/png
"
,
url
:
"
http://export.highcharts.com/
"
,
buttons
:{
contextButton
:{
menuClassName
:
"
highcharts-contextmenu
"
,
symbol
:
"
menu
"
,
_titleKey
:
"
contextButtonTitle
"
,
menuItems
:[{
textKey
:
"
printChart
"
,
onclick
:
function
(){
this
.
print
()}},{
separator
:
!
0
},{
textKey
:
"
downloadPNG
"
,
onclick
:
function
(){
this
.
exportChart
()}},{
textKey
:
"
downloadJPEG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/jpeg
"
})}},{
textKey
:
"
downloadPDF
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
application/pdf
"
})}},{
textKey
:
"
downloadSVG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/svg+xml
"
})}}]}}};
f
.
post
=
function
(
b
,
a
,
d
){
var
c
,
b
=
l
(
"
form
"
,
k
({
method
:
"
post
"
,
symbol
:
"
menu
"
,
_titleKey
:
"
contextButtonTitle
"
,
menuItems
:[{
textKey
:
"
printChart
"
,
onclick
:
function
(){
this
.
print
()}},{
separator
:
!
0
},{
textKey
:
"
downloadPNG
"
,
onclick
:
function
(){
this
.
exportChart
()}},{
textKey
:
"
downloadJPEG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/jpeg
"
})}},{
textKey
:
"
downloadPDF
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
application
s
/pdf
"
})}},{
textKey
:
"
downloadSVG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/svg+xml
"
})}}]}}};
f
.
post
=
function
(
b
,
a
,
d
){
var
c
,
b
=
l
(
"
form
"
,
k
({
method
:
"
post
"
,
action
:
b
,
enctype
:
"
multipart/form-data
"
},
d
),{
display
:
"
none
"
},
j
.
body
);
for
(
c
in
a
)
l
(
"
input
"
,{
type
:
"
hidden
"
,
name
:
c
,
value
:
a
[
c
]},
null
,
b
);
b
.
submit
();
o
(
b
)};
p
(
A
.
prototype
,{
getSVG
:
function
(
b
){
var
a
=
this
,
d
,
c
,
z
,
h
,
g
=
k
(
a
.
options
,
b
);
if
(
!
j
.
createElementNS
)
j
.
createElementNS
=
function
(
a
,
b
){
return
j
.
createElement
(
b
)};
b
=
l
(
"
div
"
,
null
,{
position
:
"
absolute
"
,
top
:
"
-9999em
"
,
width
:
a
.
chartWidth
+
"
px
"
,
height
:
a
.
chartHeight
+
"
px
"
},
j
.
body
);
c
=
a
.
renderTo
.
style
.
width
;
h
=
a
.
renderTo
.
style
.
height
;
c
=
g
.
exporting
.
sourceWidth
||
g
.
chart
.
width
||
/px$/
.
test
(
c
)
&&
parseInt
(
c
,
10
)
||
600
;
h
=
g
.
exporting
.
sourceHeight
||
g
.
chart
.
height
||
/px$/
.
test
(
h
)
&&
parseInt
(
h
,
10
)
||
400
;
p
(
g
.
chart
,{
animation
:
!
1
,
renderTo
:
b
,
forExport
:
!
0
,
width
:
c
,
height
:
h
});
g
.
exporting
.
enabled
=!
1
;
g
.
series
=
[];
r
(
a
.
series
,
function
(
a
){
z
=
k
(
a
.
options
,{
animation
:
!
1
,
showCheckbox
:
!
1
,
visible
:
a
.
visible
});
z
.
isInternal
||
g
.
series
.
push
(
z
)});
d
=
new
f
.
Chart
(
g
,
a
.
callback
);
r
([
"
xAxis
"
,
"
yAxis
"
],
function
(
b
){
r
(
a
[
b
],
function
(
a
,
c
){
var
g
=
d
[
b
][
c
],
f
=
a
.
getExtremes
(),
h
=
f
.
userMin
,
f
=
f
.
userMax
;
g
&&
(
h
!==
void
0
||
f
!==
void
0
)
&&
g
.
setExtremes
(
h
,
f
,
!
0
,
!
1
)})});
c
=
d
.
container
.
innerHTML
;
g
=
null
;
d
.
destroy
();
o
(
b
);
c
=
c
.
replace
(
/zIndex="
[^
"
]
+"/g
,
""
).
replace
(
/isShadow="
[^
"
]
+"/g
,
""
).
replace
(
/symbolName="
[^
"
]
+"/g
,
""
).
replace
(
/jQuery
[
0-9
]
+="
[^
"
]
+"/g
,
""
).
replace
(
/url
\([^
#
]
+#/g
,
"
url(#
"
).
replace
(
/<svg /
,
'
<svg xmlns:xlink="http://www.w3.org/1999/xlink"
'
).
replace
(
/ href=/g
,
"
xlink:href=
"
).
replace
(
/
\n
/
,
"
"
).
replace
(
/<
\/
svg>.*
?
$/
,
"
</svg>
"
).
replace
(
/ /g
,
"
"
).
replace
(
/­/g
,
"
"
).
replace
(
/<IMG /g
,
"
<image
"
).
replace
(
/height=
([^
"
]
+
)
/g
,
'
height="$1"
'
).
replace
(
/width=
([^
"
]
+
)
/g
,
...
...
apps/static/js/plugins/highcharts/highcharts.src.js
浏览文件 @
775cd523
...
...
@@ -4447,7 +4447,7 @@ extend(SVGRenderer.prototype, {
* START OF INTERNET EXPLORER <= 8 SPECIFIC CODE *
* *
* For applications and websites that don't need IE support, like platform *
* targeted mobile
terminal and web terminal
, this code can be removed. *
* targeted mobile
applications and web applications
, this code can be removed. *
* *
*****************************************************************************/
...
...
apps/static/js/plugins/highcharts/modules/exporting.js
浏览文件 @
775cd523
...
...
@@ -8,7 +8,7 @@
*/
(
function
(
f
){
var
A
=
f
.
Chart
,
t
=
f
.
addEvent
,
B
=
f
.
removeEvent
,
l
=
f
.
createElement
,
o
=
f
.
discardElement
,
v
=
f
.
css
,
k
=
f
.
merge
,
r
=
f
.
each
,
p
=
f
.
extend
,
D
=
Math
.
max
,
j
=
document
,
C
=
window
,
E
=
f
.
isTouchDevice
,
F
=
f
.
Renderer
.
prototype
.
symbols
,
s
=
f
.
getOptions
(),
y
;
p
(
s
.
lang
,{
printChart
:
"
Print chart
"
,
downloadPNG
:
"
Download PNG image
"
,
downloadJPEG
:
"
Download JPEG image
"
,
downloadPDF
:
"
Download PDF document
"
,
downloadSVG
:
"
Download SVG vector image
"
,
contextButtonTitle
:
"
Chart context menu
"
});
s
.
navigation
=
{
menuStyle
:{
border
:
"
1px solid #A0A0A0
"
,
background
:
"
#FFFFFF
"
,
padding
:
"
5px 0
"
},
menuItemStyle
:{
padding
:
"
0 10px
"
,
background
:
"
none
"
,
color
:
"
#303030
"
,
fontSize
:
E
?
"
14px
"
:
"
11px
"
},
menuItemHoverStyle
:{
background
:
"
#4572A5
"
,
color
:
"
#FFFFFF
"
},
buttonOptions
:{
symbolFill
:
"
#E0E0E0
"
,
symbolSize
:
14
,
symbolStroke
:
"
#666
"
,
symbolStrokeWidth
:
3
,
symbolX
:
12.5
,
symbolY
:
10.5
,
align
:
"
right
"
,
buttonSpacing
:
3
,
height
:
22
,
theme
:{
fill
:
"
white
"
,
stroke
:
"
none
"
},
verticalAlign
:
"
top
"
,
width
:
24
}};
s
.
exporting
=
{
type
:
"
image/png
"
,
url
:
"
http://export.highcharts.com/
"
,
buttons
:{
contextButton
:{
menuClassName
:
"
highcharts-contextmenu
"
,
symbol
:
"
menu
"
,
_titleKey
:
"
contextButtonTitle
"
,
menuItems
:[{
textKey
:
"
printChart
"
,
onclick
:
function
(){
this
.
print
()}},{
separator
:
!
0
},{
textKey
:
"
downloadPNG
"
,
onclick
:
function
(){
this
.
exportChart
()}},{
textKey
:
"
downloadJPEG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/jpeg
"
})}},{
textKey
:
"
downloadPDF
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
application/pdf
"
})}},{
textKey
:
"
downloadSVG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/svg+xml
"
})}}]}}};
f
.
post
=
function
(
b
,
a
,
d
){
var
c
,
b
=
l
(
"
form
"
,
k
({
method
:
"
post
"
,
symbol
:
"
menu
"
,
_titleKey
:
"
contextButtonTitle
"
,
menuItems
:[{
textKey
:
"
printChart
"
,
onclick
:
function
(){
this
.
print
()}},{
separator
:
!
0
},{
textKey
:
"
downloadPNG
"
,
onclick
:
function
(){
this
.
exportChart
()}},{
textKey
:
"
downloadJPEG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/jpeg
"
})}},{
textKey
:
"
downloadPDF
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
application
s
/pdf
"
})}},{
textKey
:
"
downloadSVG
"
,
onclick
:
function
(){
this
.
exportChart
({
type
:
"
image/svg+xml
"
})}}]}}};
f
.
post
=
function
(
b
,
a
,
d
){
var
c
,
b
=
l
(
"
form
"
,
k
({
method
:
"
post
"
,
action
:
b
,
enctype
:
"
multipart/form-data
"
},
d
),{
display
:
"
none
"
},
j
.
body
);
for
(
c
in
a
)
l
(
"
input
"
,{
type
:
"
hidden
"
,
name
:
c
,
value
:
a
[
c
]},
null
,
b
);
b
.
submit
();
o
(
b
)};
p
(
A
.
prototype
,{
getSVG
:
function
(
b
){
var
a
=
this
,
d
,
c
,
z
,
h
,
g
=
k
(
a
.
options
,
b
);
if
(
!
j
.
createElementNS
)
j
.
createElementNS
=
function
(
a
,
b
){
return
j
.
createElement
(
b
)};
b
=
l
(
"
div
"
,
null
,{
position
:
"
absolute
"
,
top
:
"
-9999em
"
,
width
:
a
.
chartWidth
+
"
px
"
,
height
:
a
.
chartHeight
+
"
px
"
},
j
.
body
);
c
=
a
.
renderTo
.
style
.
width
;
h
=
a
.
renderTo
.
style
.
height
;
c
=
g
.
exporting
.
sourceWidth
||
g
.
chart
.
width
||
/px$/
.
test
(
c
)
&&
parseInt
(
c
,
10
)
||
600
;
h
=
g
.
exporting
.
sourceHeight
||
g
.
chart
.
height
||
/px$/
.
test
(
h
)
&&
parseInt
(
h
,
10
)
||
400
;
p
(
g
.
chart
,{
animation
:
!
1
,
renderTo
:
b
,
forExport
:
!
0
,
width
:
c
,
height
:
h
});
g
.
exporting
.
enabled
=!
1
;
g
.
series
=
[];
r
(
a
.
series
,
function
(
a
){
z
=
k
(
a
.
options
,{
animation
:
!
1
,
showCheckbox
:
!
1
,
visible
:
a
.
visible
});
z
.
isInternal
||
g
.
series
.
push
(
z
)});
d
=
new
f
.
Chart
(
g
,
a
.
callback
);
r
([
"
xAxis
"
,
"
yAxis
"
],
function
(
b
){
r
(
a
[
b
],
function
(
a
,
c
){
var
g
=
d
[
b
][
c
],
f
=
a
.
getExtremes
(),
h
=
f
.
userMin
,
f
=
f
.
userMax
;
g
&&
(
h
!==
void
0
||
f
!==
void
0
)
&&
g
.
setExtremes
(
h
,
f
,
!
0
,
!
1
)})});
c
=
d
.
container
.
innerHTML
;
g
=
null
;
d
.
destroy
();
o
(
b
);
c
=
c
.
replace
(
/zIndex="
[^
"
]
+"/g
,
""
).
replace
(
/isShadow="
[^
"
]
+"/g
,
""
).
replace
(
/symbolName="
[^
"
]
+"/g
,
""
).
replace
(
/jQuery
[
0-9
]
+="
[^
"
]
+"/g
,
""
).
replace
(
/url
\([^
#
]
+#/g
,
"
url(#
"
).
replace
(
/<svg /
,
'
<svg xmlns:xlink="http://www.w3.org/1999/xlink"
'
).
replace
(
/ href=/g
,
"
xlink:href=
"
).
replace
(
/
\n
/
,
"
"
).
replace
(
/<
\/
svg>.*
?
$/
,
"
</svg>
"
).
replace
(
/ /g
,
"
"
).
replace
(
/­/g
,
"
"
).
replace
(
/<IMG /g
,
"
<image
"
).
replace
(
/height=
([^
"
]
+
)
/g
,
'
height="$1"
'
).
replace
(
/width=
([^
"
]
+
)
/g
,
...
...
apps/static/js/plugins/highcharts/modules/exporting.src.js
浏览文件 @
775cd523
...
...
@@ -128,7 +128,7 @@ defaultOptions.exporting = {
textKey
:
'
downloadPDF
'
,
onclick
:
function
()
{
this
.
exportChart
({
type
:
'
application/pdf
'
type
:
'
application
s
/pdf
'
});
}
},
{
...
...
apps/static/js/plugins/steps/jquery.steps.min.js
浏览文件 @
775cd523
此差异已折叠。
点击以展开。
apps/static/js/record.js
浏览文件 @
775cd523
...
...
@@ -16,7 +16,7 @@ NgApp.config(['$httpProvider', function ($httpProvider) {
$httpProvider
.
defaults
.
xsrfHeaderName
=
'
X-CSRFToken
'
;
$httpProvider
.
defaults
.
headers
.
common
[
'
X-Requested-With
'
]
=
'
XMLHttpRequest
'
;
$httpProvider
.
defaults
.
headers
.
post
=
{
'
Content-Type
'
:
'
application/x-www-form-urlencoded
'
'
Content-Type
'
:
'
application
s
/x-www-form-urlencoded
'
}
}]);
NgApp
.
controller
(
'
TerminalRecordCtrl
'
,
function
(
$scope
,
$http
)
{
...
...
@@ -121,7 +121,7 @@ NgApp.controller('TerminalRecordCtrl', function ($scope, $http) {
timelist
=
timelist
.
sort
(
function
(
a
,
b
){
return
a
-
b
});
totalTime
=
totalTime
*
1000
;
document
.
getElementById
(
"
afterScrubberText
"
).
innerHTML
=
buildTimeString
(
totalTime
);
term
.
open
(
document
.
getElementById
(
'
terminal
'
));
term
.
open
(
document
.
getElementById
(
'
apps
'
));
timer
=
setInterval
(
advance
,
TICK
);
})
...
...
apps/static/js/term.js
浏览文件 @
775cd523
...
...
@@ -588,7 +588,7 @@ Terminal.bindKeys = function(document) {
},
true
);
// If we click somewhere other than a
//
terminal, unfocus the terminal
.
//
applications, unfocus the applications
.
on
(
document
,
'
mousedown
'
,
function
(
ev
)
{
if
(
!
Terminal
.
focus
)
return
;
...
...
@@ -742,7 +742,7 @@ Terminal.insertStyle = function(document, bg, fg) {
// textContent doesn't work well with IE for <style> elements.
style
.
innerHTML
=
''
+
'
.
terminal
{
\n
'
+
'
.
applications
{
\n
'
+
'
float: left;
\n
'
+
'
border:
'
+
bg
+
'
solid 5px;
\n
'
+
'
font-family: "DejaVu Sans Mono", "Liberation Mono", monospace;
\n
'
...
...
@@ -751,7 +751,7 @@ Terminal.insertStyle = function(document, bg, fg) {
+
'
background:
'
+
bg
+
'
;
\n
'
+
'
}
\n
'
+
'
\n
'
+
'
.
terminal
-cursor {
\n
'
+
'
.
applications
-cursor {
\n
'
+
'
color:
'
+
bg
+
'
;
\n
'
+
'
background:
'
+
fg
+
'
;
\n
'
+
'
}
\n
'
;
...
...
@@ -802,7 +802,7 @@ Terminal.prototype.open = function(parent) {
this
.
isMSIE
=
!!~
this
.
context
.
navigator
.
userAgent
.
indexOf
(
'
MSIE
'
);
}
// Create our main
terminal
element.
// Create our main
applications
element.
this
.
element
=
this
.
document
.
createElement
(
'
div
'
);
this
.
element
.
className
=
'
terminal
'
;
this
.
element
.
style
.
outline
=
'
none
'
;
...
...
@@ -811,7 +811,7 @@ Terminal.prototype.open = function(parent) {
this
.
element
.
style
.
backgroundColor
=
this
.
colors
[
256
];
this
.
element
.
style
.
color
=
this
.
colors
[
257
];
// Create the lines for our
terminal
.
// Create the lines for our
applications
.
this
.
children
=
[];
for
(;
i
<
this
.
rows
;
i
++
)
{
div
=
this
.
document
.
createElement
(
'
div
'
);
...
...
@@ -1020,7 +1020,7 @@ Terminal.prototype.open = function(parent) {
if
(
!
(
'
useMouse
'
in
this
.
options
)
||
this
.
options
.
useMouse
)
{
// Listen for mouse events and translate
// them into
terminal
mouse protocols.
// them into
applications
mouse protocols.
this
.
bindMouse
();
}
...
...
@@ -1549,7 +1549,7 @@ Terminal.prototype.refresh = function(start, end) {
}
if
(
data
!==
this
.
defAttr
)
{
if
(
data
===
-
1
)
{
out
+=
'
<span class="reverse-video
terminal
-cursor">
'
;
out
+=
'
<span class="reverse-video
applications
-cursor">
'
;
}
else
{
out
+=
'
<span style="
'
;
...
...
@@ -1660,7 +1660,7 @@ Terminal.prototype.refresh = function(start, end) {
}
if
(
this
.
_textarea
)
{
var
cursorElement
=
this
.
element
.
querySelector
(
'
.
terminal
-cursor
'
);
var
cursorElement
=
this
.
element
.
querySelector
(
'
.
applications
-cursor
'
);
if
(
cursorElement
){
var
cursor_x
=
cursorElement
.
offsetLeft
;
var
cursor_y
=
cursorElement
.
offsetTop
;
...
...
@@ -2031,7 +2031,7 @@ Terminal.prototype.write = function(data) {
// ESC = Application Keypad (DECPAM).
case
'
=
'
:
this
.
log
(
'
Serial port requested application keypad.
'
);
this
.
log
(
'
Serial port requested application
s
keypad.
'
);
this
.
applicationKeypad
=
true
;
this
.
state
=
normal
;
break
;
...
...
@@ -2474,7 +2474,7 @@ Terminal.prototype.write = function(data) {
// break;
// CSI > Ps p Set pointer mode.
// CSI ! p Soft
terminal
reset (DECSTR).
// CSI ! p Soft
applications
reset (DECSTR).
// CSI Ps$ p
// Request ANSI mode (DECRQM).
// CSI ? Ps$ p
...
...
@@ -3959,7 +3959,7 @@ Terminal.prototype.HPositionRelative = function(params) {
};
// CSI Ps c Send Device Attributes (Primary DA).
// Ps = 0 or omitted -> request attributes from
terminal
. The
// Ps = 0 or omitted -> request attributes from
applications
. The
// response depends on the decTerminalID resource setting.
// -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'')
// -> CSI ? 1 ; 0 c (``VT101 with No Options'')
...
...
@@ -3967,7 +3967,7 @@ Terminal.prototype.HPositionRelative = function(params) {
// -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'')
// The VT100-style response parameters do not mean anything by
// themselves. VT220 parameters do, telling the host what fea-
// tures the
terminal
supports:
// tures the
applications
supports:
// Ps = 1 -> 132-columns.
// Ps = 2 -> Printer.
// Ps = 6 -> Selective erase.
...
...
@@ -3978,12 +3978,12 @@ Terminal.prototype.HPositionRelative = function(params) {
// Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode).
// CSI > Ps c
// Send Device Attributes (Secondary DA).
// Ps = 0 or omitted -> request the
terminal
's identification
// Ps = 0 or omitted -> request the
applications
's identification
// code. The response depends on the decTerminalID resource set-
// ting. It should apply only to VT220 and up, but xterm extends
// this to VT100.
// -> CSI > Pp ; Pv ; Pc c
// where Pp denotes the
terminal
type
// where Pp denotes the
applications
type
// Pp = 0 -> ``VT100''.
// Pp = 1 -> ``VT220''.
// and Pv is the firmware version (for xterm, this was originally
...
...
@@ -3992,7 +3992,7 @@ Terminal.prototype.HPositionRelative = function(params) {
// always zero.
// More information:
// xterm/charproc.c - line 2012, for more information.
// vim responds with ^[[?0c or ^[[?1c after the
terminal
's response (?)
// vim responds with ^[[?0c or ^[[?1c after the
applications
's response (?)
Terminal
.
prototype
.
sendDeviceAttributes
=
function
(
params
)
{
if
(
params
[
0
]
>
0
)
return
;
...
...
@@ -4193,7 +4193,7 @@ Terminal.prototype.setMode = function(params) {
// this.cursorBlink = true;
break
;
case
66
:
this
.
log
(
'
Serial port requested application keypad.
'
);
this
.
log
(
'
Serial port requested application
s
keypad.
'
);
this
.
applicationKeypad
=
true
;
break
;
case
9
:
// X10 Mouse
...
...
@@ -4217,19 +4217,19 @@ Terminal.prototype.setMode = function(params) {
// focusout: ^[[O
this
.
sendFocus
=
true
;
break
;
case
1005
:
// utf8
terminal
mode mouse
case
1005
:
// utf8
applications
mode mouse
this
.
utfMouse
=
true
;
// for wide terminals
// simply encodes large values as utf8 characters
break
;
case
1006
:
// sgr
terminal
mode mouse
case
1006
:
// sgr
applications
mode mouse
this
.
sgrMouse
=
true
;
// for wide terminals
// does not add 32 to fields
// press: ^[[<b;x;yM
// release: ^[[<b;x;ym
break
;
case
1015
:
// urxvt
terminal
mode mouse
case
1015
:
// urxvt
applications
mode mouse
this
.
urxvtMouse
=
true
;
// for wide terminals
// numbers for fields
...
...
@@ -4406,13 +4406,13 @@ Terminal.prototype.resetMode = function(params) {
case
1004
:
// send focusin/focusout events
this
.
sendFocus
=
false
;
break
;
case
1005
:
// utf8
terminal
mode mouse
case
1005
:
// utf8
applications
mode mouse
this
.
utfMouse
=
false
;
break
;
case
1006
:
// sgr
terminal
mode mouse
case
1006
:
// sgr
applications
mode mouse
this
.
sgrMouse
=
false
;
break
;
case
1015
:
// urxvt
terminal
mode mouse
case
1015
:
// urxvt
applications
mode mouse
this
.
urxvtMouse
=
false
;
break
;
case
25
:
// hide cursor
...
...
@@ -4622,7 +4622,7 @@ Terminal.prototype.setPointerMode = function(params) {
;
};
// CSI ! p Soft
terminal
reset (DECSTR).
// CSI ! p Soft
applications
reset (DECSTR).
// http://vt100.net/docs/vt220-rm/table4-10.html
Terminal
.
prototype
.
softReset
=
function
(
params
)
{
this
.
cursorHidden
=
false
;
...
...
@@ -4870,7 +4870,7 @@ Terminal.prototype.enableFilterRectangle = function(params) {
// CSI Ps x Request Terminal Parameters (DECREQTPARM).
// if Ps is a "0" (default) or "1", and xterm is emulating VT100,
// the control sequence elicits a response of the same form whose
// parameters describe the
terminal
:
// parameters describe the
applications
:
// Ps -> the given Ps incremented by 2.
// Pn = 1 <- no parity.
// Pn = 1 <- eight bits.
...
...
@@ -6030,7 +6030,7 @@ Terminal.charsets = {};
// DEC Special Character and Line Drawing Set.
// http://vt100.net/docs/vt102-ug/table5-13.html
// A lot of curses
terminal
use this if they see TERM=xterm.
// A lot of curses
applications
use this if they see TERM=xterm.
// testing: echo -e '\e(0a\e(B'
// The xterm output sometimes seems to conflict with the
// reference above. xterm seems in line with the reference
...
...
@@ -6113,7 +6113,7 @@ function inherits(child, parent) {
}
// if bold is broken, we can't
// use it in the
terminal
.
// use it in the
applications
.
function
isBoldBroken
(
document
)
{
var
body
=
document
.
getElementsByTagName
(
'
body
'
)[
0
];
var
terminal
=
document
.
createElement
(
'
div
'
);
...
...
apps/static/js/webterminal.js
浏览文件 @
775cd523
...
...
@@ -13,7 +13,7 @@ WSSHClient.prototype._generateEndpoint = function (options) {
var
protocol
=
'
ws://
'
;
}
var
endpoint
=
protocol
+
document
.
URL
.
match
(
RegExp
(
'
//(.*?)/
'
))[
1
]
+
'
/ws/
terminal
'
+
document
.
URL
.
match
(
/
(\?
.*
)
/
);
var
endpoint
=
protocol
+
document
.
URL
.
match
(
RegExp
(
'
//(.*?)/
'
))[
1
]
+
'
/ws/
applications
'
+
document
.
URL
.
match
(
/
(\?
.*
)
/
);
return
endpoint
;
};
WSSHClient
.
prototype
.
connect
=
function
(
options
)
{
...
...
@@ -81,7 +81,7 @@ function openTerminal(options) {
term
.
on
(
'
data
'
,
function
(
data
)
{
client
.
send
(
data
)
});
$
(
'
.
terminal
'
).
detach
().
appendTo
(
'
#term
'
);
$
(
'
.
applications
'
).
detach
().
appendTo
(
'
#term
'
);
//term.resize(colWidth, rowHeight);
term
.
write
(
'
Connecting...
'
);
client
.
connect
(
$
.
extend
(
options
,
{
...
...
@@ -100,13 +100,13 @@ function openTerminal(options) {
term
.
write
(
data
);
}
}));
//rowHeight = 0.0 + 1.00 * $('.
terminal
').height() / 24;
//colWidth = 0.0 + 1.00 * $('.
terminal
').width() / 80;
//rowHeight = 0.0 + 1.00 * $('.
applications
').height() / 24;
//colWidth = 0.0 + 1.00 * $('.
applications
').width() / 80;
return
{
'
term
'
:
term
,
'
client
'
:
client
};
}
//function resize() {
// $('.
terminal
').css('width', window.innerWidth - 25);
// $('.
applications
').css('width', window.innerWidth - 25);
// console.log(window.innerWidth);
// console.log(window.innerWidth - 10);
// var rows = Math.floor(window.innerHeight / rowHeight) - 2;
...
...
@@ -145,10 +145,10 @@ $(document).ready(function () {
term_client
.
client
.
send
({
'
resize
'
:
{
'
rows
'
:
row
,
'
cols
'
:
col
}});
$
(
'
#ssh
'
).
show
();
});
$
(
"
.
terminal
"
).
mouseleave
(
function
()
{
$
(
"
.
applications
"
).
mouseleave
(
function
()
{
$
(
"
.termChangBar
"
).
slideDown
();
});
$
(
"
.
terminal
"
).
mouseenter
(
function
()
{
$
(
"
.
applications
"
).
mouseenter
(
function
()
{
$
(
"
.termChangBar
"
).
slideUp
();
})
});
\ No newline at end of file
apps/static/js/wssh.js
浏览文件 @
775cd523
...
...
@@ -47,7 +47,7 @@ WSSHClient.prototype._generateEndpoint = function(options) {
var
protocol
=
'
ws://
'
;
}
var
endpoint
=
protocol
+
window
.
location
.
host
+
'
:8080
'
+
'
/
terminal
'
;
var
endpoint
=
protocol
+
window
.
location
.
host
+
'
:8080
'
+
'
/
applications
'
;
return
endpoint
;
};
...
...
apps/templates/_nav.html
浏览文件 @
775cd523
...
...
@@ -35,10 +35,13 @@
</ul>
</li>
<li
id=
"terminal"
>
<a
href=
"{% url 'terminal:terminal-list' %}"
>
<i
class=
"fa fa-desktop"
></i><span
class=
"nav-label"
>
{% trans 'Terminal' %}
</span><span
class=
"label label-info pull-right"
></span>
</a>
<li
id=
"applications"
>
<a>
<i
class=
"fa fa-coffee"
></i>
<span
class=
"nav-label"
>
{% trans 'Applications' %}
</span><span
class=
"fa arrow"
></span>
</a>
<ul
class=
"nav nav-second-level"
>
<li
id=
"terminal"
><a
href=
"{% url 'applications:terminal-list' %}"
>
{% trans 'Terminal' %}
</a></li>
</ul>
</li>
<li
id=
"ops"
>
...
...
apps/terminal/migrations/__init__.py
已删除
100644 → 0
浏览文件 @
a8fa4d2f
apps/users/api.py
浏览文件 @
775cd523
...
...
@@ -13,7 +13,7 @@ from django_filters.rest_framework import DjangoFilterBackend
from
common.mixins
import
IDInFilterMixin
from
common.utils
import
get_logger
from
.utils
import
check_user_valid
,
ge
t_or_refresh
_token
from
.utils
import
check_user_valid
,
ge
nerate
_token
from
.models
import
User
,
UserGroup
from
.hands
import
write_login_log_async
from
.permissions
import
IsSuperUser
,
IsAppUser
,
IsValidUser
,
IsSuperUserOrAppUser
...
...
@@ -91,7 +91,7 @@ class UserToken(APIView):
def
get
(
self
,
request
):
if
not
request
.
user
:
return
Response
({
'error'
:
'unauthorized'
})
token
=
ge
t
_token
(
request
)
token
=
ge
nerate
_token
(
request
)
return
Response
({
'token'
:
token
})
...
...
@@ -111,14 +111,14 @@ class UserAuthApi(APIView):
password
=
request
.
data
.
get
(
'password'
,
''
)
public_key
=
request
.
data
.
get
(
'public_key'
,
''
)
remote_addr
=
request
.
data
.
get
(
'remote_addr'
,
''
)
terminal
=
request
.
data
.
get
(
'
terminal
'
,
''
)
terminal
=
request
.
data
.
get
(
'
applications
'
,
''
)
login_type
=
request
.
data
.
get
(
'login_type'
,
'T'
)
user
=
check_user_valid
(
username
=
username
,
password
=
password
,
public_key
=
public_key
)
if
user
:
token
=
cache
.
get
(
'%s_%s'
%
(
user
.
id
,
remote_addr
))
if
not
token
:
token
=
token_gen
(
user
)
token
=
generate_token
(
request
)
cache
.
set
(
token
,
user
.
id
,
self
.
expiration
)
cache
.
set
(
'%s_%s'
%
(
user
.
id
,
remote_addr
),
token
,
self
.
expiration
)
...
...
apps/users/authentication.py
浏览文件 @
775cd523
...
...
@@ -9,14 +9,13 @@ from django.core.cache import cache
from
django.conf
import
settings
from
django.utils.translation
import
ugettext
as
_
from
rest_framework
import
authentication
,
exceptions
,
permissions
from
rest_framework.compat
import
is_authenticated
from
django.utils.six
import
text_type
from
django.utils.translation
import
ugettext_lazy
as
_
from
rest_framework
import
HTTP_HEADER_ENCODING
from
common.utils
import
get_object_or_none
,
make_signature
,
http_to_unixtime
from
.utils
import
get_or_
refresh_token
from
.models
import
User
,
AccessKey
from
.utils
import
refresh_token
from
.models
import
User
,
AccessKey
,
PrivateToken
def
get_request_date_header
(
request
):
...
...
@@ -93,7 +92,6 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
def
authenticate
(
self
,
request
):
auth
=
authentication
.
get_authorization_header
(
request
).
split
()
if
not
auth
or
auth
[
0
].
lower
()
!=
self
.
keyword
.
lower
().
encode
():
return
None
...
...
@@ -109,14 +107,18 @@ class AccessTokenAuthentication(authentication.BaseAuthentication):
except
UnicodeError
:
msg
=
_
(
'Invalid token header. Sign string should not contain invalid characters.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
return
self
.
authenticate_credentials
(
token
,
request
)
return
self
.
authenticate_credentials
(
token
)
def
authenticate_credentials
(
self
,
token
,
request
):
def
authenticate_credentials
(
self
,
token
):
user_id
=
cache
.
get
(
token
)
print
(
'Auth id: %s'
%
user_id
)
user
=
get_object_or_none
(
User
,
id
=
user_id
)
if
not
user
:
return
None
get_or_refresh_token
(
request
,
user
)
msg
=
_
(
'Invalid token or cache refreshed.'
)
raise
exceptions
.
AuthenticationFailed
(
msg
)
refresh_token
(
token
,
user
)
return
user
,
None
class
PrivateTokenAuthentication
(
authentication
.
TokenAuthentication
):
model
=
PrivateToken
apps/users/hands.py
浏览文件 @
775cd523
...
...
@@ -10,7 +10,7 @@
:license: GPL v2, see LICENSE for more details.
"""
from
terminal
.models
import
Terminal
from
applications
.models
import
Terminal
from
audits.tasks
import
write_login_log_async
from
users.models
import
User
# from perms.models import AssetPermission
...
...
apps/users/models/authentication.py
浏览文件 @
775cd523
...
...
@@ -8,10 +8,7 @@ from django.utils.translation import ugettext_lazy as _
from
rest_framework.authtoken.models
import
Token
from
.
import
User
__all__
=
[
'AccessKey'
]
def
get_uuid_string
():
return
uuid
.
uuid4
().
__str__
()
__all__
=
[
'AccessKey'
,
'PrivateToken'
]
class
AccessKey
(
models
.
Model
):
...
...
apps/users/models/user.py
浏览文件 @
775cd523
...
...
@@ -12,7 +12,6 @@ from django.db import models, IntegrityError
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils
import
timezone
from
django.shortcuts
import
reverse
from
rest_framework.authtoken.models
import
Token
from
common.utils
import
signer
,
date_expired_default
from
.
import
UserGroup
...
...
@@ -100,10 +99,6 @@ class User(AbstractUser):
else
:
return
False
@
property
def
is_app
(
self
):
return
self
.
role
==
'App'
@
is_superuser
.
setter
def
is_superuser
(
self
,
value
):
if
value
is
True
:
...
...
@@ -111,6 +106,10 @@ class User(AbstractUser):
else
:
self
.
role
=
'User'
@
property
def
is_app
(
self
):
return
self
.
role
==
'App'
@
property
def
is_staff
(
self
):
if
self
.
is_authenticated
and
self
.
is_valid
:
...
...
@@ -134,18 +133,20 @@ class User(AbstractUser):
@
property
def
private_token
(
self
):
return
self
.
get
_private_token
()
return
self
.
create
_private_token
()
def
get_private_token
(
self
):
def
create_private_token
(
self
):
from
.authentication
import
PrivateToken
try
:
token
=
Token
.
objects
.
get
(
user
=
self
)
except
Token
.
DoesNotExist
:
token
=
Token
.
objects
.
create
(
user
=
self
)
token
=
Private
Token
.
objects
.
get
(
user
=
self
)
except
Private
Token
.
DoesNotExist
:
token
=
Private
Token
.
objects
.
create
(
user
=
self
)
return
token
.
key
def
refresh_private_token
(
self
):
Token
.
objects
.
filter
(
user
=
self
).
delete
()
return
Token
.
objects
.
create
(
user
=
self
)
from
.authentication
import
PrivateToken
PrivateToken
.
objects
.
filter
(
user
=
self
).
delete
()
return
PrivateToken
.
objects
.
create
(
user
=
self
)
def
is_member_of
(
self
,
user_group
):
if
user_group
in
self
.
groups
.
all
():
...
...
apps/users/utils.py
浏览文件 @
775cd523
...
...
@@ -197,13 +197,21 @@ def check_user_valid(**kwargs):
return
None
def
get_or_refresh_token
(
request
,
user
):
def
refresh_token
(
token
,
user
):
expiration
=
settings
.
CONFIG
.
TOKEN_EXPIRATION
or
3600
cache
.
set
(
token
,
user
.
id
,
expiration
)
def
generate_token
(
request
):
expiration
=
settings
.
CONFIG
.
TOKEN_EXPIRATION
or
3600
remote_addr
=
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
remote_addr
=
base64
.
b16encode
(
remote_addr
).
replace
(
'='
,
''
)
token
=
cache
.
get
(
'%s_%s'
%
(
user
.
id
,
remote_addr
))
token
=
cache
.
get
(
'%s_%s'
%
(
request
.
user
.
id
,
remote_addr
))
if
not
token
:
token
=
uuid
.
uuid4
().
get_hex
()
print
(
'Set cache: %s'
%
token
)
cache
.
set
(
token
,
request
.
user
.
id
,
expiration
)
cache
.
set
(
'%s_%s'
%
(
request
.
user
.
id
,
remote_addr
),
token
,
expiration
)
return
uuid
.
uuid4
().
get_hex
()
return
token
apps/users/views.py
浏览文件 @
775cd523
...
...
@@ -577,7 +577,7 @@ class UserExportView(View):
user
.
role
,
user
.
phone
,
user
.
wechat
,
user
.
comment
])
filename
=
'users-{}.xlsx'
.
format
(
timezone
.
localtime
(
timezone
.
now
()).
strftime
(
'%Y-%m-%d_%H-%M-%S'
))
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'application/vnd.ms-excel'
)
response
=
HttpResponse
(
save_virtual_workbook
(
wb
),
content_type
=
'application
s
/vnd.ms-excel'
)
response
[
'Content-Disposition'
]
=
'attachment; filename="%s"'
%
filename
return
response
...
...
utils/clean_migrations.sh
浏览文件 @
775cd523
#!/bin/bash
#
for
app
in
users
assets perms audits
teminal op
s
;
do
for
app
in
users
assets perms audits
ops application
s
;
do
rm
-f
../apps/
$app
/migrations/000
*
done
utils/generate_fake.sh
0 → 100644
浏览文件 @
775cd523
#!/bin/bash
#
python ../apps/manage.py loaddata fake
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录