Как стать автором
Обновить

Как не надо делать проверку валидности email

Время на прочтение 4 мин
Количество просмотров 32K
Автор оригинала: Wendy Liu
imageПредставьте на минутку, что вы — недавно принятый на работу программист, которому предстоит работать с популярной системой управления обучением (LMS) Hot4Learning. Ваш предшественник когда-то поработал над добавлением к системе возможности отправки email — для того, чтобы любой пользователь в школе мог отправить другому пользователю электронное письмо с помощью веб-интерфейса. Но, увы, судьба оказалась к нему неблагосклонна — его сбил автобус, и он так никогда и не завершил свой magnum opus, свою лебединую песню. Ваша задача — довести его дело до конца, добавив функцию валидации введенного email — чтобы можно было быть уверенным, что письма отправляются только в том случае, когда в качестве адресата вводится правильный адрес, привязанный к школе.

Приведем конкретный пример: допустим, Боб — студент в Университете Макгилла, и он должен иметь возможность отправить письмо на любой валидный адрес @mail.mcgill.ca или @mcgill.ca. Если адрес его подружки Джейн выглядит как jane.smith@mail.mcgill.ca, то тогда Боб имеет полное право отправлять на него письма. В другом случае — скажем, если ее адрес jane.smith@mail.ru — он, понятное дело, права на это не имеет, как и на отсылку писем на адрес thisisnotavalidemail@mail.mcgill.ca.

Итак, ваша задача — реализовать эту возможность; при этом предполагается, что у вас есть список валидных адресов почты для конкретного учебного заведения.

Скорее всего, вы сейчас подумали «Да бросьте, ерунда какая-то, а не задача. Сначала, я создаю строку, в которой делаю конкатенацию всех адресов школы в список с разделителем '|****|', затем я передаю ее клиенту, присваивая строку переменной внутри тэга . Затем, в JavaScript, я создаю массив и присваиваю его переменной, любовно обозванной temp. Каждый раз, когда пользователь вводит email, я перевожу его в нижний регистр и сохраняю в переменную с заманчивым названием curForwardUserName... а еще я создам переменную validUserName, которую я сделаю равной строке '0', потому что зачем мне использовать boolean, если я могу использовать строку? Затем, я в цикле пройду по всему содержимому temp; для каждого адреса почты в temp я переведу его в нижний регистр, затем проверю, совпадает ли он с curForwardUserName - и если это так, то я задам validUserName равной строке '1' и вызову break. Наконец, если validUserName равняется строке '1', то я могу спокойно считать, что curForwardUserName - валидный адрес; в противном случае, он нам не подходит"

"Что за бред?" - подумали вы наверняка. Я надеюсь, что вам вряд ли пришло в голову написанное выше. Скорее, в вашей голове появилась следующая мысль: "ОК, очевидно, что валидацию я буду делать на стороне сервера. Я могу хранить валидные адреса почты в структуре данных, которая позволяет проводить сравнения со сложностью в O(1), и затем проверять, содержится ли в ней введенный email". И это нормально - ведь это правильный способ решения задачи.

Вот как решит эту задачу ваш мозг

В Python правильный способ решения этой задачи будет выглядеть следующим образом:

if input_email in valid_emails_set:
    send_email(input_email, another_param, etc)


А вот как решит эту задачу ваш мозг под наркотиками

Но если злодейка-судьба закинула вас работать с великим и ужасным Hot4Learning, то вы, вполне возможно, всей душой ненавидите свою работу, и вам каждый день приходится от души "упарываться" наркотиками, чтобы вы могли хотя бы до нее дойти. Зато ваш наркомозг способен выдать такое:
Внимание: NSFWUYWOH (Not Safe For Work Unless You Work On Hot4Learning - Небезопасно Для Работы Только Если Вы Не Разработчик Hot4Learning)

<script>
// [какой-то еще код]
var userNamesStr = 'a.fakelastname@mail.mcgill.ca|****|another.fakelastname@mail.mcgill.ca
|****|(представим, что здесь лежит еще 70,000 emailов)|****|zamboni.man@mail.mcgill.ca';
var temp = new Array();
temp = userNamesStr.split('|****|');
var validUserName = '0';
// [вырезано цензурой]
for( i =0; i< temp.length; i++){
if( curForwardUserName == temp[i].toLowerCase() ) {
validUserName = '1';
break;
}
// [и еще немного бесценной мудрости]
</script>

Кстати, вышеприведенный код отправляет все 70,000+ адресов Университета Макгилла на клиент при каждой загрузке страницы. Исходный код страницы весит около 2.5MB, считай что чистого текста. Ну, а поскольку тот человек, что занимается код-ревью, и сам сидит на мете - ваш код легким движением руки попадает в продакшн.

Голая правда

В прошлом году, IT-отдел Университета МакГилла заменил старую LMS (Blackboard) на новую систему (которая на самом деле называется не совсем Hot4Learning, но давайте не будем мелочиться - ведь все остальное в лучших традициях Попова не тронуто). Поскольку старая система рассыпалась на глазах из-за уязвимостей и страдала от кучи других проблем, новую систему ждали с огромной надеждой на светлое будущее. Надежда умерла с той же скоростью, с какой у вышеозначенного наркомана когда-то безвозвратно умерли клетки головного мозга.

Клик на вкладку "email" встречал меня 10 секундами белого экрана и ожиданием того момента, когда браузер наконец загрузит страницу. Возник логичный вопрос - "Какого оно вообще столько грузится? Не может же оно пытаться загрузить все валидные адреса, хехех... Стоп. Блин..."
Словами трудно описать тот ужас, что охватил меня при просмотре исходников страницы. Страшнее в моей жизни был только сон про то, что мне удалось проспать экзамен по криптографии.

Увы, "вживую" вам на этот код полюбоваться уже не удастся - был отправлен баг-репорт как об уязвимости утечки данных, и поставщик ПО за две недели все исправил. Код, приведенный выше - один в один тот, что использовался в приложении - разве что, были опущены не имеющие отношения к его работе места. Все соображения по поводу того, на чем сидит программист-автор, принимаются на мой твиттер @dellsystem.

ПРЕДУПРЕЖДЕНИЕ: Злоупотребление наркотиками плохо влияет на ваш исходный код.
Теги:
Хабы:
+36
Комментарии 63
Комментарии Комментарии 63

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн