doorkeeper-openid_connect 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.ruby-version +1 -0
- data/Gemfile +10 -0
- data/LICENSE.txt +22 -0
- data/README.md +90 -0
- data/Rakefile +7 -0
- data/app/controllers/doorkeeper/openid_connect/userinfo_controller.rb +19 -0
- data/config/locales/en.yml +20 -0
- data/doorkeeper-openid_connect.gemspec +27 -0
- data/lib/doorkeeper/openid_connect.rb +65 -0
- data/lib/doorkeeper/openid_connect/claims_builder.rb +24 -0
- data/lib/doorkeeper/openid_connect/config.rb +125 -0
- data/lib/doorkeeper/openid_connect/engine.rb +9 -0
- data/lib/doorkeeper/openid_connect/models/claims/aggregated_claim.rb +11 -0
- data/lib/doorkeeper/openid_connect/models/claims/claim.rb +15 -0
- data/lib/doorkeeper/openid_connect/models/claims/distributed_claim.rb +11 -0
- data/lib/doorkeeper/openid_connect/models/claims/normal_claim.rb +28 -0
- data/lib/doorkeeper/openid_connect/models/id_token.rb +63 -0
- data/lib/doorkeeper/openid_connect/models/user_info.rb +39 -0
- data/lib/doorkeeper/openid_connect/rails/routes.rb +50 -0
- data/lib/doorkeeper/openid_connect/rails/routes/mapper.rb +30 -0
- data/lib/doorkeeper/openid_connect/rails/routes/mapping.rb +34 -0
- data/lib/doorkeeper/openid_connect/version.rb +5 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +7 -0
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +12 -0
- data/spec/dummy/app/controllers/home_controller.rb +17 -0
- data/spec/dummy/app/controllers/metal_controller.rb +11 -0
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +11 -0
- data/spec/dummy/app/helpers/application_helper.rb +5 -0
- data/spec/dummy/app/models/user.rb +31 -0
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +55 -0
- data/spec/dummy/config/boot.rb +6 -0
- data/spec/dummy/config/database.yml +15 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +62 -0
- data/spec/dummy/config/environments/test.rb +56 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/doorkeeper.rb +59 -0
- data/spec/dummy/config/initializers/secret_token.rb +9 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/doorkeeper.en.yml +5 -0
- data/spec/dummy/config/mongo.yml +11 -0
- data/spec/dummy/config/mongoid2.yml +9 -0
- data/spec/dummy/config/mongoid3.yml +18 -0
- data/spec/dummy/config/mongoid4.yml +19 -0
- data/spec/dummy/config/routes.rb +52 -0
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +9 -0
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +5 -0
- data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +41 -0
- data/spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb +7 -0
- data/spec/dummy/db/schema.rb +65 -0
- data/spec/dummy/log/test.log +16605 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/lib/doorkeeper/openid_connect/config_spec.rb +65 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/spec_helper_integration.rb +48 -0
- metadata +239 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module Models
|
4
|
+
module Claims
|
5
|
+
class NormalClaim < Claim
|
6
|
+
attr_reader :value
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
super(options)
|
10
|
+
@value = options[:value]
|
11
|
+
end
|
12
|
+
|
13
|
+
def type
|
14
|
+
:normal
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(method_sym, *arguments, &block)
|
18
|
+
@value
|
19
|
+
end
|
20
|
+
|
21
|
+
def response_to?(method_sym, *arguments, &block)
|
22
|
+
method_sym.to_s == @name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'sandal'
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module OpenidConnect
|
5
|
+
module Models
|
6
|
+
class IdToken
|
7
|
+
include ActiveModel::Validations
|
8
|
+
|
9
|
+
def initialize(access_token)
|
10
|
+
@access_token = access_token
|
11
|
+
@resource_owner = access_token.instance_eval(&Doorkeeper::OpenidConnect.configuration.resource_owner_from_access_token)
|
12
|
+
@issued_at = Time.now
|
13
|
+
@signer = Sandal::Sig::RS256.new(Doorkeeper::OpenidConnect.configuration.jws_private_key)
|
14
|
+
@public_key = Doorkeeper::OpenidConnect.configuration.jws_public_key
|
15
|
+
end
|
16
|
+
|
17
|
+
def claims
|
18
|
+
{
|
19
|
+
iss: issuer,
|
20
|
+
sub: subject,
|
21
|
+
aud: audience,
|
22
|
+
exp: expiration,
|
23
|
+
iat: issued_at
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def as_json(options = {})
|
28
|
+
claims
|
29
|
+
end
|
30
|
+
|
31
|
+
# TODO make signature strategy configurable with keys?
|
32
|
+
# TODO move this out of the model
|
33
|
+
def as_jws_token
|
34
|
+
Sandal.encode_token(claims, @signer, {
|
35
|
+
kid: @public_key
|
36
|
+
})
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def issuer
|
42
|
+
Doorkeeper::OpenidConnect.configuration.issuer
|
43
|
+
end
|
44
|
+
|
45
|
+
def subject
|
46
|
+
@resource_owner.instance_eval(&Doorkeeper::OpenidConnect.configuration.subject).to_s
|
47
|
+
end
|
48
|
+
|
49
|
+
def audience
|
50
|
+
@access_token.application.uid
|
51
|
+
end
|
52
|
+
|
53
|
+
def expiration
|
54
|
+
(@issued_at.utc + Doorkeeper::OpenidConnect.configuration.expiration).to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def issued_at
|
58
|
+
@issued_at.utc.to_i
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module Models
|
4
|
+
class UserInfo
|
5
|
+
include ActiveModel::Validations
|
6
|
+
|
7
|
+
def initialize(resource_owner)
|
8
|
+
@resource_owner = resource_owner
|
9
|
+
end
|
10
|
+
|
11
|
+
def claims
|
12
|
+
base_claims.merge resource_owner_claims
|
13
|
+
end
|
14
|
+
|
15
|
+
def as_json(options = {})
|
16
|
+
claims
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def base_claims
|
22
|
+
{
|
23
|
+
sub: subject
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def resource_owner_claims
|
28
|
+
Doorkeeper::OpenidConnect.configuration.claims.to_h.map do |claim_name, claim_value|
|
29
|
+
[claim_name, @resource_owner.instance_eval(&claim_value)]
|
30
|
+
end.to_h
|
31
|
+
end
|
32
|
+
|
33
|
+
def subject
|
34
|
+
@resource_owner.instance_eval(&Doorkeeper::OpenidConnect.configuration.subject).to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'doorkeeper/openid_connect/rails/routes/mapping'
|
2
|
+
require 'doorkeeper/openid_connect/rails/routes/mapper'
|
3
|
+
|
4
|
+
module Doorkeeper
|
5
|
+
module OpenidConnect
|
6
|
+
module Rails
|
7
|
+
class Routes
|
8
|
+
module Helper
|
9
|
+
def use_doorkeeper_openid_connect(options = {}, &block)
|
10
|
+
Doorkeeper::OpenidConnect::Rails::Routes.new(self, &block).generate_routes!(options)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.install!
|
15
|
+
ActionDispatch::Routing::Mapper.send :include, Doorkeeper::OpenidConnect::Rails::Routes::Helper
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_accessor :routes
|
19
|
+
|
20
|
+
def initialize(routes, &block)
|
21
|
+
@routes, @block = routes, block
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_routes!(options)
|
25
|
+
@mapping = Mapper.new.map(&@block)
|
26
|
+
routes.scope options[:scope] || 'oauth', as: 'oauth' do
|
27
|
+
map_route(:userinfo, :userinfo_routes)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def map_route(name, method)
|
34
|
+
unless @mapping.skipped?(name)
|
35
|
+
send method, @mapping[name]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def userinfo_routes(mapping)
|
40
|
+
routes.resource(
|
41
|
+
:userinfo,
|
42
|
+
path: 'userinfo',
|
43
|
+
only: [:show], as: mapping[:as],
|
44
|
+
controller: mapping[:controllers]
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module Rails
|
4
|
+
class Routes
|
5
|
+
class Mapper
|
6
|
+
def initialize(mapping = Mapping.new)
|
7
|
+
@mapping = mapping
|
8
|
+
end
|
9
|
+
|
10
|
+
def map(&block)
|
11
|
+
self.instance_eval(&block) if block
|
12
|
+
@mapping
|
13
|
+
end
|
14
|
+
|
15
|
+
def controllers(controller_names = {})
|
16
|
+
@mapping.controllers.merge!(controller_names)
|
17
|
+
end
|
18
|
+
|
19
|
+
def skip_controllers(*controller_names)
|
20
|
+
@mapping.skips = controller_names
|
21
|
+
end
|
22
|
+
|
23
|
+
def as(alias_names = {})
|
24
|
+
@mapping.as.merge!(alias_names)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Doorkeeper
|
2
|
+
module OpenidConnect
|
3
|
+
module Rails
|
4
|
+
class Routes
|
5
|
+
class Mapping
|
6
|
+
attr_accessor :controllers, :as, :skips
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@controllers = {
|
10
|
+
userinfo: 'doorkeeper/openid_connect/userinfo'
|
11
|
+
}
|
12
|
+
|
13
|
+
@as = {
|
14
|
+
userinfo: :userinfo
|
15
|
+
}
|
16
|
+
|
17
|
+
@skips = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](routes)
|
21
|
+
{
|
22
|
+
controllers: @controllers[routes],
|
23
|
+
as: @as[routes]
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def skipped?(controller)
|
28
|
+
@skips.include?(controller)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
3
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
4
|
+
|
5
|
+
require File.expand_path('../config/application', __FILE__)
|
6
|
+
|
7
|
+
Dummy::Application.load_tasks
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class HomeController < ApplicationController
|
2
|
+
def index
|
3
|
+
end
|
4
|
+
|
5
|
+
def sign_in
|
6
|
+
session[:user_id] = if Rails.env.development?
|
7
|
+
User.first || User.create!(name: 'Joe', password: 'sekret')
|
8
|
+
else
|
9
|
+
User.first
|
10
|
+
end
|
11
|
+
redirect_to '/'
|
12
|
+
end
|
13
|
+
|
14
|
+
def callback
|
15
|
+
render text: 'ok'
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# case DOORKEEPER_ORM
|
2
|
+
# when :active_record
|
3
|
+
# class User < ActiveRecord::Base
|
4
|
+
# end
|
5
|
+
# when :mongoid2, :mongoid3, :mongoid4
|
6
|
+
# class User
|
7
|
+
# include Mongoid::Document
|
8
|
+
# include Mongoid::Timestamps
|
9
|
+
#
|
10
|
+
# field :name, type: String
|
11
|
+
# field :password, type: String
|
12
|
+
# end
|
13
|
+
# when :mongo_mapper
|
14
|
+
# class User
|
15
|
+
# include MongoMapper::Document
|
16
|
+
# timestamps!
|
17
|
+
#
|
18
|
+
# key :name, String
|
19
|
+
# key :password, String
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# class User
|
24
|
+
# if ::Rails.version.to_i < 4
|
25
|
+
# attr_accessible :name, :password
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# def self.authenticate!(name, password)
|
29
|
+
# User.where(name: name, password: password).first
|
30
|
+
# end
|
31
|
+
# end
|
File without changes
|