cosmos_authentication 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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