Skip to content

Commit

Permalink
add geo location information to membership submissions (#94)
Browse files Browse the repository at this point in the history
This patch adds an `ip_address` field to the SlackMembershipSubmission
model which gets set to the clients IP address upon form submission. It
is then displayed in the admin screens when reviewing submissions
showing the city, region, and country.

It utilizes the free service from http://ip-api.com

test plan:
  - % bundle install
  - % rails s

  - delete any pending membership submissions you have locally

      % rails runner SlackMembershipSubmission.delete_all

  - visit home page
  - click 'join now' button
  - fill out form and submit
  - go to /admin
  - go to pending submissions
  - note that under the 'Location' field there isn't any additional
    text.
  - open rails console and tweak your submission to give it a public ip
    address:

      % rails c
      > sms = SlackMembershipSubmission.first
      > sms.ip_address = "73.11.237.17"
      > sms.save!

  - reload pending submissions screen
  - note that under 'Location' field it now says 'Olympia, WA, United
    States'
  • Loading branch information
phallstrom committed Mar 24, 2019
1 parent ba39488 commit 2fbade8
Show file tree
Hide file tree
Showing 24 changed files with 561 additions and 3 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ group :development, :test do
gem 'factory_bot_rails', '~> 4.8' # provides integration between factory_bot and rails
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # ruby debugger
gem 'pry-rails' # use pry as your rails console
gem 'vcr', '~> 4.0' # record test suite's http interactions and replay them during future test runs
gem 'webmock', '~> 3.5.1' # allows stubbing http requests and setting expectations on http requests
end

group :development do
Expand Down
14 changes: 14 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ GEM
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
arel (8.0.0)
bindex (0.5.0)
builder (3.2.3)
Expand All @@ -51,6 +53,8 @@ GEM
money (~> 6.9)
sixarm_ruby_unaccent (~> 1.1)
unicode_utils (~> 1.4)
crack (0.4.3)
safe_yaml (~> 1.0.0)
crass (1.0.4)
diff-lcs (1.3)
dotenv (2.5.0)
Expand All @@ -74,6 +78,7 @@ GEM
gli (2.18.0)
globalid (0.4.1)
activesupport (>= 4.2.0)
hashdiff (0.3.8)
hashie (3.5.7)
i18n (1.0.1)
concurrent-ruby (~> 1.0)
Expand Down Expand Up @@ -126,6 +131,7 @@ GEM
method_source (~> 0.9.0)
pry-rails (0.3.6)
pry (>= 0.10.4)
public_suffix (3.0.3)
puma (3.12.0)
rack (2.0.6)
rack-attack (5.2.0)
Expand Down Expand Up @@ -189,6 +195,7 @@ GEM
rspec_junit_formatter (0.3.0)
rspec-core (>= 2, < 4, != 2.12.0)
ruby_dep (1.5.0)
safe_yaml (1.0.5)
sass (3.5.6)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
Expand Down Expand Up @@ -241,11 +248,16 @@ GEM
uglifier (4.1.19)
execjs (>= 0.3.0, < 3)
unicode_utils (1.4.0)
vcr (4.0.0)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
webmock (3.5.1)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
Expand Down Expand Up @@ -290,7 +302,9 @@ DEPENDENCIES
sucker_punch (~> 2.0)
tzinfo-data
uglifier (>= 1.3.0)
vcr (~> 4.0)
web-console (>= 3.3.0)
webmock (~> 3.5.1)

RUBY VERSION
ruby 2.4.4p296
Expand Down
1 change: 1 addition & 0 deletions app/controllers/membership_submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ def create
redirect_to root_path and return if submission_params.key?(:fax)

@submission = SlackMembershipSubmission.new(submission_params)
@submission.ip_address = request.remote_ip

if @submission.save
flash[:info] = "Thanks! Look for an email from us in the next couple of days."
Expand Down
19 changes: 19 additions & 0 deletions app/models/ip_info.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# See http://ip-api.com/docs/api:json
#
class IpInfo
def initialize(ip_address)
@ip_address = ip_address
@info = JSON.parse(Net::HTTP.get("ip-api.com", "/json/#{@ip_address}"))
end

def successful?
@info["status"] == "success"
end

def method_missing(symbol, *args)
key = symbol.to_s.camelize(:lower)
return @info[key] if @info.key?(key)
super
end
end
7 changes: 7 additions & 0 deletions app/models/slack_membership_submission.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,11 @@ def approve_and_invite!

raise e
end

def ip_address_location
return if ip_address.nil?
ii = IpInfo.new(ip_address.to_s)
return unless ii.successful?
[ii.city, ii.region, ii.country].join(", ")
end
end
4 changes: 3 additions & 1 deletion app/views/admin/membership_submissions/pending.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ section.section
label.label Location
.control
input.input[type="text" disabled value=@submission.location]

.help
= @submission.ip_address_location

.field
label.label Created At
.control
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddIpAddressToSlackMembershipSubmissions < ActiveRecord::Migration[5.1]
def change
add_column :slack_membership_submissions, :ip_address, :inet
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20180516054141) do
ActiveRecord::Schema.define(version: 20190323212047) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand Down Expand Up @@ -44,6 +44,7 @@
t.string "website_url"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.inet "ip_address"
t.index ["email"], name: "index_slack_membership_submissions_on_email", unique: true
t.index ["slack_user_id"], name: "index_slack_membership_submissions_on_slack_user_id"
t.index ["status"], name: "index_slack_membership_submissions_on_status"
Expand Down
34 changes: 34 additions & 0 deletions spec/fixtures/vcr/IpInfo/invalid_ip_addresses/is_unsuccessful.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions spec/fixtures/vcr/IpInfo/private_ip_addresses/is_unsuccessful.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions spec/fixtures/vcr/IpInfo/private_ip_ranges/is_unsuccessful.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions spec/fixtures/vcr/IpInfo/valid_ip_addresses/is_successful.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2fbade8

Please sign in to comment.