InPanel 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- inpanel/__init__.py +29 -0
- inpanel/acme.py +289 -0
- inpanel/aliyuncs.py +269 -0
- inpanel/app.py +514 -0
- inpanel/apt.py +223 -0
- inpanel/base.py +200 -0
- inpanel/config.py +139 -0
- inpanel/data/config.ini +29 -0
- inpanel/data/history +5 -0
- inpanel/data/runlogs.ini +12 -0
- inpanel/data/update_info.ini +4 -0
- inpanel/dnf.py +225 -0
- inpanel/lib/__init__.py +9 -0
- inpanel/lib/async_process.py +98 -0
- inpanel/lib/filelock.py +82 -0
- inpanel/lib/magic.py +233 -0
- inpanel/lib/pxssh.py +310 -0
- inpanel/lib/pyDes.py +867 -0
- inpanel/mod/__init__.py +0 -0
- inpanel/mod/apt.py +316 -0
- inpanel/mod/certificate.py +268 -0
- inpanel/mod/config.py +372 -0
- inpanel/mod/cron.py +315 -0
- inpanel/mod/disk.py +322 -0
- inpanel/mod/dnf.py +239 -0
- inpanel/mod/file.py +722 -0
- inpanel/mod/firewall.py +199 -0
- inpanel/mod/firewall_base.py +137 -0
- inpanel/mod/firewall_firewalld.py +170 -0
- inpanel/mod/firewall_iptables.py +176 -0
- inpanel/mod/firewall_macos.py +213 -0
- inpanel/mod/firewall_ufw.py +128 -0
- inpanel/mod/ftp.py +231 -0
- inpanel/mod/httpd.py +1205 -0
- inpanel/mod/lighttpd.py +26 -0
- inpanel/mod/login.py +98 -0
- inpanel/mod/mysql.py +577 -0
- inpanel/mod/named.py +26 -0
- inpanel/mod/nginx.py +2327 -0
- inpanel/mod/package.py +33 -0
- inpanel/mod/package_apt.py +62 -0
- inpanel/mod/package_base.py +77 -0
- inpanel/mod/package_dnf.py +62 -0
- inpanel/mod/package_map.py +366 -0
- inpanel/mod/package_yum.py +64 -0
- inpanel/mod/php.py +289 -0
- inpanel/mod/process.py +291 -0
- inpanel/mod/proftpd.py +26 -0
- inpanel/mod/pureftpd.py +26 -0
- inpanel/mod/query.py +108 -0
- inpanel/mod/server.py +1319 -0
- inpanel/mod/service.py +262 -0
- inpanel/mod/setting.py +228 -0
- inpanel/mod/shell.py +78 -0
- inpanel/mod/ssh.py +280 -0
- inpanel/mod/system.py +220 -0
- inpanel/mod/task.py +1337 -0
- inpanel/mod/ufw.py +14 -0
- inpanel/mod/user.py +306 -0
- inpanel/mod/vsftpd.py +67 -0
- inpanel/mod/yum.py +243 -0
- inpanel/plugins/__init__.py +10 -0
- inpanel/plugins/__pycache__/__init__.cpython-313.pyc +0 -0
- inpanel/plugins/acme/static/index.html +10 -0
- inpanel/plugins/acme/static/index.js +13 -0
- inpanel/plugins/shadowsocks-libev/__pycache__/info.cpython-313.pyc +0 -0
- inpanel/plugins/shadowsocks-libev/info.py +73 -0
- inpanel/plugins/shadowsocks-libev/static/index.html +70 -0
- inpanel/plugins/shadowsocks-libev/static/index.js +18 -0
- inpanel/public/css/global.css +138 -0
- inpanel/public/favicon.ico +0 -0
- inpanel/public/images/alipay.jpg +0 -0
- inpanel/public/images/loading.gif +0 -0
- inpanel/public/images/weixin.jpg +0 -0
- inpanel/public/index.html +94 -0
- inpanel/public/js/controllers/controllers.js +566 -0
- inpanel/public/js/controllers/database.js +590 -0
- inpanel/public/js/controllers/ecs.js +624 -0
- inpanel/public/js/controllers/file.js +940 -0
- inpanel/public/js/controllers/plugins.js +105 -0
- inpanel/public/js/controllers/service.js +1460 -0
- inpanel/public/js/controllers/site.js +1241 -0
- inpanel/public/js/controllers/utils.js +2319 -0
- inpanel/public/js/core.js +221 -0
- inpanel/public/js/directives.js +784 -0
- inpanel/public/js/filters.js +395 -0
- inpanel/public/js/services.js +257 -0
- inpanel/public/lib/angular/1.0.2/angular-resource.min.js +10 -0
- inpanel/public/lib/angular/1.0.2/angular.min.js +158 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.css +587 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.css.map +1 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css +6 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css.map +1 -0
- inpanel/public/lib/bootstrap/css/bootstrap.css +6757 -0
- inpanel/public/lib/bootstrap/css/bootstrap.css.map +1 -0
- inpanel/public/lib/bootstrap/css/bootstrap.min.css +6 -0
- inpanel/public/lib/bootstrap/css/bootstrap.min.css.map +1 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- inpanel/public/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
- inpanel/public/lib/bootstrap/img/glyphicons-halflings.png +0 -0
- inpanel/public/lib/bootstrap/js/bootstrap.js +2377 -0
- inpanel/public/lib/bootstrap/js/bootstrap.min.js +7 -0
- inpanel/public/lib/bootstrap/js/npm.js +13 -0
- inpanel/public/lib/codemirror/codemirror-compressed.js +1 -0
- inpanel/public/lib/codemirror/codemirror.css +173 -0
- inpanel/public/lib/jquery/jquery-1.12.4.min.js +5 -0
- inpanel/public/lib/md5/md5.js +379 -0
- inpanel/public/lib/md5/md5.min.js +1 -0
- inpanel/public/partials/database/index.html +172 -0
- inpanel/public/partials/database/mysql/dbedit.html +462 -0
- inpanel/public/partials/database/mysql/dbnew.html +348 -0
- inpanel/public/partials/database/mysql/useredit.html +310 -0
- inpanel/public/partials/database/mysql/usernew.html +97 -0
- inpanel/public/partials/directives/message.html +20 -0
- inpanel/public/partials/directives/navbar.html +25 -0
- inpanel/public/partials/directives/selector.html +57 -0
- inpanel/public/partials/directives/srvbase.html +72 -0
- inpanel/public/partials/directives/srvext.html +34 -0
- inpanel/public/partials/directives/srvfile.html +23 -0
- inpanel/public/partials/directives/srvinstall.html +34 -0
- inpanel/public/partials/directives/srvlog.html +23 -0
- inpanel/public/partials/directives/srvminiop.html +28 -0
- inpanel/public/partials/directives/srvuninstall.html +38 -0
- inpanel/public/partials/directives/srvupdate.html +30 -0
- inpanel/public/partials/ecs/account.html +156 -0
- inpanel/public/partials/ecs/ecs.html +198 -0
- inpanel/public/partials/ecs/index.html +40 -0
- inpanel/public/partials/ecs/setings.html +459 -0
- inpanel/public/partials/file/file.html +501 -0
- inpanel/public/partials/file/trash.html +95 -0
- inpanel/public/partials/ftp.html +36 -0
- inpanel/public/partials/log.html +83 -0
- inpanel/public/partials/login.html +79 -0
- inpanel/public/partials/logout.html +22 -0
- inpanel/public/partials/main.html +534 -0
- inpanel/public/partials/plugins/index.html +55 -0
- inpanel/public/partials/plugins/plugins.html +13 -0
- inpanel/public/partials/secure.html +13 -0
- inpanel/public/partials/service/apache.html +147 -0
- inpanel/public/partials/service/cron.html +71 -0
- inpanel/public/partials/service/index.html +293 -0
- inpanel/public/partials/service/iptables.html +40 -0
- inpanel/public/partials/service/lighttpd.html +63 -0
- inpanel/public/partials/service/mariadb.html +113 -0
- inpanel/public/partials/service/memcache.html +36 -0
- inpanel/public/partials/service/minio.html +44 -0
- inpanel/public/partials/service/mongodb.html +44 -0
- inpanel/public/partials/service/mysql.html +113 -0
- inpanel/public/partials/service/named.html +61 -0
- inpanel/public/partials/service/nginx.html +296 -0
- inpanel/public/partials/service/ntp.html +40 -0
- inpanel/public/partials/service/php.html +250 -0
- inpanel/public/partials/service/proftpd.html +59 -0
- inpanel/public/partials/service/pureftpd.html +59 -0
- inpanel/public/partials/service/redis.html +40 -0
- inpanel/public/partials/service/samba.html +58 -0
- inpanel/public/partials/service/sendmail.html +40 -0
- inpanel/public/partials/service/ssh.html +186 -0
- inpanel/public/partials/service/tomcat.html +65 -0
- inpanel/public/partials/service/vsftpd.html +195 -0
- inpanel/public/partials/setting.html +299 -0
- inpanel/public/partials/site/apache/site.html +277 -0
- inpanel/public/partials/site/index.html +344 -0
- inpanel/public/partials/site/nginx/site.html +558 -0
- inpanel/public/partials/sorry.html +19 -0
- inpanel/public/partials/storage/autofm.html +103 -0
- inpanel/public/partials/storage/backup.html +42 -0
- inpanel/public/partials/storage/index.html +360 -0
- inpanel/public/partials/storage/migrate.html +93 -0
- inpanel/public/partials/storage/movedata.html +98 -0
- inpanel/public/partials/storage/remote.html +77 -0
- inpanel/public/partials/utils/cron.html +486 -0
- inpanel/public/partials/utils/firewall.html +266 -0
- inpanel/public/partials/utils/index.html +193 -0
- inpanel/public/partials/utils/network.html +118 -0
- inpanel/public/partials/utils/process.html +239 -0
- inpanel/public/partials/utils/repository.html +373 -0
- inpanel/public/partials/utils/shell.html +28 -0
- inpanel/public/partials/utils/ssl.html +319 -0
- inpanel/public/partials/utils/time.html +109 -0
- inpanel/public/partials/utils/user.html +359 -0
- inpanel/public/robots.txt +2 -0
- inpanel/remote.py +109 -0
- inpanel/templates/file/preview.html +34 -0
- inpanel/templates/index.html +93 -0
- inpanel/utils.py +282 -0
- inpanel/web.py +1811 -0
- inpanel/yum.py +756 -0
- inpanel-1.2.1.dist-info/METADATA +399 -0
- inpanel-1.2.1.dist-info/RECORD +198 -0
- inpanel-1.2.1.dist-info/WHEEL +5 -0
- inpanel-1.2.1.dist-info/entry_points.txt +2 -0
- inpanel-1.2.1.dist-info/licenses/LICENSE +30 -0
- inpanel-1.2.1.dist-info/top_level.txt +1 -0
inpanel/mod/lighttpd.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# InPanel is distributed under the terms of the New BSD License.
|
|
7
|
+
# The full license can be found in 'LICENSE'.
|
|
8
|
+
|
|
9
|
+
"""Module for Lighttpd configuration management."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def web_handler(self):
|
|
13
|
+
action = self.get_argument('action', '')
|
|
14
|
+
if action == 'getsettings':
|
|
15
|
+
self.write({'code': 0, 'msg': 'Lighttpd 配置信息获取成功!', 'data': get_config()})
|
|
16
|
+
elif action == 'savesettings':
|
|
17
|
+
self.write({'code': 0, 'msg': 'Lighttpd 服务配置保存成功!', 'data': set_config(self)})
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_config():
|
|
22
|
+
return dict()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def set_config(self):
|
|
26
|
+
return dict()
|
inpanel/mod/login.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# InPanel is distributed under the terms of the (new) BSD License.
|
|
7
|
+
# The full license can be found in 'LICENSE'.
|
|
8
|
+
|
|
9
|
+
'''Module for login handling'''
|
|
10
|
+
|
|
11
|
+
import time
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from hashlib import md5
|
|
14
|
+
import hmac
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def handle_login(config, username, password):
|
|
18
|
+
"""Handle login request.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
config: config object
|
|
22
|
+
username: username from request
|
|
23
|
+
password: password from request
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
dict with 'code' and 'msg' keys
|
|
27
|
+
"""
|
|
28
|
+
loginlock = config.get('runtime', 'loginlock')
|
|
29
|
+
|
|
30
|
+
if config.get('runtime', 'mode') == 'demo':
|
|
31
|
+
loginlock = 'off'
|
|
32
|
+
|
|
33
|
+
# check if login is locked
|
|
34
|
+
if loginlock == 'on':
|
|
35
|
+
loginlockexpire = config.getint('runtime', 'loginlockexpire')
|
|
36
|
+
if time.time() < loginlockexpire:
|
|
37
|
+
return {
|
|
38
|
+
'code': -1,
|
|
39
|
+
'msg': '登录已被锁定,请在 %s 后重试登录。<br>'\
|
|
40
|
+
'如需立即解除锁定,请在服务器上执行以下命令:<br>'\
|
|
41
|
+
'inpanel config loginlock off' %
|
|
42
|
+
datetime.fromtimestamp(loginlockexpire)
|
|
43
|
+
.strftime('%Y-%m-%d %H:%M:%S')
|
|
44
|
+
}
|
|
45
|
+
else:
|
|
46
|
+
config.set('runtime', 'loginlock', 'off')
|
|
47
|
+
config.set('runtime', 'loginlockexpire', 0)
|
|
48
|
+
|
|
49
|
+
loginfails = config.getint('runtime', 'loginfails')
|
|
50
|
+
cfg_username = config.get('auth', 'username')
|
|
51
|
+
cfg_password = config.get('auth', 'password')
|
|
52
|
+
|
|
53
|
+
if not username:
|
|
54
|
+
return {'code': -1, 'msg': '账号不能为空!'}
|
|
55
|
+
elif not password:
|
|
56
|
+
return {'code': -1, 'msg': '密码不能为空!'}
|
|
57
|
+
elif cfg_password == '':
|
|
58
|
+
return {
|
|
59
|
+
'code': -1,
|
|
60
|
+
'msg': '登录密码还未设置,请在服务器上执行以下命令进行设置:<br>inpanel config password \'您的密码\''
|
|
61
|
+
}
|
|
62
|
+
elif username != cfg_username:
|
|
63
|
+
return {'code': -1, 'msg': '用户不存在!'}
|
|
64
|
+
else:
|
|
65
|
+
cfg_password, key = cfg_password.split(':')
|
|
66
|
+
if hmac.new(key.encode('utf-8'), password.encode('utf-8'), md5).hexdigest() == cfg_password:
|
|
67
|
+
if loginfails > 0:
|
|
68
|
+
config.set('runtime', 'loginfails', 0)
|
|
69
|
+
|
|
70
|
+
passwordcheck = config.getboolean('auth', 'passwordcheck')
|
|
71
|
+
if passwordcheck:
|
|
72
|
+
return {'code': 1, 'msg': '%s,您已登录成功!' % username}
|
|
73
|
+
else:
|
|
74
|
+
return {'code': 0, 'msg': '%s,您已登录成功!' % username}
|
|
75
|
+
else:
|
|
76
|
+
if config.get('runtime', 'mode') == 'demo':
|
|
77
|
+
return {'code': -1, 'msg': '用户名或密码错误!'}
|
|
78
|
+
|
|
79
|
+
loginfails = loginfails + 1
|
|
80
|
+
config.set('runtime', 'loginfails', loginfails)
|
|
81
|
+
if loginfails >= 5:
|
|
82
|
+
# lock 24 hours
|
|
83
|
+
config.set('runtime', 'loginlock', 'on')
|
|
84
|
+
config.set('runtime', 'loginlockexpire', int(time.time()) + 86400)
|
|
85
|
+
return {'code': -1, 'msg': '用户名或密码错误!<br>'\
|
|
86
|
+
'已连续错误 5 次,登录已被禁止!'}
|
|
87
|
+
else:
|
|
88
|
+
return {'code': -1, 'msg': '用户名或密码错误!<br>'\
|
|
89
|
+
'连续错误 5 次后将被禁止登录,还有 %d 次机会。' % (5 - loginfails)}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def handle_logout():
|
|
93
|
+
"""Handle logout request.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
None (logout is handled by clearing cookie)
|
|
97
|
+
"""
|
|
98
|
+
pass
|
inpanel/mod/mysql.py
ADDED
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#-*- coding: utf-8 -*-
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
5
|
+
# All rights reserved.
|
|
6
|
+
#
|
|
7
|
+
# InPanel is distributed under the terms of the (new) BSD License.
|
|
8
|
+
# The full license can be found in 'LICENSE'.
|
|
9
|
+
|
|
10
|
+
"""Module for mysql operations."""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import re
|
|
14
|
+
import shlex
|
|
15
|
+
import time
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
import pexpect
|
|
19
|
+
from ..utils import valid_filename
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def updatepwd(pwd, oldpwd):
|
|
23
|
+
"""Update password of root.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
cmd = shlex.split(f'mysqladmin -uroot password "{pwd}" -p')
|
|
27
|
+
except:
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
child = pexpect.spawn(cmd[0], cmd[1:])
|
|
31
|
+
i = child.expect(['Enter password', pexpect.EOF])
|
|
32
|
+
if i == 1:
|
|
33
|
+
if child.isalive():
|
|
34
|
+
child.wait()
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
child.sendline(oldpwd)
|
|
38
|
+
i = child.expect(['error', pexpect.EOF])
|
|
39
|
+
if child.isalive():
|
|
40
|
+
return child.wait() == 0
|
|
41
|
+
return i != 0
|
|
42
|
+
|
|
43
|
+
def shutdown(pwd):
|
|
44
|
+
"""Shutdown mysql server.
|
|
45
|
+
"""
|
|
46
|
+
try:
|
|
47
|
+
cmd = shlex.split('mysqladmin -uroot shutdown -p')
|
|
48
|
+
except:
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
child = pexpect.spawn(cmd[0], cmd[1:])
|
|
52
|
+
i = child.expect(['Enter password', pexpect.EOF])
|
|
53
|
+
if i == 1:
|
|
54
|
+
if child.isalive(): child.wait()
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
child.sendline(pwd)
|
|
58
|
+
i = child.expect(['error', pexpect.EOF])
|
|
59
|
+
if child.isalive(): return child.wait() == 0
|
|
60
|
+
return i != 0
|
|
61
|
+
|
|
62
|
+
def _mysql(pwd):
|
|
63
|
+
"""Open a mysql client and auth login.
|
|
64
|
+
"""
|
|
65
|
+
cmd = shlex.split('mysql -uroot -p -A')
|
|
66
|
+
child = pexpect.spawn(cmd[0], cmd[1:])
|
|
67
|
+
if not _auth(child, pwd): return False
|
|
68
|
+
return child
|
|
69
|
+
|
|
70
|
+
def _auth(child, pwd):
|
|
71
|
+
"""Auth a mysql client login.
|
|
72
|
+
"""
|
|
73
|
+
i = child.expect(['Enter password', pexpect.EOF])
|
|
74
|
+
if i == 1:
|
|
75
|
+
if child.isalive(): child.wait()
|
|
76
|
+
return False
|
|
77
|
+
|
|
78
|
+
child.sendline(pwd)
|
|
79
|
+
i = child.expect(['mysql>', pexpect.EOF])
|
|
80
|
+
if i == 1:
|
|
81
|
+
if child.isalive(): child.wait()
|
|
82
|
+
return False
|
|
83
|
+
return True
|
|
84
|
+
|
|
85
|
+
def _exit(child):
|
|
86
|
+
"""Exit a mysql client.
|
|
87
|
+
"""
|
|
88
|
+
child.sendline('exit')
|
|
89
|
+
child.expect([pexpect.EOF])
|
|
90
|
+
if child.isalive(): child.wait()
|
|
91
|
+
|
|
92
|
+
def _parse_result(output, includefields=True):
|
|
93
|
+
"""Parse result into a list.
|
|
94
|
+
"""
|
|
95
|
+
lines = output.split('\n')[1:]
|
|
96
|
+
if lines[0].startswith('Empty set'): return []
|
|
97
|
+
if lines[0].startswith('Query OK'): return True
|
|
98
|
+
if lines[0].startswith('+'):
|
|
99
|
+
if includefields:
|
|
100
|
+
fields = [f.strip() for f in lines[1].strip().strip('|').split('|')]
|
|
101
|
+
datalines = lines[3:]
|
|
102
|
+
rows = []
|
|
103
|
+
for dline in datalines:
|
|
104
|
+
if dline.startswith('|'):
|
|
105
|
+
rows.append([v.strip() for v in dline.strip().strip('|').split('|')])
|
|
106
|
+
else:
|
|
107
|
+
break
|
|
108
|
+
if includefields:
|
|
109
|
+
return [dict(zip(fields, row)) for row in rows]
|
|
110
|
+
else:
|
|
111
|
+
return rows
|
|
112
|
+
return True
|
|
113
|
+
|
|
114
|
+
def _sql(child, sql, returnresult=True, includefields=True):
|
|
115
|
+
"""Execute SQL statement in interactive mode.
|
|
116
|
+
"""
|
|
117
|
+
sql = sql.strip()
|
|
118
|
+
if '\n' in sql:
|
|
119
|
+
sql = ' '.join([line.strip() for line in sql.split('\n')])
|
|
120
|
+
if not sql.endswith(';'):
|
|
121
|
+
sql += ';'
|
|
122
|
+
|
|
123
|
+
child.sendline(sql)
|
|
124
|
+
i = child.expect(['ERROR', 'mysql>', pexpect.EOF])
|
|
125
|
+
if i == 0:
|
|
126
|
+
# skip old lines
|
|
127
|
+
i = child.expect(['mysql>', pexpect.EOF])
|
|
128
|
+
if i != 0: _exit(child)
|
|
129
|
+
return False
|
|
130
|
+
elif i == 2:
|
|
131
|
+
_exit(child)
|
|
132
|
+
return False
|
|
133
|
+
|
|
134
|
+
if returnresult:
|
|
135
|
+
return _parse_result(child.before, includefields=includefields)
|
|
136
|
+
else:
|
|
137
|
+
return True
|
|
138
|
+
|
|
139
|
+
def _escape(string):
|
|
140
|
+
"""Escape a string.
|
|
141
|
+
"""
|
|
142
|
+
return re.escape(string).replace(r'\_', '_').replace(r'\%', '%')
|
|
143
|
+
|
|
144
|
+
def fupdatepwd(pwd):
|
|
145
|
+
"""Force update password of root.
|
|
146
|
+
|
|
147
|
+
MySQL server should first enter rescue mode.
|
|
148
|
+
"""
|
|
149
|
+
child = pexpect.spawn('mysql -A')
|
|
150
|
+
i = child.expect(['mysql>', pexpect.EOF])
|
|
151
|
+
if i == 1:
|
|
152
|
+
if child.isalive(): child.wait()
|
|
153
|
+
return False
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
if not _sql(child, 'UPDATE mysql.user SET Password=PASSWORD("%s") WHERE User="root"' % _escape(pwd)): raise Exception()
|
|
157
|
+
if not _sql(child, 'FLUSH PRIVILEGES'): raise Exception()
|
|
158
|
+
except:
|
|
159
|
+
_exit(child)
|
|
160
|
+
return False
|
|
161
|
+
else:
|
|
162
|
+
_exit(child)
|
|
163
|
+
|
|
164
|
+
return True
|
|
165
|
+
|
|
166
|
+
def checkpwd(pwd):
|
|
167
|
+
"""Validate password of root.
|
|
168
|
+
"""
|
|
169
|
+
child = _mysql(pwd)
|
|
170
|
+
if not child: return False
|
|
171
|
+
_exit(child)
|
|
172
|
+
return True
|
|
173
|
+
|
|
174
|
+
def show_databases(pwd, fullinfo=True):
|
|
175
|
+
"""Show database list.
|
|
176
|
+
"""
|
|
177
|
+
child = _mysql(pwd)
|
|
178
|
+
if not child: return False
|
|
179
|
+
|
|
180
|
+
ignore_tables = ('information_schema', 'performance_schema', 'mysql')
|
|
181
|
+
|
|
182
|
+
if not fullinfo:
|
|
183
|
+
dbs = _sql(child, 'SHOW DATABASES', includefields=False)
|
|
184
|
+
if not dbs:
|
|
185
|
+
_exit(child)
|
|
186
|
+
return False
|
|
187
|
+
dbs = [db[0] for db in dbs if db[0] not in ignore_tables]
|
|
188
|
+
else:
|
|
189
|
+
# REF: http://stackoverflow.com/questions/184560/how-to-monitor-mysql-space
|
|
190
|
+
sql = '''
|
|
191
|
+
SELECT schema_name name, charset, collation,
|
|
192
|
+
IFNULL(tables, 0) tables,
|
|
193
|
+
IFNULL(datsum, 0) datasize,
|
|
194
|
+
IFNULL(ndxsum, 0) indexsize,
|
|
195
|
+
IFNULL(totsum, 0) totalsize
|
|
196
|
+
FROM (
|
|
197
|
+
SELECT schema_name, default_character_set_name charset, default_collation_name collation
|
|
198
|
+
FROM information_schema.SCHEMATA
|
|
199
|
+
WHERE schema_name NOT IN %s
|
|
200
|
+
) A LEFT JOIN (
|
|
201
|
+
SELECT db, COUNT(1) tables, SUM(dat) datsum, SUM(ndx) ndxsum, SUM(dat+ndx) totsum
|
|
202
|
+
FROM (
|
|
203
|
+
SELECT table_schema db, data_length dat, index_length ndx
|
|
204
|
+
FROM information_schema.tables WHERE engine IS NOT NULL
|
|
205
|
+
AND table_schema NOT IN %s
|
|
206
|
+
) AA
|
|
207
|
+
GROUP BY db
|
|
208
|
+
) B ON A.schema_name=B.db''' % (repr(ignore_tables), repr(ignore_tables))
|
|
209
|
+
dbs = _sql(child, sql)
|
|
210
|
+
|
|
211
|
+
_exit(child)
|
|
212
|
+
return dbs
|
|
213
|
+
|
|
214
|
+
def show_database(pwd, dbname):
|
|
215
|
+
"""Show a database info.
|
|
216
|
+
"""
|
|
217
|
+
child = _mysql(pwd)
|
|
218
|
+
if not child: return False
|
|
219
|
+
|
|
220
|
+
sql = '''
|
|
221
|
+
SELECT schema_name name, charset, collation,
|
|
222
|
+
IFNULL(tables, 0) tables,
|
|
223
|
+
IFNULL(datsum, 0) datasize,
|
|
224
|
+
IFNULL(ndxsum, 0) indexsize,
|
|
225
|
+
IFNULL(totsum, 0) totalsize
|
|
226
|
+
FROM (
|
|
227
|
+
SELECT schema_name, default_character_set_name charset, default_collation_name collation
|
|
228
|
+
FROM information_schema.SCHEMATA
|
|
229
|
+
WHERE schema_name='%s'
|
|
230
|
+
) A LEFT JOIN (
|
|
231
|
+
SELECT db, COUNT(1) tables, SUM(dat) datsum, SUM(ndx) ndxsum, SUM(dat+ndx) totsum
|
|
232
|
+
FROM (
|
|
233
|
+
SELECT table_schema db, data_length dat, index_length ndx
|
|
234
|
+
FROM information_schema.tables WHERE engine IS NOT NULL
|
|
235
|
+
AND table_schema='%s'
|
|
236
|
+
) AA
|
|
237
|
+
GROUP BY db
|
|
238
|
+
) B ON A.schema_name=B.db''' % (_escape(dbname), _escape(dbname))
|
|
239
|
+
dbinfo = _sql(child, sql)
|
|
240
|
+
if dbinfo: dbinfo = dbinfo[0]
|
|
241
|
+
|
|
242
|
+
_exit(child)
|
|
243
|
+
return dbinfo
|
|
244
|
+
|
|
245
|
+
def create_database(pwd, dbname, charset='utf8', collation='utf8_general_ci'):
|
|
246
|
+
"""Create a new database.
|
|
247
|
+
"""
|
|
248
|
+
child = _mysql(pwd)
|
|
249
|
+
if not child: return False
|
|
250
|
+
sql = 'CREATE DATABASE %s CHARACTER SET %s COLLATE %s' % \
|
|
251
|
+
(_escape(dbname), _escape(charset), _escape(collation))
|
|
252
|
+
if not _sql(child, sql):
|
|
253
|
+
_exit(child)
|
|
254
|
+
return False
|
|
255
|
+
_exit(child)
|
|
256
|
+
return True
|
|
257
|
+
|
|
258
|
+
def alter_database(pwd, dbname, charset='utf8', collation='utf8_general_ci'):
|
|
259
|
+
"""Alter database.
|
|
260
|
+
"""
|
|
261
|
+
child = _mysql(pwd)
|
|
262
|
+
if not child: return False
|
|
263
|
+
sql = 'ALTER DATABASE %s CHARACTER SET %s COLLATE %s' % \
|
|
264
|
+
(_escape(dbname), _escape(charset), _escape(collation))
|
|
265
|
+
if not _sql(child, sql):
|
|
266
|
+
_exit(child)
|
|
267
|
+
return False
|
|
268
|
+
_exit(child)
|
|
269
|
+
return True
|
|
270
|
+
|
|
271
|
+
def rename_database(pwd, dbname, newname):
|
|
272
|
+
"""Rename a database.
|
|
273
|
+
"""
|
|
274
|
+
child = _mysql(pwd)
|
|
275
|
+
if not child: return False
|
|
276
|
+
|
|
277
|
+
try:
|
|
278
|
+
create_sql = _sql(child, 'SHOW CREATE DATABASE %s' % _escape(dbname), includefields=False)
|
|
279
|
+
if not create_sql: raise Exception()
|
|
280
|
+
create_sql = create_sql[0][1]
|
|
281
|
+
if not _sql(child, 'USE %s' % _escape(dbname)): raise Exception()
|
|
282
|
+
tables = _sql(child, 'SHOW TABLES', includefields=False)
|
|
283
|
+
if tables == False: raise Exception()
|
|
284
|
+
|
|
285
|
+
if not _sql(child, create_sql.replace(dbname, newname)): raise Exception()
|
|
286
|
+
for table in tables:
|
|
287
|
+
table = table[0]
|
|
288
|
+
sql = 'RENAME TABLE `%s`.`%s` TO `%s`.`%s`' % (_escape(dbname), table, _escape(newname), table)
|
|
289
|
+
if not _sql(child, sql): raise Exception()
|
|
290
|
+
if not _sql(child, 'DROP DATABASE %s' % _escape(dbname)): raise Exception()
|
|
291
|
+
except:
|
|
292
|
+
_exit(child)
|
|
293
|
+
return False
|
|
294
|
+
else:
|
|
295
|
+
_exit(child)
|
|
296
|
+
return True
|
|
297
|
+
|
|
298
|
+
def drop_database(pwd, dbname):
|
|
299
|
+
"""Drop a database.
|
|
300
|
+
"""
|
|
301
|
+
child = _mysql(pwd)
|
|
302
|
+
if not child: return False
|
|
303
|
+
if not _sql(child, 'DROP DATABASE %s' % _escape(dbname)):
|
|
304
|
+
_exit(child)
|
|
305
|
+
return False
|
|
306
|
+
_exit(child)
|
|
307
|
+
return True
|
|
308
|
+
|
|
309
|
+
def export_database(pwd, dbname, exportpath):
|
|
310
|
+
"""Export database to a file.
|
|
311
|
+
"""
|
|
312
|
+
filename = '%s_%s.sql' % (dbname, time.strftime('%Y%m%d_%H%M%S'))
|
|
313
|
+
filepath = str(Path(exportpath) / filename)
|
|
314
|
+
if not valid_filename(filename): return False
|
|
315
|
+
|
|
316
|
+
cmd = 'mysqldump -uroot -p %s' % dbname
|
|
317
|
+
cmd = '/bin/bash -c "%s > %s"' % (cmd, filepath)
|
|
318
|
+
child = pexpect.spawn(cmd)
|
|
319
|
+
|
|
320
|
+
i = child.expect(['Enter password', pexpect.EOF])
|
|
321
|
+
if i == 1:
|
|
322
|
+
if child.isalive(): child.wait()
|
|
323
|
+
return False
|
|
324
|
+
|
|
325
|
+
child.sendline(pwd)
|
|
326
|
+
i = child.expect(['error', pexpect.EOF])
|
|
327
|
+
if child.isalive():
|
|
328
|
+
w = child.wait()
|
|
329
|
+
return w == 0
|
|
330
|
+
|
|
331
|
+
return i != 0
|
|
332
|
+
|
|
333
|
+
def show_users(pwd, dbname=None):
|
|
334
|
+
"""Show all user list, or user list of specified database.
|
|
335
|
+
"""
|
|
336
|
+
child = _mysql(pwd)
|
|
337
|
+
if not child: return False
|
|
338
|
+
|
|
339
|
+
if not dbname:
|
|
340
|
+
sql = "SELECT *, IF(`Password` = _latin1 '', 'N', 'Y') AS 'Password' FROM `mysql`.`user` ORDER BY `User` ASC, `Host` ASC"
|
|
341
|
+
else:
|
|
342
|
+
sql = '''
|
|
343
|
+
(SELECT `User`, `Host`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`,
|
|
344
|
+
`Grant_priv`, `Index_priv`, `Alter_priv`, `References_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`,
|
|
345
|
+
`Create_view_priv`, `Show_view_priv`, `Create_routine_priv`, `Alter_routine_priv`, `Execute_priv`, `Event_priv`, `Trigger_priv`, `Db`
|
|
346
|
+
FROM `mysql`.`db` WHERE '%s' LIKE `Db` AND NOT (
|
|
347
|
+
`Select_priv` = 'N' AND `Insert_priv` = 'N' AND `Update_priv` = 'N' AND `Delete_priv` = 'N' AND `Create_priv` = 'N' AND `Drop_priv` = 'N'
|
|
348
|
+
AND `Grant_priv` = 'N' AND `References_priv` = 'N' AND `Create_tmp_table_priv` = 'N' AND `Lock_tables_priv` = 'N' AND `Create_view_priv` = 'N'
|
|
349
|
+
AND `Show_view_priv` = 'N' AND `Create_routine_priv` = 'N' AND `Alter_routine_priv` = 'N' AND `Execute_priv` = 'N' AND `Event_priv` = 'N'
|
|
350
|
+
AND `Trigger_priv` = 'N'
|
|
351
|
+
)) UNION (
|
|
352
|
+
SELECT `User`, `Host`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`, `Create_priv`, `Drop_priv`,
|
|
353
|
+
`Grant_priv`, `Index_priv`, `Alter_priv`, `References_priv`, `Create_tmp_table_priv`, `Lock_tables_priv`,
|
|
354
|
+
`Create_view_priv`, `Show_view_priv`, `Create_routine_priv`, `Alter_routine_priv`, `Execute_priv`, `Event_priv`, `Trigger_priv`, '*' AS `Db`
|
|
355
|
+
FROM `mysql`.`user` WHERE NOT (
|
|
356
|
+
`Select_priv` = 'N' AND `Insert_priv` = 'N' AND `Update_priv` = 'N' AND `Delete_priv` = 'N' AND `Create_priv` = 'N' AND `Drop_priv` = 'N'
|
|
357
|
+
AND `Grant_priv` = 'N' AND `References_priv` = 'N' AND `Create_tmp_table_priv` = 'N' AND `Lock_tables_priv` = 'N' AND `Create_view_priv` = 'N'
|
|
358
|
+
AND `Show_view_priv` = 'N' AND `Create_routine_priv` = 'N' AND `Alter_routine_priv` = 'N' AND `Execute_priv` = 'N' AND `Event_priv` = 'N'
|
|
359
|
+
AND `Trigger_priv` = 'N'
|
|
360
|
+
)) ORDER BY `User` ASC, `Host` ASC, `Db` ASC''' % _escape(dbname)
|
|
361
|
+
|
|
362
|
+
privs = _sql(child, sql)
|
|
363
|
+
|
|
364
|
+
_exit(child)
|
|
365
|
+
return privs
|
|
366
|
+
|
|
367
|
+
def show_user_globalprivs(pwd, user, host):
|
|
368
|
+
"""Show user global privileges.
|
|
369
|
+
"""
|
|
370
|
+
child = _mysql(pwd)
|
|
371
|
+
if not child: return False
|
|
372
|
+
|
|
373
|
+
sql = "SELECT * FROM `mysql`.`user` WHERE `User` = '%s' AND `Host` = '%s'" % (_escape(user), _escape(host))
|
|
374
|
+
privs = _sql(child, sql)
|
|
375
|
+
privs = privs and privs[0] or False
|
|
376
|
+
|
|
377
|
+
_exit(child)
|
|
378
|
+
return privs
|
|
379
|
+
|
|
380
|
+
def show_user_dbprivs(pwd, user, host, dbname=None):
|
|
381
|
+
"""Show user privileges in database.
|
|
382
|
+
"""
|
|
383
|
+
child = _mysql(pwd)
|
|
384
|
+
if not child: return False
|
|
385
|
+
|
|
386
|
+
if not dbname:
|
|
387
|
+
sql = "SELECT * FROM `mysql`.`db` WHERE `User` = '%s' AND `Host` = '%s' ORDER BY `Db` ASC" % (_escape(user), _escape(host))
|
|
388
|
+
else:
|
|
389
|
+
sql = "SELECT * FROM `mysql`.`db` WHERE `User` = '%s' AND `Host` = '%s' AND '%s' LIKE `Db`" % (_escape(user), _escape(host), _escape(dbname))
|
|
390
|
+
|
|
391
|
+
privs = _sql(child, sql)
|
|
392
|
+
if privs and dbname: privs = privs[0]
|
|
393
|
+
|
|
394
|
+
_exit(child)
|
|
395
|
+
return privs
|
|
396
|
+
|
|
397
|
+
def revoke_user_privs(pwd, user, host, dbname=None):
|
|
398
|
+
"""Revoke user's privileges.
|
|
399
|
+
"""
|
|
400
|
+
child = _mysql(pwd)
|
|
401
|
+
if not child: return False
|
|
402
|
+
|
|
403
|
+
if not dbname:
|
|
404
|
+
dbexpr = '*.*'
|
|
405
|
+
else:
|
|
406
|
+
dbexpr = '`%s`.*' % _escape(dbname)
|
|
407
|
+
|
|
408
|
+
try:
|
|
409
|
+
sql = "REVOKE ALL PRIVILEGES ON %s FROM '%s'@'%s'" % (dbexpr, _escape(user), _escape(host))
|
|
410
|
+
if not _sql(child, sql, False): raise Exception()
|
|
411
|
+
sql = "REVOKE GRANT OPTION ON %s FROM '%s'@'%s'" % (dbexpr, _escape(user), _escape(host))
|
|
412
|
+
if not _sql(child, sql, False): raise Exception()
|
|
413
|
+
if not dbname:
|
|
414
|
+
sql = "GRANT USAGE ON *.* TO '%s'@'%s' " \
|
|
415
|
+
"WITH MAX_QUERIES_PER_HOUR 0 " \
|
|
416
|
+
"MAX_CONNECTIONS_PER_HOUR 0 " \
|
|
417
|
+
"MAX_UPDATES_PER_HOUR 0 " \
|
|
418
|
+
"MAX_USER_CONNECTIONS 0" % (_escape(user), _escape(host))
|
|
419
|
+
if not _sql(child, sql, False): raise Exception()
|
|
420
|
+
except:
|
|
421
|
+
_exit(child)
|
|
422
|
+
return False
|
|
423
|
+
else:
|
|
424
|
+
_exit(child)
|
|
425
|
+
return True
|
|
426
|
+
|
|
427
|
+
def update_user_privs(pwd, user, host, privs, dbname=None):
|
|
428
|
+
"""Update user's privileges.
|
|
429
|
+
"""
|
|
430
|
+
child = _mysql(pwd)
|
|
431
|
+
if not child: return False
|
|
432
|
+
|
|
433
|
+
allprivs = [
|
|
434
|
+
'SELECT', 'INSERT', 'UPDATE', 'DELETE',
|
|
435
|
+
'CREATE', 'ALTER', 'INDEX', 'DROP', 'CREATE TEMPORARY TABLES',
|
|
436
|
+
'SHOW VIEW', 'CREATE ROUTINE', 'ALTER ROUTINE', 'EXECUTE',
|
|
437
|
+
'CREATE VIEW', 'EVENT', 'TRIGGER',
|
|
438
|
+
'GRANT', 'LOCK TABLES', 'REFERENCES'
|
|
439
|
+
]
|
|
440
|
+
|
|
441
|
+
if not dbname:
|
|
442
|
+
allprivs.extend([
|
|
443
|
+
'FILE', 'SUPER', 'PROCESS', 'RELOAD', 'SHUTDOWN', 'SHOW DATABASES',
|
|
444
|
+
'REPLICATION CLIENT', 'REPLICATION SLAVE', 'CREATE USER'
|
|
445
|
+
])
|
|
446
|
+
dbexpr = '*.*'
|
|
447
|
+
else:
|
|
448
|
+
dbexpr = '`%s`.*' % _escape(dbname)
|
|
449
|
+
|
|
450
|
+
privs = filter(lambda a: a in allprivs, privs)
|
|
451
|
+
|
|
452
|
+
# revoke privileges
|
|
453
|
+
if len(privs) == 0:
|
|
454
|
+
_exit(child)
|
|
455
|
+
return revoke_user_privs(pwd, user, host, dbname)
|
|
456
|
+
|
|
457
|
+
if 'GRANT' in privs:
|
|
458
|
+
grant_option = 'WITH GRANT OPTION'
|
|
459
|
+
privs = filter(lambda a: a != 'GRANT', privs)
|
|
460
|
+
else:
|
|
461
|
+
grant_option = ''
|
|
462
|
+
if len(privs) == len(allprivs)-1:
|
|
463
|
+
grant_sql = "GRANT ALL PRIVILEGES ON %s TO '%s'@'%s' %s" % (dbexpr, _escape(user), _escape(host), grant_option)
|
|
464
|
+
else:
|
|
465
|
+
grant_sql = "GRANT %s ON %s TO '%s'@'%s' %s" % (','.join(privs), dbexpr, _escape(user), _escape(host), grant_option)
|
|
466
|
+
|
|
467
|
+
try:
|
|
468
|
+
# don't check revoke result, the user may not exists
|
|
469
|
+
sql = "REVOKE ALL PRIVILEGES ON %s FROM '%s'@'%s'" % (dbexpr, _escape(user), _escape(host))
|
|
470
|
+
_sql(child, sql, False)
|
|
471
|
+
sql = "REVOKE GRANT OPTION ON %s FROM '%s'@'%s'" % (dbexpr, _escape(user), _escape(host))
|
|
472
|
+
_sql(child, sql, False)
|
|
473
|
+
if not _sql(child, grant_sql, False): raise Exception()
|
|
474
|
+
except:
|
|
475
|
+
_exit(child)
|
|
476
|
+
return False
|
|
477
|
+
else:
|
|
478
|
+
_exit(child)
|
|
479
|
+
return True
|
|
480
|
+
|
|
481
|
+
def create_user(pwd, user, host, password=None):
|
|
482
|
+
"""Create a user.
|
|
483
|
+
"""
|
|
484
|
+
child = _mysql(pwd)
|
|
485
|
+
if not child: return False
|
|
486
|
+
|
|
487
|
+
if password:
|
|
488
|
+
sql = "CREATE USER '%s'@'%s' IDENTIFIED BY '%s'" % (_escape(user), _escape(host), _escape(password))
|
|
489
|
+
else:
|
|
490
|
+
sql = "CREATE USER '%s'@'%s'" % (_escape(user), _escape(host))
|
|
491
|
+
rs = _sql(child, sql, False)
|
|
492
|
+
|
|
493
|
+
_exit(child)
|
|
494
|
+
return rs
|
|
495
|
+
|
|
496
|
+
def drop_user(pwd, user, host):
|
|
497
|
+
"""Drop a user.
|
|
498
|
+
"""
|
|
499
|
+
child = _mysql(pwd)
|
|
500
|
+
if not child:
|
|
501
|
+
return False
|
|
502
|
+
|
|
503
|
+
rs = _sql(child, "DROP USER '%s'@'%s'" % (_escape(user), _escape(host)), False)
|
|
504
|
+
|
|
505
|
+
_exit(child)
|
|
506
|
+
return rs
|
|
507
|
+
|
|
508
|
+
def set_user_password(pwd, user, host, password=None):
|
|
509
|
+
"""Set password for user.
|
|
510
|
+
"""
|
|
511
|
+
child = _mysql(pwd)
|
|
512
|
+
if not child: return False
|
|
513
|
+
|
|
514
|
+
if password:
|
|
515
|
+
sql = "SET PASSWORD FOR '%s'@'%s' = PASSWORD('%s')" % (_escape(user), _escape(host), _escape(password))
|
|
516
|
+
else:
|
|
517
|
+
sql = "SET PASSWORD FOR '%s'@'%s' = ''" % (_escape(user), _escape(host))
|
|
518
|
+
rs = _sql(child, sql, False)
|
|
519
|
+
|
|
520
|
+
_exit(child)
|
|
521
|
+
return rs
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
def web_handler(context):
|
|
525
|
+
action = context.get_argument('action', '')
|
|
526
|
+
password = context.get_argument('password', '')
|
|
527
|
+
|
|
528
|
+
if action == 'updatepwd':
|
|
529
|
+
newpassword = context.get_argument('newpassword', '')
|
|
530
|
+
newpasswordc = context.get_argument('newpasswordc', '')
|
|
531
|
+
|
|
532
|
+
if newpassword != newpasswordc:
|
|
533
|
+
context.write({'code': -1, 'msg': '两次密码输入不一致!'})
|
|
534
|
+
return
|
|
535
|
+
|
|
536
|
+
if updatepwd(newpassword, password):
|
|
537
|
+
context.write({'code': 0, 'msg': '密码设置成功!'})
|
|
538
|
+
else:
|
|
539
|
+
context.write({'code': -1, 'msg': '密码设置失败!'})
|
|
540
|
+
|
|
541
|
+
elif action == 'checkpwd':
|
|
542
|
+
if checkpwd(password):
|
|
543
|
+
context.write({'code': 0, 'msg': '密码验证成功!'})
|
|
544
|
+
else:
|
|
545
|
+
context.write({'code': -1, 'msg': '密码验证失败!(密码不正确,或 MySQL 服务未启动)'})
|
|
546
|
+
|
|
547
|
+
elif action == 'alter_database':
|
|
548
|
+
dbname = context.get_argument('dbname', '')
|
|
549
|
+
collation = context.get_argument('collation', '')
|
|
550
|
+
rt = alter_database(password, dbname, collation=collation)
|
|
551
|
+
if rt:
|
|
552
|
+
context.write({'code': 0, 'msg': '数据库编码保存成功!'})
|
|
553
|
+
else:
|
|
554
|
+
context.write({'code': -1, 'msg': '数据库编码保存失败!'})
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
if __name__ == '__main__':
|
|
558
|
+
import pprint
|
|
559
|
+
pp = pprint.PrettyPrinter(indent=4)
|
|
560
|
+
|
|
561
|
+
#pp.pprint(checkpwd('admin'))
|
|
562
|
+
#pp.pprint(show_databases('admin'))
|
|
563
|
+
#pp.pprint(show_database('admin', 'abcd'))
|
|
564
|
+
#pp.pprint(create_database('admin', 'abcd'))
|
|
565
|
+
#pp.pprint(alter_database('admin', 'abcd', 'latin1', 'latin1_swedish_ci'))
|
|
566
|
+
#pp.pprint(drop_database('admin', 'abcd'))
|
|
567
|
+
#pp.pprint(rename_database('admin', 'abcd', 'test'))
|
|
568
|
+
#pp.pprint(export_database('admin', 'abcd', '/root'))
|
|
569
|
+
#pp.pprint(show_users('admin', 'abcd'))
|
|
570
|
+
#pp.pprint(show_users('admin'))
|
|
571
|
+
#pp.pprint(show_user_globalprivs('admin', 'ddyh', 'localhost'))
|
|
572
|
+
#pp.pprint(show_user_dbprivs('admin', 'ddyh', 'localhost'))
|
|
573
|
+
#pp.pprint(revoke_user_privs('admin', 'ddyh', 'localhost', 'abcd'))
|
|
574
|
+
#pp.pprint(update_user_privs('admin', 'hilyjiang', 'localhost', ['SELECT']))
|
|
575
|
+
#pp.pprint(create_user('admin', 'hilyjiang', '%'))
|
|
576
|
+
#pp.pprint(drop_user('admin', 'hilyjiang', 'localhost'))
|
|
577
|
+
#pp.pprint(set_user_password('admin', 'ddyh', 'localhost', 'ddyh'))
|