четверг, 17 апреля 2014 г.

User (пользователи) в YII.

Существует модуль user для фреймворка yii, который уже давно не поддерживается. Много людей его используют, но есть там и некоторые минусы. Для меня неудобства заключались как в именовании модуль/контроллер/экшн так и в весьма устаревшей модели шифрования паролей. Yii 2.0 еще не пробовал, работаю пока еще с версией Yii 1.1.14, в которой уже существует специальный класс для работы с паролями на основе криптоалгоритма Blowfish. 
Еще одна "недоделка" в модуле user на мой взгляд явилась в отсутствии поддержки токенов. Токены - это массив данных о пользователе, подписанный цифровой подписью. По сути это зашифрованная строка, которую очень легко расшифровать и получить исходный массив, но довольно сложно получить токен с данными для другого пользователя, для этого нужна цифровая подпись. 
Для формирования токенов, точнее для их подписи я решил использовать алгоритм SHA-256 + RSA. Если что, можно и SHA-512 конечно. Принцип довольно легкий - генерируются закрытый и открытый ключи для RSA. Закрытым ключом подписывается хэш массива - это и есть токен, для проверки валидности токена используется открытый ключ. 
Основное предназначение токена - хранит основную информацию о пользователе, без необходимости дополнительных обращений к БД и позволяет использовать кросс-доменные запросы, что очень удобно, когда, к примеру, модуль обмена сообщениями находится на другом поддомене (и другом сервере/серверах) для снижения нагрузки.
Для внедрения поддержки токенов в YII пришлось довольно сильно потрудиться... Самым логичным вариантом размещения проверки валидности токена был этап инициализации компонента user - класс, унаследованный от CWebUser. Но данный вариант весьма неудобно использовать при получении переменных, хранимых как члены класса. На данный момент Yii::app()->user === null. Поэтому использовать ActiveRecord, где используется обращение к данному компоненту, к сожалению, не получается. Я решил изменить схему расположения - вместо модуля будут обычные компоненты и модели внутри приложения и отдельные контроллеры для фронтэнда и бэкэнда. Свой вариант по мере доработки постараюсь выложить на GitHub.

четверг, 18 апреля 2013 г.

Возня с android'ом или попытки сделать табы внизу экрана

Несколько дней пытался разгадать эту загадку (как сделать табы внизу экрана). Пробовал различные варианты. И, наконец, озарение!
Предыстория.
Хотелось сделать универсальный вариант, без использования deprecated методов и классов.
К тому же на каждый таб предполагалась обработка в отдельных классах. А использование Intent для загрузки классов требует setup'а с LocalActivityManager, который уже устарел.
Основной класс унаследован от FragmentActivity, который не в android.app, а в android.support.v4.app


FragmentTabHost mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);

вторник, 5 февраля 2013 г.

iOS разработка или первое знакомство с Objective C

После долгого пропуска решил немного написать. Быть может это пригодится еще кому-нибудь. Сталкиваюсь с информацией, на которую большой спрос в англоязычной части интернета и весьма скудное описание в русскоязычной. Objective C. Это то, с чем мне пришлось познакомиться не так давно. Пока воспоминания свежи напишу, пока разрозненно, потом постараюсь "собрать в кучу". Итак. Кажется, что это C/C++ с небольшими отличиями.
1) вместо обычного расширения  .c или .cpp  - .m
2) вместо #include - #import/
3) вместо class - @interface в заголовочном файле и @implementation в основном. Чем-то такая конструкция напомнила pascal с его модулями unit. Но никак не ожидал подобное увидеть в C.
4) вместо static - "+". для nonstatic (то есть принадлежащих объектам, а не классам) членов - "-".

5) Конкатенация (слияние) строк - отдельная тема для разговора. Конструкции такие, как "string1"."string2" как в php или хотя бы "string1"+"string2" - как в javascript или C# не работают. Самый "простой" (без преобразования типов в NSMutableString или NSArray) вариант - вызов сообщения stringByAppendingString как пример -
NSString *str;
NSString *res;
...
res=[str stringByAppendingString:@"_"];

Второй вариант сцепления строк -

[NSString stringWithFormat:@"%@/%@/%@", one, two, three];
Третий вариант - написание собственной статичной функции:

+ (NSString *) append:(id) first, ...
{
    NSString * result = @"";
    id eachArg;
    va_list alist;
    if(first)
    {
     result = [result stringByAppendingString:first];
     va_start(alist, first);
     while (eachArg = va_arg(alist, id)) 
      result = [result stringByAppendingString:eachArg];
     va_end(alist);
    }
    return result;
}

среда, 28 марта 2012 г.

Форматирование даты в JavaScript с помощью regex



Столкнулся с задачей в JavaScript вывода даты/времени с добавлением "0" (аналог функций lpad в mySql или Oracle), если значение меньше 10. В интернете данная задача решается с помощью создания функции, например, такой:

function pad(num, size) {
    var s = num+"";
    while (s.length < size) s = "0" + s;
    return s;
}
или такие:
function pad(num, size) {
    var s = "000000000" + num;
    return s.substr(s.length-size);
}

function zeroPad(num, places) {
  var zero = places - num.toString().length + 1;
  return Array(+(zero > 0 && zero)).join("0") + num;
}

вторник, 31 января 2012 г.

Размышления об изменениях...

Вчера вечером получил письмо от Google. Озаглавлено оно было так:
Изменения в Политике конфиденциальности и Условиях использования сервисов Google 

Особенно "понравилась" часть насчет персонального поиска:

Персонализация

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


На мой взгляд, такой подход является плохим. Чтобы узнать то, что человеку нужно именно в этот момент, необходимо прочитать его мысли. Так как до сих пор еще нет устройства, позволяющего их читать, то использование "личных предпочтений" будет весьма негативно для конечных пользователей. Одно дело, когда один и тот же человек на протяжении многих лет, интересуется, например, политикой или авто, рыбалкой или туризмом. И его взгляды неизменны  на протяжении многих лет. Но что делать мне? Или таким как я. Сегодня услышал про старый фильм, заинтересовался им, поискал, завтра - новым авто, а Google все запомнил и так и норовит мне предложить то, что когда-то интересовало (причем интерес был сиюминутным), а сейчас уже это не то, что неинтересно, а совершенно безразлично. Представляете, поиск будет работать как старая газета или книга. Один раз прочитал - интересно, второй, третий, пятый - уже не так... А про десятый уже и говорить неохота. В общем никакой новизны. Поискал один раз цитату из Пушкина и всё. Так и любой запрос будет Google'м сначала все книги из Пушкина проверяться... Не очень, скажу, радостная перспектива. А как же настроение? У меня же оно меняется... Зато Google всё запомнит... Не хочу такой персонализации!!! Это  мне придется целую кучу аккаунтов заводить под каждое настроение или жизненный случай. Что за однобокость в мышлении?

среда, 25 января 2012 г.

Управление службой .NET через WinApi

Предыстория.
Для службы сбора данных через DDE необходимо активировать "Взаимодействие с рабочим столом" в свойствах службы. По какой-то причине встроенные функции установки службы не позволяют управлять данной возможностью. Имеется в виду классы ServiceInstaller и ServiceProcessInstaller. Из-за этого, а также в виду необходимости перезапуска службы при наступлении определенных событий, не используя при этом bat-файлы, планировщики задач и отдельные программы, появился такой класс:


пятница, 20 января 2012 г.

Основы AGAL

Начну с того, что AGALMiniAssembler.as который активно используется во всех примерах официально не поддерживается компанией Adobe, вследствие чего содержит небольшие неточности.
Во-первых, в нем описаны инструкции AGAL, которые на самом деле еще не реализованы (исключены). Это:

инструкции ifzinzifeineifgifliegielelseifreperpbrk, sgn.
А во-вторых, в нем нет двух инструкций, которые поддерживаются Flash Player'ом:
seq, sne.
Эти две инструкции аналогичны sge, slt.