warden-github 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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