bouncer-client 0.1.2 → 0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 83c7547cc0455dedc3b0e335ec4ed3947929c251
4
- data.tar.gz: 582dfcc1a9e43ca10f94f4bcaa1da2a044220a2c
3
+ metadata.gz: e17c125be2501897971c0c22c6ca32a50952d9fa
4
+ data.tar.gz: 972ca02953b1b93bfb24b87bd0fb23d71b7de85a
5
5
  SHA512:
6
- metadata.gz: ee79644b7406739aa651d8a87410e7e890a5daa84552da502ddebc458acdbbc34e4d5e888a5a72a88573e3c17f6550c01b5a0e4a52bb78f07d048d6956437fbb
7
- data.tar.gz: c964178c31e5f10057946ecff4cafd25549f2f11c867f6c9257f2f7a77fa8b28a94e2eaf5e79c9da88db43f5b6259ae664e58279994250eccbb8c907945d317a
6
+ metadata.gz: b69f105cac219e2fa3c37feedfa7f4b9bba06c6f9e9b87ac446e39cb5ed4e6ecf3bacb21776d041ab7788f178f63e042e65c9f25aa84e7c01e26f23c380c27aa
7
+ data.tar.gz: dea2489cc65034126e3d828d209f53ad3ae45ac66369709f03be0e16daf0284de31d9dc547f0cdadacb6dcce58c6d0abed330b60180f92af62fc0ad60a70ff35
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ *.swp
1
2
  .env
2
3
  /.bundle/
3
4
  /.yardoc
@@ -19,6 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency 'faraday'
22
+ spec.add_dependency 'faraday_middleware'
22
23
  spec.add_dependency 'redis'
23
24
  spec.add_development_dependency 'codeclimate-test-reporter'
24
25
  spec.add_development_dependency "rake", "~> 10.0"
@@ -1,5 +1,40 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
1
3
  module Bouncer
2
4
  class Client
5
+ def self.current
6
+ raise "Missing BOUNCER_URL environment" unless ENV['BOUNCER_URL']
7
+ @client ||= Bouncer::Client.new ENV['BOUNCER_URL']
8
+ end
3
9
 
10
+ def initialize bouncer_url
11
+ @conn = Faraday.new(url: bouncer_url, headers: { accept: 'application/json' }) do |faraday|
12
+ faraday.response :json, :content_type => /\bjson$/
13
+ faraday.request :json
14
+ faraday.use Faraday::Response::RaiseError
15
+ faraday.adapter Faraday.default_adapter
16
+ faraday.headers['Content-Type'] = 'application/json'
17
+ end
18
+ end
19
+
20
+ def service_token
21
+ @conn.authorization :Service, ENV['SERVICE_TOKEN']
22
+ end
23
+
24
+ def token token
25
+ @conn.authorization :Bearer, token
26
+ end
27
+
28
+ def me
29
+ @conn.get('/me')
30
+ end
31
+
32
+ def user id
33
+ @conn.get("/users/#{id}")
34
+ end
35
+
36
+ def token_info
37
+ @conn.get('/oauth/token/info')
38
+ end
4
39
  end
5
40
  end
@@ -0,0 +1,11 @@
1
+ module Bouncer
2
+ class Device
3
+ attr_accessor :id, :created_at
4
+ def self.from_json json
5
+ device = Device.new
6
+ device.id = json['id']
7
+ device.created_at = json['created_at']
8
+ device
9
+ end
10
+ end
11
+ end
@@ -1,8 +1,6 @@
1
- require 'faraday'
2
1
  require 'redis'
3
2
  module Bouncer
4
3
  class Token
5
- attr_reader :payload
6
4
  def initialize token
7
5
  @token = token.split(' ')[1]
8
6
  return get_from_bouncer unless redis.exists "TOKEN:#{@token}"
@@ -15,39 +13,34 @@ module Bouncer
15
13
  end
16
14
  end
17
15
 
18
- def id
19
- model['id']
20
- end
21
-
22
- def email
23
- model["email"] if user?
24
- end
25
-
26
- def phone
27
- model["phone"] if user?
28
- end
29
-
30
- def image
31
- model["image"] if user?
16
+ def validate!
17
+ puts "DEPRECATED: valid? should be used instead of validate!"
18
+ valid?
32
19
  end
33
20
 
34
- def validate!
21
+ def valid?
35
22
  return false unless @payload
36
23
  @payload["users"] != nil || @payload["devices"] != nil
37
24
  end
38
25
 
39
- def super_admin?
40
- model["super_admin"] == true
41
- end
42
-
43
26
  def device?
44
27
  @payload['devices'] && !@payload['devices'].empty?
45
28
  end
46
29
 
30
+ def device
31
+ return nil unless device?
32
+ @device ||= build_model
33
+ end
34
+
47
35
  def user?
48
36
  @payload['users'] && !@payload['users'].empty?
49
37
  end
50
38
 
39
+ def user
40
+ return nil unless user?
41
+ @user ||= build_model
42
+ end
43
+
51
44
  def self.present? request
52
45
  return false unless auth_header = request.headers['authorization']
53
46
  auth_header.split(' ')[0] == 'Bearer'
@@ -56,33 +49,26 @@ module Bouncer
56
49
  private
57
50
 
58
51
  def get_from_bouncer
59
- raise "No BOUNCER_URL" unless ENV['BOUNCER_URL']
60
- conn = Faraday.new(url: ENV['BOUNCER_URL']) do |faraday|
61
- faraday.request :url_encoded
62
- faraday.adapter Faraday.default_adapter
63
- faraday.headers['Content-Type'] = 'application/json'
64
- faraday.headers['Authorization'] = 'Bearer ' + @token
65
- end
52
+ client = Bouncer::Client.current
53
+ client.token @token
66
54
 
67
- response = conn.get("/oauth/token/info")
68
- @expires_in = JSON.parse(response.body)["expires_in_seconds"]
69
- if response.success?
70
- raw = conn.get("/me")
71
- if raw.success?
72
- @payload = JSON.parse(raw.body)
73
- redis.setex("TOKEN:#{@token}", @expires_in, @payload.to_json)
74
- return
75
- end
76
- end
55
+ begin
56
+ response = client.token_info
57
+ @expires_in = response.body["expires_in_seconds"]
58
+ raw = client.me
59
+ @payload = raw.body
60
+ redis.setex("TOKEN:#{@token}", @expires_in, @payload.to_json)
61
+ rescue Faraday::ClientError
77
62
  @payload = nil
78
63
  redis.del("TOKEN:#{@token}")
64
+ end
79
65
  end
80
66
 
81
- def model
67
+ def build_model
82
68
  if device?
83
- @payload['devices'][0]
69
+ Bouncer::Device.from_json @payload['devices'][0]
84
70
  else
85
- @payload['users'][0]
71
+ Bouncer::User.from_json @payload['users'][0]
86
72
  end
87
73
  end
88
74
 
@@ -0,0 +1,27 @@
1
+ module Bouncer
2
+ class User
3
+ attr_accessor :id, :email, :name, :phone, :image, :super_admin, :created_at
4
+
5
+ def self.from_id id
6
+ client = Bouncer::Client.current
7
+ client.service_token
8
+ raw = client.user id
9
+ from_json raw.body['users'][0]
10
+ end
11
+
12
+ def self.from_json json
13
+ user = User.new
14
+ user.id = json['id']
15
+ user.email = json['email']
16
+ user.phone = json['phone']
17
+ user.image = json['image']
18
+ user.super_admin = json['super_admin']
19
+ user.created_at = json['created_at']
20
+ user
21
+ end
22
+
23
+ def super_admin?
24
+ @super_admin
25
+ end
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Bouncer
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2"
3
3
  end
@@ -1,2 +1,5 @@
1
1
  require 'bouncer-client/token'
2
2
  require 'bouncer-client/errors'
3
+ require 'bouncer-client/user'
4
+ require 'bouncer-client/device'
5
+ require 'bouncer-client/client'
@@ -0,0 +1,62 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://mbouncer.herokuapp.com/oauth/token/info
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Authorization:
13
+ - Bearer junk
14
+ User-Agent:
15
+ - Faraday v0.9.1
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 401
23
+ message: Unauthorized
24
+ headers:
25
+ Server:
26
+ - Cowboy
27
+ Connection:
28
+ - close
29
+ Date:
30
+ - Thu, 19 Feb 2015 19:53:04 GMT
31
+ Status:
32
+ - 401 Unauthorized
33
+ X-Frame-Options:
34
+ - SAMEORIGIN
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ X-Content-Type-Options:
38
+ - nosniff
39
+ Cache-Control:
40
+ - no-store
41
+ Pragma:
42
+ - no-cache
43
+ Content-Type:
44
+ - application/json; charset=utf-8
45
+ Www-Authenticate:
46
+ - Bearer realm="Doorkeeper", error="invalid_request", error_description="The
47
+ request is missing a required parameter, includes an unsupported parameter
48
+ value, or is otherwise malformed."
49
+ X-Request-Id:
50
+ - 3ec4f699-efa2-46bd-bcc8-4dda83815cec
51
+ X-Runtime:
52
+ - '0.007876'
53
+ Via:
54
+ - 1.1 vegur
55
+ body:
56
+ encoding: UTF-8
57
+ string: '{"error":"invalid_request","error_description":"The request is missing
58
+ a required parameter, includes an unsupported parameter value, or is otherwise
59
+ malformed."}'
60
+ http_version:
61
+ recorded_at: Thu, 19 Feb 2015 19:53:03 GMT
62
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,56 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://mbouncer.herokuapp.com/users/960dd380-85db-43c7-b79b-ed3f3c7d4a88
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/json
12
+ Content-Type:
13
+ - application/json
14
+ User-Agent:
15
+ - Faraday v0.9.1
16
+ Authorization:
17
+ - Service a41c1636c6d341c9766ce3e1194d8b1a5f12168abf0c547af2d82c63dff8874f
18
+ Accept-Encoding:
19
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Server:
26
+ - Cowboy
27
+ Connection:
28
+ - close
29
+ Date:
30
+ - Thu, 19 Feb 2015 22:59:40 GMT
31
+ Status:
32
+ - 200 OK
33
+ X-Frame-Options:
34
+ - SAMEORIGIN
35
+ X-Xss-Protection:
36
+ - 1; mode=block
37
+ X-Content-Type-Options:
38
+ - nosniff
39
+ Content-Type:
40
+ - application/json; charset=utf-8
41
+ Etag:
42
+ - W/"f3b0c963380b198b62bf64cc73b32e13"
43
+ Cache-Control:
44
+ - max-age=0, private, must-revalidate
45
+ X-Request-Id:
46
+ - d2b2d060-e687-4d32-85ab-c636bc5d0162
47
+ X-Runtime:
48
+ - '0.156021'
49
+ Via:
50
+ - 1.1 vegur
51
+ body:
52
+ encoding: UTF-8
53
+ string: '{"users":[{"id":"960dd380-85db-43c7-b79b-ed3f3c7d4a88","image":"https://secure.gravatar.com/avatar/ebfcbe366c47be18e8d3d6eb13d51d17?d=mm\u0026s=50","phone":"4075120689","email":"kurt@monsieur.co","name":null,"super_admin":true,"confirmed_at":"2000-01-01T18:46:46.786Z"}]}'
54
+ http_version:
55
+ recorded_at: Thu, 19 Feb 2015 22:59:40 GMT
56
+ recorded_with: VCR 2.9.3
@@ -3,18 +3,26 @@ require 'spec_helper'
3
3
  describe Bouncer::Token do
4
4
  let(:admin_token) { Bouncer::Token.new('Bearer ' + ENV['ADMIN_TOKEN']) }
5
5
  let(:device_token) { Bouncer::Token.new('Bearer ' + ENV['DEVICE_TOKEN'])}
6
- describe "#validate!" do
6
+ let(:invalid_token) { Bouncer::Token.new('Bearer junk') }
7
+
8
+ describe "#valid?" do
7
9
  it "validates admin tokens" do
8
10
  VCR.use_cassette 'bouncer/valid_admin' do
9
- expect(admin_token.validate!).to eq true #hit network
10
- expect(admin_token.validate!).to eq true #redis cache
11
+ expect(admin_token).to be_valid #hit network
12
+ expect(admin_token).to be_valid #redis cache
11
13
  end
12
14
  end
13
15
 
14
16
  it 'validates device tokens' do
15
17
  VCR.use_cassette 'bouncer/valid_device' do
16
- expect(device_token.validate!).to eq true
17
- expect(device_token.validate!).to eq true
18
+ expect(device_token).to be_valid
19
+ expect(device_token).to be_valid
20
+ end
21
+ end
22
+
23
+ it 'does not validate bad token' do
24
+ VCR.use_cassette 'bouncer/invalid_token' do
25
+ expect(invalid_token).to_not be_valid
18
26
  end
19
27
  end
20
28
  end
@@ -22,7 +30,7 @@ describe Bouncer::Token do
22
30
  describe "#super_admin?" do
23
31
  it "returns true" do
24
32
  VCR.use_cassette 'bouncer/valid_admin' do
25
- expect(admin_token).to be_super_admin
33
+ expect(admin_token.user).to be_super_admin
26
34
  end
27
35
  end
28
36
  end
@@ -30,26 +38,30 @@ describe Bouncer::Token do
30
38
  describe "#id" do
31
39
  context "device token" do
32
40
  it 'is correct' do
33
- VCR.use_cassette('bouncer/valid_device') { expect(device_token.id).to eq "e6b89f6d-fc60-4001-b666-8a5a7bb8b369" }
41
+ VCR.use_cassette('bouncer/valid_device') { expect(device_token.device.id).to eq "e6b89f6d-fc60-4001-b666-8a5a7bb8b369" }
34
42
  end
35
43
  end
36
44
  context "user token" do
37
45
  it 'is correct' do
38
- VCR.use_cassette('bouncer/valid_admin') { expect(admin_token.id).to eq "960dd380-85db-43c7-b79b-ed3f3c7d4a88" }
46
+ VCR.use_cassette('bouncer/valid_admin') { expect(admin_token.user.id).to eq "960dd380-85db-43c7-b79b-ed3f3c7d4a88" }
39
47
  end
40
48
  end
41
49
  end
42
50
 
43
51
  describe "#email" do
44
- context "user token" do
45
- it 'is correct' do
46
- VCR.use_cassette('bouncer/valid_admin') { expect(admin_token.email).to eq "kurt@monsieur.co" }
47
- end
52
+ it 'is correct' do
53
+ VCR.use_cassette('bouncer/valid_admin') { expect(admin_token.user.email).to eq "kurt@monsieur.co" }
48
54
  end
49
- context "device token" do
50
- it 'is nil' do
51
- VCR.use_cassette('bouncer/valid_device') { expect(device_token.email).to eq nil }
52
- end
55
+ end
56
+
57
+ describe "device token" do
58
+ it 'does not have a user' do
59
+ VCR.use_cassette('bouncer/valid_device') { expect(device_token.user).to eq nil }
60
+ end
61
+ end
62
+ describe "user token" do
63
+ it 'does not have a device' do
64
+ VCR.use_cassette('bouncer/valid_admin') { expect(admin_token.device).to eq nil }
53
65
  end
54
66
  end
55
67
 
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bouncer::User do
4
+ it 'is created from an ID' do
5
+ uuid = "960dd380-85db-43c7-b79b-ed3f3c7d4a88"
6
+ VCR.use_cassette 'bouncer/user' do
7
+ user = Bouncer::User.from_id uuid
8
+ expect(user.id).to eq uuid
9
+ end
10
+ end
11
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bouncer-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kurt Nelson
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: redis
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -213,13 +227,18 @@ files:
213
227
  - lib/bouncer-client.rb
214
228
  - lib/bouncer-client/client.rb
215
229
  - lib/bouncer-client/controller_mixin.rb
230
+ - lib/bouncer-client/device.rb
216
231
  - lib/bouncer-client/errors.rb
217
232
  - lib/bouncer-client/test_helpers.rb
218
233
  - lib/bouncer-client/token.rb
234
+ - lib/bouncer-client/user.rb
219
235
  - lib/bouncer-client/version.rb
236
+ - spec/cassettes/bouncer/invalid_token.yml
237
+ - spec/cassettes/bouncer/user.yml
220
238
  - spec/cassettes/bouncer/valid_admin.yml
221
239
  - spec/cassettes/bouncer/valid_device.yml
222
240
  - spec/model/token_spec.rb
241
+ - spec/model/user_spec.rb
223
242
  - spec/spec_helper.rb
224
243
  homepage: ''
225
244
  licenses:
@@ -246,7 +265,10 @@ signing_key:
246
265
  specification_version: 4
247
266
  summary: Allows Rails to easily use a Bouncer instance for authentication
248
267
  test_files:
268
+ - spec/cassettes/bouncer/invalid_token.yml
269
+ - spec/cassettes/bouncer/user.yml
249
270
  - spec/cassettes/bouncer/valid_admin.yml
250
271
  - spec/cassettes/bouncer/valid_device.yml
251
272
  - spec/model/token_spec.rb
273
+ - spec/model/user_spec.rb
252
274
  - spec/spec_helper.rb