warden-github 0.12.1 → 0.13.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/warden-github.rb DELETED
@@ -1,14 +0,0 @@
1
- require 'warden'
2
- require 'oauth2'
3
- require 'yajl'
4
-
5
- module Warden
6
- module Github
7
- class GithubMisconfiguredError < StandardError; end
8
- end
9
- end
10
-
11
- require 'warden-github/user'
12
- require 'warden-github/proxy'
13
- require 'warden-github/version'
14
- require 'warden-github/strategy'
@@ -1,45 +0,0 @@
1
- module Warden
2
- module Github
3
- module Oauth
4
- class Proxy
5
- attr_accessor :client_id, :secret, :scopes, :oauth_domain, :callback_url
6
- def initialize(client_id, secret, scopes, oauth_domain, callback_url)
7
- @client_id, @secret, @scopes, @oauth_domain, @callback_url = client_id, secret, scopes, oauth_domain, callback_url
8
- end
9
-
10
- def ssl_options
11
- ca_file = "/usr/lib/ssl/certs/ca-certificates.crt"
12
- if File.exists?(ca_file)
13
- { :ca_file => ca_file }
14
- else
15
- { :ca_file => ''}
16
- end
17
- end
18
-
19
- def client
20
- @client ||= OAuth2::Client.new(@client_id, @secret,
21
- :ssl => ssl_options,
22
- :site => oauth_domain,
23
- :token_url => '/login/oauth/access_token',
24
- :authorize_url => '/login/oauth/authorize')
25
- end
26
-
27
- def api_for(code)
28
- client.auth_code.get_token(code, :redirect_uri => callback_url)
29
- end
30
-
31
- def state
32
- @state ||= Digest::SHA1.hexdigest(rand(36**8).to_s(36))
33
- end
34
-
35
- def authorize_url
36
- client.auth_code.authorize_url(
37
- :state => state,
38
- :scope => scopes,
39
- :redirect_uri => callback_url
40
- )
41
- end
42
- end
43
- end
44
- end
45
- end
@@ -1,83 +0,0 @@
1
- Warden::Strategies.add(:github) do
2
- # Need to make sure that we have a pure representation of the query string.
3
- # Rails adds an "action" parameter which causes the openid gem to error
4
- def params
5
- @params ||= Rack::Utils.parse_query(request.query_string)
6
- end
7
-
8
- def authenticate!
9
- if(params['code'] && params['state'] &&
10
- env['rack.session']['github_oauth_state'] &&
11
- env['rack.session']['github_oauth_state'].size > 0 &&
12
- params['state'] == env['rack.session']['github_oauth_state'])
13
- begin
14
- api = api_for(params['code'])
15
-
16
- user_info = Yajl.load(user_info_for(api.token))
17
- user_info.delete('bio') # Delete bio, as it can easily make the session cookie too long.
18
-
19
- success!(Warden::Github::Oauth::User.new(user_info, api.token))
20
- rescue OAuth2::Error
21
- %(<p>Outdated ?code=#{params['code']}:</p><p>#{$!}</p><p><a href="/auth/github">Retry</a></p>)
22
- end
23
- else
24
- env['rack.session']['github_oauth_state'] = state
25
- env['rack.session']['return_to'] = env['REQUEST_URI']
26
- throw(:warden, [ 302, {'Location' => authorize_url}, [ ]])
27
- end
28
- end
29
-
30
- private
31
-
32
- def state
33
- oauth_proxy.state
34
- end
35
-
36
- def oauth_client
37
- oauth_proxy.client
38
- end
39
-
40
- def authorize_url
41
- oauth_proxy.authorize_url
42
- end
43
-
44
- def api_for(code)
45
- oauth_proxy.api_for(code)
46
- end
47
-
48
- def oauth_proxy
49
- @oauth_proxy ||= Warden::Github::Oauth::Proxy.new(env['warden'].config[:github_client_id],
50
- env['warden'].config[:github_secret],
51
- env['warden'].config[:github_scopes],
52
- env['warden'].config[:github_oauth_domain],
53
- callback_url)
54
- end
55
-
56
- def user_info_for(token)
57
- @user_info ||= RestClient.get(github_api_uri + "/user", :params => {:access_token => token})
58
- end
59
-
60
- def callback_url
61
- absolute_url(request, env['warden'].config[:github_callback_url], env['HTTP_X_FORWARDED_PROTO'])
62
- end
63
-
64
- def absolute_url(request, suffix = nil, proto = "http")
65
- port_part = case request.scheme
66
- when "http"
67
- request.port == 80 ? "" : ":#{request.port}"
68
- when "https"
69
- request.port == 443 ? "" : ":#{request.port}"
70
- end
71
-
72
- proto = "http" if proto.nil?
73
- "#{proto}://#{request.host}#{port_part}#{suffix}"
74
- end
75
-
76
- def github_api_uri
77
- if ENV['OCTOKIT_API_ENDPOINT']
78
- ENV['OCTOKIT_API_ENDPOINT']
79
- else
80
- "https://api.github.com"
81
- end
82
- end
83
- end
@@ -1,159 +0,0 @@
1
- require 'yajl'
2
- require 'octokit'
3
- require 'rest-client'
4
-
5
- module Warden
6
- module Github
7
- module Oauth
8
- class User < Struct.new(:attribs, :token)
9
- def login
10
- attribs['login']
11
- end
12
-
13
- def name
14
- attribs['name']
15
- end
16
-
17
- def gravatar_id
18
- attribs['gravatar_id']
19
- end
20
-
21
- def email
22
- attribs['email']
23
- end
24
-
25
- def company
26
- attribs['company']
27
- end
28
-
29
- # See if the user is a public member of the named organization
30
- #
31
- # name - the organization name
32
- #
33
- # Returns: true if the user is publicized as an org member
34
- def publicized_organization_member?(org_name)
35
- github_raw_request("orgs/#{org_name}/public_members/#{login}").code == 204
36
- rescue RestClient::Forbidden, RestClient::Unauthorized, RestClient::ResourceNotFound => e
37
- false
38
- end
39
-
40
- # See if the user is a member of the named organization
41
- #
42
- # name - the organization name
43
- #
44
- # Returns: true if the user has access, false otherwise
45
- def organization_member?(org_name)
46
- github_raw_request("orgs/#{org_name}/members/#{login}").code == 204
47
- rescue RestClient::Forbidden, RestClient::Unauthorized, RestClient::ResourceNotFound => e
48
- false
49
- end
50
-
51
- # See if the user is a member of the team id
52
- #
53
- # team_id - the team's id
54
- #
55
- # Returns: true if the user has access, false otherwise
56
- def team_member?(team_id)
57
- github_raw_request("teams/#{team_id}/members/#{login}").code == 204
58
- rescue RestClient::Forbidden, RestClient::Unauthorized, RestClient::ResourceNotFound => e
59
- false
60
- end
61
-
62
- # Send a V3 API PUT request to path and parses the response body
63
- #
64
- # path - the path on api.github.com to hit
65
- # params - extra params for calling the api
66
- #
67
- def get(path, params)
68
- github_request(path, params)
69
- end
70
-
71
- # Send a V3 API PUT request to path and parses the response body
72
- #
73
- # path - the path on api.github.com to hit
74
- # params - extra params for calling the api
75
- #
76
- def post(path, params)
77
- headers = {:Authorization => "token #{token}", :content_type => :json, :accept => :json}
78
- res = RestClient.post("#{github_api_uri}/#{path}", params.to_json, headers)
79
- Yajl.load(res)
80
- end
81
-
82
- # Send a V3 API PUT request to path and parses the response body
83
- #
84
- # path - the path on api.github.com to hit
85
- # params - extra params for calling the api
86
- #
87
- def put(path, params)
88
- headers = {:Authorization => "token #{token}", :content_type => :json, :accept => :json}
89
- res = RestClient.put("#{github_api_uri}/#{path}", params.to_json, headers)
90
- Yajl.load(res)
91
- end
92
-
93
- # Send a V3 API DELETE request to path and parses the response body
94
- #
95
- # path - the path on api.github.com to hit
96
- # params - extra params for calling the api
97
- #
98
- def delete(path, params)
99
- headers = {:Authorization => "token #{token}", :content_type => :json, :accept => :json}
100
- res = RestClient.delete("#{github_api_uri}/#{path}", params.to_json, headers)
101
- Yajl.load(res)
102
- end
103
-
104
- # Access the GitHub API from Octokit
105
- #
106
- # Octokit is a robust client library for the GitHub API
107
- # https://github.com/pengwynn/octokit
108
- #
109
- # Returns a cached client object for easy use
110
- def api
111
- @api ||= Octokit::Client.new(:login => login, :oauth_token => token)
112
- end
113
-
114
- # Send a V3 API GET request to path and parse the response body
115
- #
116
- # path - the path on api.github.com to hit
117
- # params - extra params for calling the api
118
- #
119
- # Returns a parsed JSON response
120
- #
121
- # Examples
122
- # github_request("/user")
123
- # # => { 'login' => 'atmos', ... }
124
- #
125
- # github_request("/user/repos", {:page => 2})
126
- # # => [ { 'name' => 'gollum' ... } ]
127
- def github_request(path, params = {})
128
- Yajl.load(github_raw_request(path, params))
129
- end
130
-
131
- # Send a V3 API GET request to path
132
- #
133
- # path - the path on api.github.com to hit
134
- #
135
- # Returns a rest client response object
136
- #
137
- # Examples
138
- # github_raw_request("/user")
139
- # # => RestClient::Response
140
- #
141
- # github_raw_request("/user/repos", {:page => 3})
142
- # # => RestClient::Response
143
- def github_raw_request(path, params = {})
144
- headers = {:Authorization => "token #{token}", :accept => :json}
145
- RestClient.get("#{github_api_uri}/#{path}", headers.merge(:params => params))
146
- end
147
-
148
- private
149
- def github_api_uri
150
- if ENV['GITHUB_OAUTH_API_DOMAIN']
151
- ENV['GITHUB_OAUTH_API_DOMAIN']
152
- else
153
- "https://api.github.com"
154
- end
155
- end
156
- end
157
- end
158
- end
159
- end
@@ -1,5 +0,0 @@
1
- module Warden
2
- module Github
3
- VERSION = "0.12.1"
4
- end
5
- end
data/spec/app.rb DELETED
@@ -1,71 +0,0 @@
1
- require 'sinatra'
2
-
3
- module Example
4
- class App < Sinatra::Base
5
- enable :sessions
6
- enable :raise_errors
7
- disable :show_exceptions
8
-
9
- use Warden::Manager do |manager|
10
- manager.default_strategies :github
11
- manager.failure_app = BadAuthentication
12
-
13
- manager[:github_client_id] = ENV['GITHUB_CLIENT_ID'] || 'ee9aa24b64d82c21535a'
14
- manager[:github_secret] = ENV['GITHUB_CLIENT_SECRET'] || 'ed8ff0c54067aefb808dab1ca265865405d08d6f'
15
-
16
- manager[:github_scopes] = ''
17
- manager[:github_oauth_domain] = ENV['GITHUB_OAUTH_DOMAIN'] || 'https://github.com'
18
- manager[:github_callback_url] = '/auth/github/callback'
19
- end
20
-
21
- helpers do
22
- def ensure_authenticated
23
- unless env['warden'].authenticate!
24
- throw(:warden)
25
- end
26
- end
27
-
28
- def user
29
- env['warden'].user
30
- end
31
- end
32
-
33
- get '/' do
34
- ensure_authenticated
35
- <<-EOS
36
- <h2>Hello There, #{user.name}!</h2>
37
- <h3>Rails Org Member: #{user.organization_member?('rails')}.</h3>
38
- <h3>Publicized Rails Org Member: #{user.publicized_organization_member?('rails')}.</h3>
39
- <h3>Rails Committer Team Member: #{user.team_member?(632)}.</h3>
40
- EOS
41
- end
42
-
43
- get '/redirect_to' do
44
- ensure_authenticated
45
- "Hello There, #{user.name}! return_to is working!"
46
- end
47
-
48
- get '/auth/github/callback' do
49
- ensure_authenticated
50
- redirect '/'
51
- end
52
-
53
- get '/logout' do
54
- env['warden'].logout
55
- "Peace!"
56
- end
57
- end
58
-
59
- class BadAuthentication < Sinatra::Base
60
- get '/unauthenticated' do
61
- status 403
62
- "Unable to authenticate, sorry bud."
63
- end
64
- end
65
-
66
- def self.app
67
- @app ||= Rack::Builder.new do
68
- run App
69
- end
70
- end
71
- end
data/spec/oauth_spec.rb DELETED
@@ -1,18 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- describe "Warden::Github" do
4
- it "requesting an url that requires authentication redirects to github" do
5
- response = get "/"
6
-
7
- uri = Addressable::URI.parse(response.headers["Location"])
8
-
9
- uri.scheme.should eql('https')
10
- uri.host.should eql('github.com')
11
-
12
- params = uri.query_values
13
- params['response_type'].should eql('code')
14
- params['scope'].should eql('')
15
- params['client_id'].should match(/\w{20}/)
16
- params['redirect_uri'].should eql('http://example.org/auth/github/callback')
17
- end
18
- end
data/spec/proxy_spec.rb DELETED
@@ -1,34 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- describe "Warden::Github::Oauth::Proxy" do
4
- before(:all) do
5
- sha = Digest::SHA1.hexdigest(Time.now.to_s)
6
- @proxy = Warden::Github::Oauth::Proxy.new(sha[0..19], sha[0..39],
7
- 'user,public_repo,repo,gist',
8
- 'http://example.org',
9
- 'http://example.org/auth/github/callback')
10
- end
11
-
12
- it "returns an authorize url" do
13
- uri = Addressable::URI.parse(@proxy.authorize_url)
14
-
15
- uri.scheme.should eql('http')
16
- uri.host.should eql('example.org')
17
-
18
- params = uri.query_values
19
- params['response_type'].should eql('code')
20
- params['scope'].should eql('user,public_repo,repo,gist')
21
- params['client_id'].should match(/\w{20}/)
22
- params['redirect_uri'].should eql('http://example.org/auth/github/callback')
23
- end
24
-
25
- it "has a client object" do
26
- @proxy.client.should_not be_nil
27
- end
28
-
29
- it "returns access tokens" do
30
- pending "this hits the network" do
31
- lambda { @proxy.access_token_for(/\w{20}/.gen) }.should_not raise_error
32
- end
33
- end
34
- end
data/spec/user_spec.rb DELETED
@@ -1,14 +0,0 @@
1
- require File.dirname(__FILE__) + '/spec_helper'
2
-
3
- describe "Warden::Github" do
4
- let(:user) do
5
- Warden::Github::Oauth::User.new({'login' => 'atmos'}, 'abcde')
6
- end
7
-
8
- it "knows the token" do
9
- user.token.should eql('abcde')
10
- end
11
- it "can access the octokit object to make api calls" do
12
- user.api.should_not be_nil
13
- end
14
- end