thisdata 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1bd194d89f48c0774d981d4c093ef12a1ed1b16e
4
+ data.tar.gz: 39ea8f55aaa501587e46cdb586e41a29f711760c
5
+ SHA512:
6
+ metadata.gz: 0f9c4c7388e0b80d34e78f798fc5691b4db3f864e7ca84db4ddd11499b1395cd76eb33ea3fcc4ff2a4faaa2e48ac428e877e99fabe63a3d2aa84fb53329488ec
7
+ data.tar.gz: fe572684f6b1790d900ee21fe12ba508c19b017196c621b7de68b1dc99ed1cb3bf7f3e4d9106ee8eddb9cc33ca2346bad2f9688b9b992a4b9f69de4872f4807b
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ /.bundle/
2
+ /Gemfile.lock
3
+ /tmp/
4
+ .DS_Store
5
+ *.gem
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ # 0.1.0
2
+
3
+ Initial release.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in this_data.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 ThisData Ltd.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # ThisData Ruby
2
+
3
+ This gem allows you to use the ThisData Login Intelligence API.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'thisdata'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install thisdata
20
+
21
+ ## Usage
22
+
23
+ Run:
24
+
25
+ rails g this_data:install YOUR_API_KEY_HERE
26
+
27
+ You can find your API key by going to [ThisData](https://thisdata.com) >
28
+ Integrations > Login Intelligence API.
29
+
30
+ The generator will create a file in `config/initializers` called "this_data.rb".
31
+ If you need to do any further configuration or customization of ThisData,
32
+ that's the place to do it!
33
+
34
+ ## Ruby
35
+
36
+ You can track any event by calling `ThisData.track` and passing a Hash which
37
+ contains an event. See examples and required fields on our API documentation:
38
+ http://help.thisdata.com/docs/apiv1events
39
+
40
+ ## Rails
41
+
42
+ The ThisData::TrackRequest module can be included in a ActionController, giving
43
+ you a handy way to track requests.
44
+
45
+ e.g. in `app/controllers/application_controller.rb`
46
+ ```
47
+ class ApplicationController < ActionController::Base
48
+ include ThisData::TrackRequest
49
+
50
+ ...
51
+ end
52
+ ```
53
+
54
+ and in your sessions controller:
55
+ ```
56
+ class SessionsController < ApplicationController
57
+
58
+ def finalize
59
+ if login_was_valid?
60
+ # do login stuff
61
+ thisdata_track
62
+ else
63
+ thisdata_track('login-denied')
64
+ end
65
+ end
66
+
67
+ end
68
+ ```
69
+
70
+
71
+
72
+ ## Development
73
+
74
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
75
+
76
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
77
+
78
+ ## Contributing
79
+
80
+ Bug reports and pull requests are welcome on GitHub at https://github.com/revertio/thisdata-ruby.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ end
9
+
10
+ task :default => :test
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "this_data"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,30 @@
1
+ module ThisData
2
+ class InstallGenerator < Rails::Generators::Base
3
+
4
+ argument :api_key
5
+
6
+ desc "This generator creates a configuration file for the ThisData ruby client inside config/initializers"
7
+ def create_configuration_file
8
+ initializer "this_data.rb" do
9
+ <<-EOS
10
+ ThisData.setup do |config|
11
+ config.api_key = "#{api_key}"
12
+
13
+ # user_method will be called on a controller when using TrackRequest
14
+ # config.user_method = :current_user
15
+
16
+ # The following methods will be called on the object returned by user_method,
17
+ # to capture details about the user
18
+ # config.user_id_method = :id
19
+ # config.user_name_method = :name
20
+ # config.user_email_method = :email
21
+ # config.user_mobile_method = :mobile
22
+
23
+ # Define a Logger instance if you want to debug / track errors
24
+ # config.logger = Rails.logger unless Rails.env.production?
25
+ end
26
+ EOS
27
+ end
28
+ end
29
+ end
30
+ end
data/lib/this_data.rb ADDED
@@ -0,0 +1,71 @@
1
+ require "httparty"
2
+ require "logger"
3
+ require "json"
4
+
5
+ require "this_data/version"
6
+ require "this_data/verbs"
7
+ require "this_data/client"
8
+ require "this_data/configuration"
9
+ require "this_data/track_request"
10
+
11
+ module ThisData
12
+
13
+ class << self
14
+
15
+ # Configuration Object (instance of ThisData::Configuration)
16
+ attr_writer :configuration
17
+
18
+ def setup
19
+ yield(configuration)
20
+ end
21
+
22
+ def configuration
23
+ @configuration ||= ThisData::Configuration.new
24
+ end
25
+
26
+ def default_configuration
27
+ configuration.defaults
28
+ end
29
+
30
+ # Creates a Client and tracks an event.
31
+ # Event must be a Hash
32
+ def track(event)
33
+ Client.new.track(event)
34
+ log("Tracked event!")
35
+ rescue => e
36
+ ThisData.error("Failed to track event:")
37
+ ThisData.error(e)
38
+ e.backtrace.each do |line|
39
+ ThisData.error(line, prefix: false)
40
+ end
41
+ false
42
+ end
43
+
44
+ # A helper method to track a log-in event. Validates that the minimum
45
+ # required data is present.
46
+ def track_login(ip: '', user: {}, user_agent: nil)
47
+ raise ArgumentError, "IP Address is required" unless ip.length
48
+ raise ArgumentError, "User needs ID value" unless user[:id].to_s.length
49
+ track({
50
+ verb: ThisData::Verbs::LOG_IN,
51
+ ip: ip,
52
+ user_agent: user_agent,
53
+ user: user
54
+ })
55
+ end
56
+
57
+ def log(message, level: 'info', prefix: true)
58
+ if prefix
59
+ message = "[ThisData] " + message.to_s
60
+ end
61
+ configuration.logger.send(level, message) if configuration.logger
62
+ end
63
+ def warn(message, prefix: true)
64
+ log(message, level: 'warn', prefix: prefix)
65
+ end
66
+ def error(message, prefix: true)
67
+ log(message, level: 'error', prefix: prefix)
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,59 @@
1
+ module ThisData
2
+ # For the ThisData REST APIv1
3
+ # http://help.thisdata.com/docs/apiv1events
4
+ class Client
5
+
6
+ USER_AGENT = "ThisData Ruby v#{ThisData::VERSION}"
7
+ NO_API_KEY_MESSAGE = "Oops: you've got no ThisData API Key configured, so we can't send events. Specify your ThisData API key using ThisData#setup (find yours at https://thisdata.com)"
8
+
9
+ include HTTParty
10
+
11
+ base_uri "https://api.thisdata.com/v1/"
12
+
13
+ def initialize
14
+ @api_key = require_api_key
15
+ @headers = {
16
+ "User-Agent" => USER_AGENT
17
+ }
18
+ end
19
+
20
+ def require_api_key
21
+ ThisData.configuration.api_key || print_api_key_warning
22
+ end
23
+
24
+ # Tracks a user initiated event which has occurred within your app, e.g.
25
+ # a user logging in.
26
+ # See http://help.thisdata.com/v1.0/docs/apiv1events for more information.
27
+ # - event (Required: Hash) the event, containing the following keys:
28
+ # - verb (Required: String) 'what' the user did, e.g. 'log-in'.
29
+ # See ThisData::Verbs for predefined options.
30
+ # - ip (Required: String) the IP address of the request
31
+ # - user_agent (Optional: String) the user agent from the request
32
+ # - user (Required: Hash)
33
+ # - id (Required: String) a unique identifier for this User
34
+ # - email (Optional*: String) the user's email address.
35
+ # - mobile (Optional*: String) a mobile phone number in E.164 format
36
+ # *email and/or mobile MUST be passed if you want ThisData
37
+ # to send 'Was This You?' notifications via email and/or SMS
38
+ # - name (Optional: String) the user's name, used in notifications
39
+ def track(event)
40
+ post_event(event)
41
+ end
42
+
43
+ private
44
+
45
+ def version
46
+ ThisData.configuration.version
47
+ end
48
+
49
+ def post_event(payload_hash)
50
+ path_with_key = "/events?api_key=#{ThisData.configuration.api_key}"
51
+ self.class.post(path_with_key, headers: @headers, body: JSON.generate(payload_hash))
52
+ end
53
+
54
+ def print_api_key_warning
55
+ $stderr.puts(NO_API_KEY_MESSAGE)
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,75 @@
1
+ require "ostruct"
2
+
3
+ module ThisData
4
+ class Configuration
5
+
6
+ # Programatically create attr accessors for config_option
7
+ def self.config_option(name)
8
+ define_method(name) do
9
+ read_value(name)
10
+ end
11
+
12
+ define_method("#{name}=") do |value|
13
+ set_value(name, value)
14
+ end
15
+ end
16
+
17
+ # Your ThisData API Key - this can be found on ThisData.com > Integrations
18
+ # > Login Intelligence API
19
+ config_option :api_key
20
+
21
+ # Log the events sent
22
+ config_option :logger
23
+
24
+ # TrackRequest config options
25
+ # We will attempt to call this method on a Controller to get the user record
26
+ # Default: :current_user
27
+ config_option :user_method
28
+ # This method should return a unique ID for a user. Default: :id
29
+ config_option :user_id_method
30
+ # This method should return the user's name. Default: :name
31
+ config_option :user_name_method
32
+ # This method should return the user's email. Default: :email
33
+ config_option :user_email_method
34
+ # This method should return the user's mobile phone number. Default: :mobile
35
+ config_option :user_mobile_method
36
+
37
+ attr_reader :defaults
38
+
39
+ def initialize
40
+ @config_values = {}
41
+
42
+ # set default attribute values
43
+ @defaults = OpenStruct.new({
44
+ user_method: :current_user,
45
+ user_id_method: :id,
46
+ user_name_method: :name,
47
+ user_email_method: :email,
48
+ user_mobile_method: :mobile
49
+ })
50
+ end
51
+
52
+ def [](key)
53
+ read_value(key)
54
+ end
55
+
56
+ def []=(key, value)
57
+ set_value(key, value)
58
+ end
59
+
60
+ private
61
+
62
+ def read_value(name)
63
+ if @config_values.has_key?(name)
64
+ @config_values[name]
65
+ else
66
+ @defaults.send(name)
67
+ end
68
+ end
69
+
70
+ def set_value(name, value)
71
+ @config_values[name] = value
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,72 @@
1
+ # Include ThisData::TrackRequest in your ApplicationController to get a handy
2
+ # track method which looks at the request and current_user variables to
3
+ # generate an event.
4
+ module ThisData
5
+ module TrackRequest
6
+ class ThisDataTrackError < StandardError; end
7
+
8
+ # Will pull request and user details from the controller, and send an event
9
+ # to ThisData.
10
+ def thisdata_track(verb: ThisData::Verbs::LOG_IN)
11
+ controller = controller_from_env
12
+ user_details = user_details_from_controller(controller)
13
+ event = {
14
+ verb: verb,
15
+ ip: request.remote_ip,
16
+ user_agent: request.user_agent,
17
+ user: user_details
18
+ }
19
+
20
+ ThisData.track(event)
21
+ rescue => e
22
+ ThisData.error "Could not track event:"
23
+ ThisData.error e
24
+ ThisData.error e.backtrace.limit(5).join("\n")
25
+ false
26
+ end
27
+
28
+ private
29
+
30
+ # Rails keeps a reference to the controller in the env variable.
31
+ # Returns a Controller
32
+ def controller_from_env
33
+ unless controller = env["action_controller.instance"]
34
+ raise ThisDataTrackError, "Could not get controller from environment"
35
+ end
36
+ controller
37
+ end
38
+
39
+ # Fetches the user record by calling the configured method on the
40
+ # controller.
41
+ # Will raise a NoMethodError if controller does not respond to the method.
42
+ # Returns an object
43
+ def user_from_controller(controller)
44
+ user = controller.send(ThisData.configuration.user_method)
45
+ end
46
+
47
+ # Will fetch a user and return a Hash of details for that User.
48
+ # Will raise a NoMethodError if controller does not return a user,
49
+ # or we can't get a user id.
50
+ def user_details_from_controller(controller)
51
+ user = user_from_controller(controller)
52
+ {
53
+ id: user.send(ThisData.configuration.user_id_method),
54
+ name: value_if_configured(user, "user_name_method"),
55
+ email: value_if_configured(user, "user_email_method"),
56
+ mobile: value_if_configured(user, "user_mobile_method"),
57
+ }
58
+ end
59
+
60
+ # Will return the result of calling a method defined in ThisData's config
61
+ # if the object responds to that method.
62
+ def value_if_configured(object, config_option)
63
+ method = ThisData.configuration.send("#{config_option}")
64
+ if object.respond_to?(method, true)
65
+ return object.send(method)
66
+ else
67
+ nil
68
+ end
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,10 @@
1
+ module ThisData
2
+ class Verbs
3
+
4
+ LOG_IN = 'log-in'
5
+ LOG_OUT = 'log-out'
6
+ LOG_IN_DENIED = 'log-in-denied'
7
+ LOG_IN_CHALLENGE = 'log-in-challenge'
8
+
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module ThisData
2
+ VERSION = "0.1.0"
3
+ end
data/thisdata.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'this_data/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "thisdata"
8
+ spec.version = ThisData::VERSION
9
+ spec.authors = ["ThisData Ltd", "Nick Malcolm"]
10
+ spec.email = ["support@thisdata.com", "nick@thisdata.com"]
11
+
12
+ spec.summary = %q{Ruby wrapper for ThisData's Login Intelligence API}
13
+ spec.description = %q{Use ThisData's Login Intelligence API in your ruby / rails app to monitor for unusual end-user activity}
14
+ spec.homepage = "https://github.com/thisdata/thisdata-ruby"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+
27
+ spec.executables = []
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_runtime_dependency "httparty", "~> 0.13"
31
+ spec.add_runtime_dependency "json", "~> 1.8"
32
+
33
+ spec.add_development_dependency "bundler", "~> 1.10"
34
+ spec.add_development_dependency "rake", "~> 10.0"
35
+ spec.add_development_dependency "minitest", "~> 5.8"
36
+ spec.add_development_dependency "fakeweb", "~> 1.3"
37
+ spec.add_development_dependency "mocha", "~> 1.1"
38
+
39
+
40
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thisdata
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - ThisData Ltd
8
+ - Nick Malcolm
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-02-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httparty
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '0.13'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '0.13'
28
+ - !ruby/object:Gem::Dependency
29
+ name: json
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.8'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.8'
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.10'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.10'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '10.0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '10.0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: minitest
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '5.8'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - "~>"
82
+ - !ruby/object:Gem::Version
83
+ version: '5.8'
84
+ - !ruby/object:Gem::Dependency
85
+ name: fakeweb
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - "~>"
89
+ - !ruby/object:Gem::Version
90
+ version: '1.3'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '1.3'
98
+ - !ruby/object:Gem::Dependency
99
+ name: mocha
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '1.1'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - "~>"
110
+ - !ruby/object:Gem::Version
111
+ version: '1.1'
112
+ description: Use ThisData's Login Intelligence API in your ruby / rails app to monitor
113
+ for unusual end-user activity
114
+ email:
115
+ - support@thisdata.com
116
+ - nick@thisdata.com
117
+ executables: []
118
+ extensions: []
119
+ extra_rdoc_files: []
120
+ files:
121
+ - ".gitignore"
122
+ - CHANGELOG
123
+ - Gemfile
124
+ - LICENSE.md
125
+ - README.md
126
+ - Rakefile
127
+ - bin/console
128
+ - bin/setup
129
+ - lib/generators/this_data/install_generator.rb
130
+ - lib/this_data.rb
131
+ - lib/this_data/client.rb
132
+ - lib/this_data/configuration.rb
133
+ - lib/this_data/track_request.rb
134
+ - lib/this_data/verbs.rb
135
+ - lib/this_data/version.rb
136
+ - thisdata.gemspec
137
+ homepage: https://github.com/thisdata/thisdata-ruby
138
+ licenses:
139
+ - MIT
140
+ metadata:
141
+ allowed_push_host: https://rubygems.org
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubyforge_project:
158
+ rubygems_version: 2.4.8
159
+ signing_key:
160
+ specification_version: 4
161
+ summary: Ruby wrapper for ThisData's Login Intelligence API
162
+ test_files: []