cosmos_authentication 0.0.1 → 0.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.
@@ -0,0 +1,17 @@
1
+ module CosmosAuthentication
2
+ module Middleware
3
+ class UseToken
4
+ def initialize(app, key = :current_body)
5
+ @app = app
6
+ @key = key
7
+ end
8
+
9
+ def call(env)
10
+ access_token = env[@key]['access_token']
11
+ header = {'Authentication' => "Bearer #{access_token}"}
12
+ env[:client].tap { |client| client.headers.merge!(header) }
13
+ @app.call env
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,137 @@
1
+ require 'cosmos_authentication/service'
2
+
3
+ module CosmosAuthentication
4
+ class RackMiddleware
5
+ class Authenticator
6
+ attr_reader :current
7
+
8
+ def initialize(opts, env)
9
+ @opts = opts
10
+ @env = env
11
+ end
12
+
13
+ def authenticate(scope = '')
14
+ begin
15
+ token = access_token(scope)
16
+ @current = service.resource_owner(token)
17
+ rescue Cosmos::UnknownLinkError => e
18
+ session[:access_token] = nil
19
+ authenticate
20
+ end
21
+
22
+ nil
23
+ end
24
+
25
+ def logged_in?
26
+ !!current
27
+ end
28
+
29
+ def logout
30
+ session[:access_token] = nil
31
+ session[:refresh_token] = nil
32
+
33
+ nil
34
+ end
35
+
36
+ private
37
+ def access_token(scope)
38
+ unless token = access_token_from_header
39
+ ensure_token(scope)
40
+ token = access_token_from_session
41
+ end
42
+
43
+ token
44
+ end
45
+
46
+ def access_token_from_header
47
+ if has_header? && match = header.match(/Bearer\s+(\w+)/i)
48
+ {'access_token' => match[1]}
49
+ end
50
+ end
51
+
52
+ def access_token_from_session
53
+ {'access_token' => session[:access_token]}
54
+ end
55
+
56
+ def code_available?
57
+ request.get? && !!params['code']
58
+ end
59
+
60
+ def get_token(scope)
61
+ if code_available?
62
+ service.get_token_via_code(params['code'])
63
+ elsif password_available?
64
+ service.get_token_via_password(
65
+ params['username'],
66
+ params['password'],
67
+ scope
68
+ )
69
+ elsif refresh_token_available?
70
+ service.get_token_via_refresh_token(
71
+ session[:refresh_token],
72
+ scope
73
+ )
74
+ end
75
+ end
76
+
77
+ def ensure_token(scope)
78
+ unless session[:access_token]
79
+ if token = get_token(scope)
80
+ session[:access_token] = token['access_token']
81
+ session[:refresh_token] = token['refresh_token']
82
+ end
83
+ end
84
+ end
85
+
86
+ def has_header?
87
+ !!header
88
+ end
89
+
90
+ def header
91
+ @env['HTTP_AUTHENTICATION']
92
+ end
93
+
94
+ def params
95
+ request.params
96
+ end
97
+
98
+ def password_available?
99
+ request.post? && !!params['username'] && !!params['password']
100
+ end
101
+
102
+ def refresh_token_available?
103
+ !!session[:refresh_token]
104
+ end
105
+
106
+ def request
107
+ @req ||= Rack::Request.new(@env)
108
+ end
109
+
110
+ def session
111
+ @env['rack.session']
112
+ end
113
+
114
+ def service
115
+ @service ||= Service.new do |config|
116
+ config.client_id = @opts[:client_id]
117
+ config.client_secret = @opts[:client_secret]
118
+ config.endpoint = @opts[:endpoint]
119
+ config.cache = @opts[:cache] if @opts[:cache]
120
+ if @opts[:resource_owner_class]
121
+ config.resource_owner_class = @opts[:resource_owner_class]
122
+ end
123
+ end
124
+ end
125
+ end
126
+
127
+ def initialize(app, opts = {})
128
+ @app = app
129
+ @opts = opts
130
+ end
131
+
132
+ def call(env)
133
+ env['authentication'] = Authenticator.new(@opts, env)
134
+ @app.call env
135
+ end
136
+ end
137
+ end
@@ -1,25 +1,13 @@
1
- require "cosmos_authentication/stub"
2
- require "cosmos_authentication/resources"
1
+ module CosmosAuthentication
2
+ class ResourceOwner
3
+ attr_accessor :collection
3
4
 
4
- module Cosmos
5
- module Authentication
6
- class ResourceOwner
7
- def initialize(client, collection)
8
- @client = client
9
- @collection = collection
10
- end
5
+ extend Forwardable
6
+ def_delegators :item, :data, :datum, :href, :link, :links
11
7
 
12
- def data
13
- @data ||= @collection.items.first.data.inject({}) do |hash, data|
14
- hash.merge!({data.name => data.value})
15
- end
16
- end
17
-
18
- def resources
19
- @resources ||= @collection.links.inject({}) do |hash, link|
20
- hash.merge!({link.rel => Stub.new(@client, Resources, link.href)})
21
- end
22
- end
8
+ private
9
+ def item
10
+ @item ||= @collection.items.first
23
11
  end
24
12
  end
25
13
  end
@@ -1,71 +1,96 @@
1
1
  require "cosmos/service"
2
2
  require "cosmos_authentication/resource_owner"
3
+ require "cosmos_authentication/middleware/use_token"
3
4
 
4
- module Cosmos
5
- module Authentication
6
- class Service < Cosmos::Service
7
- attr_accessor :client_id, :client_secret
5
+ module CosmosAuthentication
6
+ class Service < Cosmos::Service
7
+ attr_accessor :client_id, :client_secret
8
+ attr_writer :resource_owner_class
8
9
 
9
- def client_with_credentials
10
- raise "No credentials configured." unless client_id && client_secret
11
- @client_with_credentials ||= client.dup.tap do |client|
12
- client.params['client_id'] = client_id
13
- client.params['client_secret'] = client_secret
14
- end
15
- end
10
+ def default_env
11
+ super.merge({
12
+ data: {
13
+ client_id: client_id,
14
+ client_secret: client_secret
15
+ }
16
+ })
17
+ end
16
18
 
17
- def client_with_token(access_token)
18
- client.dup.tap do |client|
19
- client.headers['Authentication'] = "Bearer #{access_token}"
20
- end
21
- end
19
+ def get_token_via_code(code)
20
+ get_token({
21
+ client_id: client_id,
22
+ client_secret: client_secret,
23
+ grant_type: 'code',
24
+ code: code
25
+ })
26
+ end
22
27
 
23
- def get_token_with_code(code)
24
- client = client_with_credentials
25
- response = client.post token_link.href, {
26
- grant_type: 'code',
27
- code: code
28
- }
29
- response.body
30
- end
28
+ def get_token_via_password(username, password, scope = '')
29
+ get_token({
30
+ client_id: client_id,
31
+ client_secret: client_secret,
32
+ grant_type: 'password',
33
+ username: username,
34
+ password: password,
35
+ scope: scope
36
+ })
37
+ end
31
38
 
32
- def get_token_with_refresh_token(refresh_token)
33
- client = client_with_credentials
34
- response = client.post token_link.href, {
35
- :grant_type => 'refresh_token',
36
- :refresh_token => refresh_token
37
- }
38
- response.body
39
- end
39
+ def get_token_via_refresh_token(refresh_token, scope = '')
40
+ get_token({
41
+ client_id: client_id,
42
+ client_secret: client_secret,
43
+ grant_type: 'refresh_token',
44
+ refresh_token: refresh_token
45
+ })
46
+ end
40
47
 
41
- def get_token_with_username_and_password(username, password, scope = '')
42
- client = client_with_credentials
43
- response = client.post token_link.href, {
44
- :grant_type => 'password',
45
- :username => username,
46
- :password => password,
47
- :scope => 'manage_companies'
48
- }
49
- response.body
48
+ def providers
49
+ get_providers
50
+ end
51
+
52
+ def resource_owner(access_token)
53
+ resource_owner_class.new.tap do |resource_owner|
54
+ resource_owner.collection = get_resource_owner(access_token)
50
55
  end
56
+ end
57
+
58
+ def resource_owner_class
59
+ @resource_owner_class || ResourceOwner
60
+ end
51
61
 
52
- def resource_owner(access_token, klass = ResourceOwner)
53
- client = client_with_token(access_token)
54
- href = endpoint.link('resource_owner').href
55
- response = client.get(href).body
56
- if response.items.length > 0
57
- response = client.get(response.items.first.href).body
58
- klass.new(client, response)
59
- end
62
+ private
63
+ def get_token(data)
64
+ output = call(data: data) do
65
+ use Cosmos::Middleware::Discover
66
+ use Cosmos::Middleware::Traverse, 'oauth2-token'
67
+ use Cosmos::Middleware::Submit
68
+ use Cosmos::Middleware::Save, :token
60
69
  end
61
70
 
62
- def token_link
63
- endpoint.link('oauth2_token')
71
+ output[:token]
72
+ end
73
+
74
+ def get_providers
75
+ output = call do
76
+ use Cosmos::Middleware::Discover
77
+ use Cosmos::Middleware::Traverse, 'providers'
78
+ use Cosmos::Middleware::Save, :providers
64
79
  end
65
80
 
66
- def use_for_warden_authentication
67
- Cosmos::Authentication.warden_service self
81
+ output[:providers]
82
+ end
83
+
84
+ def get_resource_owner(access_token)
85
+ output = call(access_token: access_token) do
86
+ use Middleware::UseToken, :access_token
87
+ use Cosmos::Middleware::Discover
88
+ use Cosmos::Middleware::Traverse, 'resource-owners'
89
+ use Cosmos::Middleware::Traverse, 'current'
90
+ use Cosmos::Middleware::Save, :resource_owner
68
91
  end
92
+
93
+ output[:resource_owner]
69
94
  end
70
95
  end
71
96
  end
@@ -1,3 +1,3 @@
1
1
  module CosmosAuthentication
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -1,12 +1,5 @@
1
1
  require "cosmos_authentication/version"
2
2
  require "cosmos_authentication/service"
3
- require "cosmos_authentication/warden" if Warden
4
3
 
5
- module Cosmos
6
- module Authentication
7
- def self.warden_service(service = nil)
8
- @warden_service = service unless service.nil?
9
- @warden_service || raise('No authentication service configured for warden.'.inspect)
10
- end
11
- end
4
+ module CosmosAuthentication
12
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cosmos_authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-22 00:00:00.000000000 Z
12
+ date: 2012-04-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cosmos
16
- requirement: &70098052432800 !ruby/object:Gem::Requirement
16
+ requirement: &70219771179280 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70098052432800
24
+ version_requirements: *70219771179280
25
25
  description: A client for the cosmos authentication service.
26
26
  email:
27
27
  - sebastian@uprise.co.nz
@@ -34,16 +34,11 @@ files:
34
34
  - Rakefile
35
35
  - cosmos_authentication.gemspec
36
36
  - lib/cosmos_authentication.rb
37
+ - lib/cosmos_authentication/middleware/use_token.rb
38
+ - lib/cosmos_authentication/rack_middleware.rb
37
39
  - lib/cosmos_authentication/resource_owner.rb
38
- - lib/cosmos_authentication/resources.rb
39
40
  - lib/cosmos_authentication/service.rb
40
- - lib/cosmos_authentication/stub.rb
41
41
  - lib/cosmos_authentication/version.rb
42
- - lib/cosmos_authentication/warden.rb
43
- - lib/cosmos_authentication/warden_strategies/access_token.rb
44
- - lib/cosmos_authentication/warden_strategies/code.rb
45
- - lib/cosmos_authentication/warden_strategies/password.rb
46
- - lib/cosmos_authentication/warden_strategies/refresh_token.rb
47
42
  homepage: https://github.com/SebastianEdwards/cosmos_authentication
48
43
  licenses: []
49
44
  post_install_message:
@@ -1,29 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- class Resources
4
- def initialize(client, collection)
5
- @client = client
6
- @collection = collection
7
- end
8
-
9
- def has_resource?(uri)
10
- matches = @collection.items.select do |item|
11
- item.href == uri
12
- end.length > 0
13
- end
14
-
15
- def all
16
- @collection.items.map do |item|
17
- Stub.new(@client, Resource, item.href)
18
- end
19
- end
20
- end
21
-
22
- class Resource
23
- def initialize(client, collection)
24
- @client = client
25
- @collection = collection
26
- end
27
- end
28
- end
29
- end
@@ -1,22 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- class Stub
4
- attr_reader :href
5
-
6
- def initialize(client, klass, href)
7
- @client = client
8
- @klass = klass
9
- @href = href
10
- end
11
-
12
- def method_missing(method_sym, *args)
13
- @object ||= @klass.new(@client, @client.get(href).body)
14
- if @object.respond_to?(method_sym)
15
- @object.send method_sym, *args
16
- else
17
- super
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,28 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- module Warden
4
- module StrategyMixin
5
- def service
6
- Cosmos::Authentication.warden_service
7
- end
8
-
9
- def resource_owner(access_token)
10
- service.resource_owner access_token
11
- end
12
-
13
- def find_user_by_access_token(access_token)
14
- if ro = resource_owner(access_token)
15
- success!(ro)
16
- else
17
- session[:access_token] = nil
18
- end
19
- end
20
- end
21
-
22
- require "cosmos_authentication/warden_strategies/access_token"
23
- require "cosmos_authentication/warden_strategies/code"
24
- require "cosmos_authentication/warden_strategies/password"
25
- require "cosmos_authentication/warden_strategies/refresh_token"
26
- end
27
- end
28
- end
@@ -1,17 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- module Warden
4
- ::Warden::Strategies.add(:access_token) do
5
- include StrategyMixin
6
-
7
- def valid?
8
- session[:access_token]
9
- end
10
-
11
- def authenticate!
12
- find_user_by_access_token(session[:access_token])
13
- end
14
- end
15
- end
16
- end
17
- end
@@ -1,20 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- module Warden
4
- ::Warden::Strategies.add(:code) do
5
- include StrategyMixin
6
-
7
- def valid?
8
- params[:code]
9
- end
10
-
11
- def authenticate!
12
- if token = service.get_token_with_code(params[:code])
13
- session[:refresh_token] = token['refresh_token']
14
- session[:access_token] = token['access_token']
15
- end
16
- end
17
- end
18
- end
19
- end
20
- end
@@ -1,21 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- module Warden
4
- ::Warden::Strategies.add(:password) do
5
- include StrategyMixin
6
-
7
- def valid?
8
- params[:username] && params[:password]
9
- end
10
-
11
- def authenticate!
12
- args = [params[:username], params[:password]]
13
- if token = service.get_token_with_username_and_password(*args)
14
- session[:refresh_token] = token['refresh_token']
15
- session[:access_token] = token['access_token']
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,21 +0,0 @@
1
- module Cosmos
2
- module Authentication
3
- module Warden
4
- ::Warden::Strategies.add(:refresh_token) do
5
- include StrategyMixin
6
-
7
- def valid?
8
- session[:refresh_token]
9
- end
10
-
11
- def authenticate!
12
- if token = service.get_token_with_refresh_token(session[:refresh_token])
13
- session[:refresh_token] = token['refresh_token']
14
- session[:access_token] = token['access_token']
15
- find_user_by_access_token(session[:access_token])
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end