diff --git a/functions.php b/functions.php
index 19844fd..1810e82 100644
--- a/functions.php
+++ b/functions.php
@@ -1616,11 +1616,17 @@ function output_comments_qq_columns( $column_name, $comment_id ){
*/
add_filter( 'get_avatar', 'change_avatar', 10, 3 );
function change_avatar($avatar){
- global $comment;
+ global $comment,$sakura_pubkey;
if ($comment) {
if( get_comment_meta( $comment->comment_ID, 'new_field_qq', true )){
$qq_number = get_comment_meta( $comment->comment_ID, 'new_field_qq', true );
- return '';
+ if(akina_option('qq_avatar_link')){
+ openssl_public_encrypt($qq_number, $encrypted, openssl_pkey_get_public($sakura_pubkey));
+ $qq_number = urlencode(base64_encode($encrypted));
+ return '';
+ }else{
+ return '';
+ }
}else{
return $avatar ;
}
@@ -1728,20 +1734,39 @@ function create_sakura_table(){
PRIMARY KEY (`mate_key`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=1 ;");
//default data
- $manifest = array(
- "mate_key" => "manifest_json",
- "mate_value" => file_get_contents(get_template_directory()."/manifest/manifest.json")
- );
- $time = array(
- "mate_key" => "json_time",
- "mate_value" => date("Y-m-d H:i:s",time())
- );
if ( !$wpdb->get_var("SELECT COUNT(*) FROM $sakura_table_name WHERE mate_key = 'manifest_json'") ){
+ $manifest = array(
+ "mate_key" => "manifest_json",
+ "mate_value" => file_get_contents(get_template_directory()."/manifest/manifest.json")
+ );
$wpdb->insert($sakura_table_name,$manifest);
}
if ( !$wpdb->get_var("SELECT COUNT(*) FROM $sakura_table_name WHERE mate_key = 'json_time'") ){
+ $time = array(
+ "mate_key" => "json_time",
+ "mate_value" => date("Y-m-d H:i:s",time())
+ );
$wpdb->insert($sakura_table_name,$time);
}
+ if ( !$wpdb->get_var("SELECT COUNT(*) FROM $sakura_table_name WHERE mate_key = 'privkey'") ){
+ $privkey = array(
+ "mate_key" => "privkey",
+ "mate_value" => file_get_contents(get_template_directory()."/manifest/private.key")
+ );
+ $wpdb->insert($sakura_table_name,$privkey);
+ }
+ if ( !$wpdb->get_var("SELECT COUNT(*) FROM $sakura_table_name WHERE mate_key = 'pubkey'") ){
+ $pubkey = array(
+ "mate_key" => "pubkey",
+ "mate_value" => file_get_contents(get_template_directory()."/manifest/public.key")
+ );
+ $wpdb->insert($sakura_table_name,$pubkey);
+ }
+ //reduce sql query
+ global $sakura_image_array,$sakura_privkey,$sakura_pubkey;
+ $sakura_image_array = $wpdb->get_var("SELECT `mate_value` FROM `wp_sakura` WHERE `mate_key`='manifest_json'");
+ $sakura_privkey = $wpdb->get_var("SELECT `mate_value` FROM `wp_sakura` WHERE `mate_key`='privkey'");
+ $sakura_pubkey = $wpdb->get_var("SELECT `mate_value` FROM `wp_sakura` WHERE `mate_key`='pubkey'");
}
add_action( 'after_setup_theme', 'create_sakura_table' );
diff --git a/inc/api.php b/inc/api.php
index 1450261..20db90c 100644
--- a/inc/api.php
+++ b/inc/api.php
@@ -20,18 +20,23 @@ add_action('rest_api_init', function () {
'methods' => 'GET',
'callback' => 'feature_gallery',
));
- register_rest_route('sakura/v1', '/image/manifest', array(
+ register_rest_route('sakura/v1', '/database/update', array(
'methods' => 'POST',
- 'callback' => 'update_manifest_json',
+ 'callback' => 'update_database',
));
register_rest_route('sakura/v1', '/qqinfo/json', array(
'methods' => 'GET',
'callback' => 'get_qq_info',
));
+ register_rest_route('sakura/v1', '/qqinfo/avatar', array(
+ 'methods' => 'GET',
+ 'callback' => 'get_qq_avatar',
+ ));
});
/**
* QQ info
+ * https://sakura.2heng.xin/wp-json/sakura/v1/qqinfo/json
*/
function get_qq_info(WP_REST_Request $request)
{
@@ -337,8 +342,8 @@ EOS;
* @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/image/cover
*/
function cover_gallery() {
- global $wpdb;
- $img_array = json_decode($wpdb->get_var("SELECT `mate_value` FROM `wp_sakura` WHERE `mate_key`='manifest_json'"), true);
+ global $wpdb,$sakura_image_array;
+ $img_array = json_decode($sakura_image_array, true);
$img = array_rand($img_array);
$img_domain = akina_option('cover_cdn') ? akina_option('cover_cdn') : get_template_directory_uri();
if(strpos($_SERVER['HTTP_ACCEPT'], 'image/webp')) {
@@ -358,8 +363,8 @@ function cover_gallery() {
* @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/image/feature
*/
function feature_gallery() {
- global $wpdb;
- $img_array = json_decode($wpdb->get_var("SELECT `mate_value` FROM `wp_sakura` WHERE `mate_key`='manifest_json'"), true);
+ global $wpdb,$sakura_image_array;
+ $img_array = json_decode($sakura_image_array, true);
$img = array_rand($img_array);
$img_domain = akina_option('cover_cdn') ? akina_option('cover_cdn') : get_template_directory_uri();
if(strpos($_SERVER['HTTP_ACCEPT'], 'image/webp')) {
@@ -375,10 +380,10 @@ function feature_gallery() {
}
/*
- * update manifest.json rest api
- * @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/image/json
+ * update database rest api
+ * @rest api接口路径:https://sakura.2heng.xin/wp-json/sakura/v1/database/update
*/
-function update_manifest_json() {
+function update_database() {
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$user = wp_authenticate($username, $password);
@@ -386,24 +391,45 @@ function update_manifest_json() {
if (in_array('administrator', (array) $user->roles)) {
global $wpdb;
$sakura_table_name = $wpdb->base_prefix.'sakura';
- $manifest = array(
- "key" => "manifest_json",
- "value" => file_get_contents($_FILES["manifest"]["tmp_name"])
- );
- $time = array(
- "key" => "json_time",
- "value" => date("Y-m-d H:i:s",time())
- );
-
- $wpdb->query("DELETE FROM `wp_sakura` WHERE `mate_key` ='manifest_json'");
- $wpdb->query("DELETE FROM `wp_sakura` WHERE `mate_key` ='json_time'");
- $wpdb->insert($sakura_table_name,$manifest);
- $wpdb->insert($sakura_table_name,$time);
+ if(isset($_FILES["manifest"])) {
+ $manifest = array(
+ "key" => "manifest_json",
+ "value" => file_get_contents($_FILES["manifest"]["tmp_name"])
+ );
+ $time = array(
+ "key" => "json_time",
+ "value" => date("Y-m-d H:i:s",time())
+ );
+ $wpdb->query("DELETE FROM `wp_sakura` WHERE `mate_key` ='manifest_json'");
+ $wpdb->query("DELETE FROM `wp_sakura` WHERE `mate_key` ='json_time'");
+ $wpdb->insert($sakura_table_name,$manifest);
+ $wpdb->insert($sakura_table_name,$time);
+ $message = "manifest.json has been stored into database.";
+ }
+ if(isset($_FILES["rsa"])){
+ if($_FILES["rsa"]["name"]=="public.key"){
+ $pubkey = array(
+ "mate_key" => "pubkey",
+ "mate_value" => file_get_contents($_FILES["rsa"]["tmp_name"])
+ );
+ $wpdb->query("DELETE FROM `wp_sakura` WHERE `mate_key` ='pubkey'");
+ $wpdb->insert($sakura_table_name,$pubkey);
+ }
+ if($_FILES["rsa"]["name"]=="private.key"){
+ $privkey = array(
+ "mate_key" => "privkey",
+ "mate_value" => file_get_contents($_FILES["rsa"]["tmp_name"])
+ );
+ $wpdb->query("DELETE FROM `wp_sakura` WHERE `mate_key` ='privkey'");
+ $wpdb->insert($sakura_table_name,$privkey);
+ }
+ $message = "key pairs has been stored into database.";
+ }
$output = array(
'status' => 200,
'success' => true,
- 'message' => 'manifest.json has been stored into database'
+ 'message' => $message
);
$result = new WP_REST_Response($output, 200);
$result->set_headers(array('Content-Type' => 'application/json'));
@@ -420,3 +446,19 @@ function update_manifest_json() {
return $result;
}
}
+
+/**
+ * QQ头像链接解密
+ */
+function get_qq_avatar(){
+ global $sakura_privkey;
+ $qq_number=$_GET["qq"];
+ $encrypted = urldecode(base64_decode($qq_number));
+ openssl_private_decrypt($encrypted, $qq_number, openssl_pkey_get_private($sakura_privkey));
+ preg_match('/^\d{3,}$/', $qq_number, $matches);
+ $imgurl='https://q2.qlogo.cn/headimg_dl?dst_uin='.$matches[0].'&spec=100';
+ $response = new WP_REST_Response();
+ $response->set_status(302);
+ $response->header('Location', $imgurl);
+ return $response;
+}
diff --git a/manifest/manifest.py b/manifest/manifest.py
index 4504583..941b3fd 100644
--- a/manifest/manifest.py
+++ b/manifest/manifest.py
@@ -10,6 +10,7 @@ import json
import requests
import base64
import hashlib
+from Crypto.PublicKey import RSA
from PIL import Image
class Single(object):
@@ -43,47 +44,82 @@ class Single(object):
'webp': [self.webp, self.webp_th]
}
- #这个最好新建一个类
- def upload_manifest(self):
- username = input('Enter your username: ')
- password = input('Enter your password: ')
- url = input('Enter your rest api url: ')
- data_string = username + ':' + password
+ def main(self):
+ self.hash()
+ # if os.path.exists(self.jpeg) and os.path.exists(self.webp):
+ self.optimize()
+ self.manifest()
+ return self.mani
+
+
+class Upload2Wordpress:
+ def __init__(self, username, password, url):
+ self.username = username
+ self.password = password
+ self.url = url
+
+ def upload(self, file, field):
+ data_string = self.username + ':' + self.password
token = base64.b64encode(data_string.encode()).decode('utf-8')
headers = {
'Authorization': 'Basic ' + token,
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97"
}
- files = {'manifest': open('manifest.json', mode="rb")}
- reply = requests.post(url, headers=headers, files=files)
+ files = {field: open(file, mode="rb")}
+ reply = requests.post(self.url, headers=headers, files=files)
print(json.loads(reply.content)['message'])
- def main(self):
- self.hash()
- # if os.path.exists(self.jpeg) and os.path.exists(self.webp):
- self.optimize()
- self.thumbnail()
- self.manifest()
- return self.mani
+ def upload_manifest(self):
+ print('start uploading `manifest.json`...')
+ self.upload('manifest.json', 'manifest')
-def main():
+ def upload_key(self):
+ print('start uploading `private.key`...')
+ self.upload('private.key', 'rsa')
+ print('start uploading `public.key`...')
+ self.upload('public.key', 'rsa')
+
+ def main(self):
+ self.upload_manifest()
+ self.upload_key()
+
+
+def gen_manifest_json():
onlyfiles = [f for f in os.listdir('gallary') if os.path.isfile(os.path.join('gallary', f))]
id = 1
Manifest = {}
-
for f in onlyfiles:
- worker = Single(f, Manifest)
- Manifest = worker.main()
- print(str(id) + '/' + str(len(onlyfiles)))
- id += 1
-
+ worker = Single(f, Manifest)
+ Manifest = worker.main()
+ print(str(id) + '/' + str(len(onlyfiles)))
+ id += 1
with open('manifest.json', 'w+') as json_file:
json.dump(Manifest, json_file)
- up_json = Single(f, Manifest)
- up_json.upload_manifest()
+
+def gen_key_pairs():
+ key = RSA.generate(1024)
+ pv_key_string = key.exportKey()
+ with open("private.key", "w+") as prv_file:
+ print("{}".format(pv_key_string.decode()), file=prv_file)
+ pb_key_string = key.publickey().exportKey()
+ with open("public.key", "w+") as pub_file:
+ print("{}".format(pb_key_string.decode()), file=pub_file)
+
+
+def main():
+ gen_manifest_json()
+ if not os.path.exists("public.key") or not os.path.exists("private.key"):
+ print("start generating key pairs...")
+ gen_key_pairs()
+ username = input('Enter your username: ')
+ password = input('Enter your password: ')
+ url = input('Enter your rest api url: ')
+ upload = Upload2Wordpress(username, password, url)
+ upload.main()
+
if __name__ == '__main__':
main()
- key = input('`manifest.json` saved. Press any key to quit.')
+ key = input('`manifest.json` saved. Press any key to quit.')
quit()
diff --git a/options.php b/options.php
index a9171a7..e659e49 100644
--- a/options.php
+++ b/options.php
@@ -1135,6 +1135,13 @@ function optionsframework_options() {
'std' => '0',
'type' => 'checkbox');
+ $options[] = array(
+ 'name' => __('QQ avatar link encryption', 'sakura'),/*QQ头像链接加密*/
+ 'desc' => __('Check to enable, do not display the user\'s qq avatar links directly.', 'sakura'),/*勾选开启,不直接暴露用户qq头像链接*/
+ 'id' => 'qq_avatar_link',
+ 'std' => '0',
+ 'type' => 'checkbox');
+
$options[] = array(
'name' => __('Comment UA infomation', 'sakura'),/*评论UA信息*/
'desc' => __('Check to enable, display the user\'s browser, operating system information', 'sakura'),/*勾选开启,显示用户的浏览器,操作系统信息*/