Rose debug info
---------------

3 часть, «кропотливая работа и долгожданный успех»

1 часть, «как нельзя относиться к корпоративным клиентам»
2 часть, «анализ, получение исходных данных»

Сделай шаг — дорога появится сама собой…

и мы приступим...

вот требования graphisoft к сложности паролей:
Ваш пароль должен:

  • содержать не менее 6 символов
  • содержать не менее одной буквы
  • содержать не менее одной заглавной буквы
  • содержать не менее одной цифры
  • отличаться от вашего адреса электронной почты
  • не содержать пробелов, знаков препинания, специальных или национальных символов.

для начала хочу показать небольшую функцию для генерации паролей, фишка в том, что пароль должен содержать минимум две цифры, да-да... хрен вы зарегистрируетесь с одной цифрой, короче ловите функцию

function randomPassword() {
    $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    $pass = array();
    $alphaLength = strlen($alphabet) - 1;
    for ($i = 0; $i < 10; $i++) {
        $n = rand(0, $alphaLength);
        $pass[] = $alphabet[$n];
    }
	$password = implode($pass);
	$password = substr_replace($password, rand(0,9), rand(1,3), 0);
	$password = substr_replace($password, rand(0,9), rand(4,7), 0);
    return $password;
}

сразу оговорюсь, при регистрации 150 учёток ни разу не споткнулась 😇

ну, вроде всё готово для реализации проекта.

Настоятельно рекомендую зайти на первую страницу и сохранить cookie, чтобы было максимально похоже на действия человека. Так же часто не отправляйте запросы, я регистрировал по одному сотруднику раз в пять минут, все таки есть опасность словить captcha. Большая активность — подозрительна. А так, раз в пять минут за ночь и пол дня всех зарегистрировал.

Не буду грузить, расписывая каждое действие, пройдусь по самым главным моментам.
При отправке данных используется три метода передачи:

  • GET
  • POST
  • PUT

пришлось их все учитывать в одной функции, чтобы не плодить сущностей

так же данные формируются разными форматами

  • application/json
  • application/x-www-form-urlencoded

я сейчас выложу мою монстровую функцию

function get_url($url, $method, $ctype, $referer, $data) {
	// $url - ссылка, на страницу
	// $method - метод передачи (GET, POST или PUT)
	// $ctype - 1, 2 или 3, смотри ниже
	// $referer - страница, с которой мы, якобы, перешли
	// $data - данные, если отправляем форму
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
	if ($data!=='') {
		if ($ctype == 1) {
			// если тип данных json
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
		} else if ($ctype == 2) {
			// если тип данных www-form
			curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
		} else if ($ctype == 3) {
			// сложная конструкция, когда нам надо работать с полученным заголовком, чтобы вытащить оттуда token авторизации
			curl_setopt($ch, CURLOPT_HEADER, 1);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
			curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
		}
	}
	curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
	// формируем заголовок запроса
	$headers = array();
	$headers[] = 'Connection: keep-alive';
	$headers[] = 'Sec-Ch-Ua: \" Not;A Brand\";v=\"99\", \"Opera\";v=\"79\", \"Chromium\";v=\"93\"';
	$headers[] = 'Dnt: 1';
	$headers[] = 'Sec-Ch-Ua-Mobile: ?0';
	$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 OPR/79.0.4143.22';
	if ($ctype == 1) {
		// если тип данных json
		$headers[] = 'Content-Type: application/json; charset=UTF-8';
	} else {
		// если тип данных www-form
		$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
	}
	$headers[] = 'Accept: application/json, text/javascript, */*; q=0.01';
	$headers[] = 'X-Requested-With: XMLHttpRequest';
	$headers[] = 'Sec-Ch-Ua-Platform: \"Windows\"';
	$headers[] = 'Sec-Fetch-Site: same-origin';
	$headers[] = 'Sec-Fetch-Mode: cors';
	$headers[] = 'Sec-Fetch-Dest: empty';
	$headers[] = 'Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7';
	$headers[] = 'Origin: '.$referer;
	$headers[] = 'Referer: '.$referer;
	// используем сформированный заголовок
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	// подключаем файл с cookie, сразу в него сохраняем и из него читаем
	curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');
	curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt');
	$response = curl_exec($ch);
	// используем глобальную переменную, чтобы получить token авторизации, который возвращается в header
	global $header;
	$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
	$header = substr($response, 0, $header_size);
	// возвращаем результатом полученный текст
	return $response;
	if (curl_errno($ch)) {
		echo 'Error:' . curl_error($ch);
	}
	curl_close($ch);
}

вот такая страхолюдина получилась в итоге

все действия по шагам:

  1. заполняем форму регистрации и отправляем запрос
    • открываем главную страницу
    • переходим на страницу личного кабинета
    • проверяем, зарегистрирован ли уже e-mail
    • генерируем пароль
    • отправляем форму с данными
  2. подтверждаем регистрацию
    • результатом отправки регистрационной формы будет json с кодом подтверждения регистрации (ура! не надо лезть в почту пользователя и искать письмо)
    • в этом же json получаем graphisoft id пользователя, потребуется позже
    • подтверждаем регистрацию двумя запросами, как оказалось второй запрос тоже необходим
  3. заходим в кабинет администратора и отправляем запрос на присоединение пользователя
    • аккуратно логинемся в кабинет, получаем json с данными организации, на потребуется graphisoft id организации, для создания запроса на присоединение пользователя
    • формируем и отправляем запрос
  4. заходим в кабинет пользователя и подтверждаем запрос
    • аккуратно логинемся в кабинет пользователя
    • формируем запрос и подтверждаем присоединение к компании

ну и сам код:

<?php

// данные регистрируемого сотрудника
$fname = 'Иван';
$sname = 'Петров';
$email = 'user@domain.ru';
$pasword = 'koo0ovo5Kamu';

// данные администратора компании
$admin_login = 'admin@domain.ru';
$admin_password = 'P@5$w0rD';

$header = '';

function get_url($url, $method, $ctype, $referer, $data) {
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
	if ($data!=='') {
		if ($ctype == 1) {
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
		} else if ($ctype == 2) {
			curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
		} else if ($ctype == 3) {
			curl_setopt($ch, CURLOPT_HEADER, 1);
			curl_setopt($ch, CURLOPT_POST, 1);
			curl_setopt($ch, CURLOPT_FOLLOWLOCATION, FALSE);
			curl_setopt($ch, CURLOPT_POSTFIELDS,http_build_query($data));
		}
	}
	curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
	$headers = array();
	$headers[] = 'Connection: keep-alive';
	$headers[] = 'Sec-Ch-Ua: \" Not;A Brand\";v=\"99\", \"Opera\";v=\"79\", \"Chromium\";v=\"93\"';
	$headers[] = 'Dnt: 1';
	$headers[] = 'Sec-Ch-Ua-Mobile: ?0';
	$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 OPR/79.0.4143.22';
	if ($ctype == 1) {
		$headers[] = 'Content-Type: application/json; charset=UTF-8';
	} else {
		$headers[] = 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8';
	}
	$headers[] = 'Accept: application/json, text/javascript, */*; q=0.01';
	$headers[] = 'X-Requested-With: XMLHttpRequest';
	$headers[] = 'Sec-Ch-Ua-Platform: \"Windows\"';
	$headers[] = 'Sec-Fetch-Site: same-origin';
	$headers[] = 'Sec-Fetch-Mode: cors';
	$headers[] = 'Sec-Fetch-Dest: empty';
	$headers[] = 'Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7';
	$headers[] = 'Origin: '.$referer;
	$headers[] = 'Referer: '.$referer;
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).'/cookie.txt');
	curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).'/cookie.txt');
	$response = curl_exec($ch);
	global $header;
	$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
	$header = substr($response, 0, $header_size);
	return $response;
	if (curl_errno($ch)) {
		echo 'Error:' . curl_error($ch);
	}
	curl_close($ch);
}

// удаляем старые куки
if (file_exists(dirname(__FILE__).'/cookie.txt')) {
   unlink(dirname(__FILE__).'/cookie.txt');
}		
// заходим на главную
get_url('https://graphisoft.com/ru','GET',1,'','');
// переходим на форму пользователя
get_url('https://graphisoftid.graphisoft.com/Account/ServiceLogin?Application=GRAPHISOFT&ReturnUrl=https://graphisoft.com/ru','GET',1,'https://graphisoftid.graphisoft.com/','');
// переходим на форму регистрации
get_url('https://graphisoftid.graphisoft.com/#/register/3/https%3a%2f%2fgraphisoft.com%2fru','GET',1,'https://graphisoftid.graphisoft.com/','');

//проверяем e-mail
$check_mail = get_url('https://graphisoftid.graphisoft.com/api/user/CheckEmail/','PUT',2,'https://graphisoftid.graphisoft.com/',array("EmailAddress" => $email));
if ($check_mail == 'true') {
	$data = array('applicationName' => null,
				  'customDataObject' => null,
				  'redirectUrl' => null,
				  'emailHintLocalizationKey' => null,
				  'firstName' => $fname,
				  'lastName' => $sname,
				  'isValidated' => true,
				  'email' => $email,
				  'password' => $pasword,
				  'confirmPassword' => $pasword,
				  'isPrivacyPolicyAccepted' => true,
				  'companyName' => 'ООО "Рога и Копыта"',
				  'countryId' => 186,
				  'federated' => false,
				  'callbackUrl' => 'https://graphisoft.com/ru',
				  'isDirty' => true,
				  'errors' => array());

	//echo json_encode($data)."\n";

	$ecoded_json = get_url('https://graphisoftid.graphisoft.com/api/user/CreateUser','POST',1,'https://graphisoftid.graphisoft.com/',$data);

	$jsonObj = json_decode($ecoded_json);

	if ($jsonObj === null && json_last_error() !== JSON_ERROR_NONE) {
	   echo "у меня не получилось отправить регистрационную форму с данными...  извините\n";
	} else {
		// удаляем старые куки
		unlink(dirname(__FILE__).'/cookie.txt');
		get_url($jsonObj->{'VerificationURL'}.$jsonObj->{'VerificationCode'},'GET',1,'','');
		$gsid_url = get_url('https://graphisoftid.graphisoft.com/api/user/VerifyUser','PUT',2,'https://graphisoftid.graphisoft.com/',array("code" => $jsonObj->{'VerificationCode'}));
		$parts = parse_url($gsid_url);
		parse_str($parts['query'], $query);
		$user_gsid = $query['gsid'];
		if ($user_gsid !== '') {
			echo "пользователь ".$email." успешно зарегистрирован (Graphisoft sid: ".$user_gsid.")\n";
			// удаляем старые куки
			unlink(dirname(__FILE__).'/cookie.txt');
			// заходим на главную
			get_url('https://graphisoft.com/ru','GET',1,'','');
			get_url('https://graphisoftid.graphisoft.com/','GET',1,'','');
			// авторизуемся под пользователем
			$data = array('email' => $admin_login,
						  'errors' => array(),
						  'isDirty' => true,
						  'isNullo' => false,
						  'password' => $admin_password);			
			$json_response = get_url('https://graphisoftid.graphisoft.com/api/Authenticate/Login','POST',1,'https://graphisoftid.graphisoft.com/',$data);
			$obj = json_decode($json_response);
			$companyGsId = $obj->{'Company'}->{'GsId'};
			// Загружаем список подключенных пользователей
			foreach ($obj->{'Company'}->{'CompanyUsers'} as $user) {
				$users_list[] = array("FirstName" => $user->{'FirstName'},"LastName" => $user->{'LastName'},"EmailAddress" => $user->{'EmailAddress'},"GsId" => $user->{'GsId'});
			}


			$data = array('companyGsId' => $companyGsId,
						  'email' => $email,
						  'errors' => array(),
						  'isDirty' => true,
						  'requestedGraphisoftUserId' => $user_gsid);
			get_url('https://graphisoftid.graphisoft.com/api/user/SendInvitation','PUT',2,'https://graphisoftid.graphisoft.com/',$data);
			echo "выслано приглашение присоединиться к компании\n";
			// удаляем старые куки
			unlink(dirname(__FILE__).'/cookie.txt');
			// переходим на форму пользователя
			get_url('https://graphisoftid.graphisoft.com/','GET',1,'','');
			// авторизуемся под пользователем
			$data = array('email' => $email,
						  'errors' => array(),
						  'isDirty' => true,
						  'isNullo' => false,
						  'password' => $pasword);			
			$json_response = get_url('https://graphisoftid.graphisoft.com/api/Authenticate/Login','POST',1,'https://graphisoftid.graphisoft.com/',$data);
			$obj = json_decode($json_response);
			$user_gsid = $obj->{'GraphisoftUser'}->{'GsId'};
			if ($user_gsid == '') {
				echo "не смог зайти под пользователем в личный кабинет\n";
			} else {
				$data = array('actionId' => 2,
							  'companyGsId' => $companyGsId,
							  'graphisoftUserGsId' => $user_gsid,
							  'reactionId' => 1);
				get_url('https://graphisoftid.graphisoft.com/api/user/ProcessingPendingRequest','PUT',1,'https://graphisoftid.graphisoft.com/',$data);
				echo "сотрудник подтвердил приглашение\n";
			}
		} else {
			echo "у меня не получилось подтвердить регистрацию...  извините\n";
		}
	}
} else {
	echo "$email уже зарегистрирован в системе\n";
}
// удаляем старые куки
unlink(dirname(__FILE__).'/cookie.txt');
?>

спасибо тем, кто дочитал до конца

Поделиться
Отправить
Запинить
 17   28 дн   ArchiCAD   Graphisoft   id   php   автоматизация