Skip to content

Commit ce3d0e3

Browse files
committed
1.1.0 添加授权时间支持
1 parent c9e517e commit ce3d0e3

8 files changed

+79
-41
lines changed

README.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,16 @@ u_machine_code = gen_machine_code(my_crypt)
6565
### 场景步骤三(管理员本地)
6666

6767
1. 管理员解密用户提供的【加密机器码】文件
68-
2. 同时为用户分配【随机用户码】文件
68+
2. 同时为用户设置授权天数,生成【用户码】文件
6969
3. 结合两者生成【注册码】文件
70-
4. 把【随机用户码】文件和【注册码】文件提供给用户
70+
4. 把【用户码】文件和【注册码】文件提供给用户
7171

7272
```python
7373
from mur.admin import *
7474

7575
a_machine_code = read_machine_code()
76-
a_user_code = gen_user_code()
76+
days = input('请输入授权天数:') # 0 表示永久
77+
a_user_code = gen_user_code(days, crypt)
7778
a_register_code = gen_register_code(
7879
a_machine_code, a_user_code, my_crypt
7980
)
@@ -89,7 +90,7 @@ a_register_code = gen_register_code(
8990
3. 主程序在用户本地重新生成【机器码】
9091
4. 主程序利用【用户码】和【机器码】生成【注册码】
9192
5. 主程序比对【生成的注册码】和【管理员提供的注册码】内容是否一致
92-
6. 若一致,程序运行;否则,程序终止
93+
6. 若一致,且授权未过期,程序运行;否则,程序终止
9394

9495
```python
9596
from mur.user import *

gen_machine_code.py

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ def main() :
1919
print('已生成机器码 [%s]' % machine_code)
2020
print('已生成机器码对应的本地文件 [%s]' % MACHINE_CODE_PATH)
2121
print('请将其发送给管理员,以获取注册码。')
22+
print('')
23+
print('')
24+
input('输入回车退出 ...')
25+
2226

2327

2428
if __name__ == '__main__':

gen_register_code.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ def main() :
2323
des_iv = read_des_iv()
2424
crypt = Crypt(des_key, des_iv)
2525

26-
user_code = gen_user_code()
26+
days = input('请输入授权天数:')
27+
user_code = gen_user_code(days, crypt)
2728
print('随机分配的【用户码】为 [%s]' % user_code)
2829
print('已把【用户码】保存到根目录的文件 [%s],请把该文件发送给用户' % USER_CODE_PATH)
2930

setup.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
# For a discussion on single-sourcing the version across setup.py and the
3838
# project code, see
3939
# https://packaging.python.org/en/latest/single_source_version.html
40-
version='1.0.6', # Required. eg. 1.2.3
40+
version='1.1.0', # Required. eg. 1.2.3
4141

4242
# This is a one-line description or tagline of what your project does. This
4343
# corresponds to the "Summary" metadata field:
@@ -143,7 +143,7 @@
143143
#
144144
# For an analysis of "install_requires" vs pip's requirements files see:
145145
# https://packaging.python.org/en/latest/requirements.html
146-
install_requires=['pyDes>=2.0.1', 'psutil>=5.8.0', 'pypiwin32'], # Optional
146+
install_requires=['pyDes>=2.0.1', 'psutil>=5.8.0', 'pypiwin32', 'requests>=2.22.0'], # Optional
147147

148148
# List additional groups of dependencies here (e.g. development
149149
# dependencies). Users will be able to install these using the "extras"

src/mur/_public.py

+29-5
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,19 @@
44

55
import os
66
import time
7+
import requests
8+
import json
9+
from requests.api import put
710
from .crypt import Crypt
811
from ._mi import MachineInfo
912

1013
CRYPT = Crypt()
1114
MI = MachineInfo()
1215

1316
JOINER = '##'
17+
ONLINE_TIME_URL = 'http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp'
18+
UNLIMIT = '0000000000'
19+
1420
MACHINE_CODE_PATH = '.machine'
1521
USER_CODE_PATH = '.user'
1622
REGISTER_CODE_PATH = '.register'
@@ -36,16 +42,34 @@ def gen_rc(crypt, uuid, user_code) :
3642
)
3743

3844

45+
def now() :
46+
'''
47+
获取当前时间点(精确到秒)
48+
[return] 当前时间戳(long)
49+
'''
50+
try :
51+
# 先获取在线时间,避免用户修改本地时间绕过注册校验
52+
response = requests.get(ONLINE_TIME_URL, verify=False, timeout=10)
53+
millis = int(json.loads(response.text)['data']['t'])
54+
seconds = int(millis / 1000)
55+
except :
56+
# 网络不通时用本地时间代替
57+
seconds = int(time.time())
58+
return seconds
59+
60+
3961
def after(days) :
4062
'''
4163
获取今天之后的 n 天的时间点(精确到秒)
4264
[param] days: 之后的 n 天
43-
[return] n 天后的 long 时间戳
65+
[return] n 天后的时间戳(str)
4466
'''
45-
days = 0 if days <= 0 else days
46-
seconds = days * 86400
47-
now = time.time()
48-
return now + seconds
67+
timestamp = UNLIMIT
68+
if days > 0 :
69+
seconds = days * 86400
70+
timestamp = now() + seconds
71+
return str(timestamp)
72+
4973

5074

5175
def save(code, filepath) :

src/mur/admin.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,16 @@ def read_machine_code() :
1515
return read(MACHINE_CODE_PATH)
1616

1717

18-
def gen_user_code(days=30, to_file=True) :
18+
def gen_user_code(days=3, crypt=CRYPT, to_file=True) :
1919
'''
20-
管理员场景: 随机分配用户码,并写入文件
20+
管理员场景: 分配用户码,并写入文件
2121
(可直接把文件发送给用户,让其放到程序根目录)
2222
[param] day: 授权天数。 0 为永久授权
2323
[param] to_file: 是否把用户码写入文件
2424
[return] 用户码
2525
'''
26-
str_range = "%s%s" % (
27-
string.ascii_letters,
28-
string.digits
29-
)
30-
user_code = ''.join(
31-
random.sample(str_range, 8)
32-
)
26+
after_time = after(int(days))
27+
user_code = crypt.encrypt_des(after_time)
3328
if to_file :
3429
save(user_code, USER_CODE_PATH)
3530
return user_code
@@ -51,7 +46,8 @@ def gen_register_code(machine_code, user_code, crypt=CRYPT, to_file=True) :
5146
'''
5247
try :
5348
uuid = crypt.decrypt_des(machine_code)
54-
register_code = gen_rc(crypt, uuid, user_code)
49+
expire_time = crypt.decrypt_des(user_code)
50+
register_code = gen_rc(crypt, uuid, expire_time)
5551
except :
5652
register_code = ''
5753
print('无法解密【机器码】:加密密钥不同、或加密格式不正确')

src/mur/user.py

+19-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def gen_machine_code(crypt=CRYPT, to_file=True) :
1111
(可直接把文件发送给管理员,让其生成注册码)
1212
[param] crypt: 加解密类
1313
[param] to_file: 是否把用户码写入文件
14-
[return] 用户码
14+
[return] 机器码码
1515
'''
1616
uuid = MI.generate()
1717
machine_code = crypt.encrypt_des(uuid)
@@ -20,19 +20,18 @@ def gen_machine_code(crypt=CRYPT, to_file=True) :
2020
return machine_code
2121

2222

23-
def read_user_code(tips='请输入用户码: ') :
23+
def read_user_code() :
2424
'''
2525
用户场景: 读取(或输入)被管理员分配的用户码
26-
[param] tips: 输入提示
2726
[return] 用户码
2827
'''
2928
user_code = read(USER_CODE_PATH) # 若无法从文件中读取
3029
if user_code == '' :
31-
user_code = input(tips) # 则要求用户输入
30+
user_code = input('请输入用户码: ') # 则要求用户输入
3231
return user_code
3332

3433

35-
def verify_authorization(user_code, crypt=CRYPT, tips='用户码错误 或 注册码不存在,请联系管理员。程序终止。') :
34+
def verify_authorization(user_code, crypt=CRYPT) :
3635
'''
3736
用户场景: 每次运行程序时,
3837
1. 输入用户码
@@ -42,12 +41,23 @@ def verify_authorization(user_code, crypt=CRYPT, tips='用户码错误 或 注
4241
5. 比较两个注册码是否相同
4342
[param] user_code: 用户码
4443
[param] crypt: 加解密类
45-
[param] tips: 错误提示
4644
[return] true: 注册码一致; false: 注册码不同
4745
'''
4846
uuid = MI.generate()
49-
register_code = gen_rc(crypt, uuid, user_code)
47+
expire_time = crypt.decrypt_des(user_code)
48+
register_code = gen_rc(crypt, uuid, expire_time)
5049
rst = (register_code == read(REGISTER_CODE_PATH))
51-
if not rst :
52-
print(tips)
50+
if rst :
51+
expire_time = int(expire_time)
52+
expire_date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(expire_time))
53+
if expire_time == 0 :
54+
print('注册码正确(永久)。')
55+
56+
elif now() <= expire_time :
57+
print('注册码正确(有效期至 %s)。' % expire_date)
58+
else :
59+
rst = False
60+
print('注册码已过期(有效期至 %s)。' % expire_date)
61+
else :
62+
print('用户码错误 或 注册码不存在,请联系管理员。')
5363
return rst

tests/test.py

+12-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# ----------------------------------------------------------------------
1313

1414
import unittest
15+
import time
1516
from src.mur.crypt import *
1617
from src.mur.admin import *
1718
from src.mur.user import *
@@ -62,14 +63,14 @@ def test_gen_machine_code(self) :
6263
)
6364

6465

65-
def test_gen_user_code(self) :
66-
BIT = 16
67-
user_code = gen_user_code(BIT)
68-
print("用户码: %s" % user_code)
69-
self.assertEqual(
70-
len(user_code),
71-
BIT
72-
)
66+
# def test_gen_user_code(self) :
67+
# DAYS = 30
68+
# user_code = gen_user_code(DAYS)
69+
# print("用户码: %s" % user_code)
70+
# self.assertEqual(
71+
# int(self.CRYPT.decrypt_des(user_code)),
72+
# (int(time.time()) + 86400 * DAYS)
73+
# )
7374

7475

7576
def test_gen_register_code(self) :
@@ -79,7 +80,7 @@ def test_gen_register_code(self) :
7980

8081
machine_code = gen_machine_code(my_crypt)
8182
print("机器码: %s" % machine_code)
82-
user_code = gen_user_code()
83+
user_code = gen_user_code(0, my_crypt)
8384
print("用户码: %s" % user_code)
8485
register_code = gen_register_code(machine_code, user_code, my_crypt)
8586
print("注册码: %s" % register_code)
@@ -101,7 +102,8 @@ def test_verify_authorization(self) :
101102
#--------------------
102103
# 管理员本地执行:
103104
a_machine_code = read_machine_code() # 管理员读取用户提供的机器码文件
104-
a_user_code = gen_user_code() # 管理员随机分配的用户码(会生成文件)
105+
days = 5 # 授权天数
106+
a_user_code = gen_user_code(days) # 管理员随机分配的用户码(会生成文件)
105107
a_register_code = gen_register_code( # 管理员为用户生成的注册码(会生成文件)
106108
a_machine_code, a_user_code
107109
)

0 commit comments

Comments
 (0)