vidibus-user 0.0.10 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/vidibus/vidibus-user.png)](https://travis-ci.org/vidibus/vidibus-user) [![Code Climate](https://codeclimate.com/github/vidibus/vidibus-user.png)](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'
|