Module: HousingMisc::ApiHelper

Included in:
LogsController, ModelReflectionsController, SidekiqQueueCheckController
Defined in:
lib/housing_misc/api_helper.rb

Constant Summary collapse

MOBILE_REQUEST_TIME_THRESHOLD =

in seconds

300

Instance Method Summary collapse

Instance Method Details

#add_attachments(email_template_hash, attachments) ⇒ Object



128
129
130
131
# File 'lib/housing_misc/api_helper.rb', line 128

def add_attachments(email_template_hash, attachments)
  email_template_hash[:params_json][:attachments] = attachments if attachments.present?
  return email_template_hash
end

#add_base_vars(email_template_hash, base_vars) ⇒ Object



90
91
92
93
94
# File 'lib/housing_misc/api_helper.rb', line 90

def add_base_vars(email_template_hash, base_vars)
  email_template_hash[:params_json].merge!(base_vars)
  email_template_hash[:test_email] = Housing.mail_test_id
  return email_template_hash
end

#add_global_merge_vars(email_template_hash, vars) ⇒ Object



105
106
107
108
109
110
111
112
# File 'lib/housing_misc/api_helper.rb', line 105

def add_global_merge_vars(email_template_hash, vars)
  email_template_hash[:params_json][:global_merge_vars][:modules].each do |mod_name|
    mod_name[:merge_vars].first.each do |key, value|
      mod_name[:merge_vars].first[key] = vars[key] if value.nil?
    end
  end
  return email_template_hash
end

#add_merge_vars(email_template_hash, vars) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/housing_misc/api_helper.rb', line 114

def add_merge_vars(email_template_hash, vars)
  email_template_hash[:params_json][:merge_vars] = []
  email_template_hash[:params_json][:users].each do |user_email|
    email = user_email[:email]
    email_template_hash[:params_json][:merge_vars].push(email_template_hash[:params_json][:global_merge_vars].merge({email: email}))
  end
  if email_template_hash[:params_json][:global_merge_vars][:template_merge_vars].present?
    email_template_hash[:params_json][:global_merge_vars][:template_merge_vars].each do |key, value|
      email_template_hash[:params_json][:global_merge_vars][:template_merge_vars][key] = vars[key]
    end
  end
  return email_template_hash
end

#add_user_emails(email_template_hash, users) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/housing_misc/api_helper.rb', line 96

def add_user_emails(email_template_hash, users)
  email_template_hash[:params_json][:users] = []
  users.each do |user_email|
    user_email = user_email.with_indifferent_access
    email_template_hash[:params_json][:users].push({name: user_email[:name], email: user_email[:email]})
  end
  return email_template_hash
end

#csrf_check(csrf_encryption_key, velocity_salt) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/housing_misc/api_helper.rb', line 58

def csrf_check(csrf_encryption_key, velocity_salt)
  unless is_request_csrf_valid?(request, cookies, params, csrf_encryption_key, velocity_salt)
    log_file ||= Logger.new("#{Rails.root}/log/unauthorized_api_requests.log")
    log_invalid_csrf_request(log_file, request, cookies, params)
    render :json => {:message => "You are not authorized to make this call", :error => "CSRF_CHECK_FAILED"}, status: 401
  end
end

#filter_parameters(params) ⇒ Object



9
10
11
12
13
# File 'lib/housing_misc/api_helper.rb', line 9

def filter_parameters(params)
  filters = Rails.application.config.filter_parameters rescue []
  f = ActionDispatch::Http::ParameterFilter.new filters
  return f.filter(params)
end

#get_api_call(url, request_timeout = 15.0) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/housing_misc/api_helper.rb', line 169

def get_api_call(url, request_timeout = 15.0)
  parsed_url = URI.parse(url)
  http = Net::HTTP.new(parsed_url.host, parsed_url.port)
  http.read_timeout = request_timeout
  request = Net::HTTP::Get.new(parsed_url.request_uri)
  begin
    response = http.request(request)
    raise "request failed :: #{response}" if response.code != "200"
    request_response = response.body
  rescue => exception
    logging_file.error("CampaignError :: #{exception}")
    raise "CampaignError for url: #{url}"
  end
  return request_response
end

#get_email_template_from_mail_service(template_slug, template_version) ⇒ Object



134
135
136
137
138
# File 'lib/housing_misc/api_helper.rb', line 134

def get_email_template_from_mail_service(template_slug, template_version)
  template_name = template_slug.gsub("-","_")
  uri = URI.parse("#{Housing.mail_service_url}v1/email/request_format?template_name=#{template_name}&template_version=#{template_version}")
  response = (Oj.load(Net::HTTP.get(uri))["data"]) rescue {}
end

#get_past_channel_details(profiles_hash, start_datetime, end_datetime, channel, template_details) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/housing_misc/api_helper.rb', line 140

def get_past_channel_details(profiles_hash, start_datetime, end_datetime, channel, template_details)
  response = {}
  query_params = {
                  template_name: template_details[:template_name],
                  end_datetime: end_datetime
                 }
  query_params[:template_version] = template_details[:template_version] if channel == "email"

  profiles_date_hash = {}
  profiles_hash.each do |key, value|
    date = value["last_activity_time"] || start_datetime
    date = Date.strptime(date.to_s,'%s').to_time.to_i
    (profiles_date_hash[date] ||= []) << key
  end

  profiles_date_hash.each do |date, email_or_numbers|
    # increasing batch size would lead to exception 414 URI too large, Please don't increase batch size
    email_or_numbers.each_slice(100) do |batch|
      query_params[identifier[channel.to_sym]] = batch.join(',')
      query_params[:start_datetime] = date
      query = query_params.to_query
      url = send("#{channel}_report_url".to_sym) + query
      batch_response = (Oj.load(get_api_call(url))["data"])
      response.merge!(batch_response)
    end
  end
  response
end

#get_request_attribute_value(headers, params, key) ⇒ Object



5
6
7
# File 'lib/housing_misc/api_helper.rb', line 5

def get_request_attribute_value(headers, params, key)
  headers["HTTP_#{key.upcase.tr('-', '_')}"] || params[key]
end

#get_shortened_url(url) ⇒ Object



200
201
202
203
204
205
206
207
208
# File 'lib/housing_misc/api_helper.rb', line 200

def get_shortened_url(url)
  shortened_url = ""
  uri = URI.parse("#{Housing.url_shortener}/shorten")
  response = Net::HTTP.post_form(uri, {url: url})
  if response.code.to_i == 200
    shortened_url = Housing.short_url_domain + JSON.parse(response.body)["id"]
  end
  shortened_url
end

#internal_host_checkObject



50
51
52
53
54
55
56
# File 'lib/housing_misc/api_helper.rb', line 50

def internal_host_check
  unless is_request_internal?(request)
    log_file ||= Logger.new("#{Rails.root}/log/unauthorized_api_requests.log")
    log_file.info "Internal host check violated | remote_ip:#{request.remote_ip}, host:#{request.host}, port:#{request.port}, params:#{filter_parameters(params)}"
    render :json => {:message => "You are not authorized to make this call"}, status: 401
  end
end

#is_request_csrf_valid?(request, cookies, params, csrf_encryption_key, velocity_salt) ⇒ Boolean

Returns:

  • (Boolean)


40
41
42
43
44
45
46
47
48
# File 'lib/housing_misc/api_helper.rb', line 40

def is_request_csrf_valid?(request, cookies, params, csrf_encryption_key, velocity_salt)
  if request.get? || is_request_internal?(request) || is_request_from_mobile?(request, params, velocity_salt)
    return true
  else
    csrf_id = cookies["cuid"] || ""
    csrf_token = request.headers["HTTP_X_CSRF_TOKEN_V2"]
    return OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), csrf_encryption_key, csrf_id) == csrf_token
  end
end

#is_request_from_mobile?(request, params, velocity_salt) ⇒ Boolean

Returns:

  • (Boolean)


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/housing_misc/api_helper.rb', line 19

def is_request_from_mobile?(request, params, velocity_salt)
  source = get_request_attribute_value(request.headers, params, "source") || ""
  time_stamp = get_request_attribute_value(request.headers, params, "ts")
  signed_param = get_request_attribute_value(request.headers, params, "sp")

  if time_stamp.blank? || signed_param.blank?
    if ["android", "ios"].include?(source.downcase) # To be removed once all the users moves to latest app version which includes ts-sp thing
      log_file ||= Logger.new("#{Rails.root}/log/app_requests_with_missing_params.log")
      log_invalid_csrf_request(log_file, request, cookies, params)
       return true 
    elsif params["app_name"] == "locon.com.datacollection" # To be removed once dc app implements ts-sp thing
      log_file ||= Logger.new("#{Rails.root}/log/dc_app_requests_with_missing_params.log")
      log_invalid_csrf_request(log_file, request, cookies, params)
       return true 
    end
  else
    return ((Time.now.to_i - time_stamp.to_i) <= MOBILE_REQUEST_TIME_THRESHOLD) && (Digest::MD5.hexdigest(velocity_salt + time_stamp) == signed_param)
  end
  return false
end

#is_request_internal?(request) ⇒ Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/housing_misc/api_helper.rb', line 15

def is_request_internal?(request)
  Rails.env != "production" || request.host.include?("internal")
end

#log_invalid_csrf_request(log_file, request, cookies, params) ⇒ Object



66
67
68
# File 'lib/housing_misc/api_helper.rb', line 66

def log_invalid_csrf_request(log_file, request, cookies, params)
  log_file.info "CSRF check violated | new_csrf_token:#{request.headers["HTTP_X_CSRF_TOKEN_V2"]} | new_csrf_id:#{cookies["cuid"]} | remote_ip:#{request.remote_ip} | host:#{request.host} | port:#{request.port} | method:#{request.method} | referrer:#{request.referrer} | User-Agent:#{request.headers["User-Agent"]} | source:#{get_request_attribute_value(request.headers, params, "source")} | time_stamp: #{get_request_attribute_value(request.headers, params, "ts")} | signed_param:#{get_request_attribute_value(request.headers, params, "sp")} | params:#{filter_parameters(params)}"
end

#logging_fileObject



185
186
187
# File 'lib/housing_misc/api_helper.rb', line 185

def logging_file
  @log_file ||= Logger.new("#{Rails.root}/log/campaign_errors.log")
end

#send_generic_mail(template_slug, template_version, users, base_vars, merge_vars, high_priority = false, attachments = [], deferred = false, send_time = nil, google_analytics_campaign = nil) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/housing_misc/api_helper.rb', line 70

def send_generic_mail(template_slug, template_version, users, base_vars, merge_vars, high_priority=false, attachments=[], deferred=false, send_time=nil, google_analytics_campaign=nil)
  base_vars = base_vars.with_indifferent_access
  merge_vars = merge_vars.with_indifferent_access
  email_template_hash = get_email_template_from_mail_service(template_slug, template_version).with_indifferent_access
  email_template_hash = add_base_vars(email_template_hash, base_vars)
  if google_analytics_campaign.present?
    email_template_hash[:params_json].merge!(google_analytics_campaign: google_analytics_campaign)
  end
  email_template_hash = add_user_emails(email_template_hash, users)
  email_template_hash = add_global_merge_vars(email_template_hash, merge_vars)
  email_template_hash = add_merge_vars(email_template_hash, merge_vars)
  email_template_hash = add_attachments(email_template_hash, attachments)
  if deferred
    response = Net::HTTP.post_form( URI( "#{Housing.mail_service_url}v1/email/send_deferred" ), "email_request"=> email_template_hash.to_json, "high_priority"=>high_priority, "send_time" => send_time)
  else
    response = Net::HTTP.post_form( URI( "#{Housing.mail_service_url}v1/email/send" ), "email_request"=> email_template_hash.to_json, "high_priority"=>high_priority)
  end
  return response.code.to_i, response.body
end

#send_generic_sms(phone_number, template_name, send_time, sms_params) ⇒ Object



189
190
191
192
193
194
195
196
197
198
# File 'lib/housing_misc/api_helper.rb', line 189

def send_generic_sms(phone_number, template_name, send_time, sms_params)
  post_args ={
    "template_name" => template_name,
    "sms_request[number]" => phone_number,
    "sms_request[test_number]" => Housing.sms_test_number,
    "send_time" => send_time,
    "sms_request[params_json]" => sms_params.to_json
  }
  response = Net::HTTP.post_form( URI("#{Housing.sms_service_url}/v0/sms/send_deferred"), post_args)
end

#upload_log_to_s3(file_path) ⇒ Object



210
211
212
213
# File 'lib/housing_misc/api_helper.rb', line 210

def upload_log_to_s3(file_path)
  s3_key = Rails.root.to_s.split('/')[-1] + '/' + file_path.split('/')[-1]
  s3_client.bucket(HousingMisc.bucket).object(s3_key).upload_file(file_path)
end