forked from typecho-fans/plugins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Plugin.php
149 lines (145 loc) · 6.4 KB
/
Plugin.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
/**
* Google Authenticator for Typecho
*
* @package GAuthenticator
* @author WeiCN
* @version 0.0.6
* @link https://cuojue.org/read/Typecho_Google_Authenticator_02.html
*/
class GAuthenticator_Plugin implements Typecho_Plugin_Interface
{
private static $pluginName = 'GAuthenticator';
/**
* 激活插件方法,如果激活失败,直接抛出异常
*
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function activate()
{
Helper::addRoute('GAuthenticator', '/GAuthenticator', 'GAuthenticator_Action', 'Action');
Typecho_Plugin::factory('admin/menu.php')->navBar = array(__CLASS__, 'Authenticator_safe');
Typecho_Plugin::factory('admin/common.php')->begin = array(__CLASS__, 'Authenticator_verification');
return _t('当前两步验证还未启用,请进行<a href="options-plugin.php?config=' . self::$pluginName . '">初始化设置</a>');
}
/**
* 禁用插件方法,如果禁用失败,直接抛出异常
*
* @static
* @access public
* @return void
* @throws Typecho_Plugin_Exception
*/
public static function deactivate(){
Helper::removeRoute('GAuthenticator');
}
/**
* 获取插件配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form 配置面板
* @return void'
*/
public static function config(Typecho_Widget_Helper_Form $form)
{
$qrurl = 'otpauth://totp/'.urlencode(Helper::options()->title.':'.Typecho_Widget::widget('Widget_User')->mail).'?secret=';
$element = new Typecho_Widget_Helper_Form_Element_Text('SecretKey', NULL, '', _t('SecretKey'), '
安装的时候自动计算密钥,手动修改无效,如需要修改请卸载重新安装或者手动修改数据库<br>
<div style="font-weight: bold; color: #000; text-align: center; display: block;padding: 30px 0 30px 0;font-size: 24px;">
请扫描下面的二维码绑定<br>
<div style="width: 300px; height: 300px; margin: 20px auto; padding: 20px; background-color: #fff"><span id="qrcode"></span></div>
</div>
<script>
window.onload = function () {
// https://github.com/jeromeetienne/jquery-qrcode/
$.getScript("'. Helper::options()->pluginUrl .'/GAuthenticator/jquery.qrcode.min.js", function () {
$("#qrcode").qrcode({width: 300, height: 300, text: "'. $qrurl .'"+$("input[name=SecretKey]").val()});
});
}
</script>');
$form->addInput($element);
$element = new Typecho_Widget_Helper_Form_Element_Text('SecretQRurl', NULL, '', _t('二维码的网址'), '本选项已过时,保留只是为了向下兼容。和上面图片的地址是相同的');
$form->addInput($element);
$element = new Typecho_Widget_Helper_Form_Element_Text('SecretTime', NULL, 2, _t('容差时间'), '允许的容差时间,单位为30秒的倍数,如果这里是2 那么就是 2* 30 sec 一分钟.');
$form->addInput($element);
$element = new Typecho_Widget_Helper_Form_Element_Text('SecretCode', NULL, '', _t('客户端代码'), '输入你APP或者其他什么鬼上面显示的六位数字。<br>用兼容的APP上面的扫描二维码或者手动输入第一行的SecretKey即可生成');
$form->addInput($element);
$element = new Typecho_Widget_Helper_Form_Element_Radio('SecretOn', array('1' => '开启','0' => '关闭'), 0, _t('插件开关'), '这里关掉了,就不需要验证即可登录。');
$form->addInput($element);
}
/**
* 手动保存配置面板
* @param $config array 插件配置
* @param $is_init bool 是否初始化
*/
public static function configHandle($config, $is_init)
{
if ($is_init) {//如果是第一次初始化插件
require_once 'GoogleAuthenticator.php';
$Authenticator = new PHPGangsta_GoogleAuthenticator();//初始化生成类
$config['SecretKey'] = $Authenticator->createSecret();//生成一个随机安全密钥
$config['SecretQRurl'] = 'http://qr.liantu.com/api.php?text='.urlencode('otpauth://totp/'.urlencode(Helper::options()->title.':'.Typecho_Widget::widget('Widget_User')->mail).'?secret='.$config['SecretKey']);//生成安全密钥的二维码网址
}else{
$config_old = Helper::options()->plugin(self::$pluginName);
if(($config['SecretCode']!='' && $config['SecretOn']==1) || $config['SecretOn']==1){//如果启用,并且验证码不为空
require_once 'GoogleAuthenticator.php';
$Authenticator = new PHPGangsta_GoogleAuthenticator();
if($Authenticator->verifyCode($config['SecretKey'], $config['SecretCode'], $config['SecretTime'])){
$config['SecretOn'] = 1;//如果匹配,则启用
}else{
throw new Typecho_Plugin_Exception('两步验证代码校验失败,请重试或选择关闭');
}
}
$config['SecretKey'] = $config_old->SecretKey;//保持初始化SecretKey不被修改
$config['SecretQRurl'] = $config_old->SecretQRurl;//保持初始化SecretQRurl不被修改 过时选项 兼容保留
}
$config['SecretCode'] = '';//每次保存不保存验证码
Helper::configPlugin(self::$pluginName, $config);//保存插件配置
}
/**
* 个人用户的配置面板
*
* @access public
* @param Typecho_Widget_Helper_Form $form
* @return void
*/
public static function personalConfig(Typecho_Widget_Helper_Form $form){}
/**
* 插件实现方法
*
* @access public
* @return void
*/
public static function Authenticator_safe()
{
$config = Helper::options()->plugin(self::$pluginName);
if($config->SecretOn==1){
echo '<span class="message success">'.htmlspecialchars('已启用 Authenticator 验证').'</span>';
}else{
echo '<span class="message error">'.htmlspecialchars('未启用 Authenticator 验证').'</span>';
}
}
public static function Authenticator_verification()
{
if(isset($Authenticator_init))return;
$Authenticator_init = true;
if (!Typecho_Widget::widget('Widget_User')->hasLogin()){
return;//如果没登录则直接返回
}else{
//已经登录就验证
$config = Helper::options()->plugin(self::$pluginName);
if (isset($_SESSION['GAuthenticator'])&&$_SESSION['GAuthenticator']) return;//如果SESSION匹配则直接返回
if (Typecho_Cookie::get('__typecho_GAuthenticator') == md5($config->SecretKey.Typecho_Cookie::getPrefix().Typecho_Widget::widget('Widget_User')->uid)) return;//如果COOKIE匹配则直接返回
if($config->SecretOn==1){
$options = Helper::options();
$request = new Typecho_Request();
require_once 'verification.php';
}else{
return;//如果未开启插件则直接返回
}
}
}
}