fortifier 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +29 -0
  5. data/app/controllers/fortifier/application_controller.rb +17 -0
  6. data/app/controllers/fortifier/auth_users_controller.rb +107 -0
  7. data/app/helpers/fortifier/application_helper.rb +4 -0
  8. data/app/helpers/fortifier/auth_users_helper.rb +4 -0
  9. data/app/helpers/fortifier/date_helper.rb +46 -0
  10. data/app/helpers/fortifier/passwords_helper.rb +4 -0
  11. data/app/mailers/fortifier/notifier_mailer.rb +66 -0
  12. data/app/models/fortifier/auth_log.rb +18 -0
  13. data/app/models/fortifier/auth_rule.rb +11 -0
  14. data/app/models/fortifier/auth_steps/check_for_blocked_ip.rb +22 -0
  15. data/app/models/fortifier/auth_steps/check_for_blocked_user.rb +16 -0
  16. data/app/models/fortifier/auth_steps/check_for_us_external_ip.rb +14 -0
  17. data/app/models/fortifier/auth_steps/check_for_whitelisted_ip.rb +38 -0
  18. data/app/models/fortifier/auth_steps/initialize_auth_attempt.rb +19 -0
  19. data/app/models/fortifier/auth_steps/initialize_batch_sso_auth_attempt.rb +18 -0
  20. data/app/models/fortifier/auth_steps/initialize_on_demand_sso_auth_attempt.rb +18 -0
  21. data/app/models/fortifier/auth_steps/messaging.rb +16 -0
  22. data/app/models/fortifier/auth_user.rb +256 -0
  23. data/app/models/fortifier/auth_user_api.rb +356 -0
  24. data/app/models/fortifier/auth_users_auth_rule.rb +8 -0
  25. data/app/models/fortifier/authentication.rb +17 -0
  26. data/app/models/fortifier/authentication_steps.rb +46 -0
  27. data/app/models/fortifier/batch_updater.rb +148 -0
  28. data/app/models/fortifier/max_mind.rb +64 -0
  29. data/app/models/fortifier/max_mind_reference_ip.rb +5 -0
  30. data/app/models/fortifier/rufus/rufus_password_expiration.rb +23 -0
  31. data/app/models/fortifier/secret.rb +189 -0
  32. data/app/views/fortifier/notifier_mailer/account_ip_blocked.html.erb +30 -0
  33. data/app/views/fortifier/notifier_mailer/account_ip_blocked_providigm.html.erb +20 -0
  34. data/app/views/fortifier/notifier_mailer/exception_notification.html.erb +88 -0
  35. data/app/views/fortifier/notifier_mailer/foreign_access.html.erb +22 -0
  36. data/app/views/fortifier/notifier_mailer/password_expiration.html.erb +28 -0
  37. data/app/views/fortifier/notifier_mailer/password_reset_token.html.erb +28 -0
  38. data/app/views/fortifier/notifier_mailer/task_exception.html.erb +18 -0
  39. data/app/views/layouts/fortifier/application.html.erb +14 -0
  40. data/config/Initializers/bcrypt.rb +1 -0
  41. data/config/Initializers/ipaddr.rb +1 -0
  42. data/config/database.yml +18 -0
  43. data/config/routes.rb +27 -0
  44. data/db/migrate/20130916194012_create_fortifier_tables.rb +63 -0
  45. data/db/migrate/20140415210139_add_auth_user_search_keywords_field.rb +9 -0
  46. data/db/migration_scripts/20140403_temp_whitelist_migration.rb +5 -0
  47. data/lib/fortifier/engine.rb +40 -0
  48. data/lib/fortifier/version.rb +3 -0
  49. data/lib/fortifier.rb +4 -0
  50. data/lib/tasks/fortifier_tasks.rake +4 -0
  51. metadata +176 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b6ed6a9fcd00d6437c0c38ce81f6f96efcbfbf7c
4
+ data.tar.gz: f60fd7efc29b5417730fa253689a86ca4b621156
5
+ SHA512:
6
+ metadata.gz: 8c1b60d42998963ee270b24a23f984c04cddc7ea73ee339f76b591e8ccc6ca77bc80a53b347effe550a5591dc7cf29dd909ee7880d758aa13512920efca40c84
7
+ data.tar.gz: 47f5af0a072b921c33fbd5aba58894d40f17c8a7f4ff3798aadb33baebb92e3827c9267574885d81878904e68114ffd1c3acd5071457ffe162204f497a4b1914
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = Fortifier
2
+
3
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Fortifier'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
@@ -0,0 +1,17 @@
1
+ module Fortifier
2
+ class ApplicationController < ActionController::Base
3
+
4
+ before_action :restrict_access
5
+
6
+ private
7
+
8
+ def restrict_access
9
+ authenticate_or_request_with_http_token do | token, options |
10
+ # TODO: (DS) Need to have an API_KEY constant defined at
11
+ # deploy time.
12
+ defined?(API_KEY) ? token == API_KEY : false
13
+ end
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,107 @@
1
+ require_dependency "fortifier/application_controller"
2
+
3
+ module Fortifier
4
+ APP_ID_ABAQIS = 'abaqis'
5
+ APP_ID_EMP_SAT = 'employee_satisfaction'
6
+
7
+ class AuthUsersController < Fortifier::ApplicationController
8
+ respond_to :json
9
+
10
+ def authenticate
11
+ results = api.authenticate(params["login"],
12
+ params["password"],
13
+ request.env["HTTP_USER_AGENT"],
14
+ request.ip)
15
+
16
+ render json: results
17
+ end
18
+
19
+ def authenticate_uuid
20
+ results = api.authenticate_uuid(params["uuid"],
21
+ params["password"],
22
+ request.env["HTTP_USER_AGENT"],
23
+ request.ip)
24
+
25
+ render json: results
26
+ end
27
+
28
+ def authenticate_batch_sso
29
+ results = api.authenticate_batch_sso(params["account-id"],
30
+ params["user-token"],
31
+ request.env["HTTP_USER_AGENT"],
32
+ request.ip)
33
+
34
+ render json: results
35
+ end
36
+
37
+ def authenticate_on_demand_sso
38
+ results = api.authenticate_on_demand_sso(params["password"],
39
+ request.env["HTTP_USER_AGENT"],
40
+ request.ip)
41
+
42
+ render json: results
43
+ end
44
+
45
+ def validate
46
+ render json: api.validate(params[:auth_user])
47
+ end
48
+
49
+ def batch_update
50
+ render json: api.batch_update(params['user_info'])
51
+ end
52
+
53
+ def create
54
+ render json: api.create(params[:auth_user])
55
+ end
56
+
57
+ def update
58
+ render json: api.update(params[:auth_user])
59
+ end
60
+
61
+ def change_password
62
+ render json: api.change_password(params[:auth_user])
63
+ end
64
+
65
+ def reset_password
66
+ render json: api.reset_password(params[:auth_user])
67
+ end
68
+
69
+ def create_password_reset_token
70
+ render json: api.create_password_reset_token(params[:email])
71
+ end
72
+
73
+ def link
74
+ render json: api.link(params[:auth_user])
75
+ end
76
+
77
+ def unlink
78
+ render json: api.unlink(params[:auth_user])
79
+ end
80
+
81
+ def find_auth_user
82
+ render json: api.find_auth_user(params[:auth_user].keys.first, params[:auth_user].values.first)
83
+ end
84
+
85
+ def find_auth_user_emails
86
+ render json: api.find_auth_user_emails(params[:uuids])
87
+ end
88
+
89
+ def search_for_auth_users
90
+ render json: api.search_for_auth_users(safe_params)
91
+ end
92
+
93
+ def auth_users_by_uuids
94
+ render json: api.auth_users_by_uuids(params[:uuids])
95
+ end
96
+
97
+ private
98
+
99
+ def api
100
+ @api ||= AuthUserApi.new
101
+ end
102
+
103
+ def safe_params
104
+ params.permit(:search,:sortcol,:sortdir,:per_page,:page,:app_uuid,:account_uuid)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,4 @@
1
+ module Fortifier
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Fortifier
2
+ module AuthUsersHelper
3
+ end
4
+ end
@@ -0,0 +1,46 @@
1
+ module Fortifier
2
+ module DateHelper
3
+
4
+ # Produces -> 5/21/2007
5
+ def american_date(date)
6
+ return nil if date.nil?
7
+ (date.is_a?(Date) || date.is_a?(Time)) ? (date.is_a?(Time) ? date.in_time_zone(DISPLAY_TIME_ZONE).strftime("%-m/%-d/%Y") : date.strftime("%-m/%-d/%Y")) : date
8
+ end
9
+
10
+ #Produces -> 2013-05-21
11
+ def euro_date(date)
12
+ return nil if date.nil?
13
+ (date.is_a?(Date) || date.is_a?(Time)) ? (date.is_a?(Time) ? date.in_time_zone(DISPLAY_TIME_ZONE).strftime("%Y-%m-%d") : date.strftime("%Y-%m-%d")) : date
14
+ end
15
+
16
+ # Produces -> 5/21/09
17
+ def short_date(date)
18
+ return nil if date.nil?
19
+ (date.is_a?(Date) || date.is_a?(Time)) ? (date.is_a?(Time) ? date.in_time_zone(DISPLAY_TIME_ZONE).strftime("%-m/%-d/%y") : date.strftime("%-m/%-d/%y")) : date
20
+ end
21
+
22
+ def format_date_long(date)
23
+ # format example: "July 29, 2013"
24
+ return nil if date.nil?
25
+ (date.is_a?(Date) || date.is_a?(Time)) ? (date.is_a?(Time) ? date.in_time_zone(DISPLAY_TIME_ZONE).strftime("%B %d, %Y") : date.strftime("%B %d, %Y")) : date
26
+ end
27
+
28
+ def format_time_12hr(time)
29
+ # format example: "4:41pm"
30
+ return nil if time.nil?
31
+ (time.is_a?(DateTime) || time.is_a?(Time)) ? time.in_time_zone(DISPLAY_TIME_ZONE).strftime("%l:%M%P").gsub(' ','') : time
32
+ end
33
+
34
+ def american_date_time(date)
35
+ return nil if date.nil?
36
+ (date.is_a?(Date) || date.is_a?(Time)) ? (date.is_a?(Time) ? date.in_time_zone(DISPLAY_TIME_ZONE).strftime("%-m/%-d/%Y %H:%M:%S") : date.strftime("%-m/%-d/%Y %H:%M:%S")) : date
37
+ end
38
+
39
+ # Produces => Mar 10,2010
40
+ def short_month_date(date)
41
+ return nil if date.nil?
42
+ (date.is_a?(Date) || date.is_a?(Time)) ? (date.is_a?(Time) ? date.in_time_zone(DISPLAY_TIME_ZONE).strftime("%b %-d, %Y") : date.strftime("%b %-d, %Y")) : date
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,4 @@
1
+ module Fortifier
2
+ module PasswordsHelper
3
+ end
4
+ end
@@ -0,0 +1,66 @@
1
+ module Fortifier
2
+ class NotifierMailer < ActionMailer::Base
3
+ add_template_helper(DateHelper)
4
+
5
+ default :from => "abaqis@providigm.com"
6
+
7
+ def foreign_access(auth_user, auth_log)
8
+ @auth_user = auth_user
9
+ @auth_log = auth_log
10
+ mail(
11
+ :to => "software.admin@providigm.com",
12
+ :subject => "Foreign IP access attempt on: #{host_uri}")
13
+ end
14
+
15
+ def password_expiration(password_model, email)
16
+ @pw_expiration_date = password_model.expiration_date
17
+ mail(
18
+ :to => Rails.env.development? ? $system_mail_recipients : email,
19
+ :subject => "Password Expiration")
20
+ end
21
+
22
+ def exception_notification(controller,request,exception)
23
+ @request = request
24
+ @controller = controller
25
+ @exception = exception
26
+ mail(
27
+ :to => "software.admin@providigm.com",
28
+ :from => "abaqis.dev@nursinghomequality.com",
29
+ :subject => "Error discovered in: #{@request.env["HTTP_HOST"]}")
30
+ end
31
+
32
+ def task_exception(exception)
33
+ @exception = exception
34
+ mail(
35
+ :to => "software.admin@providigm.com",
36
+ :from => "abaqis.dev@nursinghomequality.com",
37
+ :subject => "Error discovered in: #{host_uri}")
38
+ end
39
+
40
+ def account_ip_blocked(auth_user, remote_addr, account)
41
+ @auth_user = auth_user
42
+ @remote_addr = remote_addr
43
+ @account = account #hash
44
+ mail(
45
+ :to => Rails.env.development? ? $system_mail_recipients : account[:email],
46
+ :subject => "IP block")
47
+ end
48
+
49
+ def account_ip_blocked_providigm(auth_user, remote_addr, account)
50
+ @auth_user = auth_user
51
+ @remote_addr = remote_addr
52
+ @account = account #hash
53
+ recipients = $system_mail_recipients + %w(csrs@providigm.com)
54
+ mail(
55
+ :to => Rails.env.development? ? $system_mail_recipients : recipients,
56
+ :subject => "IP block - #{account[:organization] || account[:name]} - #{remote_addr}")
57
+ end
58
+
59
+ private
60
+
61
+ def host_uri
62
+ defined?(HOST_URI) ? HOST_URI : 'local.abaqis.com'
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+ module Fortifier
2
+ class AuthLog < ActiveRecord::Base
3
+ BLOCK_COUNT = 20 # an ip is actually blocked at 21 failed attempts
4
+
5
+ belongs_to :auth_user
6
+
7
+ def self.block_ip?(remote_addr)
8
+ # TODO: (DK) remove when no longer needed as reference:
9
+ # subselect = "SELECT status FROM fortifier_auth_logs WHERE remote_addr = '#{remote_addr}'
10
+ # AND created_at > '#{Time.now.utc - 10.minutes}' ORDER BY id desc LIMIT #{BLOCK_COUNT}"
11
+ # count = self.count_by_sql("select count(*) from (#{subselect}) subsel where subsel.status = 0")
12
+ BLOCK_COUNT == Fortifier::AuthLog.where(remote_addr: remote_addr, status: 0)
13
+ .where('created_at > ?', Time.now.utc-10.minutes)
14
+ .limit(BLOCK_COUNT)
15
+ .count
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Fortifier
2
+ class AuthRule < ActiveRecord::Base
3
+ TYPE_IP_FILTER = "ip_filter"
4
+ TYPE_PW_EXPIRATION_PERIOD = 'pw_expiration_period'
5
+ TYPE_PW_LOOKBACK_PERIOD = 'pw_lookback_period'
6
+
7
+ serialize :rule_value
8
+
9
+ has_many :auth_users_auth_rules
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class CheckForBlockedIp
4
+ def self.skip_step?(params)
5
+ params[:auth_msg].present?
6
+ end
7
+
8
+ def self.invoke(params)
9
+ auth_user = params[:auth_user]
10
+ remote_addr = params[:remote_addr]
11
+ account = params[:account]
12
+ ip_blocked = AuthLog.block_ip?(remote_addr)
13
+ if ip_blocked
14
+ # TODO: (DK) ? auth_log.destroy # this is so one user can't block an IP
15
+ NotifierMailer.account_ip_blocked(auth_user, remote_addr, account).deliver
16
+ NotifierMailer.account_ip_blocked_providigm(auth_user, remote_addr, account).deliver
17
+ end
18
+ params.merge! auth_msg: ip_blocked ? Messaging::IP_BLOCKED : nil
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class CheckForBlockedUser
4
+ def self.skip_step?(params)
5
+ auth_user = params[:auth_user]
6
+ params[:auth_msg].present? || auth_user.blank? || !auth_user.successful_log_in?
7
+ end
8
+
9
+ def self.invoke(params)
10
+ auth_user = params[:auth_user]
11
+ auth_user_blocked = auth_user.blocked?
12
+ params.merge! auth_msg: auth_user_blocked ? Messaging::USER_BLOCKED : nil
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,14 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class CheckForUsExternalIp
4
+ def self.skip_step?(params)
5
+ params[:auth_msg].present?
6
+ end
7
+
8
+ def self.invoke(params)
9
+ allowed = MaxMind.valid_ip?(params[:auth_log])
10
+ params.merge! auth_msg: allowed ? nil : Messaging::MAX_MIND_EXTERNAL_IP
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class CheckForWhitelistedIp
4
+ def self.skip_step?(params)
5
+ params[:auth_msg].present?
6
+ end
7
+
8
+ def self.invoke(params)
9
+ remote_addr = params[:auth_log].remote_addr
10
+ ip_ranges = Fortifier::AuthRule.
11
+ joins(:auth_users_auth_rules).
12
+ where('auth_user_id = ? and rule_type = ?', params[:auth_user].id, Fortifier::AuthRule::TYPE_IP_FILTER).
13
+ pluck(:rule_value).
14
+ flatten(1)
15
+ range_results = []
16
+
17
+ # TODO: (DK) refactor once tests are written for this
18
+ if ip_ranges.present?
19
+ ip_ranges.each do |ipr|
20
+ if ipr.count==1 #e.g. single-string range, like ['192.168.1.1/16']
21
+ range = (IPAddr.new(ipr.first)) # .to_i here will cause '.include?' to blowup, so don't use
22
+ range_results << range.include?(IPAddr.new(remote_addr).to_i)
23
+ elsif ipr.count==2 #e.g. double-string range, like ['192.168.1.1', '192.168.1.255']
24
+ range = (IPAddr.new(ipr.first).to_i..IPAddr.new(ipr.last).to_i)
25
+ range_results << range.include?(IPAddr.new(remote_addr).to_i)
26
+ else
27
+ # no ip ranges were specified
28
+ range_results << true
29
+ end
30
+ end
31
+ else
32
+ range_results << true
33
+ end
34
+ params.merge! auth_msg: range_results.include?(true) ? nil : Messaging::EXTERNAL_IP
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class InitializeAuthAttempt
4
+ def self.invoke(params)
5
+ secret = params[:secret]
6
+ auth_user = AuthUser.where(login: params[:login]).first
7
+ auth_success = secret.blank? || auth_user.blank? ? false : auth_user.authenticated?(secret)
8
+ auth_log = Fortifier::AuthLog.create(auth_user: auth_user,
9
+ user_agent: params[:user_agent],
10
+ remote_addr: params[:remote_addr],
11
+ status: (auth_success ? 1 : 0))
12
+
13
+ params.merge! auth_user: auth_user,
14
+ auth_log: auth_log,
15
+ auth_msg: (auth_user && auth_success) ? nil : Messaging::NO_AUTH_USER
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class InitializeBatchSsoAuthAttempt
4
+ def self.invoke(params)
5
+ token = params[:token]
6
+ auth_user = Fortifier::AuthUser.authenticate_batch_sso(params[:account_uuid], token) unless token.blank?
7
+ auth_log = Fortifier::AuthLog.create(auth_user: auth_user,
8
+ user_agent: params["HTTP_USER_AGENT"],
9
+ remote_addr: params["IP"],
10
+ status: (auth_user ? 1 : 0))
11
+
12
+ params.merge auth_user: auth_user,
13
+ auth_log: auth_log,
14
+ auth_msg: auth_user ? nil : Messaging::NO_AUTH_USER
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class InitializeBatchSsoAuthAttempt
4
+ def self.invoke(params)
5
+ token = params[:token]
6
+ auth_user = Fortifier::AuthUser.authenticate_on_demand_sso(params[:account_uuid], token) unless token.blank?
7
+ auth_log = Fortifier::AuthLog.create(auth_user: auth_user,
8
+ user_agent: params["HTTP_USER_AGENT"],
9
+ remote_addr: params["IP"],
10
+ status: (auth_user ? 1 : 0))
11
+
12
+ params.merge auth_user: auth_user,
13
+ auth_log: auth_log,
14
+ auth_msg: auth_user ? nil : Messaging::NO_AUTH_USER
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module Fortifier
2
+ module AuthSteps
3
+ class Messaging
4
+ GENERIC_FAIL_MESSAGE = :incorrect_login_or_password
5
+ INVALID_IP_MESSAGE = :invalid_ip
6
+
7
+ NO_AUTH_USER = GENERIC_FAIL_MESSAGE
8
+ NO_USER = GENERIC_FAIL_MESSAGE
9
+ USER_DISABLED = GENERIC_FAIL_MESSAGE
10
+ USER_BLOCKED = GENERIC_FAIL_MESSAGE
11
+ IP_BLOCKED = GENERIC_FAIL_MESSAGE
12
+ EXTERNAL_IP = INVALID_IP_MESSAGE
13
+ MAX_MIND_EXTERNAL_IP = INVALID_IP_MESSAGE
14
+ end
15
+ end
16
+ end