omniauth-khan-academy 0.0.1
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/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +56 -0
- data/Rakefile +2 -0
- data/lib/omniauth-khan-academy.rb +2 -0
- data/lib/omniauth-khan-academy/version.rb +5 -0
- data/lib/omniauth/strategies/khan_academy.rb +107 -0
- data/omniauth-khan-academy.gemspec +25 -0
- data/spec/omniauth/strategies/khan_academy_spec.rb +58 -0
- data/spec/spec_helper.rb +6 -0
- metadata +124 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Dipil
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# OmniAuth KhanAcademy
|
2
|
+
|
3
|
+
This is an [OmniAuth 1.0](https://github.com/intridea/omniauth) strategy for authenticating to KhanAcademy.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'omniauth-khan-academy'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install omniauth-khan-academy
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Register[http://www.khanacademy.org/api-apps/register] your app at KhanAcademy and get your consumer token and secret.
|
22
|
+
|
23
|
+
|
24
|
+
In a Rack application:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
use OmniAuth::Builder do
|
28
|
+
provider :khan_academy, CONSUMER_TOKEN, CONSUMER_SECRET
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
For Rails, put this in your omniauth configuration file:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
36
|
+
provider :khan_academy, CONSUMER_TOKEN, CONSUMER_SECRET
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
Restart the server and visit "*/auth/khanacademy" to try it out.
|
41
|
+
|
42
|
+
The default callback is routed to "*/auth/khanacademy/callback" but you can override it as shown:
|
43
|
+
|
44
|
+
provider :khan_academy, CONSUMER_TOKEN, CONSUMER_SECRET, callback_url: "my_callback_url"
|
45
|
+
|
46
|
+
## Author
|
47
|
+
|
48
|
+
[Dipil Saud (@dipil-saud)](https://github.com/dipil-saud)
|
49
|
+
|
50
|
+
## Contributing
|
51
|
+
|
52
|
+
1. Fork it
|
53
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
54
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
55
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
56
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require "multi_json"
|
2
|
+
require "omniauth"
|
3
|
+
require "oauth"
|
4
|
+
|
5
|
+
# for Hash#to_query
|
6
|
+
require "active_support/core_ext"
|
7
|
+
|
8
|
+
module OmniAuth
|
9
|
+
module Strategies
|
10
|
+
|
11
|
+
class KhanAcademy
|
12
|
+
include OmniAuth::Strategy
|
13
|
+
|
14
|
+
args [:consumer_key, :consumer_secret]
|
15
|
+
|
16
|
+
option :consumer_key, nil
|
17
|
+
option :consumer_secret, nil
|
18
|
+
option :callback_url, nil
|
19
|
+
option :client_options, {}
|
20
|
+
|
21
|
+
DEFAULT_CLIENT_OPTIONS = {
|
22
|
+
"http_method" => :get,
|
23
|
+
"site" => "http://www.khanacademy.org",
|
24
|
+
"request_token_path" => "/api/auth/request_token",
|
25
|
+
"access_token_path" => "/api/auth/access_token"
|
26
|
+
}
|
27
|
+
|
28
|
+
attr_reader :access_token
|
29
|
+
|
30
|
+
# this will redirect to the KhanAcademy login page where you can login using google, facebook or khan"s login
|
31
|
+
# Khan returns the required credentials for the request token after authentication
|
32
|
+
def request_phase
|
33
|
+
session["oauth"] ||= {}
|
34
|
+
redirect login_url
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def callback_phase
|
39
|
+
raise OmniAuth::NoSessionError.new("Session Expired") if session["oauth"].nil?
|
40
|
+
# Create a request token from the token and secret provided in the response
|
41
|
+
request_token = ::OAuth::AccessToken.new(consumer, request["oauth_token"], request["oauth_token_secret"])
|
42
|
+
# Request access_token from the created request_token
|
43
|
+
@access_token = consumer.get_access_token(request_token, {oauth_callback: callback_url, oauth_verifier: request["oauth_verifier"]})
|
44
|
+
|
45
|
+
super
|
46
|
+
rescue ::Timeout::Error => e
|
47
|
+
fail!(:timeout, e)
|
48
|
+
rescue ::Net::HTTPFatalError, ::OpenSSL::SSL::SSLError => e
|
49
|
+
fail!(:service_unavailable, e)
|
50
|
+
rescue ::OAuth::Unauthorized => e
|
51
|
+
fail!(:invalid_credentials, e)
|
52
|
+
rescue ::MultiJson::DecodeError => e
|
53
|
+
fail!(:invalid_response, e)
|
54
|
+
rescue ::OmniAuth::NoSessionError => e
|
55
|
+
fail!(:session_expired, e)
|
56
|
+
end
|
57
|
+
|
58
|
+
def raw_info
|
59
|
+
@raw_info ||= MultiJson.decode(access_token.get("/api/v1/user").body)
|
60
|
+
end
|
61
|
+
|
62
|
+
uid do
|
63
|
+
raw_info["user_id"]
|
64
|
+
end
|
65
|
+
|
66
|
+
credentials do
|
67
|
+
{"token" => access_token.token, "secret" => access_token.secret}
|
68
|
+
end
|
69
|
+
|
70
|
+
extra do
|
71
|
+
{"access_token" => access_token, "raw_info" => raw_info}
|
72
|
+
end
|
73
|
+
|
74
|
+
info do
|
75
|
+
{
|
76
|
+
"email" => raw_info["email"],
|
77
|
+
"nickname" => raw_info["nickname"]
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
def client_options
|
82
|
+
DEFAULT_CLIENT_OPTIONS.merge(options.client_options || {})
|
83
|
+
end
|
84
|
+
|
85
|
+
def callback_url
|
86
|
+
options.callback_url || super
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def consumer
|
91
|
+
@consumer ||= ::OAuth::Consumer.new(options.consumer_key, options.consumer_secret, client_options)
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def login_url
|
96
|
+
req = consumer.create_signed_request(:get, consumer.request_token_url, nil, {oauth_callback: callback_url})
|
97
|
+
|
98
|
+
oauth_params_string = req.instance_variable_get("@header")["authorization"].first
|
99
|
+
oauth_params_hash = req.parse_header(oauth_params_string)
|
100
|
+
|
101
|
+
"#{consumer.request_token_url}?#{oauth_params_hash.to_query}"
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/omniauth-khan-academy/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Dipil"]
|
6
|
+
gem.email = ["dipil.saud@gmail.com"]
|
7
|
+
gem.description = %q{A KhanAcademy OAuth strategy for OmniAuth 1.0}
|
8
|
+
gem.summary = %q{A KhanAcademy OAuth strategy for OmniAuth 1.0}
|
9
|
+
gem.homepage = "https://github.com/dipil-saud/omniauth-khan-academy"
|
10
|
+
|
11
|
+
gem.add_runtime_dependency 'omniauth', '~> 1.0'
|
12
|
+
gem.add_runtime_dependency 'oauth'
|
13
|
+
gem.add_runtime_dependency 'multi_json'
|
14
|
+
gem.add_runtime_dependency 'active_support'
|
15
|
+
|
16
|
+
gem.add_development_dependency 'rspec', '~> 2.7'
|
17
|
+
gem.add_development_dependency 'pry'
|
18
|
+
|
19
|
+
gem.files = `git ls-files`.split($\)
|
20
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
21
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
22
|
+
gem.name = "omniauth-khan-academy"
|
23
|
+
gem.require_paths = ["lib"]
|
24
|
+
gem.version = Omniauth::KhanAcademy::VERSION
|
25
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe OmniAuth::Strategies::KhanAcademy do
|
4
|
+
let(:consumer_token){ "dummy_consumer_token" }
|
5
|
+
let(:consumer_secret){ "dummy_consumer_secret" }
|
6
|
+
|
7
|
+
let(:khan_academy){ OmniAuth::Strategies::KhanAcademy.new({}, consumer_secret, consumer_token) }
|
8
|
+
subject{ khan_academy }
|
9
|
+
|
10
|
+
|
11
|
+
describe "DEFAULT_CLIENT_OPTIONS" do
|
12
|
+
subject{ OmniAuth::Strategies::KhanAcademy::DEFAULT_CLIENT_OPTIONS }
|
13
|
+
|
14
|
+
it{ should eq({"http_method" => :get, "site" => "http://www.khanacademy.org", "request_token_path" => "/api/auth/request_token", "access_token_path" => "/api/auth/access_token"}) }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#client_options" do
|
18
|
+
context "when the option client_options are not specified" do
|
19
|
+
it "should equal the default_client_options" do
|
20
|
+
subject.client_options.should eq(OmniAuth::Strategies::KhanAcademy::DEFAULT_CLIENT_OPTIONS)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the option client_options are specified" do
|
25
|
+
let(:custom_client_options){ {"http_method" => :post} }
|
26
|
+
|
27
|
+
subject{ OmniAuth::Strategies::KhanAcademy.new({}, consumer_secret, consumer_token, client_options: custom_client_options) }
|
28
|
+
|
29
|
+
it "should equal the default_client_options merged with the custom options" do
|
30
|
+
subject.client_options.should eq(OmniAuth::Strategies::KhanAcademy::DEFAULT_CLIENT_OPTIONS.merge(custom_client_options))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#request_phase" do
|
36
|
+
before do
|
37
|
+
khan_academy.stub(:login_url).and_return('login_url')
|
38
|
+
khan_academy.stub(:session).and_return({})
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should redirect to the login url at khan_academy" do
|
42
|
+
khan_academy.should_receive(:redirect).with('login_url').once
|
43
|
+
|
44
|
+
khan_academy.request_phase
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "login_url" do
|
49
|
+
before do
|
50
|
+
khan_academy.stub(:callback_url).and_return("http://callback.url")
|
51
|
+
end
|
52
|
+
|
53
|
+
subject { khan_academy.login_url }
|
54
|
+
|
55
|
+
it{ should be_a(String) }
|
56
|
+
it{ should =~ /\Ahttp:\/\/www.khanacademy.org\/api\/auth\/request_token\?oauth_callback=.+&oauth_consumer_key=\w+&oauth_nonce=\w+&oauth_signature.+&oauth_signature_method=HMAC-SHA1&oauth_timestamp=\d+&oauth_version=1\.0\z/ }
|
57
|
+
end
|
58
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: omniauth-khan-academy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dipil
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: omniauth
|
16
|
+
requirement: &77917510 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *77917510
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: oauth
|
27
|
+
requirement: &77917300 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *77917300
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: multi_json
|
38
|
+
requirement: &77917070 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *77917070
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: active_support
|
49
|
+
requirement: &77916860 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *77916860
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec
|
60
|
+
requirement: &77916610 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '2.7'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *77916610
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: &77916400 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *77916400
|
80
|
+
description: A KhanAcademy OAuth strategy for OmniAuth 1.0
|
81
|
+
email:
|
82
|
+
- dipil.saud@gmail.com
|
83
|
+
executables: []
|
84
|
+
extensions: []
|
85
|
+
extra_rdoc_files: []
|
86
|
+
files:
|
87
|
+
- .gitignore
|
88
|
+
- Gemfile
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
- Rakefile
|
92
|
+
- lib/omniauth-khan-academy.rb
|
93
|
+
- lib/omniauth-khan-academy/version.rb
|
94
|
+
- lib/omniauth/strategies/khan_academy.rb
|
95
|
+
- omniauth-khan-academy.gemspec
|
96
|
+
- spec/omniauth/strategies/khan_academy_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
homepage: https://github.com/dipil-saud/omniauth-khan-academy
|
99
|
+
licenses: []
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 1.8.11
|
119
|
+
signing_key:
|
120
|
+
specification_version: 3
|
121
|
+
summary: A KhanAcademy OAuth strategy for OmniAuth 1.0
|
122
|
+
test_files:
|
123
|
+
- spec/omniauth/strategies/khan_academy_spec.rb
|
124
|
+
- spec/spec_helper.rb
|