Profile

coolwolf0: (Default)
coolwolf0

July 2025

S M T W T F S
  123 45
6789101112
13141516171819
20212223242526
2728293031  

Custom Text

Буквально вчера была окончательно решена проблема перманентного логина в Андроид-приложении.

Краткое содержание предыдущих серий.

1. Немного суровой реальности. Браузер общается с сайтом при помощи так называемой "сессии", то есть некоего набора данных, признаваемого обеими сторонами. В какой-то момент сессия считается просроченной и все данные о контактах браузера с сервером обнуляются. Если, например, сервер подтвердил ввод пароля для данной сессии, то потеряв сессию браузер не сможет утверждать серверу, что он имеет право совершать действия от имени пользователя. Естественно, народ уже давно решил эту проблему при помощи всяких исхищрений. Одним из них, например, является хранение контекста (или токена для его восстановления) в памяти браузера (кукис или локальное хранилище)

2. Ещё более суровая реальность. До сих пор мои сайты и андроид-приложения эксплуатировали эту фичу без зазрения совести. В webView кукис сохраняются так же, как в обычном браузере, достаточно подключить нужную функцию в классе приложения. Но вот настали трудные времена и все внезапно озаботились приватностью. Откладывать кукисы, даже для упрощения логина, оказалось страшно опасным действием. Все сайты вняли требованиям возмущённых пользователей и начали требовать от них добровольно соглашаться на сию потерю анальной девственности. В частности, мои сайты были занесены в "красный список" сами-понимате-какой-корпорацией именно за отсутствие "консента". Пройдя унизительную процедуру я вернул сайтам честное имя, но пользователям от этого лучше не стало. Периодически у них выскакивают напоминания "этот сайт следит за тобой, нажми кнопку чтобы стать его рабом". Логин при этом мягко говоря про%бывается и пользователю приходится совершать дополнительные телодвижения для его восстановления (да, без ввода пароля, но всё равно геморрой).

Какова же альтернатива? Я подумал тут с Gemini, и мы пришли к выводу, что можно хранить токен не в памяти браузера, а в приложении, передавая его туда-сюда через адресную строку. Для десктопного браузера это неприемлемо, ведь тем самым мы позволяем пользователю сверкать у всех навиду голой жопой секретным токеном. Но для смартфона такой опасности нет. Адресная строка в приложении отсутствует, а значит всё, что там лежит остаётся между приложением и сервером. Короче, страничка логина принудительно получает от приложения дополнительный параметр, означающий "это мобильный клиент, ему - можно". При удачном логине сервер делает для такого клиента исключение. Он генерит этому пользователю персональный токен, запомнинает его вместе с датой выдачи и возвращает его в виде аргумента при перенаправлении на основную страницу. А поскольку основная страница тоже рендерится приложением, оно потихоньку считывает этот токен и запоминает его. Но запоминает уже не в виде богомерзкого кукиса, а в своей родненькой памяти, о которой никакой гугель-шмугель не знает, и знать не должОн. Если в следующий раз ему попадётся основная страничка, он пороется в своей памяти и, при наличии там токена, впрыснет его в адресную строку, чисто на всякий случай. В результате, основная страничка, подгружаемая в единожды залогиненом приложении, гарантированно получит токен. Всё, задачка решена, можно удалять код, откладывающий кукисы, а с ним заодно и консент-контент!

Ну и на дессерт: как я решил проблему пароля для регистрации и логина. Основной опасностью тут является хищение пароля всякими сниферами. Так вот, при моей схеме пароль тупо не передаётся на сторону сервера (и соответственно там его нет). Даже если вы сидите на канале пользователя и прорвались через HTTPS, то всё равно увидите только чек-сумму, да и то не самого пароля, а чего-то наложенного на ещё что-то. Как это работает? Очень просто. При регистрации в браузер посылается "соль" которой посыпается пароль. После этого результат (в виде чек-суммы) отправляется на сервер и там сохраняется. Каждая попытка логина сопровождается генерацией дополнительного секретного компонента (назовём его "перец"). Браузер накладывает на введённый пароль и "соль", и "перец" перед тем как вернуть результат на проверку. Сервер вытаскивает "посоленную" чек-сумму для данного пользователя, накладывает на неё индивидуальный "перец" и сравнивает результат с предъявленным браузером. Подделать или зареверсить эту схему практически невозможно.

Дополнительная "фишка" - защита от поддельного запроса на аутентикацию. Дело в том, что в роли "перца" выступает юникс-тайм на данный момент времени (со стороны сервера). Если кто-то вздумает повторить запрос на логин со старым "перцем", то сервер его отвергнет, так как он уже "просрочен" по сравнению с последним успешным логином. Единственной лазейкой является полная имитация всех алгоритмов на стороне браузера, плюс кража секретной чек-суммы пароля (что является фактически кражей самого пароля).
Если быть точнее, то рыбы две. Во-первых, получить работающий проект на АндроидСтудио оказалось невыполнимым квестом. При создании нового проекта та же самая версия IDE упорно выдаёт webView который не может прочитать ни одну страничку ни с какого сайта. Тупо падает на необъяснимой ошибке и всё. Единственным способом изготовления нового приложения оказалось размножение всей директории и тотальное переименование переменных и директорий внутри. Как ни странно, после такого шаманства приложение спокойно серфит куда ни попадя. Всезнающий AI на вопрос "чо за нах?" только железными руками разводит и несёт какую-то чушь.

Вторая рыба - покрупнее. Это целый PHP и Апач к нему. Уже несколько раз я натыкался на ситуёвину, когда из браузера шлёшь запрос в PHP API, пытаешься распарсить полученный JSON, и ... вылетаешь по exception "illegal character". Особо зоркий глаз может при этом разглядеть в дампе полученного пакета некий мерзкий непечатный символ перед самым началом JSON-структуры. И что бы я ни делал в самом коде - ничего не помогает. Ни танцы с бубном насчёт заголовка, ни поиски вражеского символа в закодированном ответе, ничегошеньки. Как вариант, в старых проектах я отчаянно вырезаю непечатные символы уже на стороне JavaScript, что есть непотребство и чёрная магия. Так вот, оказывается при редактировании исходника на PHP в самом начале файла могут влететь те самые непечатные символы. Называются они BOM (на английском) и означают некий префикс для распознавания кодировки. Если удалить этот самый BOM из исходника, всё работает как положено. И вот тут возникает вопрос: АНАХ#Я? Почему ни интерпретатор PHP, ни многоуважаемый Апач эту дрянь не фильтруют? Кому нужна такая какашка? Может быть есть сценарий, когда BOM посылается в начале реального HTML? Может быть. Но блин, как жестоко при этом пролетают разработчики API! :-[
Сначала - краткое содержание предыдущих серий. Года два-три тому назад я сделал из говна и палок своё первое андроид-приложение. Поскольку тогда ни о каком генеративном AI речи быть не могло, пришлось использовать видео-тьюториалы, наговоренные какими-то индийскими умельцами. С горем пополам то приложение было доведено до нужной кондиции, а его сорсы сданы в архив. И вот настал день "Икс", когда заглючил сайт у моего бесплатного хостера. Перенос кода и базы данных на другого хостера показал, что дело таки действительно было в хостинге. Ну ладно, причина и решение найдены, как теперь переучить имеющееся приложение работать с другим сайтом? На прошлой неделе я буквально за два дня восстановил приложение путём переноса в оригинальный IDE (на самом последнем сорсы тупо не компилировались). Всё, казалось бы хеппи энд... Но суровая реальность отвергла моё половинчатое решение. Приложение не ставилось на реальном "железе", а после декомпиляции и шаманства с цифровой подписью - зависало и вылетало.

Пришлось начать весь цикл заново. Я, уже наученный горьким опытом, задавал своему механическому наставнику правильно поставленные вопросы, заранее отсекая всякие боковые сюжетные линии. Мы с ним решили выбросить в топку старую версию АндроидСтудио "Flamingo" и перейти к более продвинутой "Iguana". В ней я тупо прошёлся по инструкциям моего опытного советчика и действительно получил самую первую работающую версию. Вот только после попытки открыть сайт она печально зависала. Причём в лучших традициях - без сообщений об ошибках. Пришлось учить, где в эмуляторе можно подглядеть консоль приложения. Дальше стало значительно легче. Ошибка была сходу распознана умным Джемини и по его совету я просто вырубил проверку сертификатов (так как эмулятор пребывал в каком-то странном состоянии рассинхронизации с реальностью). Ещё несколько итераций, и приложений прекрасно сработало в дебаг-режиме. После этого я стал терроризировать железного сенсея насчёт создания APK с валидной цифровой подписью, что в конечном счёте и удалось сделать. Приложение заработало на моём смартфоне, и тут можно было бы поставить точку. Но я ещё чуть-чуть пошаманил, встроил перезагрузку страницы по свайпу вниз, добавил в приложение свою фирменную иконку, зум по нажатию двумя пальцами и наконец - передачу информации наружу через "поделиться". Последним штрихом была отмена мерзкого фона в заголовке окна, диктуемого Material3 - пришлось подружиться и с этой частью настроек.

В целом я более чем доволен. На всю бодягу ушло два вечера мозговых штурмов в компании с Джемини. Приложение полностью восстановлено и теперь, если понадобится, я могу сварганить ещё что-то в аналогичном стиле. Например приложение в котором будут лежать планы поездки за границу, со всеми маршрутами, достопримечательностями, расписаниями и документами. А то я задолбался рассылать всей семье ссылки на очередной план путешествия.
Хулить корпорацию, проливающую в наш мир свет из своих "окон" - традиционное занятие современного человека, независимо от степени его продвинутости в компьютерной области. И система у них "висючая", и офис "глючный", и даже мышь "дурацкая". Но вот уже немало лет, как встроенный в ОС "защитник" вытеснил все сторонние антивирусы, встроенная поддержка ZIP избавила простых пользователей от необходимости чикаться с архиваторами, аутентикация перестала задавать ненужные вопросы при переходе на сенсоры (отпечаток пальца, face ID).

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

У меня с давних пор (лет 20 как минимум) есть заброшенный аккаунт Skype. В своё время их купили всё те же мелкомягкие и понеслось. Каждые пол-года (или что-то вроде того) мне на почту стали приходить угрожающие мейлы, мол ваши деньги на счету Skype пропадут, если вы не сделаете хотя бы один звонок или СМС. Приходилось периодически повторять эту дурацкую церемонию. В результате баланс всё равно убывал - на несколько центов. Судя по всему, кто-то вздрючил их за такую практику, потому что сегодня мейл был немножечко другой. Достаточно зайти в свой аккаунт и ... просто нажать на кнопку "продолжить". И ВСЁ! А что, с самого начала нельзя было так сделать?
Так уж получилось, что последний раз, когда мне довелось сваять настоящую графическую морду к программе, на дворе был где-то 2008 год (а может и ещё раньше). С тех пор как-то обходился консольными скриптами и веб-приложениями. Но вот приспичило автоматизировать некий процесс и чтобы всенепременно с полноценным гуём. И тут всё заверте...

Во-первых, старый как говно мамонта Tk выглядит сейчас мягко говоря неуместно. Соответствено, более продвинутый QT никак не прикручивается к Python2 (поскольку эта версия давно в "чёрных списках" у всех модулей). Закручинился добрый молодец, да видно некуда ему деваться - пришлось ставить самый продвинутый Пайтон - аж 3.12! К нему сразу же приставил QT5, ну и PyInstaller. Вот с этим "джентльменским набором" я и сваял простейший гуй к уже работающей консольной части. После компиляции (с помощью PyInstaller) получился полноценный виндовый экзешник, который сходу заработал на абсолютно постороннем для него компьютере. В процессе написанию кода пришлось пару раз сбегать на поклон к всезнающему Гугелю, а то в этом QT хрен знает какие методы для работы с виджетами (а ваш покорный слуга всё никак не поставит себе IDE более продвинутый чем gvim). В конечном итоге функционал вышел неплохой, а морда даже чем-то напоминает хакерские программки вроде кейгенов или инсталляторов вареза.

Да, если кому нужно - могу отдать за спасибо. Суть утилиты в обёртке вокруг ffmpeg: из ютьюб-ссылки извлекается её "секретный" плейлист m3u8 и вуаля - видео скачивается в нужном формате. Так что пишите письма ;-)
Если ваш сайт попал в "красный список" Гугеля и его величество Хром реагирует на все странички красным-малопрекрасным экраном, знайте: выход есть. Будет немного трудно, порой мучительно стыдно, но придётся пройти процедуру диспансеризации в корпорации Добра.

Итак, первый этап: осознание. Вдохните глубоко и проговорите мысленно "я понимаю, что использование кукиз выглядит подозрительно с точки зрения безопасности, даже если мой сайт отложил их для удобства пользователя". Если серьёзно, все советы ниже относятся в основном к такой категории маркировки сайтов. На случай иных проблем пожалуйста идите на поклон к тематическим форумам и их гуру.

Второй этап: отрицание. Вам придётся отречься от девственной чистоты сайта и изгадить его всплывающим баннером об использовании кукиз. Это позорно, но таковы требования к публичному отрицанию вины (consent). Я использовал вот этот сервис. Сгенерировав код для вставки на сайт вы тупо копируете его в заголовки своих страничек.

Третий этап: торг. Тут ваш путь лежит прямиком в логово врага. Залогиньтесь своим гугл-аккаунтом на поисковую консоль, введите адрес сайта и начните унизительную процедуру подачи челобитной. Первым делом вам придётся доказать, что сайт - ваш. Для этого надо скопировать сгенерированные гуглом сигнатуры в DNS-регистр вашего сайта. У меня это CNAME. После этого сайт можно пересканировать и попросить review. Всё, мы сделали это.

Последний этап: принятие. Через 2-3 дня вам придёт радостное (или не очень) сообщение, мол ваша просьба рассмотрена, мы вас поздравляем (или наоборот, посылаем), засим подписуемся и всё такое прочее. С этого момента ваш сайт должен быть удалён из мерзких списков "подозрительных" (или возвращайтесь в начальную точку и ищите, что же ему там не пондравилось).
Технический дыбр. Если вкратце, то "всегда записывайте пароли" и "делайте копии".

Итак, преамбула: что-то подтолкнуло меня сегодня зайти с домашнего компа на свой сайт-визитку. Сайт был создан практически в прошлом веке, на допотопном хостинге, а в 2010-м переехал на чуть менее допотопный. С тех пор я на него заливал чёрт-те что исключительно по FTP через удобный плагин FarCommander-а. И вот сегодня сайт отказался открываться. Если точнее, то браузер обнаружил отсутствие HTTPS и зарезал доступ как к неблагонадёжному источнику. Я спокойно попытался обойти эти грозные предупреждения и ... попал на странную страничку типа "аккаунт удалён или доступ невозможен". Оп-па, вот тебе и сюрпризик. Начинаю судорожно искать какую-нибудь домашнюю страничку хостера, а хостер занимается ерундой и перефутболивает меня на малопонятные формы входа. Логин и пароль из памяти браузера внезапно не подходят, а ссылка по восстановлению пароля ведёт на форму "свяжитесь с нами" из допотопных времён веб-1.0! Начинаю тихо сползать со стула: это же мой сайт-визитка, как же теперь жить дальше??! К счастью, мне хватает соображалки проверить доступ по FTP: там всё работает как обычно. Более того, на другом компе браузер спокойно открывает сайт, при всём его пренебрежении к HTTPS... Ну ладно, думаю я себе, пока что тревога была ложной, но как бы таки получить доступ к контрол-панели и врубить тот самый HTTPS? Заполняю форму, посылаю параллельно мейл провайдеру и ... вскоре получаю ответ от живого человека. Он мне пишет, мол чувак, есть у тебя контрол-панель, давай, открывай и всё тебе будет. Перечитываю ответ раза три, пробую и получаю тот же результат: форма входа, где ни один пароль не подходит. Начинаю внутреннее расследование - пытаюсь вытащить пароль из сохранённого соединения FTP в Far. Вумные люди на форуме пользователей советуют поставить специальный плагин. Ставлю - он требует продвинутую версию самого Far-а. Переезжаю на продвинутую версию, запускаю и с третьего раза вытаскиваю треклятый пароль ... который я и так знал!

Короче, примерно к концу второго часа мне стало ясно, что имя пользователя я вводил обычное, а надо было - название сайта! Кто поменял политику использования логина и не сообщил мне об этом - одному чёрту известно. Главное, что контроль был восстановлен. Треклятый HTTPS включён в два клика, а заодно в обновлённом меню обнаружены PHP (правда почему-то максимум 7-й версии) и MySQL (довольно примитивно организованный, но рабочий).
Не прошло и 20 лет, как ваш покорный слуга обнаружил на своём хостинге возможность динамической генерации страниц. А это повод для создания версии сайта 2.0, не так ли?
Речь пойдёт о чтении новостей. Дело в том, что я подписался на телеграм-канал местных событий в области безопасности (как это точнее перевести на русский не знаю) и в какой-то момент осознал некую наркоманскую зависимость от телеграм-новостей. Вумные люди называют это "дум-скроллинг". Заходишь в какое-то приложение и крутишь ленту пока не исчерпаются новости, потом переходишь в другое приложение, ну и так до бесконечности.

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

Однако этот телеграм никак не вписывался в мою автоматизацию, пока я не набрёл на замечательный сервис, преобразующий любой телеграм-канал в RSS. Для этого копируем адрес канала (после значка "@") и дописываем его к адресу сервиса https://rsshub.app/telegram/channel/. Например, канал https://t.me/intellinews_russian имеет официальный адрес https://web.telegram.org/k/#@intellinews_russian, так что его RSS-адрес будет выглядеть так: https://rsshub.app/telegram/channel/intellinews_russian (аналогично - со всеми другими каналами). Кстати, благодаря переходу на RSS я наконец-то избавился от сигналов воздушной тревоги, ретранслируемых этим каналом. У нас в городе (если кто интересуется) за всё время военных действий была единственная тревога, да и то - ложная. Но приложение от службы тыла я поставил, так что при реальной тревоге оно меня точно оповестит.

Найдя лазейку с автогенерацией RSS для телеграм-каналов, я решил и другую проблему. Ещё в самом начале войны я заметил, что все новостные каналы вещают RSS нормально, и только сайт 9-го канала выдаёт ошибки при чтении с "заграничного" адреса агрегатора. Что поделать, мой агрегатор хостится на халявном интернациональном сервере и я не вижу необходимости тащить его в родные края. Судя по всему, сисадмины "девятки" тупо зарезали доступ со всех не-местных адресов во избежание атак. Чем им провинился сервис RSS и как кроме DDoS его можно атаковать я даже не представляю. По удачному стечению обстоятельств сегодня утром жена включила телевизор, и в информационной вставке я услышал, что помимо сайта, у них имеется телеграм-канал. Ага, сказал я себе, вот вы и попались! Запустил поиск в "телеге", нашёл канал "девятки" и прикрутил его к ретранслятору RSS - voila, их новости вернулись в мою ленту.
Да простят меня читатели, но я о своём, о "компьютерном".
Если быть совсем точным, то это уже не компьютер, ибо ВПС наконец-то (к 55 годам) смог наваять приложение для ондроед-устройства, который как бы уже и не персоналка, а чёрт-те-что.
И хоть "программа" получилась на несколько строчек длиннее "Hello, world!", к тому же написанная под копирку с лекций каких-то индийских товаристчей, но тем не менее, из неё вышло полноценное приложение (открывающее во встроенном браузере захардкоденную ссылку на сайт).
Более того, я даже скопипастил туда две фичи: не выходить из приложения по кнопке "назад", пока не достигнут нулевой уровень переходов, а также выполнить "зум" при нажатии пальчиками в двух местах.
Жалко, что перезагрузка страницы (по свайпу вниз) оказалась мудрёной, а так - всё работает как будто действие происходит в обычном браузере.
В планах теперь допилить поддержку свайпа вниз и приделать некую среду компиляции+установщик. Логично было бы что-то вроде NPM, но по сути можно обойтись двухстрочными BAT-файлами. Тем более, что вопрос закачки по FTP я буквально недавно решил - с десктопа можно заливать файлы в пакетном режиме при помощи встроенного FTP-клиента от мелкомягких или (более кошерно) - официально-бесплатным клиентом WinScp.
Теперь окончательно решён вопрос переноса на андроид аггрегатора новостей FreeRSS2, а также семейного списка покупок my-shopping-list. Осталось только допилить код, чтобы можно было скачать приложение с главной страницы (но это уже на вебе).

UPD: нашёл и впендюрил перезагрузку странички по свайпу! При этом один проект покорёжился, так что пришлось его подымать из руин. Срочно бегу загонять сорсы в GIT...
Сегодня на территории зеркального аккаунта FreeRSS были проведены учения, максимально приближённые к боевой обстановке.
Учения проводились с целью отработки восстановления хостинга при прямом пропадании всего, нажитого непосильным трудом.
В ходе учений были проведены следующие мероприятия: полное копирование кода с перезаписью старых сорсов, полный дамп всей базы данных на донорском хостинге (силами собственного PHP-скрипта), удаление подчистую всей схемы на целевом хостинге и применение к нему дампа (практически вслепую, без правки исходников).

По результатам учений была получена оригинальная "морда" донорской версии и абсолютно те же данные. Командование от лица службы выражает само себе благодарность за портируемый, независимый код, позволяющий подцепить донорский дамп где угодно.

Но наши бойцы не останавливаются на достигнутом, тем более, что хостер категорически запретил доступ через API к приложению. Поэтому параллельно идёт работа над созданием JSON-дампа, который можно будет перенести с хостинга на хостинг без танцев с бубнами вроде скачивания по FTP и запуска SQL в веб-интерфейсе. Если получится, то в следующий отпуск смогу поехать уверенным в несокрушимости закромов RSS, вплоть до восстановления аккаунта в антисанитарных условиях, по WiFi, в какой-нибудь гробнице. Дополнительное преимущество этого подхода в том, что дистиллированные данные можно объединять с имеющимися при переносе туда-сюда (в отличие от полного дампа SQL).
Только я затронул тему "таинственного" поведения программ, как буквально сегодня "стрельнуло" в совсем неожиданном месте.
Итак, есть веб-страничка, генерируемая пе-ха-пе на стороне сервера, и на страничке имеются кнопки/ссылки вызывающие некую JavaScript функцию. Функция быстро-быстро что-то делает и обновляет страничку, дабы показать результат. Всё работало, пока не купила баба порося: захотелось мне перед выполнением функции переспросить пользователя, мол "ты точно уверен?".

Пруф-оф-концепт прекрасно отработал на одной веб-страничке и я смело перенёс тот же код на другую страничку с похожим функционалом. И вот тут началось: открывается окно, и сколько бы я ни кликал кнопку "отмена" - окно открывается снова и снова!
Что за фак, подумал я, и вставил отладочные печати в JavaScript код. Результат вышел просто феерический: по клику функция "переспросить" вызывалась снова, как в сказке про белого бычка! Попытки как-то стрейсить эту засаду не дали ничего: стек содержит какой-то анонимный источник, явно не из жабаскрипта.

Что делать? Не бросать же работающий прототип в топку. Я начал с другого конца, открыл DOM-модель и начал искать вызовы функции там. Что же обнаружилось? Тихий ужас: ссылки на пресловутый коллбек были расставлены буквально на всех уровнях DOM, начиная с основной кнопки-ссылки. По крайней мере стало ясно, откуда сдох бобик: куда бы я ни кликнул, соответствующий объект внезапно обнаруживал у себя onclick-событие и отрабатывал его вызовом многострадальной функции с открытием модального окна. Первой мыслью был некий вирус (ага, в собственном коде, генерируемом к тому же на пе-ха-пе со стороны сервера). По трезвому размышлению я отверг бредовый вариант, внимательно посмотрел на HTML-код и ... обмер: у тега <a href="..."> не было закрывающей части! Вот такой лес, без деревьев! А поскольку HTML - не язык программирования, там непарные конструкции - не более, чем причуда клиента, поэтому браузер прикидывается ветошью и ... продолжает отрабатывать незакрытый тег! В результате доблестная DOM-модель продолжила считать ссылкой весь код после пресловутой кнопки. Ну как тут не ругнуться на всех известных языках!?
Как говорится, "каждый год, 31-го числа, мы с друзьями идём в баню". Но это даже не второе, о чём вы подумали. Мой хостер что-то там у себя посчитал и забанил на сутки аккаунт аггрегатора новостей. Ему, видите ли, не понравилась повышенная нагрузка на SQL-сервер. Можно подумать, что я там какую-то аналитику считаю или, прости господи, биткойны майню. Блокировка оказалась полной - даже аварийный дамп базы не вытащить. Ну что поделать, накатил апдейты на резервный аккаунт, покрутился сутки на старых данных. Зато получил статистику: в сутки мои сети вылавливают около 600 статей! Подавляющее большинство из них я не открывая помечаю как прочитанные. А всё потому, что каждый раздел содержит новости только на определённую тему (например, "музыка" или "аудиокниги") - пробежал взглядом на предмет интересных авторов или тематики, и смело нажал кнопку "удалить и показать оставшееся".

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

Несколько неудачно прошёл первый коммит (не в плане техники, а из-за моих развесистых ушей).
Дело в том, что до начала полноценной работы с сорс-контролом, я вбил явки-пароли подключения к MySQL в некий файл концигурации. Естественно, после деплоймента на сервак, для пользователя он невидим, но у меня хватило ума закоммитить его в GIT со всеми остальными сорсами.

Казалось бы, что за беда - удали файл и залей "пустышечную" версию... Но это если бы речь шла о статической системе. А сорс-контрол (как мстительный интернет) помнит всё! Так что никогда не повторяйте мою ошибку - коммитить можно только специально приготовленную копию проекта, без паролей и прочих чувствительных данных.
Короче, пришлось пересоздать проект (благо там было полторы версии) и заодно прикрутить самодельный патчер, чтобы "если чо" выпечь файл конфигурации из внешнего конфига.

Ну что я вам скажу, всё очень мило, кавайно и хайтечно. В наше время такой няшности не было (в далёком 97-м я только-только познакомился с RCS - по нынешним меркам это реальная жесть). Впрочем, о чём это я, - уже в антисоветской ОС NTS было понятие версии на уровне файловой системы, и там это работало как часы (я думаю, современные часы имеют столько же оперативки, сколько в том шкафе, размером с холодильник-другой). А другой опен-сорс проект я коммитил SVN-ом на флешку, сидя с лептопом в тамбуре поезда - это было лет 15 тому назад. Теперь всё онлайн, и можно не бояться внезапной потери хард-копии, будь то смерть диска или пропажа компьютера (тьфу-тьфу-тьфу).

Ещё чуть-чуть, и можно будет перейти от PoC версии к "нулевому релизу". От винта!

git stash
git update
git pull --rebase
git stash pop
В связи с изменением законов на Плюке, дабы не получить пожизненный эцих с гвоздями, вынужден был переехать на параллельную платформу. Переезд занял неделю, так как шибко вумные админы ЖиЖи блокируют траффик зеркалирующего API. Короче, терпение и труд перетёрли эту проблему. В связи с чем и постю тут клип на новый сингл Рамштайна "Время".


... с хостером. Не пугайтесь, я на других фронтах раненый ;-)

Короче, хостер у меня строгий, но справедливый: на халяву разрешает только в бирюльки играться. Чуть какая важная функция - давай, бабки гони.
Но я и не претендую ни на что особенное: малюсенькая база MySQL (footprint практически не растёт, потому что накопить информацию вручную много не получится), какой-никакой PHP (не самая последняя версия, но и не старьё), доступ по FTP - вот и все требования.
И вот настал тот час, когда у хостера начали периодически выскакивать отлупы при соединении апачевской сессии с базой. В результате скрипт вылетает по мерзкому эксцепшену "Connection failed: SQLSTATE[HY000] [2002] Connection refused". Я его конечно же оттрассировал и попытался "поймать" через try ... catch, но проблема в том, что поймать можно что угодно, а потом-то чего прикажете делать? Попытаться тут же в цикле повторить соединение? Плохая идея, ибо в таких делах надо уметь держать себя в руках и дать второй стороне шанс успокоиться. Короче, в архитектурном плане стандартное решение - retry after delay (и так несколько раз, увеличивая длительность задержек).
Но, как оказалось после первой попытки, мой хостер тупо запретил sleep, usleep и вообще, любые попытки затянуть время обработки запроса. Я почесал лысую репу и выдал то, чему учат сисадмины: exec("ping -n 2 -i 1 127.0.0.1"); то есть "чеши яйца с интервалом в секунду". Второй раз забросил старик невод, и пришёл невод с той же тиной морскою - хостер строжайше запретил любые экзеки (хорошо хоть в ответ по морде не навешал).
Ладно, думаю, ты так, а мы - вот так! Запросы наружу по TCP работают? Значит им можно тайм-аут назначить? Ну вот тут-то ты и попался!

Короче, вот вам функция, которая ходит туда, незнамо куда, и отрубается в строго отсчитанный момент.

Read more... )

Скорее всего гугловский DNS не обидится, что ему шлют запросы на несуществующий URL. Я же его не DoS-ю, а так, в качестве "груши" использую, когда со мной родная база говорить отказывается.
Я тут потихоньку ваяю код для полноценного аггрегатора RSS, чтоб базировался на вебе, с мордой от Bootstrap. Мой древний самопал бежит строго на локальной машине, а это бардак и каменный век с точки зрения доступа. Про внешнее оформление в стиле Веб-1.0 вообще молчу.
Уже сейчас имеется подкачка RSS-лент с сайтов по списку и умное хранение обновлений в базе, постраничное отображение статей, отметка прочитанного, редактирование кое-каких деталей имеющихся лент, поддержка клавиатурных шорткатов, плюс адаптивный дизайн под десктоп и смартфон.

Помимо всяких заморочек с базой данных, жабаскриптом и пе-ха-пе, приходится кое-где и велосипеды изобретать.
В частности, задумал я накатать свой алгоритм для шифрования и передачи пароля (как нового, так и при логине).
Сразу предупреждаю: мой проект не будет хранить никаких супер-пупер секретных или интимных личных данных.
Просто мне надо разграничить доступ между пользователями, ну и предотвратить возможный вандализм с угоном аккаунта, порчей или замусориванием данных, вот это всё... Код хотелось бы сделать открытым (но не содержимое базы данных, естественно).

Итак, задача номер один: как секьюрно передать первоначальный пароль в систему, с учётом того, что хакеры могут прослушивать траффик. Идея состоит в том, что я вообще не собираюсь принимать от пользователя какой-то пароль при регистрации. Он оставляет на сайте свой запрос и получает от меня первоначальный пароль мейлом. При этом я не храню сам пароль в системе, а только его чексумму.

Вторая задача состоит в том чтобы передать пароль зарегистрированного пользователя (с учётом того, что на этот раз хакеры точно смогут прослушивать траффик). Решение выглядит так: сначала клиентская часть отправляет в систему запрос "пользователь такой-то хочет передать пароль". Система генерирует временный кусок "соли" и пересылает его клиенту обратно. После этого клиентский жабаскрипт считает чексумму пароля, на неё накладывает кусок "соли", и полученный результат возвращает в систему. Система убеждается, что это та самая сессия, накладывает свою "соль" на свою сохранённую чексумму пароля и сравнивает её с полученным от клиента кодом.

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

Фактически, я разрубил гордиев узел несекьюрного канала при помощи вспомогательного канала (мейл).
Насколько мой сценарий опасен с точки зрения реальной жизни? Есть какие идеи?
Ролики в интернете

Берёзовый киберпанк выпустил очередную порцию стёба, как обычно - на злободневную тему. На этот раз стебутся над медициной.





Read more... )
Прочитал в пейсбуке пост профессионального психолога и специалиста по НЛП: человек не понимает, почему ему задают "дурацкие вопросы" сотрудники службы безопасности в аэропорту, короче это его БЕСИТ. В ответ (помимо прямых и подробных объяснений сути таких собеседований) комментаторы начали переходить на личность топикстартера, а автор - обкладывать непарламентскими анатомическими эпитетами весёлых комментаторов. В конце концов комментарии к посту были заблокированы. Отсюда следует сразу несколько выводов, но основной таков: в разговоре, будь то интернет или оффлайн, никогда не переходите на личности (если вы не профессиональный психолог). Во-первых, это унижает не только вашего визави, а во-вторых, уводит дискуссию в неконструктивное русло. Зато если вы - психолог, то можно крыть x**ми кого угодно, чего стесняться, в этом вся суть профессии!

PS: уважаю психологов, не люблю непрофессионалов и шарлатанов.
Музыка

"Бодкин" - что у вас ассоциируется с этим словом? Оказывается, не только инфекционист и одноимённая больница.
Британский коллектив, игравший прогрессивный рок во времена Пинк-Флойда (и вполне себе на их уровне).



Увы, это их первый и последний альбом. А могли бы стать не менее популярными...

Read more... )
Мой сайт для записи списка продуктов оказался внезапно очень важным для всей семьи. Ещё бы: без обзвонов, диктовки, согласования и прочей ботвы, каждый член семьи может зайти на сайт и обновить информацию: добавить продукт в список, удалить неактуальное, отметить покупку в режиме онлайн. Я знаю, что есть всякие гуглоформы и приложения, но у меня это работает именно как интегральный продукт: название товара сопровождается картинкой, список общий для определённых пользователей, весь функционал одинаково доступен как на телефонах/планшетах, так и в обычном десктопном браузере.

И всё бы хорошо, но хостится эта аппликация у бесплатных провайдеров, то есть безо всякого суппорта. Например, пока я был в Румынии, провайдер зачем-то заблокировал аккаунт. Судя по тикету, ему не понравилось, что я зарегистрировался с мейлом из домена rambler.ru (за что и был коллективно наказан). Ладно, тот инцидент улажен, но вот вчера случилось что-то совсем странное: база не просто упала, а "поломалась". Причём поломалась как-то странно: в консоли MySQL выскакивают предупреждения о сбое системных таблиц, но дамп и прочие запросы отрабатываются (и слава богу, иначе со старыми бекапами я бы вообще потерял лицо перед тёщей). Ну ошибки ошибками, а в какой-то момент и аппликация перестала логиниться к базе: пароль не принимается, выдаётся системная ошибка. Ошибку эту в нормальном мире решают как два пальца об асфальт, перезапуском mysqld, но я тут не хозяин, чтобы сервера перезапускать (а суппорта нет!)... Попытка создать новый аккаунт и накатить на него базу проваливается, ибо сервак у них общий, и он не сотрудничает со следствием.

Ну и конечно же, вся эта халабуда упала именно тогда, когда мы всей семьёй составили список, и жена с дочкой уехали по нему закупаться. А аппликация-то "ку-ку". Что делать? Гипс снимают, клиент уезжает! Но мы тоже не пальцем деланные: быстро (пока не получил от тёщи выговор с занесением) ищу аналогичный бесплатный хостинг, очень быстро создаю аккаунт, подымаю базу из бекапа, заливаю сорсы, подправляю файл конфигурации ... и всё работает! Это реально был случай экстремального администрирования.

Что характерно, параллельно с конвенциональным хостингом я позарился на хостинг от Амазона. Тот самый, знаменитый, облачный. Там всё такое из себя, пальцы веером, сопли пузырём, какие-то облака, виртуальные сервисы и прочие достижения технической мысли. Но вот поднять базу к бесплатному веб-аккаунту - низзя. Только за очень большие доллары, причём не в год, а в месяц! И мигрировать обычный MySQL бекап через их веб-форму мне тоже не удалось, ибо потребовалось заполнить какие-то формуляры, понасоздавать секретных сертификатов, ещё какой-то хрени... Ребяты, вы создаёте сервис для бесплатного хостинга или предоставляете мне доступ к материалам министерства энергетики США (ЕВПОЧЯ)? Почему бесплатный хостер сходу открывает мне доступ по FTP к моим сорцам, а вы разрешаете мне закачать ... ОДИН ФАЙЛ и только через веб-интерфейс? И если вы такие вумные, то почему нельзя просто задеплоить проект из чего-то локального (если я правильно понял, там даже github оказался не в почёте). Короче, обиделся я на них и вернулся в лоно обычных провайдеров. Более того, им я охотнее заплачу свои кровные доллары, потому что тёплое, LAMPовое, красивое.