honest_renter 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +7 -0
  4. data/Gemfile.lock +23 -1
  5. data/LICENSE.txt +22 -0
  6. data/README.md +116 -1
  7. data/Rakefile +11 -0
  8. data/honest_renter.gemspec +6 -1
  9. data/lib/authenticator.rb +76 -0
  10. data/lib/client.rb +11 -0
  11. data/lib/honest_renter.rb +12 -0
  12. data/lib/request.rb +71 -0
  13. data/lib/requests/expandable.rb +10 -0
  14. data/lib/requests/filter.rb +9 -0
  15. data/lib/requests/find_all.rb +27 -0
  16. data/lib/requests/find_all_by_filter.rb +38 -0
  17. data/lib/requests/find_by_id.rb +23 -0
  18. data/lib/requests/post.rb +15 -0
  19. data/lib/requires.rb +18 -0
  20. data/lib/response.rb +30 -0
  21. data/lib/session.rb +20 -0
  22. data/models/applicant.rb +42 -0
  23. data/models/base_model.rb +57 -0
  24. data/models/candidate.rb +31 -0
  25. data/models/child.rb +20 -0
  26. data/models/code.rb +27 -0
  27. data/models/cooccupant.rb +20 -0
  28. data/models/country.rb +16 -0
  29. data/models/email.rb +21 -0
  30. data/models/emergency_contact.rb +20 -0
  31. data/models/ethnicity.rb +16 -0
  32. data/models/failed_login.rb +21 -0
  33. data/models/gender.rb +16 -0
  34. data/models/inbox_filters.rb +26 -0
  35. data/models/invite_settings.rb +23 -0
  36. data/models/member.rb +24 -0
  37. data/models/name.rb +22 -0
  38. data/models/notification.rb +18 -0
  39. data/models/notification_type.rb +19 -0
  40. data/models/organization.rb +23 -0
  41. data/models/participant.rb +21 -0
  42. data/models/person.rb +30 -0
  43. data/models/pet.rb +22 -0
  44. data/models/pet_age_category.rb +18 -0
  45. data/models/pet_size_category.rb +18 -0
  46. data/models/pet_type.rb +18 -0
  47. data/models/phone.rb +24 -0
  48. data/models/phone_type.rb +18 -0
  49. data/models/position.rb +23 -0
  50. data/models/reason_for_archive.rb +18 -0
  51. data/models/reason_for_eviction.rb +18 -0
  52. data/models/reason_for_exclusion.rb +18 -0
  53. data/models/reference.rb +20 -0
  54. data/models/relationship_type.rb +19 -0
  55. data/models/reminder.rb +19 -0
  56. data/models/residence.rb +25 -0
  57. data/models/smoking_status_category.rb +18 -0
  58. data/models/sort_by_option.rb +18 -0
  59. data/models/time_of_day.rb +18 -0
  60. data/models/title.rb +17 -0
  61. data/models/user.rb +20 -0
  62. data/models/vehicle.rb +21 -0
  63. data/modules/requests_unsupported.rb +21 -0
  64. data/modules/unrequestable.rb +23 -0
  65. data/test/fixtures/ethnicities/find_all.json +38 -0
  66. data/test/fixtures/members/find.json +31 -0
  67. data/test/fixtures/titles/find_all_by_filters.json +11 -0
  68. data/test/integration/find_all_by_filters_test.rb +12 -0
  69. data/test/integration/find_all_test.rb +11 -0
  70. data/test/integration/find_test.rb +10 -0
  71. data/test/lib/authenticator_test.rb +75 -0
  72. data/test/lib/requests/filter_test.rb +14 -0
  73. data/test/lib/requests/find_all_by_filter_test.rb +44 -0
  74. data/test/lib/requests/find_all_test.rb +59 -0
  75. data/test/lib/requests/find_by_id_test.rb +30 -0
  76. data/test/lib/requests/post_test.rb +38 -0
  77. data/test/lib/response_test.rb +46 -0
  78. data/test/lib/session_test.rb +45 -0
  79. data/test/models/base_model_test.rb +62 -0
  80. data/test/test_helper.rb +76 -0
  81. data/version.rb +1 -1
  82. metadata +134 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1b494a11487cac01e41c828d91b7e4c867a39844
4
- data.tar.gz: 3320d13a682183ec172bc8073dc6744cbcd5a68f
3
+ metadata.gz: 6c8358538a5ebe627ece107b6e93a7bcdda7a05d
4
+ data.tar.gz: b3344c770695ee716e5a3078628b8603782b4e0c
5
5
  SHA512:
6
- metadata.gz: 5652e2a0952c4cea25c294d664536c31168f573b421589432f247e4a1d8b12c16d07f468a98ff10b03e32b99b422bdc03ff7b6afc4e24d8f7d7ab1843942c89a
7
- data.tar.gz: 7952b85e388d1b3aa788b064cd6f50f91ec042d63aa55134ed35967935d2afd375b8e9c70ce74d59efca6daca2058da877074eb3107186bc140f8f8ea6f09808
6
+ metadata.gz: b80d7e826bcd59e1c20d1fb2c3e435b65b80f4b0873ef887bb24647f889db57705b13f5b9c4516c8b5548c4fa684ca7a850014ffb51fd3e99a63782393a2149b
7
+ data.tar.gz: 2f8352e77c4e6bad859ce739e697eeeb09b5b26133e96876041ff205e4a19d16ff0e0f9501337643e570716c74afc46229ed094d4728df2e4e12a20b5e016b6d
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *.gem
2
+ console.sh
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.0
5
+ - 2.2.1
6
+ - 2.3.0
7
+ script: bundle exec rake test
data/Gemfile.lock CHANGED
@@ -1,12 +1,31 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honest_renter (0.0.0)
4
+ honest_renter (1.0.0)
5
+ faraday (~> 0.9)
5
6
 
6
7
  GEM
7
8
  remote: https://rubygems.org/
8
9
  specs:
10
+ addressable (2.4.0)
11
+ crack (0.4.3)
12
+ safe_yaml (~> 1.0.0)
13
+ diff-lcs (1.2.5)
14
+ faraday (0.9.2)
15
+ multipart-post (>= 1.2, < 3)
16
+ hashdiff (0.3.0)
17
+ minitest (4.3.2)
18
+ multipart-post (2.0.0)
9
19
  rake (10.5.0)
20
+ rspec-mocks (3.4.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.4.0)
23
+ rspec-support (3.4.1)
24
+ safe_yaml (1.0.4)
25
+ webmock (1.24.2)
26
+ addressable (>= 2.3.6)
27
+ crack (>= 0.3.2)
28
+ hashdiff
10
29
 
11
30
  PLATFORMS
12
31
  ruby
@@ -14,7 +33,10 @@ PLATFORMS
14
33
  DEPENDENCIES
15
34
  bundler (~> 1.3)
16
35
  honest_renter!
36
+ minitest (= 4.3.2)
17
37
  rake (~> 10)
38
+ rspec-mocks (~> 3)
39
+ webmock (~> 1.0)
18
40
 
19
41
  BUNDLED WITH
20
42
  1.11.2
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2016 Jake Yesbeck
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 CHANGED
@@ -1,3 +1,118 @@
1
1
  ## Honest Renter API Wrapper
2
2
 
3
- [Docs](https://www.honestrenter.com/api/docs)
3
+ [![Build Status](https://travis-ci.org/yez/honest_renter.svg?branch=master)](https://travis-ci.org/yez/honest_renter)
4
+
5
+ ## Basic Objects
6
+
7
+ All supported objects have their own class. Each of these classes inherits from the `BaseModel` class.
8
+
9
+ It is suggested that when using this gem, you create your own wrapper class which inherits from these classes.
10
+
11
+ For example:
12
+
13
+ ```ruby
14
+ class Person < HonestRenter::Person
15
+ end
16
+ ```
17
+
18
+ ### `to_h`
19
+
20
+ All models in the `honest_renter` gem respond to the `to_h` method. This method iterates over a model's attributes and returns a Hash.
21
+
22
+ ## Authentication
23
+
24
+ Two authentication methods exist. An authenticated `Session` object must be present for each remote HonestRenter API call.
25
+
26
+ For more information, check out the [official authentication documentation](https://honestrenter.com/api/docs/general-principles#authorization)
27
+
28
+ Each of the two authentication methods are initialized via the `HonestRenter::Authenticator` factory methods:
29
+
30
+ ### Address and Password
31
+
32
+ To authenticate via an (email) address and password, use the `.from_address_and_password` class method.
33
+
34
+ ```ruby
35
+ auth = HonestRenter::Authenticator.from_address_and_password(
36
+ 'me@example.com',
37
+ 'supersecretpassword')
38
+ # => AddressPasswordAuthenticator
39
+
40
+ auth.session
41
+ # => HonestRenter::Session
42
+ ```
43
+
44
+ This `HonestRenter::Session` object is used when calling all class level query methods (`find` and `find_all`, etc)
45
+
46
+ ### Secret Key
47
+
48
+ To authenticate using a `SecretKey` and `MemberId`, the aptly named `.from_secret_key_member_id` class method can be used.
49
+
50
+ ```ruby
51
+ auth = HonestRenter::Authenticator.from_secret_key_member_id(
52
+ '5up3r53cr3t',
53
+ 'mymember_id')
54
+ # => AddressPasswordAuthenticator
55
+
56
+ auth.session
57
+ # => HonestRenter::Session
58
+ ```
59
+
60
+ ## Request Methods
61
+
62
+ The HonestRenter API supports querying for objects by their ID or by a set of filters. All querying operations require an authenticated `HonestRenter::Session`.
63
+
64
+ ### `find`
65
+
66
+ To find a specific object by its identifier, simply call the `.find` class method on the object or your application's inherited version of that object:
67
+
68
+ ```ruby
69
+ HonestRenter::Member.find('some_member_id', session)
70
+ ```
71
+
72
+ The `session` variable can be a session created by either the `HonestRenter::AddressPasswordAuthenticator` or the `HonestRenter::SecretKeyMemberIdAuthenticator`.
73
+
74
+ The model will automatically return an instance of the class upon with the `.find` method was called with its attributes filled.
75
+
76
+ ### `find_all`
77
+
78
+ To find a complete list of a certain model, the `.find_all` class method exists. This method has 1 required parameter and 2 optional parameters.
79
+
80
+ Like the `.find` method, a `session` is the required parameter.
81
+
82
+ ```ruby
83
+ HonestRenter::Country.find_all(session)
84
+ ```
85
+
86
+ Optionally, a `limit` and `offset` can be given to the `.find_all` method to enable pagination.
87
+
88
+ ```ruby
89
+ limit = 10
90
+ offset = 5
91
+ HonestRenter::Country.find_all(session, limit, offset)
92
+ ```
93
+
94
+ ### `find_all`
95
+
96
+ To find a list of a certain model that matches a set of passed in filters, the `.find_all_by_filters` class method exists. This method has 2 required parameters and 2 optional parameters.
97
+
98
+ The first required parameter is an Array or other enumerable structure containing `Filters`. Like the `.find` method, a `session` is the other required parameter.
99
+
100
+ An `HonestRenter::Filter` is a simple class that accepts two parameters, a `key` and a `value`. The `key` is the field on which to filter.
101
+
102
+ ```ruby
103
+ filters = [HonestRenter::Filter.new(:owner, 'Ted')]
104
+ HonestRenter::Pet.find_all_by_filter(filters, session)
105
+ ```
106
+
107
+ Optionally, a `limit` and `offset` can be given to the `.find_all_by_filters` method to enable pagination.
108
+
109
+ ```ruby
110
+ limit = 10
111
+ offset = 5
112
+ filters = [HonestRenter::Filter.new(owner: 'Ted')]
113
+ HonestRenter::Pet.find_all_by_filter(filters, session, limit, offset)
114
+ ```
115
+
116
+ ## More Information
117
+
118
+ For more information, refer to the [Official Honest Renter API Docs](https://www.honestrenter.com/api/docs)
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require 'rake/testtask'
2
+
3
+ task default: [:test]
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.libs << 'lib'
7
+ t.libs << 'models'
8
+ t.libs << 'test'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ t.verbose = true
11
+ end
@@ -1,5 +1,5 @@
1
1
  lib = File.expand_path('../lib/', __FILE__)
2
- $:.unshift lib unless $:.include?(lib)
2
+ $:.unshift(lib) unless $:.include?(lib)
3
3
  require './version'
4
4
 
5
5
  Gem::Specification.new do |s|
@@ -18,6 +18,11 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.required_ruby_version = '>= 2.0.0'
20
20
 
21
+ s.add_dependency 'faraday', '~> 0.9'
22
+
21
23
  s.add_development_dependency 'bundler', '~> 1.3'
22
24
  s.add_development_dependency 'rake', '~>10'
25
+ s.add_development_dependency 'minitest', '4.3.2'
26
+ s.add_development_dependency 'rspec-mocks', '~> 3'
27
+ s.add_development_dependency 'webmock', '~> 1.0'
23
28
  end
@@ -0,0 +1,76 @@
1
+ module HonestRenter
2
+ class Authenticator
3
+ class << self
4
+ def from_secret_key_member_id(secret_key, member_id)
5
+ SecretKeyMemberIdAuthenticator.new(secret_key, member_id)
6
+ end
7
+
8
+ def from_address_and_password(address, password)
9
+ AddressPasswordAuthenticator.new(address, password)
10
+ end
11
+ end
12
+
13
+ def initialize(*args)
14
+ after_initialize(*args)
15
+ end
16
+
17
+ def session
18
+ @session ||= build_session
19
+ end
20
+
21
+ def renew!
22
+ @session = nil
23
+ session
24
+ end
25
+ end
26
+
27
+ class SecretKeyMemberIdAuthenticator < Authenticator
28
+ require 'openssl'
29
+
30
+ ONE_HOUR = 3600
31
+
32
+ def after_initialize(secret_key, member_id)
33
+ @secret_key = secret_key
34
+ @member_id = member_id
35
+ end
36
+
37
+ def build_session
38
+ json_hash = JSON(raw_hash)
39
+ digest = OpenSSL::Digest.new('sha256')
40
+ encoded = OpenSSL::HMAC.hexdigest(digest, @secret_key, json_hash)
41
+
42
+ HonestRenter::Session.new(encoded, json_hash)
43
+ end
44
+
45
+ def raw_hash
46
+ now = Time.now
47
+
48
+ {
49
+ apiKey: ENV['HONEST_RENTER_API_KEY'],
50
+ authorization: 'member',
51
+ expires: now.to_i + ONE_HOUR,
52
+ person: @member_id,
53
+ renewableUntil: now.to_i + (3 * ONE_HOUR)
54
+ }
55
+ end
56
+ end
57
+
58
+ class AddressPasswordAuthenticator < Authenticator
59
+ def after_initialize(address, password)
60
+ @address = address
61
+ @password = password
62
+ end
63
+
64
+ def build_session
65
+ raw_session = HonestRenter::Post.new('members/session',
66
+ address: @address,
67
+ password: @password)
68
+ .call
69
+
70
+ HonestRenter::Session.new(
71
+ raw_session.headers['honr-authentication-token'],
72
+ raw_session.headers['honr-session']
73
+ )
74
+ end
75
+ end
76
+ end
data/lib/client.rb ADDED
@@ -0,0 +1,11 @@
1
+ module HonestRenter
2
+ class Client
3
+ def initialize(faraday_adapter = Faraday.default_adapter)
4
+ @faraday_adapter = faraday_adapter
5
+ end
6
+
7
+ def connection
8
+ @connection ||= Faraday.new
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ module HonestRenter
2
+ def snake_case(key)
3
+ key.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase
4
+ end
5
+
6
+ module_function :snake_case
7
+ end
8
+
9
+ require 'faraday'
10
+ require 'logger'
11
+ require 'json'
12
+ require_relative './requires'
data/lib/request.rb ADDED
@@ -0,0 +1,71 @@
1
+ module HonestRenter
2
+ class Request
3
+ class ExpiredSession < StandardError; end
4
+
5
+ attr_reader :client, :session
6
+
7
+ BASE_URL = 'https://honestrenter.com/api/'.freeze
8
+ EXPIRES_LENGTH = 3600
9
+ RENEWABLE_MULTIPLIER = 3
10
+
11
+ def initialize(client, session = nil)
12
+ @client = client
13
+ @session = session
14
+
15
+ if !@session.nil? && session.expired?
16
+ raise ExpiredSession, "session expired at: #{ session.expires_at }, please re-authenticate."
17
+ end
18
+ end
19
+
20
+ def headers
21
+ {
22
+ 'Accept' => 'Application/vnd.honestrenter.v1+json'
23
+ }.tap do |_headers|
24
+ unless @session.nil?
25
+ _headers['HONR-Session'] = JSON(@session.honr_session)
26
+ _headers['HONR-Authentication-Token'] = @session.honr_authentication_token
27
+ end
28
+ end
29
+ end
30
+
31
+ def get(url, query_params = {})
32
+ raw_response = client.connection.get("#{BASE_URL}#{url}") do |request|
33
+ request.headers = headers
34
+ request.params['apiKey'] = api_key
35
+ query_params.each_pair do |key, value|
36
+ request.params[key] = value
37
+ end
38
+ end
39
+
40
+ respond(raw_response)
41
+ end
42
+
43
+ def post(url, body, query_params = {})
44
+ _body = post_body(body.merge(apiKey: api_key))
45
+
46
+ raw_response = client.connection.post("#{BASE_URL}#{url}", _body) do |request|
47
+ request.headers = headers
48
+ end
49
+
50
+ respond(raw_response)
51
+ end
52
+
53
+ private
54
+
55
+ def respond(raw_response)
56
+ response = Response.new(raw_response)
57
+
58
+ raise response.error unless response.success?
59
+
60
+ response
61
+ end
62
+
63
+ def post_body(hash)
64
+ hash.map { |k, v| "#{k}=#{v}" }.join('&')
65
+ end
66
+
67
+ def api_key
68
+ ENV['HONEST_RENTER_API_KEY']
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,10 @@
1
+ module HonestRenter
2
+ module Expandable
3
+ def expanding(attribute)
4
+ @expansions ||= []
5
+ @expansions << attribute
6
+
7
+ self
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module HonestRenter
2
+ class Filter
3
+ attr_accessor :key, :value
4
+ def initialize(key, value)
5
+ @key = key
6
+ @value = value
7
+ end
8
+ end
9
+ end