作者 邓超

login

... ... @@ -244,3 +244,34 @@ CREATE TABLE `system` (
SET FOREIGN_KEY_CHECKS=1;
INSERT INTO `system` (`name`, `value`) VALUES ('roundcube-version', '2020122900');
CREATE TABLE `email_server_address` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`mail_suffix` varchar(20) NOT NULL DEFAULT '' COMMENT '邮件后缀',
`imap` varchar(50) NOT NULL DEFAULT '' COMMENT 'imap服务器地址',
`smtp` varchar(50) NOT NULL DEFAULT '' COMMENT 'stmp服务器地址',
`service_provider` varchar(50) NOT NULL DEFAULT '' COMMENT '服务商名称',
PRIMARY KEY (`id`),
KEY `mail_suffix` (`mail_suffix`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='email服务器地址';
CREATE TABLE `platform_users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`platform_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT ' platform 表id',
`user_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT 'user表id',
`platform_user_id` int(10) unsigned NOT NULL COMMENT '接入平台的用户id',
`created_at` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `platform` (`platform_id`,`platform_user_id`,`user_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='接入平台,用户关系表';
CREATE TABLE `platform` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '' COMMENT '那个平台',
`appid` int(1) unsigned NOT NULL DEFAULT '0' COMMENT 'appid',
`appkey` varchar(64) NOT NULL DEFAULT '' COMMENT 'key,来源验证使用',
`status` tinyint(1) unsigned NOT NULL DEFAULT '1' COMMENT '1,正常使用,0禁止使用',
`ip` varchar(64) NOT NULL DEFAULT '' COMMENT 'ipv6,ipv4,ip白名单',
PRIMARY KEY (`id`),
UNIQUE KEY `appid` (`appid`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='平台';
\ No newline at end of file
... ...
<?php
/**
+-------------------------------------------------------------------------+
| Roundcube Webmail IMAP Client |
| Version 1.5.3 |
| |
| Copyright (C) The Roundcube Dev Team |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License (with exceptions |
| for skins & plugins) as published by the Free Software Foundation, |
| either version 3 of the License, or (at your option) any later version. |
| |
| This file forms part of the Roundcube Webmail Software for which the |
| following exception is added: Plugins and Skins which merely make |
| function calls to the Roundcube Webmail Software, and for that purpose |
| include it by reference shall not be considered modifications of |
| the software. |
| |
| If you wish to use this file in another project or create a modified |
| version that will not be part of the Roundcube Webmail Software, you |
| may remove the exception above and use this source code under the |
| original version of the license. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see http://www.gnu.org/licenses/. |
| |
+-------------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-------------------------------------------------------------------------+
*/
+-------------------------------------------------------------------------+
| Roundcube Webmail IMAP Client |
| Version 1.5.3 |
| |
| Copyright (C) The Roundcube Dev Team |
| |
| This program is free software: you can redistribute it and/or modify |
| it under the terms of the GNU General Public License (with exceptions |
| for skins & plugins) as published by the Free Software Foundation, |
| either version 3 of the License, or (at your option) any later version. |
| |
| This file forms part of the Roundcube Webmail Software for which the |
| following exception is added: Plugins and Skins which merely make |
| function calls to the Roundcube Webmail Software, and for that purpose |
| include it by reference shall not be considered modifications of |
| the software. |
| |
| If you wish to use this file in another project or create a modified |
| version that will not be part of the Roundcube Webmail Software, you |
| may remove the exception above and use this source code under the |
| original version of the license. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program. If not, see http://www.gnu.org/licenses/. |
| |
+-------------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-------------------------------------------------------------------------+
*/
// include environment
require_once 'program/include/iniset.php';
... ... @@ -49,6 +49,44 @@ $RCMAIL->output->common_headers(!empty($_SESSION['user_id']));
// turn on output buffering
ob_start();
// 测试链接
//?_platform=login&platform=2022072201&platform_user_id=1&sign=1
// TODO::测试链接
if(rcube_utils::get_input_value('_task', rcube_utils::INPUT_GET) == 'test'){
header("location:/?_platform=login&platform=2022072201&platform_user_id=1&sign=".(rcube_platform::create_token(1,2022072201,'BMeCgIi367f6lJ53dJI6dQ13u2NxLEqJuVaS8xgcXqw1pDdcjYa7MfWB2V6WWYjY')));
exit();
}
// 平台登录
if(rcube_utils::get_input_value('_platform', rcube_utils::INPUT_GET) == 'login'){
// 平台用户id
$platform_user_id = rcube_utils::get_input_value('platform_user_id', rcube_utils::INPUT_GET);
$appid = rcube_utils::get_input_value('platform', rcube_utils::INPUT_GET);
$sign = rcube_utils::get_input_value('sign', rcube_utils::INPUT_GET);
// 验证加密签名
if(rcube_platform::check_token($platform_user_id,$appid,$sign)){
setcookie('platform_user_id',$platform_user_id);
setcookie('platform_appid',$appid);
setcookie('platform_id',(new rcube_platform())->getIdByAppId($appid));
//
}else{
setcookie('platform_user_id','0');
setcookie('platform_appid','0');
setcookie('platform_id','0');
}
}
// 是否验证过平台来源,当前访问回话没有验证来源
if(empty($_COOKIE['platform_user_id'])||empty($_COOKIE['platform_appid'])){
rcmail::raise_error(['code' => 403, 'message' => '你没有权限访问'], false, true);
//}else{
// 验证平台是否正常使用
// $platform = (new rcube_platform())->firstByAppId($_SESSION['platform_appid']);
// if($platform['status'] == rcube_platform::STATUS_DISABLED){
// rcmail::raise_error(['code' => 403, 'message' => '你没有权限访问'], false, true);
// }
}
// check if config files had errors
if ($err_str = $RCMAIL->config->get_error()) {
rcmail::raise_error(['code' => 601, 'message' => $err_str], false, true);
... ... @@ -120,9 +158,23 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
]);
// Login
if ($auth['valid'] && !$auth['abort']
&& $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], $auth['cookiecheck'])
) {
$is_login = $auth['valid'] && !$auth['abort'] && $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'], $auth['cookiecheck']);
if($is_login){
// 登录成功,创建绑定关系
$platform_user = (new rcube_platform_users())->create($_COOKIE['platform_id'],$RCMAIL->user->ID,$_COOKIE['platform_user_id']);
// 创建成功
if($platform_user){
// platform_user表的自增id
$_SESSION['table_platform_user_pk_id'] = $platform_user['id'];
// 当前选中操作的用户id
$_SESSION['selected_user_id'] = $RCMAIL->user->ID;
}else{
$RCMAIL->kill_session();
$is_login = false;
$auth['error'] = $RCMAIL->output->show_message('loginfailed', 'warning');
}
}
if ($is_login) {
// create new session ID, don't destroy the current session
// it was destroyed already by $RCMAIL->kill_session() above
$RCMAIL->session->remove('temp');
... ...
... ... @@ -37,26 +37,27 @@ class help extends rcube_plugin
function startup($args)
{
$rcmail = rcmail::get_instance();
if (!$rcmail->output->framed) {
// add taskbar button
$this->add_button([
'command' => 'help',
'class' => 'button-help',
'classsel' => 'button-help button-selected',
'innerclass' => 'button-inner',
'label' => 'help.help',
'type' => 'link',
], 'taskbar'
);
$this->include_script('help.js');
$rcmail->output->set_env('help_open_extwin', $rcmail->config->get('help_open_extwin', false), true);
}
// add style for taskbar button (must be here) and Help UI
$this->include_stylesheet($this->local_skin_path() . '/help.css');
// TODO::帮助按钮
// $rcmail = rcmail::get_instance();
//
// if (!$rcmail->output->framed) {
// // add taskbar button
// $this->add_button([
// 'command' => 'help',
// 'class' => 'button-help',
// 'classsel' => 'button-help button-selected',
// 'innerclass' => 'button-inner',
// 'label' => 'help.help',
// 'type' => 'link',
// ], 'taskbar'
// );
//
// $this->include_script('help.js');
// $rcmail->output->set_env('help_open_extwin', $rcmail->config->get('help_open_extwin', false), true);
// }
//
// // add style for taskbar button (must be here) and Help UI
// $this->include_stylesheet($this->local_skin_path() . '/help.css');
}
function action()
... ...
... ... @@ -49,6 +49,7 @@ class rcmail_action_utils_error extends rcmail_action
$error_title = $rcmail->gettext('errrequestcheckfailed');
$error_text = nl2br($rcmail->gettext('errcsrfprotectionexplain')) . '<p>' . $add . '</p>';
$error_text .= nl2br($ERROR_MESSAGE);
}
// failed request (wrong step in URL)
else if ($ERROR_CODE == 404) {
... ...
... ... @@ -113,6 +113,19 @@ class rcmail extends rcube
// Remember default skin, before it's replaced by user prefs
$this->default_skin = $this->config->get('skin');
// 当前登录平台关系的用户id platform_users表的自增id
// 查询当前用户
// $platform_users = (new rcube_platform_users($this->get_dbh()))->firstById(($_SESSION['table_platform_users_id']??0));
// if($platform_users){
//
// }
// 当前平台登录用户所选中的user_id;并设置为当前管理的邮箱用户
if(isset($_SESSION['selected_user_id']) && $_SESSION['selected_user_id']){
$_SESSION['user_id'] = $_SESSION['selected_user_id'];
}
// create user object
$this->set_user(new rcube_user(isset($_SESSION['user_id']) ? $_SESSION['user_id'] : null));
... ...
... ... @@ -418,6 +418,26 @@ class rcube_config
}
$result = (string) $result;
}
// 2022-07-22 邮箱服务器
else if($name == 'default_host' || $name == 'smtp_server'){
if(!$result){
$result = [];
$rows = rcube_email_server_address::all($rcube->get_dbh());
foreach ($rows as $row){
$result['imaps'][$row['imap']] = $row['name'];
$result['stmps'][parse_url($row['imap'])['host']] = $row['smtp'];
}
$this->set('default_host',$result['imaps']??[]);
$this->set('smtp_server',$result['stmps']??[]);
$result = $name == 'default_host' ? ($result['imaps']??[]) : ($result['stmps']??[]);
}
}
$plugin = $rcube->plugins->exec_hook('config_get', [
'name' => $name,
... ...
<?php
/**
* 邮件服务商,通过邮件后缀来自动确定要请求的服务商
* @author:dc
* @time 2022/7/22 14:10
* Class rcube_email_server_address
*/
class rcube_email_server_address{
// /**
// * @var int
// */
// public $id = 0;
//
// /**
// * 邮箱后缀
// * qq.com
// * @var string
// */
// public $mail_suffix;
//
// /**
// * ssl://imap.qq.com
// * @var string
// */
// public $imap;
//
// /**
// * smtp.qq.com
// * @var string
// */
// public $smtp;
//
// /**
// * 服务商名称
// * @var string
// */
// public $name;
//
//
// private $rc;
//
// private $db;
//
// public static $rows;
//
/**
* 表
* @var string
*/
// public $table = 'email_server_address';
/**
* Object constructor
*
* @param int $db
*/
// function __construct($db = null)
// {
//
// if(!$db){
// $db = rcube::get_instance()->get_dbh();
// }
// // 查询数据
// $result = $db->query("select * from ". $db->table_name($this->table,true) );
//
// // 获取列表
// $rows = $result->fetchAll(PDO::FETCH_ASSOC);
//
// foreach ($rows as $row){
// static::$rows[$row['mail_suffix']] = [
// 'name' => $row['service_provider'],
// 'smtp' => $row['smtp'],
// 'imap' => $row['imap'],
// ];
// }
//
// $rows = null;
//
// }
public static function all($db = null)
{
if(!$db){
$db = rcube::get_instance()->get_dbh();
}
// 查询数据
$result = $db->query("select * from ". $db->table_name('email_server_address',true) );
// 获取列表
$rows = [];
foreach ($result->fetchAll(PDO::FETCH_ASSOC) as $row){
$rows[$row['mail_suffix']] = [
'name' => $row['service_provider'],
'smtp' => $row['smtp'],
'imap' => $row['imap'],
];
}
return $rows;
}
}
\ No newline at end of file
... ...
<?php
/**
* 接入平台
* @author:dc
* @time 2022/7/22 14:10
* Class rcube_email_server_address
*/
class rcube_platform {
const STATUS_ACTIVE = 1;
const STATUS_DISABLED = 0;
private $db;
/**
* 表
* @var string
*/
public $table;
/**
* rcube_platform constructor.
* @param null $db
*/
public function __construct($db = null)
{
$this->db = $db ? $db : rcube::get_instance()->get_dbh();
$this->table = $this->db->table_name('platform',true);
}
public function lists(){
// 查询数据
$result = $this->db->query("select * from ". $this->table);
return $result->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 查询一条数据
* @param $id
* @return array|false
* @author:dc
* @time 2022/7/23 14:50
*/
public function firstById($id)
{
// 查询数据
$result = $this->db->query("select * from ". $this->table ." where `id` = ? limit 1",$id);
return $this->db->fetch_assoc($result);
}
/**
* 查询一条数据
* @param $appid
* @return array|false
* @author:dc
* @time 2022/7/23 14:50
*/
public function firstByAppId($appid)
{
// 查询数据
$result = $this->db->query("select * from ". $this->table ." where `appid` = ? limit 1",$appid);
return $this->db->fetch_assoc($result);
}
/**
* 根据appid获取id
* @param $appid
* @return int|mixed
* @author:dc
* @time 2022/7/23 15:14
*/
public function getIdByAppId($appid){
// 查询数据
$result = $this->db->query("select `id` from ". $this->table ." where `appid` = ? limit 1",$appid);
$row = $this->db->fetch_assoc($result);
if($row){
return $row['id'];
}
return 0;
}
/**
* 创建验证规则
* @param $user_id
* @param $appid
* @param $appkey
* @return string
* @author:dc
* @time 2022/7/23 9:56
*/
public static function create_token($user_id,$appid,$appkey)
{
// 有效时间一分钟
$sign = md5("ui={$user_id}&ai={$appid}&ak={$appkey}&t=".date('ymdhi'));
return strtoupper($sign);
}
/**
* 验证token规则
* @param $user_id
* @param $appid
* @param $sign
* @return bool
* @author:dc
* @time 2022/7/23 10:00
*/
public static function check_token($user_id,$appid,$sign):bool {
if($sign){
$row = (new static())->firstByAppId($appid);
if($row){
return self::create_token($user_id,$appid,$row['appkey']) === $sign;
}
}
return false;
}
}
\ No newline at end of file
... ...
<?php
/**
* 接入平台的用户
* @author:dc
* @time 2022/7/22 14:10
* Class rcube_platform_users
*/
class rcube_platform_users{
private $db;
/**
* 表
* @var string
*/
public $table;
/**
* rcube_platform constructor.
* @param null $db
*/
public function __construct($db = null)
{
$this->db = $db ? $db : rcube::get_instance()->get_dbh();
$this->table = $this->db->table_name('platform_users',true);
}
public function firstByPlatformUserId($platform_user_id)
{
// 查询数据
$result = $this->db->query("select * from ". $this->table ." where `platform_user_id` = ?",$platform_user_id);
return $this->db->fetch_assoc($result);
}
public function firstById($id){
// 查询数据
$result = $this->db->query("select * from ". $this->table ." where `id` = ?",$id);
return $this->db->fetch_assoc($result);
}
/**
* 创建用户,平台用户
* @param $platform_id
* @param $user_id
* @param $platform_user_id
* @author:dc
* @time 2022/7/23 14:21
*/
public function create($platform_id,$user_id,$platform_user_id){
// 存在,就直接返回
$result = $this->db->query("select `id`,`platform_id`,`user_id`,`platform_user_id` from {$this->table} where `platform_id` = ? and `user_id` = ? and `platform_user_id` = ? limit 1",$platform_id,$user_id,$platform_user_id);
$row = $this->db->fetch_assoc($result);
if($row){
return $row;
}
// 使用参数绑定一样要按照?所排列的字段来,不然会混乱
// 不存在,则新增
$insert = $this->db->query("insert into {$this->table} set `platform_id` = ? , `user_id` = ? , `platform_user_id` = ? , `created_at` = ?",$platform_id,$user_id,$platform_user_id,date('Y-m-d H:i:s'));
if ($insert && $this->db->affected_rows($insert) && ($id = $this->db->insert_id('platform_users'))) {
return $this->firstById($id);
}else{
return false;
}
}
}
\ No newline at end of file
... ...
plugins
skins
\ No newline at end of file
... ...
... ... @@ -33,8 +33,7 @@
<roundcube:add_label name="lightmode" />
<roundcube:button name="theme" label="darkmode" type="link" innerClass="inner" class="theme dark" />
<roundcube:endif />
<roundcube:button name="about" label="about" type="link"
class="about" innerClass="inner" onclick="UI.about_dialog(this)" />
<!-- <roundcube:button name="about" label="about" type="link" class="about" innerClass="inner" onclick="UI.about_dialog(this)" />-->
<roundcube:button command="logout" label="logout" type="link"
class="logout" innerClass="inner" />
</span>
... ...
linux 服务器
public_html目录下没有skins和plugins两个目录的软链接请在 public_html目录下面执行以下命令
ln -s ../skins skins
ln -s ../plugins plugins
如不进行软链接,则无法访问静态文件
... ...