<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Воронин: заметки с тегом id</title>
<link>https://voronin.one/tags/id/</link>
<description>воронин, voronin, it</description>
<author></author>
<language>ru</language>
<generator>Aegea 11.4 (v4171)</generator>

<itunes:subtitle>воронин, voronin, it</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>3 часть, «кропотливая работа и долгожданный успех»</title>
<guid isPermaLink="false">3</guid>
<link>https://voronin.one/all/kropotlivaya-rabota-i-dolgozhdanny-uspeh/</link>
<pubDate>Fri, 24 Sep 2021 17:22:16 +0300</pubDate>
<author></author>
<comments>https://voronin.one/all/kropotlivaya-rabota-i-dolgozhdanny-uspeh/</comments>
<description>
&lt;p&gt;&lt;a href="https://voronin.one/all/kak-nelzya-otnositsya-k-korporativnym-klientam/"&gt;1 часть, «как нельзя относиться к корпоративным клиентам»&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://voronin.one/all/analiz-poluchenie-ishodnyh-dannyh/"&gt;2 часть, «анализ, получение исходных данных»&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Сделай шаг — дорога появится сама собой…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_163318.png" width="300" height="225" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;и мы приступим...&lt;/p&gt;
&lt;p&gt;вот требования graphisoft к сложности паролей:&lt;br /&gt;
Ваш пароль должен:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;содержать не менее 6 символов&lt;/li&gt;
&lt;li&gt;содержать не менее одной буквы&lt;/li&gt;
&lt;li&gt;содержать не менее одной заглавной буквы&lt;/li&gt;
&lt;li&gt;содержать не менее одной цифры&lt;/li&gt;
&lt;li&gt;отличаться от вашего адреса электронной почты&lt;/li&gt;
&lt;li&gt;не содержать пробелов, знаков препинания, специальных или национальных символов.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;для начала хочу показать небольшую функцию для генерации паролей, фишка в том, что &lt;b&gt;пароль должен содержать минимум две цифры&lt;/b&gt;, да-да... хрен вы зарегистрируетесь с одной цифрой, короче ловите функцию&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;function randomPassword() {
    $alphabet = &amp;quot;abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789&amp;quot;;
    $pass = array();
    $alphaLength = strlen($alphabet) - 1;
    for ($i = 0; $i &amp;lt; 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;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;сразу оговорюсь, при регистрации 150 учёток ни разу не споткнулась 😇&lt;/p&gt;
&lt;p&gt;ну, вроде всё готово для реализации проекта.&lt;/p&gt;
&lt;p&gt;Настоятельно рекомендую зайти на первую страницу и сохранить cookie, чтобы было максимально похоже на действия человека. Так же часто не отправляйте запросы, я регистрировал по одному сотруднику раз в пять минут,  все таки есть опасность словить captcha. Большая активность — подозрительна. А так, раз в пять минут за ночь и пол дня всех зарегистрировал.&lt;/p&gt;
&lt;p&gt;Не буду грузить, расписывая каждое действие, пройдусь по самым главным моментам.&lt;br /&gt;
При отправке данных используется три метода передачи:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GET&lt;/li&gt;
&lt;li&gt;POST&lt;/li&gt;
&lt;li&gt;PUT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;пришлось их все учитывать в одной функции, чтобы не плодить сущностей&lt;/p&gt;
&lt;p&gt;так же данные формируются разными форматами&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;application/json&lt;/li&gt;
&lt;li&gt;application/x-www-form-urlencoded&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;я сейчас выложу мою монстровую функцию&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;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!==&amp;#039;&amp;#039;) {
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, &amp;#039;gzip, deflate&amp;#039;);
// формируем заголовок запроса
$headers = array();
$headers[] = &amp;#039;Connection: keep-alive&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua: \&amp;quot; Not;A Brand\&amp;quot;;v=\&amp;quot;99\&amp;quot;, \&amp;quot;Opera\&amp;quot;;v=\&amp;quot;79\&amp;quot;, \&amp;quot;Chromium\&amp;quot;;v=\&amp;quot;93\&amp;quot;&amp;#039;;
$headers[] = &amp;#039;Dnt: 1&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua-Mobile: ?0&amp;#039;;
$headers[] = &amp;#039;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&amp;#039;;
if ($ctype == 1) {
// если тип данных json
$headers[] = &amp;#039;Content-Type: application/json; charset=UTF-8&amp;#039;;
} else {
// если тип данных www-form
$headers[] = &amp;#039;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&amp;#039;;
}
$headers[] = &amp;#039;Accept: application/json, text/javascript, */*; q=0.01&amp;#039;;
$headers[] = &amp;#039;X-Requested-With: XMLHttpRequest&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua-Platform: \&amp;quot;Windows\&amp;quot;&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Site: same-origin&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Mode: cors&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Dest: empty&amp;#039;;
$headers[] = &amp;#039;Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7&amp;#039;;
$headers[] = &amp;#039;Origin: &amp;#039;.$referer;
$headers[] = &amp;#039;Referer: &amp;#039;.$referer;
// используем сформированный заголовок
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// подключаем файл с cookie, сразу в него сохраняем и из него читаем
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).&amp;#039;/cookie.txt&amp;#039;);
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).&amp;#039;/cookie.txt&amp;#039;);
$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 &amp;#039;Error:&amp;#039; . curl_error($ch);
}
curl_close($ch);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;вот такая страхолюдина получилась в итоге&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_165916.png" width="300" height="190" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;все действия по шагам:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;заполняем форму регистрации и отправляем запрос
&lt;ul&gt;
  &lt;li&gt;открываем главную страницу&lt;/li&gt;
  &lt;li&gt;переходим на страницу личного кабинета&lt;/li&gt;
  &lt;li&gt;проверяем, зарегистрирован ли уже e-mail&lt;/li&gt;
  &lt;li&gt;генерируем пароль&lt;/li&gt;
  &lt;li&gt;отправляем форму с данными&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;подтверждаем регистрацию
&lt;ul&gt;
  &lt;li&gt;результатом отправки регистрационной формы будет json с кодом подтверждения регистрации (ура! не надо лезть в почту пользователя и искать письмо)&lt;/li&gt;
  &lt;li&gt;в этом же json получаем graphisoft id пользователя, потребуется позже&lt;/li&gt;
  &lt;li&gt;подтверждаем регистрацию двумя запросами, как оказалось второй запрос тоже необходим&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;заходим в кабинет администратора и отправляем запрос на присоединение пользователя
&lt;ul&gt;
  &lt;li&gt;аккуратно логинемся в кабинет, получаем json с данными организации, на потребуется graphisoft id организации, для создания запроса на присоединение пользователя&lt;/li&gt;
  &lt;li&gt;формируем и отправляем запрос&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;заходим в кабинет пользователя и подтверждаем запрос
&lt;ul&gt;
  &lt;li&gt;аккуратно логинемся в кабинет пользователя&lt;/li&gt;
  &lt;li&gt;формируем запрос и подтверждаем присоединение к компании&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ну и сам код:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;?php

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

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

$header = &amp;#039;&amp;#039;;

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!==&amp;#039;&amp;#039;) {
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, &amp;#039;gzip, deflate&amp;#039;);
$headers = array();
$headers[] = &amp;#039;Connection: keep-alive&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua: \&amp;quot; Not;A Brand\&amp;quot;;v=\&amp;quot;99\&amp;quot;, \&amp;quot;Opera\&amp;quot;;v=\&amp;quot;79\&amp;quot;, \&amp;quot;Chromium\&amp;quot;;v=\&amp;quot;93\&amp;quot;&amp;#039;;
$headers[] = &amp;#039;Dnt: 1&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua-Mobile: ?0&amp;#039;;
$headers[] = &amp;#039;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&amp;#039;;
if ($ctype == 1) {
$headers[] = &amp;#039;Content-Type: application/json; charset=UTF-8&amp;#039;;
} else {
$headers[] = &amp;#039;Content-Type: application/x-www-form-urlencoded; charset=UTF-8&amp;#039;;
}
$headers[] = &amp;#039;Accept: application/json, text/javascript, */*; q=0.01&amp;#039;;
$headers[] = &amp;#039;X-Requested-With: XMLHttpRequest&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua-Platform: \&amp;quot;Windows\&amp;quot;&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Site: same-origin&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Mode: cors&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Dest: empty&amp;#039;;
$headers[] = &amp;#039;Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7&amp;#039;;
$headers[] = &amp;#039;Origin: &amp;#039;.$referer;
$headers[] = &amp;#039;Referer: &amp;#039;.$referer;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_COOKIEFILE, dirname(__FILE__).&amp;#039;/cookie.txt&amp;#039;);
curl_setopt($ch, CURLOPT_COOKIEJAR, dirname(__FILE__).&amp;#039;/cookie.txt&amp;#039;);
$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 &amp;#039;Error:&amp;#039; . curl_error($ch);
}
curl_close($ch);
}

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

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

//echo json_encode($data).&amp;quot;\n&amp;quot;;

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

$jsonObj = json_decode($ecoded_json);

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


$data = array(&amp;#039;companyGsId&amp;#039; =&amp;gt; $companyGsId,
  &amp;#039;email&amp;#039; =&amp;gt; $email,
  &amp;#039;errors&amp;#039; =&amp;gt; array(),
  &amp;#039;isDirty&amp;#039; =&amp;gt; true,
  &amp;#039;requestedGraphisoftUserId&amp;#039; =&amp;gt; $user_gsid);
get_url(&amp;#039;https://graphisoftid.graphisoft.com/api/user/SendInvitation&amp;#039;,&amp;#039;PUT&amp;#039;,2,&amp;#039;https://graphisoftid.graphisoft.com/&amp;#039;,$data);
echo &amp;quot;выслано приглашение присоединиться к компании\n&amp;quot;;
// удаляем старые куки
unlink(dirname(__FILE__).&amp;#039;/cookie.txt&amp;#039;);
// переходим на форму пользователя
get_url(&amp;#039;https://graphisoftid.graphisoft.com/&amp;#039;,&amp;#039;GET&amp;#039;,1,&amp;#039;&amp;#039;,&amp;#039;&amp;#039;);
// авторизуемся под пользователем
$data = array(&amp;#039;email&amp;#039; =&amp;gt; $email,
  &amp;#039;errors&amp;#039; =&amp;gt; array(),
  &amp;#039;isDirty&amp;#039; =&amp;gt; true,
  &amp;#039;isNullo&amp;#039; =&amp;gt; false,
  &amp;#039;password&amp;#039; =&amp;gt; $pasword);
$json_response = get_url(&amp;#039;https://graphisoftid.graphisoft.com/api/Authenticate/Login&amp;#039;,&amp;#039;POST&amp;#039;,1,&amp;#039;https://graphisoftid.graphisoft.com/&amp;#039;,$data);
$obj = json_decode($json_response);
$user_gsid = $obj-&amp;gt;{&amp;#039;GraphisoftUser&amp;#039;}-&amp;gt;{&amp;#039;GsId&amp;#039;};
if ($user_gsid == &amp;#039;&amp;#039;) {
echo &amp;quot;не смог зайти под пользователем в личный кабинет\n&amp;quot;;
} else {
$data = array(&amp;#039;actionId&amp;#039; =&amp;gt; 2,
  &amp;#039;companyGsId&amp;#039; =&amp;gt; $companyGsId,
  &amp;#039;graphisoftUserGsId&amp;#039; =&amp;gt; $user_gsid,
  &amp;#039;reactionId&amp;#039; =&amp;gt; 1);
get_url(&amp;#039;https://graphisoftid.graphisoft.com/api/user/ProcessingPendingRequest&amp;#039;,&amp;#039;PUT&amp;#039;,1,&amp;#039;https://graphisoftid.graphisoft.com/&amp;#039;,$data);
echo &amp;quot;сотрудник подтвердил приглашение\n&amp;quot;;
}
} else {
echo &amp;quot;у меня не получилось подтвердить регистрацию...  извините\n&amp;quot;;
}
}
} else {
echo &amp;quot;$email уже зарегистрирован в системе\n&amp;quot;;
}
// удаляем старые куки
unlink(dirname(__FILE__).&amp;#039;/cookie.txt&amp;#039;);
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;спасибо тем, кто дочитал до конца&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_172110.png" width="300" height="225" alt="" /&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>2 часть, «анализ, получение исходных данных»</title>
<guid isPermaLink="false">2</guid>
<link>https://voronin.one/all/analiz-poluchenie-ishodnyh-dannyh/</link>
<pubDate>Fri, 24 Sep 2021 12:30:50 +0300</pubDate>
<author></author>
<comments>https://voronin.one/all/analiz-poluchenie-ishodnyh-dannyh/</comments>
<description>
&lt;p&gt;&lt;a href="https://voronin.one/all/kak-nelzya-otnositsya-k-korporativnym-klientam/"&gt;1 часть, «как нельзя относиться к корпоративным клиентам»&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Всегда начинайте со сбора информации, это важно! Исходные данные определят направление и общую схему работы вашего решения.&lt;/p&gt;
&lt;p&gt;Любая задача решается по принципу «от общего к частному».&lt;/p&gt;
&lt;p&gt;давайте рассмотрим алгоритм действия администратора:&lt;/p&gt;
&lt;ol start="1"&gt;
&lt;li&gt;регистрация пользователя на сайте graphisoft.com&lt;/li&gt;
&lt;li&gt;подтверждение регистрации в посте пользователя&lt;/li&gt;
&lt;li&gt;авторизация на сайте graphisoft.com под административной учетной записью&lt;/li&gt;
&lt;li&gt;отправка приглашения пользователю&lt;/li&gt;
&lt;li&gt;авторизация  на сайте graphisoft.com под пользовательской учетной записью&lt;/li&gt;
&lt;li&gt;подтверждение приглашения&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_111857.png" width="300" height="179" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Вроде, не сложно...  да и в процессе тестовой регистрации я не заметил использования captcha. Это очень важно, иначе полная автоматизация была бы невозможна.&lt;/p&gt;
&lt;p&gt;Какие данные нам нужны, чтобы проделать весь вышеописанный алгоритм?&lt;br /&gt;
данные пользователя:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;имя&lt;/li&gt;
&lt;li&gt;фамилия&lt;/li&gt;
&lt;li&gt;e-mail&lt;/li&gt;
&lt;li&gt;пароль (пароль будем генерировать с учетом требований безопасности graphisoft)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;данные администратора:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;e-mail&lt;/li&gt;
&lt;li&gt;пароль&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_112041.png" width="300" height="236" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Осталось выбрать инструмент для реализации задуманного, я решил остановиться на php, т. к. у нас уже есть некий фундамент автоматизации рутинных процессов, который имеет web интерфейс и уже написан на php. В качестве хранилища информации выступит база MariaDB 10.&lt;/p&gt;
&lt;p&gt;Использовать будем curl, это «наше всё» для работы с web серверами.&lt;/p&gt;
&lt;p&gt;Начнем аккуратно, тут спешка не нужна, будем максимально повторять действия пользователя:&lt;br /&gt;
для начала откроем главную страницу и сохраним все cookies. Они будут, при первом открытии сайта вам сразу предложат принять cookie.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_120651.png" width="677" height="142" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;файл для хранения cookie так и назовём «cookie.txt»&lt;/p&gt;
&lt;p&gt;очень удобно в браузере копировать все необходимые ключи для curl сразу в буфер обмена&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_121005.png" width="767" height="557" alt="" /&gt;
&lt;/div&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;curl &amp;#039;https://graphisoftid.graphisoft.com/&amp;#039; \
  -H &amp;#039;Connection: keep-alive&amp;#039; \
  -H &amp;#039;sec-ch-ua: &amp;quot; Not;A Brand&amp;quot;;v=&amp;quot;99&amp;quot;, &amp;quot;Opera&amp;quot;;v=&amp;quot;79&amp;quot;, &amp;quot;Chromium&amp;quot;;v=&amp;quot;93&amp;quot;&amp;#039; \
  -H &amp;#039;sec-ch-ua-mobile: ?0&amp;#039; \
  -H &amp;#039;sec-ch-ua-platform: &amp;quot;Windows&amp;quot;&amp;#039; \
  -H &amp;#039;DNT: 1&amp;#039; \
  -H &amp;#039;Upgrade-Insecure-Requests: 1&amp;#039; \
  -H &amp;#039;User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 OPR/79.0.4143.50&amp;#039; \
  -H &amp;#039;Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&amp;#039; \
  -H &amp;#039;Sec-Fetch-Site: none&amp;#039; \
  -H &amp;#039;Sec-Fetch-Mode: navigate&amp;#039; \
  -H &amp;#039;Sec-Fetch-User: ?1&amp;#039; \
  -H &amp;#039;Sec-Fetch-Dest: document&amp;#039; \
  -H &amp;#039;Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7&amp;#039; \
  --compressed&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;для ленивых предлагаю воспользоваться online сервисом &lt;a href="https://incarnate.github.io/curl-to-php/"&gt;https://incarnate.github.io/curl-to-php/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Сконвертируем ключи командной строки curl в код php и получим следующее:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, &amp;#039;https://graphisoftid.graphisoft.com/&amp;#039;);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &amp;#039;GET&amp;#039;);

curl_setopt($ch, CURLOPT_ENCODING, &amp;#039;gzip, deflate&amp;#039;);

$headers = array();
$headers[] = &amp;#039;Connection: keep-alive&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua: \&amp;quot; Not;A Brand\&amp;quot;;v=\&amp;quot;99\&amp;quot;, \&amp;quot;Opera\&amp;quot;;v=\&amp;quot;79\&amp;quot;, \&amp;quot;Chromium\&amp;quot;;v=\&amp;quot;93\&amp;quot;&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua-Mobile: ?0&amp;#039;;
$headers[] = &amp;#039;Sec-Ch-Ua-Platform: \&amp;quot;Windows\&amp;quot;&amp;#039;;
$headers[] = &amp;#039;Dnt: 1&amp;#039;;
$headers[] = &amp;#039;Upgrade-Insecure-Requests: 1&amp;#039;;
$headers[] = &amp;#039;User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36 OPR/79.0.4143.50&amp;#039;;
$headers[] = &amp;#039;Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Site: none&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Mode: navigate&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-User: ?1&amp;#039;;
$headers[] = &amp;#039;Sec-Fetch-Dest: document&amp;#039;;
$headers[] = &amp;#039;Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7&amp;#039;;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo &amp;#039;Error:&amp;#039; . curl_error($ch);
}
curl_close($ch);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;осталось рассмотреть механизм php работы с почтовым ящиком, нам нужен по сути только механизм IMAP, не буду вас сильно грузить, оставлю готовый скрипт, который открывает почтовый ящик пользователя в режиме readonly и находит последнее письмо (если их несколько) от «register-noreply@graphisoft.com», расшифровывает тело письма и вытаскивает код подтверждения. Результатом работы скрипта будет ссылка на подтверждение регистрации или ничего, если письма не было.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;&amp;lt;?php

$auth_mail = &amp;#039;username@mail.com&amp;#039;;
$auth_pass = &amp;#039;P@$$woRd&amp;#039;;

function get_string_between($string, $start, $end){
    $string = &amp;#039; &amp;#039; . $string;
    $ini = strpos($string, $start);
    if ($ini == 0) return &amp;#039;&amp;#039;;
    $ini += strlen($start);
    $len = strpos($string, $end, $ini) - $ini;
    return substr($string, $ini, $len);
}

$imap   = imap_open(&amp;#039;{imap.mail.com:993/imap/ssl}INBOX&amp;#039;, $auth_mail, $auth_pass, OP_READONLY);
if ($imap) {
$some = imap_search($imap, &amp;#039;FROM &amp;quot;register-noreply@graphisoft.com&amp;quot;&amp;#039;, SE_UID);
if (count($some)&amp;gt;0) {
$mail_body = base64_decode(imap_body($imap, $some[0]));
$key = get_string_between($mail_body,&amp;#039;&amp;lt;span style=&amp;quot;font-weight:bold;&amp;quot;&amp;gt;&amp;#039;,&amp;#039;&amp;lt;/span&amp;gt;&amp;#039;);
echo &amp;#039;https://graphisoftid.graphisoft.com/#/verification/&amp;#039;.$key.&amp;quot;\n&amp;quot;;
}
}
?&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Вроде, все попробовали, ко всему готовы... В процессе реализации обязательно что-то всплывёт... но, в целом мы готовы!&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://voronin.one/pictures/izobrazhenie_2021-09-24_122739.png" width="300" height="230" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://voronin.one/all/kropotlivaya-rabota-i-dolgozhdanny-uspeh/"&gt;3 часть, «кропотливая работа и долгожданный успех»&lt;/a&gt;&lt;/p&gt;
</description>
</item>


</channel>
</rss>