Skip to content

Commit d89e710

Browse files
author
fuze
committed
Метод регистрации пользователя,
различные уточнения и исправления.
1 parent 4c4b61e commit d89e710

File tree

7 files changed

+288
-13
lines changed

7 files changed

+288
-13
lines changed

package/system/controllers/api/actions/method.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ public function run($method_name = null){
146146
);
147147
}
148148

149+
// проверяем sig, если включена проверка
150+
if(!empty($this->method_action->check_sig)){
151+
if(!check_sig($this->request->get('sig', ''))){
152+
return $this->error(115);
153+
}
154+
}
155+
149156
// валидация параметров запроса
150157
$params_error = $this->validateMethodParams();
151158
if($params_error !== false){
@@ -156,8 +163,11 @@ public function run($method_name = null){
156163
if(method_exists($this->method_action, 'validateApiRequest')){
157164
$error = call_user_func_array(array($this->method_action, 'validateApiRequest'), $this->method_params);
158165
if($error !== false){
159-
return $this->error((isset($error['error_code']) ? $error['error_code'] : 100),
160-
(isset($error['error_msg']) ? $error['error_msg'] : ''));
166+
return $this->error(
167+
(isset($error['error_code']) ? $error['error_code'] : 100),
168+
(isset($error['error_msg']) ? $error['error_msg'] : ''),
169+
(isset($error['request_params']) ? $error['request_params'] : array())
170+
);
161171
}
162172
}
163173

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
<?php
2+
3+
class actionAuthApiAuthSignup extends cmsAction {
4+
5+
/**
6+
* Блокировка прямого вызова экшена
7+
* обязательное свойство
8+
* @var boolean
9+
*/
10+
public $lock_explicit_call = true;
11+
/**
12+
* Результат запроса
13+
* обязательное свойство
14+
* @var array
15+
*/
16+
public $result;
17+
/**
18+
* Флаг, обязующий проверять параметр sig запроса
19+
* sig привязан к домену сайта и к ip адресу посетителя
20+
* @var boolean
21+
*/
22+
public $check_sig = true;
23+
24+
/**
25+
* Возможные параметры запроса
26+
* с правилами валидации
27+
* Если запрос имеет параметры, необходимо описать их здесь
28+
* Правила валидации параметров задаются по аналогии с полями форм
29+
* @var array
30+
*/
31+
public $request_params = array();
32+
33+
private $users_model, $user;
34+
35+
public function validateApiRequest() {
36+
37+
if (empty($this->options['is_reg_enabled'])){
38+
return array('error_code' => 323);
39+
}
40+
41+
if (!$this->isIPAllowed(cmsUser::get('ip'))){
42+
43+
return array(
44+
'error_code' => 15,
45+
'error_msg' => strip_tags(sprintf(LANG_AUTH_RESTRICTED_IP, cmsUser::get('ip')))
46+
);
47+
48+
}
49+
50+
$form = $this->getForm('registration');
51+
if(!$form){ return array('error_code' => 1); }
52+
53+
// загружаем модель пользователя
54+
$this->users_model = cmsCore::getModel('users');
55+
56+
//
57+
// Добавляем поле для кода приглашения,
58+
// если регистрация доступна только по приглашениям
59+
//
60+
if ($this->options['is_reg_invites']){
61+
62+
$fieldset_id = $form->addFieldsetToBeginning(LANG_REG_INVITED_ONLY);
63+
64+
$form->addField($fieldset_id, new fieldString('inv', array(
65+
'title' => LANG_REG_INVITE_CODE,
66+
'rules' => array(
67+
array('required'),
68+
array('min_length', 10),
69+
array('max_length', 10)
70+
)
71+
)));
72+
73+
}
74+
75+
//
76+
// Добавляем поле выбора группы,
77+
// при наличии публичных групп
78+
//
79+
$public_groups = $this->users_model->getPublicGroups();
80+
81+
if ($public_groups) {
82+
83+
$pb_items = array();
84+
foreach($public_groups as $pb) { $pb_items[ $pb['id'] ] = $pb['title']; }
85+
86+
$form->addFieldToBeginning('basic',
87+
new fieldList('group_id', array(
88+
'title' => LANG_USER_GROUP,
89+
'items' => $pb_items
90+
)
91+
)
92+
);
93+
94+
}
95+
96+
//
97+
// Добавляем в форму обязательные поля профилей
98+
//
99+
$content_model = cmsCore::getModel('content');
100+
$content_model->setTablePrefix('');
101+
$content_model->orderBy('ordering');
102+
$fields = $content_model->getRequiredContentFields('{users}');
103+
104+
// Разбиваем поля по группам
105+
$fieldsets = cmsForm::mapFieldsToFieldsets($fields);
106+
107+
// Добавляем поля в форму
108+
foreach($fieldsets as $fieldset){
109+
110+
$fieldset_id = $form->addFieldset($fieldset['title']);
111+
112+
foreach($fieldset['fields'] as $field){
113+
if ($field['is_system']) { continue; }
114+
$form->addField($fieldset_id, $field['handler']);
115+
}
116+
117+
}
118+
119+
$user = $form->parse($this->request, true);
120+
121+
$user['groups'] = array();
122+
123+
if (!empty($this->options['def_groups'])){
124+
$user['groups'] = $this->options['def_groups'];
125+
}
126+
127+
if (isset($user['group_id'])) {
128+
if (!in_array($user['group_id'], $user['groups'])){
129+
$user['groups'][] = $user['group_id'];
130+
}
131+
}
132+
133+
//
134+
// убираем поля которые не относятся к выбранной пользователем группе
135+
//
136+
foreach($fieldsets as $fieldset){
137+
foreach($fieldset['fields'] as $field){
138+
if (!$field['groups_edit']) { continue; }
139+
if (in_array(0, $field['groups_edit'])) { continue; }
140+
if (!in_array($user['group_id'], $field['groups_edit'])){
141+
$form->disableField($field['name']);
142+
unset($user[$field['name']]);
143+
}
144+
}
145+
}
146+
147+
$errors = $form->validate($this, $user, false);
148+
149+
if($errors){
150+
151+
return array(
152+
'error_code' => 100,
153+
'error_msg' => '',
154+
'request_params' => $errors
155+
);
156+
157+
}
158+
159+
//
160+
// проверяем код приглашения
161+
//
162+
if ($this->options['is_reg_invites']){
163+
$invite = $this->model->getInviteByCode($user['inv']);
164+
if (!$invite) {
165+
$errors['inv'] = LANG_REG_WRONG_INVITE_CODE;
166+
} else {
167+
if ($this->options['is_invites_strict'] && ($invite['email'] != $user['email'])) {
168+
$errors['inv'] = LANG_REG_WRONG_INVITE_CODE_EMAIL;
169+
} else {
170+
$user['inviter_id'] = $invite['user_id'];
171+
}
172+
}
173+
}
174+
175+
//
176+
// проверяем допустимость e-mail и имени
177+
//
178+
if (!$this->isEmailAllowed($user['email'])){
179+
$errors['email'] = sprintf(LANG_AUTH_RESTRICTED_EMAIL, $user['email']);
180+
}
181+
182+
if (!$this->isNameAllowed($user['nickname'])){
183+
$errors['nickname'] = sprintf(LANG_AUTH_RESTRICTED_NAME, $user['nickname']);
184+
}
185+
186+
if($errors){
187+
188+
return array(
189+
'error_code' => 100,
190+
'error_msg' => '',
191+
'request_params' => $errors
192+
);
193+
194+
}
195+
196+
unset($user['inv']);
197+
198+
//
199+
// Блокируем пользователя, если включена верификация e-mail
200+
//
201+
if ($this->options['verify_email']){
202+
$user = array_merge($user, array(
203+
'is_locked' => true,
204+
'lock_reason' => LANG_REG_CFG_VERIFY_LOCK_REASON,
205+
'pass_token' => string_random(32, $user['email']),
206+
'date_token' => ''
207+
));
208+
}
209+
210+
$result = $this->users_model->addUser($user);
211+
212+
if (!$result['success']){
213+
214+
return array(
215+
'error_code' => 100,
216+
'error_msg' => '',
217+
'request_params' => (array)$result['errors']
218+
);
219+
220+
}
221+
222+
223+
$user['id'] = $result['id'];
224+
225+
cmsUser::setUPS('first_auth', 1, $user['id']);
226+
227+
$this->user = $user;
228+
229+
return false;
230+
231+
}
232+
233+
public function run(){
234+
235+
// отправляем письмо верификации e-mail
236+
if ($this->options['verify_email']){
237+
238+
$messenger = cmsCore::getController('messages');
239+
$to = array('email' => $this->user['email'], 'name' => $this->user['nickname']);
240+
$letter = array('name' => 'reg_verify');
241+
242+
$messenger->sendEmail($to, $letter, array(
243+
'nickname' => $this->user['nickname'],
244+
'page_url' => href_to_abs('auth', 'verify', $this->user['pass_token']),
245+
'pass_token' => $this->user['pass_token'],
246+
'valid_until' => html_date(date('d.m.Y H:i', time() + ($this->options['verify_exp'] * 3600)), true)
247+
));
248+
249+
} else {
250+
251+
cmsEventsManager::hook('user_registered', $this->user);
252+
253+
}
254+
255+
$this->result = array(
256+
'user_id' => $this->user['id'],
257+
'is_verify_email' => (bool) $this->options['verify_email'],
258+
'success_text' => ($this->options['verify_email'] ? sprintf(LANG_REG_SUCCESS_NEED_VERIFY, $this->user['email']) : LANG_REG_SUCCESS)
259+
);
260+
261+
}
262+
263+
}

package/system/controllers/api/api_actions/api_auth_signup_fields.php

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,6 @@ class actionAuthApiAuthSignupFields extends cmsAction {
1515
*/
1616
public $result;
1717

18-
/**
19-
* Возможные параметры запроса
20-
* с правилами валидации
21-
* Если запрос имеет параметры, необходимо описать их здесь
22-
* Правила валидации параметров задаются по аналогии с полями форм
23-
* @var array
24-
*/
25-
public $request_params = array();
26-
2718
public function validateApiRequest() {
2819

2920
if (empty($this->options['is_reg_enabled'])){
@@ -113,7 +104,8 @@ public function run(){
113104

114105
}
115106

116-
$this->result = form_to_params($form);
107+
$this->result['item'] = form_to_params($form);
108+
$this->result['sig'] = get_sig();
117109

118110
}
119111

package/system/controllers/api/api_actions/api_content_get_item.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ public function run($ctype_name){
192192

193193
list($this->ctype, $this->item, $fields) = cmsEventsManager::hook('content_before_item', array($this->ctype, $this->item, $fields));
194194
list($this->ctype, $this->item, $fields) = cmsEventsManager::hook("content_{$this->ctype['name']}_before_item", array($this->ctype, $this->item, $fields));
195+
list($this->ctype, $this->item, $fields) = cmsEventsManager::hook('api_content_before_item', array($this->ctype, $this->item, $fields));
195196

196197
// парсим поля
197198
foreach($fields as $name => $field){

package/system/controllers/api/frontend.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,4 +276,11 @@ function form_to_params($form) {
276276

277277
return $params;
278278

279-
}
279+
}
280+
function get_sig() {
281+
$ip = cmsUser::getIp();
282+
return md5($ip.md5(md5(cmsConfig::get('host')).sprintf('%u',ip2long($ip)).md5(cmsConfig::get('db_pass'))));
283+
}
284+
function check_sig($sig) {
285+
return $sig === get_sig();
286+
}

package/system/languages/en/controllers/api/api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
define('LANG_API_ERROR2', 'Access key is disabled');
2525
define('LANG_API_ERROR23', 'This method was disabled ');
2626
define('LANG_API_ERROR15', 'Access denied');
27+
define('LANG_API_ERROR115', 'Sig parameter is not passed or is incorrect');
2728
define('LANG_API_ERROR100', 'One of the parameters specified was missing or invalid');
2829
define('LANG_API_ERROR8', 'Invalid request ');
2930
define('LANG_API_ERROR12', 'Unable to compile code');

package/system/languages/ru/controllers/api/api.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
define('LANG_API_ERROR2', 'Ключ доступа выключен');
2525
define('LANG_API_ERROR23', 'Метод был выключен');
2626
define('LANG_API_ERROR15', 'Доступ запрещён');
27+
define('LANG_API_ERROR115', 'Параметр sig не передан или является некорректным');
2728
define('LANG_API_ERROR100', 'Один из необходимых параметров был не передан или неверен');
2829
define('LANG_API_ERROR8', 'Неверный запрос');
2930
define('LANG_API_ERROR12', 'Невозможно скомпилировать код');

0 commit comments

Comments
 (0)