vidibus-user 0.0.10 → 1.0.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.
- data/README.md +32 -0
- data/Rakefile +12 -30
- data/config/routes.rb +2 -2
- data/lib/vidibus/user/callback_app.rb +5 -5
- data/lib/vidibus/user/errors.rb +7 -0
- data/lib/vidibus/user/extensions/controller.rb +21 -39
- data/lib/vidibus/user/extensions/helper.rb +29 -0
- data/lib/vidibus/user/extensions.rb +14 -3
- data/lib/vidibus/user/mongoid.rb +4 -2
- data/lib/vidibus/user/railstie.rb +19 -0
- data/lib/vidibus/user/version.rb +5 -0
- data/lib/vidibus/user/warden/callbacks/after_set_user.rb +4 -0
- data/lib/vidibus/user/warden/callbacks/before_logout.rb +5 -0
- data/lib/vidibus/user/warden/callbacks.rb +2 -0
- data/lib/vidibus/user/warden/failure_app.rb +30 -0
- data/lib/vidibus/user/warden/helper.rb +55 -0
- data/lib/vidibus/user/warden/serialize.rb +7 -0
- data/lib/vidibus/user/warden/strategies/single_sign_on.rb +77 -0
- data/lib/vidibus/user/warden/strategies.rb +1 -0
- data/lib/vidibus/user/warden.rb +5 -0
- data/lib/vidibus/user.rb +20 -3
- data/lib/vidibus-user.rb +3 -20
- metadata +226 -217
- data/.document +0 -5
- data/.rspec +0 -2
- data/Gemfile +0 -18
- data/LICENSE +0 -20
- data/README.rdoc +0 -43
- data/VERSION +0 -1
- data/lib/vidibus/user/warden_strategy.rb +0 -80
- data/spec/spec_helper.rb +0 -26
- data/vidibus-user.gemspec +0 -92
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Vidibus::User [](https://travis-ci.org/vidibus/vidibus-user) [](https://codeclimate.com/github/vidibus/vidibus-user)
|
2
|
+
|
3
|
+
Provides single sign-on through OAuth2 authentication. It adds a simple user model to your application which can be extended easily.
|
4
|
+
|
5
|
+
This gem is part of [Vidibus](http://vidibus.org), an open source toolset for building distributed (video) applications.
|
6
|
+
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
Add `gem 'vidibus-service'` to your Gemfile. Then call `bundle install` on your console.
|
11
|
+
|
12
|
+
|
13
|
+
## Obtaining user data
|
14
|
+
|
15
|
+
After authorization via OAuth2 this gem requests user data from the providing service. It expects `GET /oauth/user` to return JSON data. The dataset must at least include the user's UUID.
|
16
|
+
|
17
|
+
The [Vidibus::Oauth2Server](https://github.com/vidibus/vidibus-oauth2_server) gem will provide a controller for this task.
|
18
|
+
|
19
|
+
|
20
|
+
## Dependencies
|
21
|
+
|
22
|
+
In order to perform authentication, this gem depends on services provided by the [Vidibus::Service](https://github.com/vidibus/vidibus-service) gem.
|
23
|
+
|
24
|
+
|
25
|
+
## TODO
|
26
|
+
|
27
|
+
Explain usage and integration.
|
28
|
+
|
29
|
+
|
30
|
+
## Copyright
|
31
|
+
|
32
|
+
Copyright (c) 2010-2013 Andre Pankratz. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,35 +1,17 @@
|
|
1
|
-
|
2
|
-
require "rake"
|
3
|
-
require "rake/rdoctask"
|
4
|
-
require "rspec"
|
5
|
-
require "rspec/core/rake_task"
|
1
|
+
$:.unshift File.expand_path('../lib/', __FILE__)
|
6
2
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
gem.description = %Q{Provides single sign-on and a local user model.}
|
13
|
-
gem.email = "andre@vidibus.com"
|
14
|
-
gem.homepage = "http://github.com/vidibus/vidibus-user"
|
15
|
-
gem.authors = ["Andre Pankratz"]
|
16
|
-
end
|
17
|
-
Jeweler::GemcutterTasks.new
|
18
|
-
rescue LoadError
|
19
|
-
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
-
end
|
3
|
+
require 'bundler'
|
4
|
+
require 'rdoc/task'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
require 'vidibus/user/version'
|
21
8
|
|
22
|
-
|
23
|
-
t.pattern = "spec/**/*_spec.rb"
|
24
|
-
t.rcov = true
|
25
|
-
t.rcov_opts = ["--exclude", "^spec,/gems/"]
|
26
|
-
end
|
9
|
+
Bundler::GemHelper.install_tasks
|
27
10
|
|
28
11
|
Rake::RDocTask.new do |rdoc|
|
29
|
-
|
30
|
-
rdoc.
|
31
|
-
rdoc.
|
32
|
-
rdoc.rdoc_files.include(
|
33
|
-
rdoc.
|
34
|
-
rdoc.options << "--charset=utf-8"
|
12
|
+
rdoc.rdoc_dir = 'rdoc'
|
13
|
+
rdoc.title = "vidibus-user #{Vidibus::User::VERSION}"
|
14
|
+
rdoc.rdoc_files.include('README*')
|
15
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
16
|
+
rdoc.options << '--charset=utf-8'
|
35
17
|
end
|
data/config/routes.rb
CHANGED
@@ -5,14 +5,14 @@ module Vidibus
|
|
5
5
|
self.new.call(env)
|
6
6
|
end
|
7
7
|
|
8
|
-
# This is
|
9
|
-
# by the
|
8
|
+
# This is a rack endpoint user authentication. It will be called
|
9
|
+
# by the consumer after requesting an authentication code.
|
10
10
|
def call(env)
|
11
|
-
env[
|
11
|
+
env['warden'].authenticate!(:scope => :user)
|
12
12
|
|
13
13
|
# Redirect to return path after signin
|
14
|
-
return_to = env[
|
15
|
-
[302, {
|
14
|
+
return_to = env['rack.session'][:user_return_to] || '/'
|
15
|
+
[302, {'Content-Type' => 'text/html', 'Location' => return_to}, ['Login successful.']]
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -1,52 +1,34 @@
|
|
1
|
+
require 'vidibus/user/extensions/helper'
|
2
|
+
|
1
3
|
module Vidibus
|
2
4
|
module User
|
3
5
|
module Extensions
|
4
|
-
|
5
|
-
# Contains extensions of ApplicationController.
|
6
6
|
module Controller
|
7
|
-
|
8
|
-
|
9
|
-
included do
|
10
|
-
helper_method :warden, :signed_in?, :user_signed_in?, :current_user, :user_session
|
11
|
-
end
|
12
|
-
|
13
|
-
protected
|
14
|
-
|
15
|
-
# Accessor for the warden proxy instance.
|
16
|
-
def warden
|
17
|
-
request.env["warden"]
|
18
|
-
end
|
19
|
-
|
20
|
-
# Performs login on Connector service.
|
21
|
-
def authenticate_user!
|
22
|
-
return if user_signed_in?
|
23
|
-
store_location
|
24
|
-
warden.authenticate!(:scope => :user)
|
25
|
-
end
|
7
|
+
include Helper
|
26
8
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
9
|
+
# Authenticates user from single sign on cookie.
|
10
|
+
# Nothing happens if authentication fails.
|
11
|
+
def single_sign_on
|
12
|
+
return if authenticated?
|
13
|
+
warden.authenticate(:single_sign_on)
|
30
14
|
end
|
31
15
|
|
32
|
-
#
|
33
|
-
|
34
|
-
|
16
|
+
# Authenticates user either from single sign on cookie
|
17
|
+
# or from email and password params.
|
18
|
+
# Calls failure app if authentication fails.
|
19
|
+
def authenticate!
|
20
|
+
return if authenticated?
|
21
|
+
warden.authenticate!
|
35
22
|
end
|
23
|
+
alias :signin! :authenticate!
|
24
|
+
alias :authenticate_user! :authenticate!
|
36
25
|
|
37
|
-
#
|
38
|
-
def
|
39
|
-
|
40
|
-
|
41
|
-
alias_method :signed_in?, :user_signed_in?
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# Stores current location in session to perform redirect after signin in session
|
46
|
-
def store_location
|
47
|
-
Rails.logger.error 'store_location: '+request.fullpath
|
48
|
-
session[:user_return_to] = request.fullpath
|
26
|
+
# Performs logout.
|
27
|
+
def logout
|
28
|
+
return unless authenticated?
|
29
|
+
warden.logout
|
49
30
|
end
|
31
|
+
alias :signout :logout
|
50
32
|
end
|
51
33
|
end
|
52
34
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Vidibus
|
2
|
+
module User
|
3
|
+
module Extensions
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
# Accessor for the warden proxy instance.
|
7
|
+
def warden
|
8
|
+
request.env['warden']
|
9
|
+
end
|
10
|
+
|
11
|
+
# Returns the user that is currently logged in.
|
12
|
+
def current_user
|
13
|
+
warden.user
|
14
|
+
end
|
15
|
+
|
16
|
+
# Returns the session of the currently signed-in user.
|
17
|
+
def user_session
|
18
|
+
warden.session if current_user
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns true if user is logged in.
|
22
|
+
def authenticated?
|
23
|
+
warden.authenticated?
|
24
|
+
end
|
25
|
+
alias :signed_in? :authenticated?
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,5 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require 'vidibus/user/extensions/controller'
|
2
|
+
require 'vidibus/user/extensions/helper'
|
2
3
|
|
3
|
-
ActiveSupport
|
4
|
-
|
4
|
+
if defined?(ActiveSupport)
|
5
|
+
ActiveSupport.on_load(:action_controller) do
|
6
|
+
include Vidibus::User::Extensions::Controller
|
7
|
+
end
|
8
|
+
|
9
|
+
ActiveSupport.on_load(:application_helper) do
|
10
|
+
include Vidibus::User::Extensions::Helper
|
11
|
+
end
|
12
|
+
|
13
|
+
ActiveSupport.on_load(:action_view) do
|
14
|
+
include Vidibus::User::Extensions::Helper
|
15
|
+
end
|
5
16
|
end
|
data/lib/vidibus/user/mongoid.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
require 'vidibus-uuid'
|
2
|
+
|
1
3
|
module Vidibus
|
2
4
|
module User
|
3
5
|
module Mongoid
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
included do
|
6
|
-
field :uuid
|
7
|
-
field :email
|
8
|
+
field :uuid, type: String
|
9
|
+
field :email, type: String
|
8
10
|
validates :uuid, :uuid => true
|
9
11
|
end
|
10
12
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
if defined?(::Rails::Engine)
|
2
|
+
module Vidibus
|
3
|
+
module User
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
|
6
|
+
# Add warden to rack stack and use vidibus strategy.
|
7
|
+
config.app_middleware.use ::Warden::Manager do |manager|
|
8
|
+
manager.default_strategies :single_sign_on
|
9
|
+
manager.default_scope = :user
|
10
|
+
manager.failure_app = Vidibus::User.failure_app
|
11
|
+
end
|
12
|
+
|
13
|
+
config.after_initialize do
|
14
|
+
Vidibus::User.logger = Rails.logger
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Vidibus
|
2
|
+
module User
|
3
|
+
module Warden
|
4
|
+
class FailureApp
|
5
|
+
include Warden::Helper
|
6
|
+
|
7
|
+
def self.call(env)
|
8
|
+
self.new.call(env)
|
9
|
+
end
|
10
|
+
|
11
|
+
# This is a rack endpoint user authentication. It will be called
|
12
|
+
# by the consumer after requesting an authentication code.
|
13
|
+
def call(env)
|
14
|
+
@env = env
|
15
|
+
body = "Please authenticate at #{host}#{Vidibus::User.login_path}"
|
16
|
+
header = {
|
17
|
+
'Content-Type' => 'text/html',
|
18
|
+
'Location' => Vidibus::User.login_path,
|
19
|
+
'Content-Length' => body.length.to_s
|
20
|
+
}
|
21
|
+
[302, header, [body]]
|
22
|
+
end
|
23
|
+
|
24
|
+
def env
|
25
|
+
@env
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Vidibus
|
2
|
+
module User
|
3
|
+
module Warden
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
# Sets credentials for Connector login in session.
|
7
|
+
# The client_secret will be validated through Vidibus' OauthServer
|
8
|
+
# when issuing an OAuth token. To protect the service's secret, a
|
9
|
+
# custom signature will be sent instead.
|
10
|
+
def credentials
|
11
|
+
@credentials ||= begin
|
12
|
+
service = ::Service.discover(:user, realm)
|
13
|
+
unless service
|
14
|
+
raise(ServiceError, 'No user service is available.')
|
15
|
+
end
|
16
|
+
{
|
17
|
+
:client_id => "#{this.uuid}-#{realm}",
|
18
|
+
:client_secret => Vidibus::Secure.sign(this.uuid, service.secret),
|
19
|
+
:service_url => service.url
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns this service
|
25
|
+
def this
|
26
|
+
@this ||= ::Service.this
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the current realm
|
30
|
+
def realm
|
31
|
+
@realm ||= params['realm'] || env[:realm]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns OAuth client
|
35
|
+
def client
|
36
|
+
@client ||= OAuth2::Client.new(credentials[:client_id], credentials[:client_secret], :site => credentials[:service_url])
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns current host.
|
40
|
+
def host
|
41
|
+
"#{protocol}#{env['HTTP_HOST']}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns protocol depending on SERVER_PORT.
|
45
|
+
def protocol
|
46
|
+
env['SERVER_PORT'] == 443 ? 'https://' : 'http://'
|
47
|
+
end
|
48
|
+
|
49
|
+
def logger
|
50
|
+
Vidibus::User.logger
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'oauth2'
|
2
|
+
|
3
|
+
# Warden strategy to authenticate user from a
|
4
|
+
# single sign-on cookie.
|
5
|
+
::Warden::Strategies.add(:single_sign_on) do
|
6
|
+
include Vidibus::User::Warden::Helper
|
7
|
+
|
8
|
+
USER_DATA_PATH = '/oauth/user'
|
9
|
+
|
10
|
+
# Run this strategy only if a realm is present.
|
11
|
+
def valid?
|
12
|
+
!!realm
|
13
|
+
end
|
14
|
+
|
15
|
+
def user
|
16
|
+
@user
|
17
|
+
end
|
18
|
+
|
19
|
+
def authenticate!
|
20
|
+
return if fetch_code
|
21
|
+
fetch_access_token
|
22
|
+
fetch_user_data
|
23
|
+
user ? success!(user) : fail!
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def args
|
29
|
+
{:redirect_url => "#{host}/authenticate_user?realm=#{realm}"}
|
30
|
+
end
|
31
|
+
|
32
|
+
def code
|
33
|
+
params['code']
|
34
|
+
end
|
35
|
+
|
36
|
+
def access_token
|
37
|
+
@access_token ||= begin
|
38
|
+
client.auth_code.get_token(code, args)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch_code
|
43
|
+
return if code
|
44
|
+
failsafe do
|
45
|
+
redirect!(client.auth_code.authorize_url(args))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def fetch_access_token
|
50
|
+
failsafe do
|
51
|
+
access_token
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def fetch_user_data
|
56
|
+
begin
|
57
|
+
response = access_token.get(USER_DATA_PATH)
|
58
|
+
user_data = JSON.parse(response.body)
|
59
|
+
query = {:uuid => user_data['uuid']}
|
60
|
+
user = User.where(query).first || User.create!(query)
|
61
|
+
user.update_attributes!(user_data)
|
62
|
+
@user = user
|
63
|
+
rescue OAuth2::Error => e
|
64
|
+
logger.error("Vidibus::User: Failed to fetch user data from #{credentials[:service_url]}/#{USER_DATA_PATH}: #{e.message}")
|
65
|
+
rescue => e
|
66
|
+
logger.error("Vidibus::User: #{e.message}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def failsafe(&block)
|
71
|
+
begin
|
72
|
+
block.call
|
73
|
+
rescue OAuth2::Error => e
|
74
|
+
raise(Vidibus::User::SingleSignOnError, e.response.body)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'vidibus/user/warden/strategies/single_sign_on'
|
data/lib/vidibus/user.rb
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require 'vidibus/user/errors'
|
2
|
+
require 'vidibus/user/mongoid'
|
3
|
+
require 'vidibus/user/warden'
|
4
|
+
require 'vidibus/user/extensions'
|
5
|
+
require 'vidibus/user/railstie'
|
6
|
+
|
7
|
+
module Vidibus
|
8
|
+
module User
|
9
|
+
extend self
|
10
|
+
|
11
|
+
attr_accessor :login_path
|
12
|
+
@login_path = '/login'
|
13
|
+
|
14
|
+
attr_accessor :logger
|
15
|
+
@logger = Logger.new(STDOUT)
|
16
|
+
|
17
|
+
attr_accessor :failure_app
|
18
|
+
@failure_app = Vidibus::User::Warden::FailureApp
|
19
|
+
end
|
20
|
+
end
|
data/lib/vidibus-user.rb
CHANGED
@@ -1,20 +1,3 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
require "user"
|
5
|
-
|
6
|
-
module Vidibus
|
7
|
-
module User
|
8
|
-
class Error < StandardError; end
|
9
|
-
class NoRealmError < Error; end
|
10
|
-
|
11
|
-
class Engine < ::Rails::Engine
|
12
|
-
|
13
|
-
# Add warden to rack stack and use connector strategy.
|
14
|
-
config.app_middleware.use Warden::Manager do |manager|
|
15
|
-
manager.default_strategies :connector
|
16
|
-
manager.default_scope = :user
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
1
|
+
require 'warden'
|
2
|
+
require 'vidibus-service'
|
3
|
+
require 'vidibus/user'
|