oauth_doorman 0.1.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/lib/oauth_doorman.rb +120 -0
- data/lib/oauth_doorman/oauth_access_api.rb +61 -0
- data/lib/oauth_doorman/oauth_domain_groups_api.rb +32 -0
- data/lib/oauth_doorman/oauth_error.rb +20 -0
- data/lib/oauth_doorman/oauth_sender.rb +24 -0
- data/lib/oauth_doorman/oauth_user_info_api.rb +30 -0
- data/lib/oauth_doorman/sinatra.rb +76 -0
- metadata +250 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'active_support/core_ext/object/blank'
|
4
|
+
require 'active_support/core_ext/hash/keys'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
require 'active_support/core_ext/object/to_query'
|
7
|
+
require 'active_support/core_ext/object/to_param'
|
8
|
+
require 'json'
|
9
|
+
require 'httpclient'
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
|
13
|
+
require "oauth_doorman/oauth_sender"
|
14
|
+
require "oauth_doorman/oauth_error"
|
15
|
+
require "oauth_doorman/oauth_access_api"
|
16
|
+
require "oauth_doorman/oauth_user_info_api"
|
17
|
+
require "oauth_doorman/oauth_domain_groups_api"
|
18
|
+
|
19
|
+
module OauthDoorman
|
20
|
+
class Api
|
21
|
+
include OauthSender
|
22
|
+
include AccessAPI
|
23
|
+
include UserInfoAPI
|
24
|
+
include DomainGroupsAPI
|
25
|
+
|
26
|
+
attr_accessor :access_token, :refresh_token, :start_time, :expires_in
|
27
|
+
|
28
|
+
DEFAULT_CONFIG =
|
29
|
+
{
|
30
|
+
:redirect_uri => "http://localhost:3000/oauth2callback",
|
31
|
+
:client_id => "393121346607.apps.googleusercontent.com",
|
32
|
+
:client_secret => "O1biKD-F1IX9h5t8LNQUFQk7",
|
33
|
+
:scopes => ["https://www.googleapis.com/auth/userinfo.email", "https://apps-apis.google.com/a/feeds/groups/"],
|
34
|
+
:auth_url => "https://accounts.google.com/o/oauth2/auth",
|
35
|
+
:token_url => "https://accounts.google.com/o/oauth2/token",
|
36
|
+
:response_type => "code",
|
37
|
+
:state => "ATAXO",
|
38
|
+
:user_info_url => "https://www.googleapis.com/oauth2/v1/userinfo",
|
39
|
+
:groups_info_url => "https://apps-apis.google.com/a/feeds/group/2.0/%s/?member=%s",
|
40
|
+
:groups_info_auth_header_name => "Authorization",
|
41
|
+
:groups_info_auth_header_content => "OAuth %s",
|
42
|
+
:groups_info_request_timeout => 5,
|
43
|
+
}
|
44
|
+
|
45
|
+
def config= conf
|
46
|
+
@config = DEFAULT_CONFIG.merge(conf)
|
47
|
+
end
|
48
|
+
|
49
|
+
def config
|
50
|
+
return @config ||= DEFAULT_CONFIG
|
51
|
+
end
|
52
|
+
|
53
|
+
def access_token
|
54
|
+
if(!@access_token)
|
55
|
+
raise "call init_connection() in your callback function first before using API methods"
|
56
|
+
end
|
57
|
+
|
58
|
+
if(access_token_has_expired)
|
59
|
+
if(@refresh_token)
|
60
|
+
@access_token = get_access_token_from_refresh_token(@refresh_token)
|
61
|
+
return @access_token
|
62
|
+
else
|
63
|
+
raise "No refresh_token to refresh access_token"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
return @access_token
|
68
|
+
end
|
69
|
+
|
70
|
+
def initialize(custom_config = nil)
|
71
|
+
if(custom_config)
|
72
|
+
self.config = custom_config
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def init_connection_by_code(code)
|
77
|
+
init_connection(code, nil)
|
78
|
+
end
|
79
|
+
|
80
|
+
def init_connection_by_refresh_token(refresh_token)
|
81
|
+
init_connection(nil, refresh_token)
|
82
|
+
end
|
83
|
+
|
84
|
+
def remaining_seconds_to_expiration()
|
85
|
+
return @expires_in - (Time.now - @start_time)
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
def init_connection(code, refresh_token)
|
90
|
+
result_hash = nil
|
91
|
+
|
92
|
+
if(code)
|
93
|
+
result_hash = get_access_or_request_token(code);
|
94
|
+
|
95
|
+
if(result_hash.keys.include?("refresh_token"))
|
96
|
+
@refresh_token = result_hash["refresh_token"]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
if(refresh_token)
|
101
|
+
@refresh_token = refresh_token
|
102
|
+
|
103
|
+
result_hash = get_access_token_from_refresh_token(@refresh_token)
|
104
|
+
end
|
105
|
+
|
106
|
+
@access_token = result_hash["access_token"]
|
107
|
+
@expires_in = result_hash["expires_in"]
|
108
|
+
|
109
|
+
@start_time = Time.now()
|
110
|
+
end
|
111
|
+
|
112
|
+
def access_token_has_expired()
|
113
|
+
if((Time.now - @start_time) > (@expires_in - 10))
|
114
|
+
return true
|
115
|
+
end
|
116
|
+
|
117
|
+
return false
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module OauthDoorman
|
4
|
+
module AccessAPI
|
5
|
+
include Error
|
6
|
+
|
7
|
+
#considering force_refresh_token flag of OauthSender redirection (both or access_token only)
|
8
|
+
def get_access_or_request_token(code)
|
9
|
+
return call_grant_request_token(code, nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def get_access_token_from_refresh_token(refresh_token)
|
13
|
+
return call_grant_request_token(nil, refresh_token)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
#returns
|
18
|
+
#{
|
19
|
+
# "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
|
20
|
+
# "expires_in":3920,
|
21
|
+
# "token_type":"Bearer"
|
22
|
+
#} if ["authorization_code"] = "refresh_token"
|
23
|
+
# or
|
24
|
+
#{
|
25
|
+
# "access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
|
26
|
+
# "expires_in":3920,
|
27
|
+
# "token_type":"Bearer",
|
28
|
+
# "refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
|
29
|
+
#} if ["authorization_code"] = "authorization_code"
|
30
|
+
def call_grant_request_token(code, refresh_token)
|
31
|
+
hash_params = {}
|
32
|
+
hash_params["client_id"] = config[:client_id]
|
33
|
+
hash_params["client_secret"] = config[:client_secret]
|
34
|
+
if(refresh_token)
|
35
|
+
hash_params["grant_type"] = "refresh_token"
|
36
|
+
hash_params["refresh_token"] = refresh_token
|
37
|
+
else
|
38
|
+
hash_params["code"] = code
|
39
|
+
hash_params["grant_type"] = "authorization_code"
|
40
|
+
hash_params["redirect_uri"] = config[:redirect_uri]
|
41
|
+
end
|
42
|
+
|
43
|
+
result = nil
|
44
|
+
|
45
|
+
begin
|
46
|
+
hash_params.each_key { |key|
|
47
|
+
hash_params[key] = URI.escape(hash_params[key])
|
48
|
+
}
|
49
|
+
|
50
|
+
http = HTTPClient.new
|
51
|
+
result = http.post(config[:token_url], hash_params).body
|
52
|
+
|
53
|
+
process_error(result)
|
54
|
+
rescue Exception => exception
|
55
|
+
raise exception
|
56
|
+
end
|
57
|
+
|
58
|
+
return JSON.parse(result)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require "nokogiri"
|
4
|
+
|
5
|
+
module OauthDoorman
|
6
|
+
module DomainGroupsAPI
|
7
|
+
include Error
|
8
|
+
|
9
|
+
def get_user_groups(domain, current_user)
|
10
|
+
result = nil
|
11
|
+
|
12
|
+
begin
|
13
|
+
url = config[:groups_info_url] % [domain, current_user]
|
14
|
+
|
15
|
+
http = HTTPClient.new
|
16
|
+
result = http.get(url, :header => {config[:groups_info_auth_header_name] => config[:groups_info_auth_header_content] % [access_token]}).body
|
17
|
+
|
18
|
+
process_error(result)
|
19
|
+
rescue Exception => exception
|
20
|
+
raise exception
|
21
|
+
end
|
22
|
+
|
23
|
+
user_groups = get_user_group_ids_from_xml(result)
|
24
|
+
return user_groups
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_user_group_ids_from_xml(groups_xml)
|
28
|
+
return Nokogiri::XML(groups_xml).xpath('//apps:property[@name="groupId"]').map { |x| x['value'] }
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
class OauthError < Exception; end
|
3
|
+
|
4
|
+
module OauthDoorman
|
5
|
+
module Error
|
6
|
+
|
7
|
+
def process_error(request_result)
|
8
|
+
if request_result == nil
|
9
|
+
raise OauthError, "nil response content"
|
10
|
+
end
|
11
|
+
|
12
|
+
json = JSON.parse(request_result) rescue nil
|
13
|
+
|
14
|
+
if json && json.has_key?("error")
|
15
|
+
raise OauthError, json
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module OauthDoorman
|
4
|
+
module OauthSender
|
5
|
+
#force_refresh_token flag for refresh_token enforcement
|
6
|
+
def compose_authentification_request_url(force_refresh_token)
|
7
|
+
hash_params = {}
|
8
|
+
hash_params["client_id"] = config[:client_id]
|
9
|
+
hash_params["response_type"] = config[:response_type]
|
10
|
+
hash_params["redirect_uri"] = config[:redirect_uri]
|
11
|
+
hash_params["state"] = config[:state]
|
12
|
+
hash_params["scope"] = config[:scopes].join(" ")
|
13
|
+
if(force_refresh_token)
|
14
|
+
hash_params["access_type"] = "offline"
|
15
|
+
hash_params["approval_prompt"] = "force"
|
16
|
+
else
|
17
|
+
hash_params["approval_prompt"] = "auto"
|
18
|
+
end
|
19
|
+
|
20
|
+
return "#{config[:auth_url]}?#{hash_params.to_query}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
module OauthDoorman
|
4
|
+
module UserInfoAPI
|
5
|
+
include Error
|
6
|
+
|
7
|
+
def get_user_email()
|
8
|
+
result_hash = get_user_info()
|
9
|
+
|
10
|
+
return result_hash["email"]
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_user_info()
|
14
|
+
result = nil
|
15
|
+
|
16
|
+
begin
|
17
|
+
url = "#{config[:user_info_url]}?access_token=#{access_token}"
|
18
|
+
|
19
|
+
http = HTTPClient.new
|
20
|
+
result = http.get(url).body
|
21
|
+
|
22
|
+
process_error(result)
|
23
|
+
rescue Exception => exception
|
24
|
+
raise exception
|
25
|
+
end
|
26
|
+
|
27
|
+
return JSON.parse(result)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
class OauthAuthorizationInvalid < Exception ; end
|
7
|
+
class OauthAuthorizationError < Exception ; end
|
8
|
+
|
9
|
+
module Sinatra
|
10
|
+
module DoormanAuth
|
11
|
+
|
12
|
+
module Helpers
|
13
|
+
|
14
|
+
def protected
|
15
|
+
redirect doorman_sign_in_url unless session[:email] && authorize_user(session[:email])
|
16
|
+
end
|
17
|
+
|
18
|
+
def doorman_sign_in_url
|
19
|
+
doorman.compose_authentification_request_url(false)
|
20
|
+
end
|
21
|
+
|
22
|
+
def doorman
|
23
|
+
OauthDoorman::Api.new(
|
24
|
+
redirect_uri: oauth_callback_url,
|
25
|
+
client_id: settings.doorman_client_id,
|
26
|
+
client_secret: settings.doorman_client_secret,
|
27
|
+
state: "Overseer"
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def oauth_callback_url
|
32
|
+
"http://#{request.env["HTTP_HOST"]}/oauth2callback"
|
33
|
+
end
|
34
|
+
|
35
|
+
def authorize_user email
|
36
|
+
raise NoMethodError, "Please implement into your sinatra 'authorize_user' method with one parameter (email). \n Return true if user is known."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.registered(app)
|
41
|
+
app.helpers DoormanAuth::Helpers
|
42
|
+
|
43
|
+
app.set :sessions, true
|
44
|
+
app.set :session_secret, Digest::SHA1.hexdigest("#{self.class} #{ENV['RACK_ENV']}")
|
45
|
+
|
46
|
+
#Set url to show after logout
|
47
|
+
app.set :default_url_after_sign_out, "/"
|
48
|
+
#Set url to show after login
|
49
|
+
app.set :default_url_after_sign_in, "/"
|
50
|
+
|
51
|
+
# oauth settings
|
52
|
+
app.set :doorman_app_name, "#{self.class}"
|
53
|
+
app.set :doorman_client_id, "FILL"
|
54
|
+
app.set :doorman_client_secret, "FILL"
|
55
|
+
|
56
|
+
app.get "/oauth2callback" do
|
57
|
+
door = doorman
|
58
|
+
door.init_connection_by_code(request.params["code"])
|
59
|
+
user_email = door.get_user_email
|
60
|
+
if authorize_user user_email
|
61
|
+
session[:email] = user_email
|
62
|
+
redirect settings.default_url_after_sign_in
|
63
|
+
else
|
64
|
+
raise OauthAuthorizationInvalid, "Sorry but your email: #{user_email} is not valid for authorization into #{settings.doorman_app_name}."
|
65
|
+
end
|
66
|
+
|
67
|
+
raise OauthAuthorizationError, "Sorry but your attemp to atuhorizate was not succesfull, try again..."
|
68
|
+
end
|
69
|
+
|
70
|
+
app.get "/sign_out" do
|
71
|
+
session[:email] = nil
|
72
|
+
redirect settings.default_url_after_sign_out
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
metadata
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oauth_doorman
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- jan pospisil
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-25 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.9.2
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.9.2
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: httpclient
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 2.2.5
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.2.5
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: json_pure
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: activesupport
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3.0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '3.0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: nokogiri
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: shoulda
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 3.1.1
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 3.1.1
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: shoulda-context
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: turn
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ~>
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 0.9.6
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: 0.9.6
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: rack-test
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: webmock
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: shotgun
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
- !ruby/object:Gem::Dependency
|
191
|
+
name: sinatra
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
193
|
+
none: false
|
194
|
+
requirements:
|
195
|
+
- - ! '>='
|
196
|
+
- !ruby/object:Gem::Version
|
197
|
+
version: '0'
|
198
|
+
type: :development
|
199
|
+
prerelease: false
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
206
|
+
description: composes authentification url, gets google acces_token of user account
|
207
|
+
and gets access to user Google API
|
208
|
+
email: jan.pospisil@ataxo.com
|
209
|
+
executables: []
|
210
|
+
extensions: []
|
211
|
+
extra_rdoc_files: []
|
212
|
+
files:
|
213
|
+
- lib/oauth_doorman.rb
|
214
|
+
- lib/oauth_doorman/oauth_sender.rb
|
215
|
+
- lib/oauth_doorman/oauth_access_api.rb
|
216
|
+
- lib/oauth_doorman/oauth_error.rb
|
217
|
+
- lib/oauth_doorman/oauth_user_info_api.rb
|
218
|
+
- lib/oauth_doorman/oauth_domain_groups_api.rb
|
219
|
+
- lib/oauth_doorman/sinatra.rb
|
220
|
+
homepage: https://github.com/Ataxo/oauth_doorman
|
221
|
+
licenses: []
|
222
|
+
post_install_message:
|
223
|
+
rdoc_options:
|
224
|
+
- --title
|
225
|
+
- Rake -- Ruby Make
|
226
|
+
- --main
|
227
|
+
- README
|
228
|
+
- --line-numbers
|
229
|
+
require_paths:
|
230
|
+
- lib
|
231
|
+
- lib/oauth_doorman
|
232
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ! '>='
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: '0'
|
238
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
239
|
+
none: false
|
240
|
+
requirements:
|
241
|
+
- - ! '>='
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: '0'
|
244
|
+
requirements: []
|
245
|
+
rubyforge_project:
|
246
|
+
rubygems_version: 1.8.23
|
247
|
+
signing_key:
|
248
|
+
specification_version: 3
|
249
|
+
summary: google 3rd party authentification
|
250
|
+
test_files: []
|