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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
<?php
/**
 * UCenter 应用程序接口 for joomla1.0.x + CB1.0.x版(discuz, xspace等comsenz系程序社区化功能与joomla1.0.x的完美整合)
 * ucenter for joomla,KOLIDON version 1.1
 ucenter支持的各类应用程序中的用户、站内短消息、好友、积分、头像,可自动同步到joomla1.0.x中。
 
 本程序基于comsenz 提供的ucenter开放的API接口进行开发,安装请参见作者个人站点。
 版本1有如下注意事项:
 * 1. 主要实现用户数据自动同步至joomla(comprofiler组件),已用于实际站点zhonghuayixue.com并运行良好;
 * 2. 用户在discuz或supesite中注册、登录、更改用户名、更改密码,joomla数据表及comprofiler组件数据表中数据均能同步;
 * 3. 请确保joomla中用户最大id小于discuz中最小id(在ucenter中多添几个用户,添至比joomla多即可);
 
 版本2:joomla内即可直接完成整站登录、注册及修改密码功能(已完成,当前正在测试Ucenter for joomla1.5.x + CB1.2RC2版);
 版本3:积分系统  (即将开始,经测试稳定后,预定于月末放出)
 版本4:支持站内短消息、头像的全站同步、支持旧有joomla用户数据一键同步至ucenter(国庆期间放出)
 版本5:支持comprofiler兼容版本joomla1.0及joomla1.5
 * @Author:	kolidon@gmail.com
 * @Site:	http://blog.treeber.com
 * licensing under CCA3.0
 **/
 
define('UC_VERSION', '1.0.0');		//UCenter 版本标识
 
define('API_DELETEUSER', 1);		//用户删除 API 接口开关
define('API_RENAMEUSER', 1);		//用户改名 API 接口开关
define('API_UPDATEPW', 1);		//用户改密码 API 接口开关
define('API_GETTAG', 0);		//获取标签 API 接口开关
define('API_SYNLOGIN', 1);		//同步登录 API 接口开关
define('API_SYNLOGOUT', 1);		//同步登出 API 接口开关
define('API_UPDATEBADWORDS', 0);	//更新关键字列表 开关
define('API_UPDATEHOSTS', 1);		//更新域名解析缓存 开关
define('API_UPDATEAPPS', 1);		//更新应用列表 开关
define('API_UPDATECLIENT', 1);		//更新客户端缓存 开关
define('API_UPDATECREDIT', 0);		//更新用户积分 开关
define('API_GETCREDITSETTINGS', 1);	//向 UCenter 提供积分设置 开关
define('API_UPDATECREDITSETTINGS', 0);	//更新应用积分设置 开关
 
define('API_RETURN_SUCCEED', '1');
define('API_RETURN_FAILED', '-1');
define('API_RETURN_FORBIDDEN', '-2');
 
//error_reporting(E_ALL);
 
//joomla library include files check this constant;
define( '_VALID_MOS', 1 );
define('UC_API', 1);
define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
 
 
define('S_ROOT', substr(dirname(__FILE__), 0, -3));
define('UC_CLIENT_ROOT', S_ROOT.'./uc_client/');
 
include_once('func_joomla_cb_user.inc.php');
include_once(S_ROOT.'./configuration.php');
include_once(UC_CLIENT_ROOT.'./client.php');
include_once(S_ROOT.'./includes/joomla.php');
 
 
$code = $_GET['code'];
parse_str(uc_authcode($code, 'DECODE', UC_KEY), $get);
 
 
if(MAGIC_QUOTES_GPC) {
	$get = dstripslashes($get);
}
 
 
if(time() - $get['time'] > 3600) {
	exit('Authracation has expiried');
}
if(empty($get)) {
	exit('Invalid Request');
}
$action = $get['action'];
$timestamp = time();
 
 
if($action == 'test') {
 
	exit(API_RETURN_SUCCEED);
 
} elseif($action == 'deleteuser') {
 
	!API_DELETEUSER && exit(API_RETURN_FORBIDDEN);
 
	//删除用户 API 接口
	$uids = $get['ids'];
 
	//todo:: clean all the content\pictures\files\videos, set their userid to 0
 
	//delete the user in joomla systable and comprofiler
	$database->setQuery("DELETE FROM #__users WHERE id IN ($uids);");
	$database->query();
 
	$database->setQuery("select aro_id FROM #__core_acl_aro WHERE value IN ($uids);");
	$aro_id = $database->loadResult();
 
	$database->setQuery("DELETE FROM #__core_acl_groups_aro_map WHERE aro_id IN ($aro_id);");
	$database->query();
 
	$database->setQuery("DELETE FROM #__core_acl_aro WHERE `value` IN ($uids);");
	$database->query();
 
	$database->setQuery("DELETE FROM #__comprofiler WHERE user_id IN ($uids);");
	$database->query();
 
	exit(API_RETURN_SUCCEED);
 
} elseif($action == 'renameuser') {
 
	!API_RENAMEUSER && exit(API_RETURN_FORBIDDEN);
 
	//用户改名 API 接口
	$id = $get['uid'];
	$usernamenew = $get['newusername'];
	$activeuser = uc_get_user($id, 1);
 
	//todo, the very first,we need to syn all the user table to prevent the username or id collision
	//Now we imagine everything is ok
 
	//if joomla user not exsits, add it
	checkuserexists_user($activeuser);
	$database->setQuery("update #__users set username='$usernamenew' WHERE id IN ($id);");
	$database->query();
 
	//if user in comprofiler not exsits, add it
	checkuserexists_comprofiler($activeuser);
 
	exit(API_RETURN_SUCCEED);
 
} elseif($action == 'updatepw') {
 
	!API_UPDATEPW && exit(API_RETURN_FORBIDDEN);
 
	$username = $get['username'];
	$password = $get['password'];
 
	$activeuser = uc_get_user($username);
	checkuserexists_user($activeuser);
	checkuserexists_comprofiler($activeuser);
 
	$database->setQuery("update #__users set password='". md5($password) ."' WHERE username ='$username';");
	$database->query();
 
	exit(API_RETURN_SUCCEED);
 
} elseif($action == 'synlogin' && $_GET['time'] == $get['time']) {
	//echo "hello";
	!API_SYNLOGIN && exit(API_RETURN_FORBIDDEN);
 
	//同步登录 API 接口
	$id = intval($get['uid']);
 
	// is uer exists?
	$activeuser = uc_get_user($id, 1);
 
	checkuserexists_user($activeuser);
	checkuserexists_comprofiler($activeuser);
 
	//include the joomla, need to get the session id
	$mainframe = new mosMainFrame( $database, '', '.' );
	$mainframe->initSession();
 
	//select username, password from #__users and make login
	//so whenever the original joomla passwd true or false, the user can login successfully
	$database->setQuery("select username, password from #__users where id=$id");
	list($username, $password) = $database->loadRow();
	$mainframe->login($username, $password, 0, $id);
 
} elseif($action == 'synlogout') {
 
	!API_SYNLOGOUT && exit(API_RETURN_FORBIDDEN);
 
	//同步登出 API 接口
	//include the joomla, need to get the session id
	$mainframe = new mosMainFrame( $database, '', '.' );
	$mainframe->initSession();
	$mainframe->logout();
} else {
	exit(API_RETURN_FAILED);
}
 
 
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
 
	$ckey_length = 4;
 
	$key = md5($key ? $key : UC_KEY);
	$keya = md5(substr($key, 0, 16));
	$keyb = md5(substr($key, 16, 16));
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
 
	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);
 
	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);
 
	$result = '';
	$box = range(0, 255);
 
	$rndkey = array();
	for($i = 0; $i <= 255; $i++) {
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}
 
	for($j = $i = 0; $i < 256; $i++) {
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}
 
	for($a = $j = $i = 0; $i < $string_length; $i++) {
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}
 
	if($operation == 'DECODE') {
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
			return substr($result, 26);
		} else {
			return '';
		}
	} else {
		return $keyc.str_replace('=', '', base64_encode($result));
	}
 
}
 
 
function dsetcookie($var, $value, $life = 0, $prefix = 1) {
	global $cookiedomain, $cookiepath, $timestamp, $_SERVER;
	setcookie($var, $value,
		$life ? $timestamp + $life : 0, $cookiepath,
		$cookiedomain, $_SERVER['SERVER_PORT'] == 443 ? 1 : 0);
}
 
function dstripslashes($string) {
	if(is_array($string)) {
		foreach($string as $key => $val) {
			$string[$key] = dstripslashes($val);
		}
	} else {
		$string = stripslashes($string);
	}
	return $string;
}