wcc-data 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 +7 -0
- data/.env.example +3 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +36 -0
- data/circle.yml +6 -0
- data/lib/wcc/data.rb +26 -0
- data/lib/wcc/data/config.rb +45 -0
- data/lib/wcc/data/enumerated_type.rb +63 -0
- data/lib/wcc/data/faraday_client_app_token_auth.rb +64 -0
- data/lib/wcc/data/mapper.rb +16 -0
- data/lib/wcc/data/mapper/attributes.rb +54 -0
- data/lib/wcc/data/mapper/json_response.rb +20 -0
- data/lib/wcc/data/mapper/rest_configuration.rb +36 -0
- data/lib/wcc/data/mapper/rest_query.rb +28 -0
- data/lib/wcc/data/model.rb +11 -0
- data/lib/wcc/data/nucleus.rb +15 -0
- data/lib/wcc/data/nucleus/address.rb +17 -0
- data/lib/wcc/data/nucleus/base.rb +6 -0
- data/lib/wcc/data/nucleus/campus.rb +47 -0
- data/lib/wcc/data/nucleus/client_app_token.rb +30 -0
- data/lib/wcc/data/nucleus/contact.rb +33 -0
- data/lib/wcc/data/nucleus/gender.rb +26 -0
- data/lib/wcc/data/nucleus/group.rb +18 -0
- data/lib/wcc/data/nucleus/marital_status.rb +41 -0
- data/lib/wcc/data/nucleus/user.rb +49 -0
- data/lib/wcc/data/rack_client_app_token_auth.rb +77 -0
- data/lib/wcc/data/response.rb +29 -0
- data/lib/wcc/data/rest_endpoint.rb +33 -0
- data/lib/wcc/data/service.rb +55 -0
- data/lib/wcc/data/version.rb +5 -0
- data/spec/spec_helper.rb +22 -0
- data/spec/support/inheritable_class_attribute_examples.rb +16 -0
- data/spec/wcc/data/config_spec.rb +113 -0
- data/spec/wcc/data/enumerated_type_spec.rb +176 -0
- data/spec/wcc/data/faraday_client_app_token_auth_spec.rb +224 -0
- data/spec/wcc/data/mapper/attributes_spec.rb +94 -0
- data/spec/wcc/data/mapper/json_response_spec.rb +50 -0
- data/spec/wcc/data/mapper/rest_configuration_spec.rb +43 -0
- data/spec/wcc/data/mapper/rest_query_spec.rb +50 -0
- data/spec/wcc/data/model_spec.rb +33 -0
- data/spec/wcc/data/nucleus/campus_spec.rb +29 -0
- data/spec/wcc/data/rack_client_app_token_auth_spec.rb +219 -0
- data/spec/wcc/data/response_spec.rb +57 -0
- data/spec/wcc/data/rest_endpoint_spec.rb +71 -0
- data/spec/wcc/data/service_spec.rb +128 -0
- data/spec/wcc/data_spec.rb +25 -0
- data/wcc-data.gemspec +28 -0
- metadata +194 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module WCC::Data::Mapper
|
2
|
+
|
3
|
+
module RESTQuery
|
4
|
+
|
5
|
+
def find(id)
|
6
|
+
ensure_endpoint_defined
|
7
|
+
new_from_response(endpoint.show(id))
|
8
|
+
end
|
9
|
+
|
10
|
+
def list(params={})
|
11
|
+
ensure_endpoint_defined
|
12
|
+
new_from_response(endpoint.index(params: params))
|
13
|
+
end
|
14
|
+
|
15
|
+
def create(attributes={})
|
16
|
+
ensure_endpoint_defined
|
17
|
+
new_from_response(endpoint.create(attributes))
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def ensure_endpoint_defined
|
23
|
+
raise EndpointUndefined unless defined?(endpoint) && endpoint
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module WCC::Data
|
2
|
+
module Nucleus
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
require_relative 'nucleus/base'
|
7
|
+
|
8
|
+
require_relative 'nucleus/address'
|
9
|
+
require_relative 'nucleus/campus'
|
10
|
+
require_relative 'nucleus/client_app_token'
|
11
|
+
require_relative 'nucleus/contact'
|
12
|
+
require_relative 'nucleus/gender'
|
13
|
+
require_relative 'nucleus/group'
|
14
|
+
require_relative 'nucleus/marital_status'
|
15
|
+
require_relative 'nucleus/user'
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class Address < Base
|
4
|
+
set_endpoint :nucleus, "api/v1/users/"
|
5
|
+
|
6
|
+
attribute :user_id
|
7
|
+
attribute :street1, writer: true
|
8
|
+
attribute :street2, writer: true
|
9
|
+
attribute :city, writer: true
|
10
|
+
attribute :state, writer: true
|
11
|
+
attribute :zip, writer: true
|
12
|
+
attribute :latitude, writer: true
|
13
|
+
attribute :longitude, writer: true
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class Campus < WCC::Data::EnumeratedType
|
4
|
+
attributes :id, :name, :key
|
5
|
+
attributes :street, :city, :state, :zip, :geo
|
6
|
+
|
7
|
+
def matches?(value)
|
8
|
+
[id, key].include?(value)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.db
|
12
|
+
[
|
13
|
+
{
|
14
|
+
id: 1,
|
15
|
+
name: 'Dallas',
|
16
|
+
key: :dallas,
|
17
|
+
street: '7540 LBJ Freeway',
|
18
|
+
city: 'Dallas',
|
19
|
+
state: 'TX',
|
20
|
+
zip: '75251',
|
21
|
+
geo: [32.922923, -96.7781638],
|
22
|
+
},
|
23
|
+
{
|
24
|
+
id: 2,
|
25
|
+
name: 'Fort Worth',
|
26
|
+
key: :ft_worth,
|
27
|
+
street: '3345 Winthrop Avenue',
|
28
|
+
city: 'Fort Worth',
|
29
|
+
state: 'TX',
|
30
|
+
zip: '76116',
|
31
|
+
geo: [32.7280064, -97.4146727],
|
32
|
+
},
|
33
|
+
{
|
34
|
+
id: 3,
|
35
|
+
name: 'Plano',
|
36
|
+
key: :plano,
|
37
|
+
street: '6400 K Avenue',
|
38
|
+
city: 'Plano',
|
39
|
+
state: 'TX',
|
40
|
+
zip: '75074',
|
41
|
+
geo: [33.060823, -96.688902],
|
42
|
+
},
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class ClientAppToken < Base
|
4
|
+
set_endpoint :nucleus, "api/v1/client_app_tokens/"
|
5
|
+
|
6
|
+
attribute :token
|
7
|
+
attribute :expires_at
|
8
|
+
attribute :expires_in
|
9
|
+
attribute :created_at
|
10
|
+
attribute :host_app
|
11
|
+
attribute :requesting_app
|
12
|
+
|
13
|
+
def host_app
|
14
|
+
App.new self[:host_app]
|
15
|
+
end
|
16
|
+
|
17
|
+
def requesting_app
|
18
|
+
App.new self[:requesting_app]
|
19
|
+
end
|
20
|
+
|
21
|
+
class App
|
22
|
+
include WCC::Data::Mapper::Attributes
|
23
|
+
attribute :id
|
24
|
+
attribute :uid
|
25
|
+
attribute :name
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class Contact < Base
|
4
|
+
set_endpoint :nucleus, "api/v1/users/"
|
5
|
+
|
6
|
+
attribute :user_id
|
7
|
+
attribute :first_name, writer: true
|
8
|
+
attribute :last_name, writer: true
|
9
|
+
attribute :email, writer: true
|
10
|
+
attribute :phone, writer: true
|
11
|
+
attribute :birthday, writer: true
|
12
|
+
attribute :marital_status_id, writer: true
|
13
|
+
attribute :gender_id, writer: true
|
14
|
+
|
15
|
+
def marital_status
|
16
|
+
MaritalStatus[marital_status_id]
|
17
|
+
end
|
18
|
+
|
19
|
+
def marital_status=(marital_status)
|
20
|
+
self.marital_status_id = marital_status.id
|
21
|
+
end
|
22
|
+
|
23
|
+
def gender
|
24
|
+
Gender[gender_id]
|
25
|
+
end
|
26
|
+
|
27
|
+
def gender=(gender)
|
28
|
+
self.gender_id = gender.id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class Gender < WCC::Data::EnumeratedType
|
4
|
+
attributes :id, :name, :key
|
5
|
+
|
6
|
+
def matches?(value)
|
7
|
+
[id, key].include?(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.db
|
11
|
+
[
|
12
|
+
{
|
13
|
+
id: 1,
|
14
|
+
name: 'Male',
|
15
|
+
key: :male,
|
16
|
+
},
|
17
|
+
{
|
18
|
+
id: 2,
|
19
|
+
name: 'Female',
|
20
|
+
key: :female,
|
21
|
+
},
|
22
|
+
]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class Group < Base
|
4
|
+
set_endpoint :nucleus, "api/v1/groups/"
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :name
|
8
|
+
attribute :member_count
|
9
|
+
attribute :created_at
|
10
|
+
attribute :updated_at
|
11
|
+
|
12
|
+
def users
|
13
|
+
User.list(group_id: id)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class MaritalStatus < WCC::Data::EnumeratedType
|
4
|
+
attributes :id, :name, :key
|
5
|
+
|
6
|
+
def matches?(value)
|
7
|
+
[id, key].include?(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.db
|
11
|
+
[
|
12
|
+
{
|
13
|
+
id: 1,
|
14
|
+
name: 'Single',
|
15
|
+
key: :single,
|
16
|
+
},
|
17
|
+
{
|
18
|
+
id: 2,
|
19
|
+
name: 'Married',
|
20
|
+
key: :married,
|
21
|
+
},
|
22
|
+
{
|
23
|
+
id: 3,
|
24
|
+
name: 'Widowed',
|
25
|
+
key: :widowed,
|
26
|
+
},
|
27
|
+
{
|
28
|
+
id: 4,
|
29
|
+
name: 'Divorced',
|
30
|
+
key: :divorced,
|
31
|
+
},
|
32
|
+
{
|
33
|
+
id: 5,
|
34
|
+
name: 'Separated',
|
35
|
+
key: :separated,
|
36
|
+
},
|
37
|
+
]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module WCC::Data::Nucleus
|
2
|
+
|
3
|
+
class User < Base
|
4
|
+
set_endpoint :nucleus, "api/v1/users/"
|
5
|
+
|
6
|
+
attribute :id
|
7
|
+
attribute :first_name
|
8
|
+
attribute :last_name
|
9
|
+
attribute :email
|
10
|
+
attribute :access_level_id
|
11
|
+
attribute :arena_id, writer: true
|
12
|
+
attribute :created_at
|
13
|
+
attribute :updated_at
|
14
|
+
attribute :user_reviewed_at, writer: true
|
15
|
+
attribute :contact
|
16
|
+
attribute :address
|
17
|
+
|
18
|
+
SAVE_ATTRS = %i[arena_id user_reviewed_at]
|
19
|
+
|
20
|
+
def contact
|
21
|
+
@contact ||= Contact.new self[:contact].merge("user_id" => id)
|
22
|
+
end
|
23
|
+
|
24
|
+
def address
|
25
|
+
@address ||= Address.new self[:address].merge("user_id" => id)
|
26
|
+
end
|
27
|
+
|
28
|
+
def update_attributes(attrs={})
|
29
|
+
self.class.endpoint.update(id, user: attrs)
|
30
|
+
end
|
31
|
+
|
32
|
+
def save
|
33
|
+
update_attributes saveable_attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
def saveable_attributes
|
37
|
+
attributes
|
38
|
+
.select { |key, _| SAVE_ATTRS.include?(key.to_sym) }
|
39
|
+
.merge(contact: contact.attributes)
|
40
|
+
.merge(address: address.attributes)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.search(string, options={})
|
44
|
+
list(options.merge(search: string))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module WCC::Data
|
2
|
+
class RackClientAppTokenAuth
|
3
|
+
class RedisCache
|
4
|
+
DEFAULT_CACHE_KEY = "org.watermark.wcc-api.client-app-token-cache-store"
|
5
|
+
DEFAULT_CACHE_LENGTH = 600
|
6
|
+
|
7
|
+
attr_reader :connection, :cache_key, :cache_length
|
8
|
+
|
9
|
+
def initialize(connection, cache_key: DEFAULT_CACHE_KEY, cache_length: DEFAULT_CACHE_LENGTH)
|
10
|
+
@connection = connection
|
11
|
+
@cache_key = cache_key
|
12
|
+
@cache_length = cache_length
|
13
|
+
end
|
14
|
+
|
15
|
+
def <<(token)
|
16
|
+
connection.call do |r|
|
17
|
+
r.set join_key(token), "1"
|
18
|
+
r.expire join_key(token), cache_length
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def find(token)
|
23
|
+
connection.call do |r|
|
24
|
+
r.get join_key(token)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def join_key(suffix)
|
31
|
+
[cache_key, suffix].join(".")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :app, :cache, :lookup_token
|
36
|
+
|
37
|
+
def initialize(app, cache: default_cache, lookup_token: method(:default_lookup_token))
|
38
|
+
@app = app
|
39
|
+
@cache = cache
|
40
|
+
@lookup_token = lookup_token
|
41
|
+
end
|
42
|
+
|
43
|
+
def find(token)
|
44
|
+
cached = cache.find(token)
|
45
|
+
return cached if cached
|
46
|
+
|
47
|
+
val = lookup_token.(token)
|
48
|
+
|
49
|
+
cache << token if val
|
50
|
+
|
51
|
+
val
|
52
|
+
end
|
53
|
+
|
54
|
+
def call(env)
|
55
|
+
_, token_string = env["HTTP_AUTHORIZATION"].split(/\s+/)
|
56
|
+
if find(token_string)
|
57
|
+
app.call(env)
|
58
|
+
else
|
59
|
+
[403, {}, '{"error":"Invalid Bearer Token"}']
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def default_cache
|
66
|
+
RedisCache.new(Sidekiq.method(:redis))
|
67
|
+
end
|
68
|
+
|
69
|
+
def default_lookup_token(token)
|
70
|
+
WCC::Data::Nucleus::ClientAppToken.find(token)
|
71
|
+
rescue WCC::Data::Mapper::InvalidResponse, WCC::Data::Mapper::RecordNotFound
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module WCC::Data
|
4
|
+
class Response
|
5
|
+
attr_reader :raw
|
6
|
+
|
7
|
+
def initialize(raw)
|
8
|
+
@raw = raw
|
9
|
+
end
|
10
|
+
|
11
|
+
def json
|
12
|
+
JSON.parse(body)
|
13
|
+
rescue JSON::ParserError
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(method, *args, &block)
|
17
|
+
if raw.respond_to?(method)
|
18
|
+
raw.public_send(method, *args, &block)
|
19
|
+
else
|
20
|
+
super
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(method)
|
25
|
+
super || raw.respond_to?(method)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|