|  Реализация общих разделов (Новости, объявления, мероприятия, информационные страницы, галерея, библиотека)На страницах новостей, объявлений, мероприятий и информационных страниц сценарий поведения пользователя схожий, в зависимости от прав он может: только просматривать содержимое (обычный пользователь), добавлять, изменять, удалять содержимое (привелигированный пользователь).
 
 Для обычного пользователя все просто, он переходит по страницам и может посмотреть новости, объявления, текущие и запланированные мероприятия, просмотреть фотографии, но ничего изменить не может. Вся информация хранится в базе данных и перед тем как отобразить все это пользователю, содержимое проходит через функцию экранирования вывода, что является встроенной возможностью фреймворка.
 
 Для пользователя, у которого есть возможность создавать, изменять новости, объявления, и т.д., необходимо осуществить фильтрацию всего пользовательского ввода, в связи с тем, что пользователь целенаправленно может внедрить исполняемый код. Наиболее распространенным языком для внедрения кода является клиентский скриптовый язык JavaScript. В фреймворке Ruby on Rails встроена автоматическая фильтрация пользовательского ввода.
 
 Например, введенное пользователем 
           в содержимое новости, при сохранении в базу данных запишется как <script>alert('Hello!')</script>. При выборке и отображении пользователю, станет просто строкой 
          , которая, естественно, не исполнится, а просто отобразится.
 
 Присутствует возможность пользователю загружать изображения в галерею, для логотипа новостей, или прикреплять к новости. Необходимо фильтровать имена файлов, в связи с тем, что злоумышленник может использовать злонамеренное имя файла для перезаписи любого файла на сервере. Эта проблема решена путем присваивания фотографиям собственных имен при загрузке на сервер.
 
 def filename
 
 "#{secure_token}.#{file.extension}" if original_filename.present?
 
 End
 def secure_token
 
 var = :"@#{mounted_as}_secure_token"
 
 model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
 
 end
 
 Реализованный функционал можно посмотреть в Приложении 2 на следующих рисунках:
 
 
            Рисунок . Новости;
 
Рисунок . Создание новости;
 
Рисунок . Объявления;
 
Рисунок . Информационная страница;
 
Рисунок . Мероприятия;
 
Рисунок . Создание мероприятия;
 
Рисунок . Организационная структура;
 
Рисунок . Телефонная книга;
 
Рисунок . Галерея;
 
Рисунок . Библиотека.
 
 
 
 
            
              
                 Реализация раздела «Предоставление расчетного листа» Доступ к странице, предоставляющей информацию о расчетном листе сотрудника, проходит по следующему сценарию:
 
 
            Пользователь должен пройти дополнительную аутентификацию, для этого он должен быть зарегистрирован в системе. (см. Приложение 2 Рисунок . Вход на сервис расчетных листов)
 
При успешной аутентификации ему отображается его расчетный лист и график выплат за выбранный период. (см. Приложение 2 Рисунок . Сервис расчетных листов)
 
 При попытке входа пользователя на страницу расчетного листа происходит проверка на наличие сессии конкретного пользователя, в случае если сессии нет, то происходит переадресация на страницу аутентификации/регистрации/восстановления пароля.
 
 def check_access_to_paysheet
 
 unless current_user.id == session[:user_id]
 
 redirect_to login_url
 
 end
 
 end
 
 В момент использования пользователем услуги предоставления расчетного листа злоумышленнику может быть интересным «прослушивание» сетевого трафика. Заинтересовать его может пароль пользователя для доступа к листу, собственно информация, содержащаяся в листе, поэтому во время аутентификации и использования услугой расчетного листа необходимо использовать защищенное соединение.
 
 При переходе пользователя на страницу для аутентификации/регистрации/восстановления пароля создается защищенное соединение, используя сертификат безопасности, подписанный центром сертификации в организации.
 
 В контроллере вызывается метод redirect_to_https, производящий переадресацию на протокол https и блокируются вызовы методов redirect_to_http, являющийся обратным методу redirect_to_https.
 
 skip_before_filter :redirect_to_http
 
 before_filter :redirect_to_https
 
 При регистрации пользователя происходит проверка на наличие согласия пользователя с условиями предоставления услуги: «Согласны ли вы использовать данный сервис для получения «Расчетного листка» через портал Филиала ООО «ЛУКОЙЛ – Инжиниринг» «КогалымНИПИнефть» в г. Тюмени?», необходимое присутствие пароля, контрольного вопроса и ответа на него, также минимальная длина, равная 6 символам и подтверждение пароля.
 
 validates :agree, acceptance: true, allow_nil: false
 
 validates :password, :question, :answer, presence: true
 
 validates :password, length: { minimum: 6 }
 
 validates :password, confirmation: true
 
 Если проверка пройдена успешно, то происходит проверка на то, имеется ли уже пароль у пользователя, в случае если имеется, генерируется ошибка и пользователю не удается зарегистрироваться. Если нет пароля, то введенный пароль преобразуется с помощью функции SHA-256 с добавлением соли. Соль генерируется c помощью применения хэш-функции над текущим временем и случайным числом. Полученное преобразование пароля и соль пишутся в базу данных, в таблицу users, в поля encrypted_password и salt, соответственно.
 
 def set_password
 
 if password.present?
 
 if encrypted_password.nil? || encrypted_password.empty?
 
 self.salt = Digest::SHA256.hexdigest((Time.now + rand(10000)).to_s)
 
 self.encrypted_password = Digest::SHA256.hexdigest("#{ salt }#{ password }")
 
 else
 
 errors.add(:encrypted_password, "У вас уже установлен пароль")
 
 errors.blank?
 
 end
 
 end
 
 end
 
 Функция входа на сервис представляет собой сравнение преобразования от введенного пользователем пароля с имеющимся в базе данных.
 
 def authenticate(password)
 
 if encrypted_password == Digest::SHA256.hexdigest("#{ salt }#{ password }")
 
 self
 
 else
 
 nil
 
 end
 
 end
 
 После успешного входа на сервис, создается сессия, в нее пишется идентификатор текущего пользователя.
 
 if current_user.authenticate(params[:password])
 
 session[:user_id] = current_user.id
 
 format.html { redirect_to paysheet_path }
 
 В случае если пользователь забыл пароль, он может воспользоваться услугой восстановления пароля, ему необходимо будет ввести ответ на вопрос. В случае совпадения введенного ответа со значением, хранящимся в базе данных, будет сгенерирована ссылка, перейдя по которой сбросится пароль. Ссылка отправляется на корпоративную почту.
 
 def send_reset_password
 
 self.reset_password_token = SecureRandom.urlsafe_base64
 
 self.reset_password_sent_at = Time.zone.now
 
 save!(validate: false)
 
 Notifier.delay.reset_password(id)
 
 end
 
 При переходе пользователя по этой ссылке проверяется соответствие ссылки со значением reset_password_token текущего пользователя. На возможность восстановления дается 1 день, после генерации ссылки.
 
 if current_user.reset_password_token == params[:id] && params[:id] != nil
 
 if current_user.reset_password_sent_at < 1.day.ago
 
 flash[:alert] = "Время, отведенное для сброса пароля, вышло"
 
 redirect_to controller: 'sessions', action:'new', formType: 1
 
 else
 
 current_user.reset_password
 
 flash[:success] = "Пароль успешно сброшен"
 
 redirect_to controller: 'sessions', action:'new', formType: 2
 
 end
 
 else
 
 raise ActionController::RoutingError.new('Not Found')
 
 end
 
 Если вход осуществлен на сервис расчетных листов, создается подключение к другой базе данных, в которой хранятся сведения о расчетных листах пользователя. Для подключения к этой базе данных используется выделенный логин, имеющий право только на чтение. В эту базу данных данные экспортируются уже из бухгалтерской базы данных. В качестве параметров запроса используется табельный номер сотрудника и период времени. Отправляемые параметры фильтруются регулярным выражением и экранируются. Возвращаемые данные уже отображаются пользователю.
 
 К критичным свойствам информации можно отнести только конфиденциальность, потому как изменение целостности и доступности информации не принесет никакого толка нарушившему, пользователю отобразится измененный, или не отобразится вовсе его расчетный лист, но он всегда может напрямую обратиться в Бухгалтерию, этот сервис сделан лишь для удобства пользователям.
 
 |