housing_misc 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +125 -0
- data/app/controllers/housing_misc/application_controller.rb +11 -0
- data/app/controllers/housing_misc/cache_controller.rb +11 -0
- data/app/controllers/housing_misc/logs_controller.rb +25 -0
- data/app/controllers/housing_misc/model_reflections_controller.rb +172 -0
- data/app/controllers/housing_misc/sidekiq_queue_check_controller.rb +62 -0
- data/app/middleware/request_tracer.rb +19 -0
- data/config/routes.rb +6 -0
- data/lib/helpers/configuration.rb +27 -0
- data/lib/housing_misc.rb +31 -0
- data/lib/housing_misc/aerospike_cache_extension.rb +100 -0
- data/lib/housing_misc/api_helper.rb +239 -0
- data/lib/housing_misc/boolean_evaluator.rb +7 -0
- data/lib/housing_misc/diff_checker.rb +30 -0
- data/lib/housing_misc/distance_unit.rb +140 -0
- data/lib/housing_misc/encrypt_decrypt.rb +21 -0
- data/lib/housing_misc/engine.rb +10 -0
- data/lib/housing_misc/json_slice_render.rb +44 -0
- data/lib/housing_misc/models_reflections_helper.rb +111 -0
- data/lib/housing_misc/net_http_generic_request.rb +14 -0
- data/lib/housing_misc/railtie.rb +24 -0
- data/lib/housing_misc/slice_helper.rb +43 -0
- data/lib/housing_misc/version.rb +3 -0
- metadata +200 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d14aaaac7217beda43bfc468aa10e03f5147b6931dcba22b4de9c16612b59e03
|
4
|
+
data.tar.gz: '08c758b5e30e795abc3cba9c575fcf3f43e7a8bfe8e648fd399e05fca2471591'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 20c039487a4e67d5f64a9e888023f6beb65fe5e822380f081d997629f319a88f14e41aecfc688a01f8b5c72fa842c8b47b2dc69c2499810acc57fe950a662f39
|
7
|
+
data.tar.gz: 9607cd387341a8786d11ea4bd88ec821e1f8c8d27dc84326f3811acb262a1ef362285c3463ca3dc373437d87be0e92ac22ec327e69255c6bd0f22e337e61830d
|
data/README.md
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
# housing.misc.gem
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
```ruby
|
5
|
+
gem 'housing_misc'
|
6
|
+
```
|
7
|
+
And then execute:
|
8
|
+
|
9
|
+
$ bundle install
|
10
|
+
|
11
|
+
Or install it yourself as:
|
12
|
+
|
13
|
+
$ gem install housing_misc
|
14
|
+
|
15
|
+
## Functions Provided
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
get_request_attribute_value(headers, params, key)
|
19
|
+
```
|
20
|
+
> Parameters:
|
21
|
+
>
|
22
|
+
1. headers (data_type: ActionDispatch::Http::Headers)
|
23
|
+
2. params (data_type: ActionController::Parameters)
|
24
|
+
3. key (data_type: String, description: Name of the attribute whose value is needed)
|
25
|
+
|
26
|
+
> Description: Returns value against the key present in headers or params, first checks in headers if it's not there then checks in params
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
is_request_internal?(request)
|
32
|
+
```
|
33
|
+
> Parameters:
|
34
|
+
>
|
35
|
+
1. request (data_type: ActionDispatch::Request)
|
36
|
+
|
37
|
+
> Description: Checks if the request passes internal host validation or not based on Rails environment and request's host and returns bool value
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
is_request_from_mobile?(request, params, velocity_salt)
|
43
|
+
```
|
44
|
+
> Parameters:
|
45
|
+
>
|
46
|
+
1. request (data_type: ActionDispatch::Request)
|
47
|
+
2. params (data_type: ActionController::Parameters)
|
48
|
+
3. velocity_salt (data_type: String, description: Salt to verify signed param with time stamp)
|
49
|
+
|
50
|
+
> Description: Checks if the request is from mobile or not based on source, time stamp, signed param and salt and returns bool value
|
51
|
+
|
52
|
+
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
is_request_csrf_valid?(request, cookies, params, csrf_encryption_key, velocity_salt)
|
56
|
+
```
|
57
|
+
> Parameters:
|
58
|
+
>
|
59
|
+
1. request (data_type: ActionDispatch::Request)
|
60
|
+
2. cookies (data_type: ActionDispatch::Cookies::CookieJar)
|
61
|
+
3. params (data_type: ActionController::Parameters)
|
62
|
+
4. csrf_encryption_key (data_type: String, length: 64 characters (0-9, a-f) i.e. 32 bytes, description: Encryption key to generate csrf token. This key should be kept secret between servers.)
|
63
|
+
5. velocity_salt (data_type: String, description: Salt to verify signed param with time stamp)
|
64
|
+
|
65
|
+
> Description: Checks if the request passes csrf validation or not and returns bool value
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
internal_host_check
|
71
|
+
```
|
72
|
+
> Description: Checks if the request passes internal host validation or not. If the validation fails then logs information in /log/unauthorized_api_requests.log and renders :json => {:message => "You are not authorized to make this call"}, status: 401
|
73
|
+
|
74
|
+
> Note: It can only be called from controller as it uses request (ActionDispatch::Request)
|
75
|
+
|
76
|
+
> Usage: In your controller:
|
77
|
+
```ruby
|
78
|
+
include HousingMisc
|
79
|
+
before_action :internal_host_check, :only => [:method_1, :method_2, ...]
|
80
|
+
```
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
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)
|
86
|
+
```
|
87
|
+
> Parameters:
|
88
|
+
>
|
89
|
+
1. template_slug (data_type:string, descriptinon:contains name of the template)
|
90
|
+
2. template_version (data_type: string, description:version of mail_template e.g. "1")
|
91
|
+
3. users (data_type: [{"email" => "xyz", "name" => "m"}], description: array of email ids)
|
92
|
+
4. base_vars (data_type: Hash, desciption: contains subject and callback_url)
|
93
|
+
5. merge_vars (data_type: Hash, description: includes vars that are embedded in mail)
|
94
|
+
6. high_priority (data_type : boolean, description:decides the priority of mail)
|
95
|
+
7. attachments (:data_type : [], deacription: contains attachments to mail)
|
96
|
+
8. deferred (data_type : boolean, description:decides if mail is to be sent later)
|
97
|
+
9. send_time (data_tpe: Time, desciption: e.g. 2018-04-06 15:55:33 +0530, nil=send_now)
|
98
|
+
10. google_analytics_campaign(data_type: string, description: Name of campaign)
|
99
|
+
|
100
|
+
|
101
|
+
> Description: Sends mail for a given template and its version to mentioned users.
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
csrf_check(csrf_encryption_key, velocity_salt)
|
107
|
+
```
|
108
|
+
> Parameters:
|
109
|
+
>
|
110
|
+
1. csrf_encryption_key (data_type: String, length: 64 characters (0-9, a-f) i.e. 32 bytes, description: Encryption key to generate csrf token. This key should be kept secret between servers.)
|
111
|
+
|
112
|
+
2. velocity_salt (data_type: String, description: Salt to verify signed param with time stamp)
|
113
|
+
|
114
|
+
> Description: Checks if the request passes csrf validation or not. If the validation fails then logs information in /log/unauthorized_api_requests.log and renders :json => {:message => "You are not authorized to make this call"}, status: 401
|
115
|
+
|
116
|
+
> Note: It can only be called from controller as it uses request (ActionDispatch::Request), cookies (ActionDispatch::Cookies::CookieJar) and params (ActionController::Parameters)
|
117
|
+
|
118
|
+
> Usage: In your controller:
|
119
|
+
```ruby
|
120
|
+
include HousingMisc
|
121
|
+
before_action :only => [:method_1, :method_2, ...] do
|
122
|
+
csrf_check(Housing.csrf_encryption_key)
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module HousingMisc
|
2
|
+
class ApplicationController < ::ActionController::Base
|
3
|
+
before_action :new_relic_custom_params
|
4
|
+
|
5
|
+
def new_relic_custom_params
|
6
|
+
::NewRelic::Agent.add_custom_attributes(:http_referer => request.referer)
|
7
|
+
::NewRelic::Agent.add_custom_attributes(:referring_app => request.headers["app-name"])
|
8
|
+
::NewRelic::Agent.add_custom_attributes(:global_request_id => Thread.current[:global_request_id])
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module HousingMisc
|
2
|
+
class CacheController < ApplicationController
|
3
|
+
def show
|
4
|
+
render json: {data: {}, message: "cache key misisng", status: 404}, status: 404 if params['cache_key'].blank?
|
5
|
+
data = Rails.cache.read(params['cache_key'])
|
6
|
+
success_message, error_message = ["success", "not found"]
|
7
|
+
data, message, status = data.present? ? [JSON.parse(data), success_message, 200] : [{}, error_message, 404]
|
8
|
+
render json: {message: message, status: status, data: data }, status: status
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HousingMisc
|
2
|
+
class LogsController < ApplicationController
|
3
|
+
include ApiHelper
|
4
|
+
before_action :validate_params
|
5
|
+
|
6
|
+
def push_logs
|
7
|
+
file_name = params[:file_name]
|
8
|
+
begin
|
9
|
+
file_path = "#{Rails.root}/log/#{file_name}"
|
10
|
+
response = upload_log_to_s3(file_path)
|
11
|
+
render json: {message: "Your file has been uploaded in bucket: #{HousingMisc.bucket}"}
|
12
|
+
rescue => e
|
13
|
+
render json: {message: e.message }, status: 422
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def validate_params
|
21
|
+
render json: {message: "file name is mandatory"}, status: 422 and return if params[:file_name].blank?
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
module HousingMisc
|
2
|
+
class ModelReflectionsController < ApplicationController
|
3
|
+
include ModelsReflectionsHelper
|
4
|
+
include HousingMisc::ApiHelper
|
5
|
+
before_action :validate_params
|
6
|
+
before_action :internal_host_check
|
7
|
+
|
8
|
+
def check_permission
|
9
|
+
return false
|
10
|
+
end
|
11
|
+
|
12
|
+
=begin
|
13
|
+
*Author* Prabal Partap
|
14
|
+
<b>Date</b>5 March, 2019
|
15
|
+
<b>Short Description</b> Api to get reflections(associations) of the given models and also the models associated with those models(found in reflections of those models)
|
16
|
+
<b>Endpoints</b> Database Prunning Service
|
17
|
+
<b>Request Type</b> GET
|
18
|
+
<b>Route </b> /model_reflections
|
19
|
+
<b>Authentication Required</b> its an internal API hence no authentication
|
20
|
+
<b>Request Format</b>
|
21
|
+
{
|
22
|
+
"models" : "WhatsappPermission,SmsRequest"
|
23
|
+
}
|
24
|
+
<b>unsuccesful Response</b>
|
25
|
+
{
|
26
|
+
"message" : "Bad request",
|
27
|
+
"error" : "incorrect model names, don't give spaces after model names"
|
28
|
+
}
|
29
|
+
<b>succesful Response</b>
|
30
|
+
{
|
31
|
+
"message": "succesful",
|
32
|
+
"error": "",
|
33
|
+
{
|
34
|
+
"whatsapp_permissions": {
|
35
|
+
"subscriptions": {
|
36
|
+
"table_name": "subscriptions",
|
37
|
+
"macros": [
|
38
|
+
"belongs_to"
|
39
|
+
],
|
40
|
+
"throughs": [
|
41
|
+
"FALSE"
|
42
|
+
],
|
43
|
+
"foreign_keys": [
|
44
|
+
"number"
|
45
|
+
],
|
46
|
+
"primary_keys": [
|
47
|
+
"number"
|
48
|
+
],
|
49
|
+
"model_name": "Subscription"
|
50
|
+
}
|
51
|
+
},
|
52
|
+
"sms_requests": {
|
53
|
+
"statuses": {
|
54
|
+
"table_name": "statuses",
|
55
|
+
"macros": [
|
56
|
+
"belongs_to"
|
57
|
+
],
|
58
|
+
"throughs": [
|
59
|
+
"FALSE"
|
60
|
+
],
|
61
|
+
"foreign_keys": [
|
62
|
+
"status_id"
|
63
|
+
],
|
64
|
+
"primary_keys": [
|
65
|
+
"id"
|
66
|
+
],
|
67
|
+
"model_name": "::Status"
|
68
|
+
},
|
69
|
+
"sms_templates": {
|
70
|
+
"table_name": "sms_templates",
|
71
|
+
"macros": [
|
72
|
+
"belongs_to"
|
73
|
+
],
|
74
|
+
"throughs": [
|
75
|
+
"FALSE"
|
76
|
+
],
|
77
|
+
"foreign_keys": [
|
78
|
+
"template_id"
|
79
|
+
],
|
80
|
+
"primary_keys": [
|
81
|
+
"id"
|
82
|
+
],
|
83
|
+
"model_name": "::SmsTemplate"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
"subscriptions": {
|
87
|
+
"whatsapp_permissions": {
|
88
|
+
"table_name": "whatsapp_permissions",
|
89
|
+
"macros": [
|
90
|
+
"has_many"
|
91
|
+
],
|
92
|
+
"throughs": [
|
93
|
+
"FALSE"
|
94
|
+
],
|
95
|
+
"foreign_keys": [
|
96
|
+
"number"
|
97
|
+
],
|
98
|
+
"primary_keys": [
|
99
|
+
"number"
|
100
|
+
],
|
101
|
+
"model_name": "WhatsappPermission"
|
102
|
+
}
|
103
|
+
},
|
104
|
+
"statuses": {},
|
105
|
+
"sms_templates": {
|
106
|
+
"gateway_types": {
|
107
|
+
"table_name": "gateway_types",
|
108
|
+
"macros": [
|
109
|
+
"belongs_to"
|
110
|
+
],
|
111
|
+
"throughs": [
|
112
|
+
"FALSE"
|
113
|
+
],
|
114
|
+
"foreign_keys": [
|
115
|
+
"gateway_type_id"
|
116
|
+
],
|
117
|
+
"primary_keys": [
|
118
|
+
"id"
|
119
|
+
],
|
120
|
+
"model_name": "GatewayType"
|
121
|
+
}
|
122
|
+
},
|
123
|
+
"gateway_types": {
|
124
|
+
"sms_templates": {
|
125
|
+
"table_name": "sms_templates",
|
126
|
+
"macros": [
|
127
|
+
"has_many"
|
128
|
+
],
|
129
|
+
"throughs": [
|
130
|
+
"FALSE"
|
131
|
+
],
|
132
|
+
"foreign_keys": [
|
133
|
+
"gateway_type_id"
|
134
|
+
],
|
135
|
+
"primary_keys": [
|
136
|
+
"id"
|
137
|
+
],
|
138
|
+
"model_name": "SmsTemplate"
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
}
|
143
|
+
=end
|
144
|
+
|
145
|
+
def models_reflections_generator
|
146
|
+
base_models = filter_params['models'].split(',')
|
147
|
+
base_tables = []
|
148
|
+
table_name = ""
|
149
|
+
base_models.each do |model|
|
150
|
+
table_name = model.constantize.table_name rescue "Invalid_Table"
|
151
|
+
break if table_name == "Invalid_Table"
|
152
|
+
base_tables.push(table_name)
|
153
|
+
end
|
154
|
+
if table_name == 'Invalid_Table'
|
155
|
+
render json: {message: "incorrect model names, don't give spaces after model names"},status: :bad_request
|
156
|
+
else
|
157
|
+
tables_reflections_hash = tables_reflections_hash_generator(base_models)
|
158
|
+
render json: tables_reflections_hash, status: :ok
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
def filter_params
|
164
|
+
params.permit(:models)
|
165
|
+
end
|
166
|
+
|
167
|
+
def validate_params
|
168
|
+
render json: {message: "model name is mandatory"}, status: :bad_request if params[:models].blank?
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module HousingMisc
|
2
|
+
class SidekiqQueueCheckController < ApplicationController
|
3
|
+
include HousingMisc::ApiHelper
|
4
|
+
before_action :internal_host_check
|
5
|
+
DEFAULT_QUEUE_SIZE = 100
|
6
|
+
DEFAULT_TOTAL_SIZE = 1000
|
7
|
+
|
8
|
+
def check_permission
|
9
|
+
return false
|
10
|
+
end
|
11
|
+
|
12
|
+
def check
|
13
|
+
return unless check_sidekiq_presence
|
14
|
+
require "sidekiq/api"
|
15
|
+
|
16
|
+
jobs_info = get_above_threshold_queue_list
|
17
|
+
alert_slack(HousingMisc.sidekiq_message_url, get_message(jobs_info)) unless jobs_info.empty?
|
18
|
+
jobs_info = {"message" => "no sidekiq queue above threshold"} if jobs_info.empty?
|
19
|
+
render json: jobs_info
|
20
|
+
end
|
21
|
+
|
22
|
+
def get_above_threshold_queue_list
|
23
|
+
jobs_info = {}
|
24
|
+
stats = Sidekiq::Stats.new
|
25
|
+
total_threshold = HousingMisc.sidekiq_custom_threshold["total"] || DEFAULT_TOTAL_SIZE
|
26
|
+
if stats.enqueued > total_threshold
|
27
|
+
jobs_info["total"] = {"jobs" => stats.enqueued, "threshold" => total_threshold }
|
28
|
+
end
|
29
|
+
stats.queues.each do |key, value|
|
30
|
+
queue_threshold = HousingMisc.sidekiq_custom_threshold[key] || DEFAULT_QUEUE_SIZE
|
31
|
+
if value > queue_threshold
|
32
|
+
jobs_info[key] = {"jobs" => value, "threshold" => queue_threshold }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
jobs_info
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_message(jobs_info)
|
39
|
+
message = "#{Time.now.to_s} :: Queues with jobs exceeding threshold in #{Rails.application.class.parent_name} service => "
|
40
|
+
jobs_info.each do |key, value|
|
41
|
+
message += " #{key} : #{value["jobs"]} jobs (Threshold : #{value["threshold"]}), "
|
42
|
+
end
|
43
|
+
message
|
44
|
+
end
|
45
|
+
|
46
|
+
def check_sidekiq_presence
|
47
|
+
return true if Gem.loaded_specs["sidekiq"].present?
|
48
|
+
render json: {"message" => "no sidekiq in this service"}
|
49
|
+
return false
|
50
|
+
end
|
51
|
+
|
52
|
+
def alert_slack(url, message)
|
53
|
+
url = URI(url)
|
54
|
+
req = Net::HTTP::Post.new url.path
|
55
|
+
req.body = {:text => message}.to_json
|
56
|
+
res = Net::HTTP.start(url.host, url.port, :use_ssl => true) do |http|
|
57
|
+
http.request req
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
=begin
|
2
|
+
*Author* Azitabh Ajit
|
3
|
+
|
4
|
+
This is a middleware to expose request id set by
|
5
|
+
This capability is added in rails 5 by default and is available by Current.request_id https://github.com/rails/rails/commit/24a864437e845febe91e3646ca008e8dc7f76b56
|
6
|
+
This usage threadlocal to make the request id available to the whole app just the way it's managed in later versions of rails :https://github.com/rails/rails/commit/24a864437e845febe91e3646ca008e8dc7f76b56#diff-3c3c0f647bc4702f9453c173a707aa06R90
|
7
|
+
This won't be required once we migrate to rails 5 or beyond
|
8
|
+
=end
|
9
|
+
class RequestTracer
|
10
|
+
def initialize app
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
def call env
|
15
|
+
Thread.current[:global_request_id] = env["action_dispatch.request_id"]
|
16
|
+
@status, @headers, @response = @app.call env
|
17
|
+
[@status, @headers, @response]
|
18
|
+
end
|
19
|
+
end
|
data/config/routes.rb
ADDED