opro 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -0
- data/Gemfile +39 -0
- data/Gemfile.lock +138 -0
- data/MIT-LICENSE +20 -0
- data/README.md +90 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/app/controllers/oauth/auth_controller.rb +74 -0
- data/app/controllers/oauth/client_application_controller.rb +15 -0
- data/app/controllers/oauth/docs_controller.rb +36 -0
- data/app/controllers/opro_application_controller.rb +8 -0
- data/app/models/oauth/access_grant.rb +42 -0
- data/app/models/oauth/client_application.rb +30 -0
- data/app/views/oauth/auth/new.html.erb +8 -0
- data/app/views/oauth/client_application/create.html.erb +11 -0
- data/app/views/oauth/client_application/index.html.erb +18 -0
- data/app/views/oauth/client_application/new.html.erb +13 -0
- data/app/views/oauth/docs/index.html.erb +14 -0
- data/app/views/oauth/docs/markdown/curl.md.erb +6 -0
- data/app/views/oauth/docs/markdown/oauth.md.erb +1 -0
- data/app/views/oauth/docs/markdown/quick_start.md.erb +70 -0
- data/app/views/oauth/docs/show.html.erb +1 -0
- data/config/routes.rb +9 -0
- data/lib/generators/active_record/opro_generator.rb +28 -0
- data/lib/generators/active_record/templates/access_grants.rb +14 -0
- data/lib/generators/active_record/templates/client_applications.rb +11 -0
- data/lib/generators/opro/install_generator.rb +21 -0
- data/lib/generators/templates/opro.rb +4 -0
- data/lib/opro.rb +86 -0
- data/lib/opro/controllers/application_controller_helper.rb +38 -0
- data/lib/opro/engine.rb +8 -0
- data/opro.gemspec +148 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/pages_controller.rb +8 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/user.rb +10 -0
- data/test/dummy/app/views/layouts/application.html.erb +20 -0
- data/test/dummy/app/views/pages/index.html.erb +1 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +49 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +22 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +26 -0
- data/test/dummy/config/environments/production.rb +49 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/devise.rb +223 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/opro.rb +4 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/devise.en.yml +57 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +63 -0
- data/test/dummy/db/migrate/20120408163038_devise_create_users.rb +49 -0
- data/test/dummy/db/migrate/20120408165729_create_opro_access_grants.rb +14 -0
- data/test/dummy/db/migrate/20120408165730_create_opro_client_applications.rb +11 -0
- data/test/dummy/db/schema.rb +54 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/prototype.js +6001 -0
- data/test/dummy/public/javascripts/rails.js +202 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/integration/auth_controller_test.rb +23 -0
- data/test/integration/client_application_controller_test.rb +24 -0
- data/test/integration/docs_controller_test.rb +8 -0
- data/test/integration/oauth_test.rb +17 -0
- data/test/opro_test.rb +24 -0
- data/test/support/integration_case.rb +5 -0
- data/test/test_helper.rb +99 -0
- metadata +251 -0
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "activesupport" , ">= 3.0.7"
|
4
|
+
gem "rails" , ">= 3.0.7"
|
5
|
+
|
6
|
+
|
7
|
+
gem 'bluecloth'
|
8
|
+
|
9
|
+
group :development, :test do
|
10
|
+
gem 'jeweler', "~> 1.6.4"
|
11
|
+
gem "bundler", ">= 1.1.3"
|
12
|
+
|
13
|
+
|
14
|
+
gem "capybara", ">= 0.4.0"
|
15
|
+
gem "sqlite3"
|
16
|
+
gem "launchy"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
group :test, :development do
|
21
|
+
gem 'devise'
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
platforms :mri_18 do
|
26
|
+
group :development, :test do
|
27
|
+
gem "rcov"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
platforms :mri_19 do
|
32
|
+
group :development, :test do
|
33
|
+
gem "simplecov"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
|
38
|
+
# gem 'ruby-debug'
|
39
|
+
# gem 'ruby-debug19'
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actionmailer (3.2.3)
|
5
|
+
actionpack (= 3.2.3)
|
6
|
+
mail (~> 2.4.4)
|
7
|
+
actionpack (3.2.3)
|
8
|
+
activemodel (= 3.2.3)
|
9
|
+
activesupport (= 3.2.3)
|
10
|
+
builder (~> 3.0.0)
|
11
|
+
erubis (~> 2.7.0)
|
12
|
+
journey (~> 1.0.1)
|
13
|
+
rack (~> 1.4.0)
|
14
|
+
rack-cache (~> 1.2)
|
15
|
+
rack-test (~> 0.6.1)
|
16
|
+
sprockets (~> 2.1.2)
|
17
|
+
activemodel (3.2.3)
|
18
|
+
activesupport (= 3.2.3)
|
19
|
+
builder (~> 3.0.0)
|
20
|
+
activerecord (3.2.3)
|
21
|
+
activemodel (= 3.2.3)
|
22
|
+
activesupport (= 3.2.3)
|
23
|
+
arel (~> 3.0.2)
|
24
|
+
tzinfo (~> 0.3.29)
|
25
|
+
activeresource (3.2.3)
|
26
|
+
activemodel (= 3.2.3)
|
27
|
+
activesupport (= 3.2.3)
|
28
|
+
activesupport (3.2.3)
|
29
|
+
i18n (~> 0.6)
|
30
|
+
multi_json (~> 1.0)
|
31
|
+
addressable (2.2.7)
|
32
|
+
arel (3.0.2)
|
33
|
+
bcrypt-ruby (3.0.1)
|
34
|
+
bluecloth (2.2.0)
|
35
|
+
builder (3.0.0)
|
36
|
+
capybara (1.1.2)
|
37
|
+
mime-types (>= 1.16)
|
38
|
+
nokogiri (>= 1.3.3)
|
39
|
+
rack (>= 1.0.0)
|
40
|
+
rack-test (>= 0.5.4)
|
41
|
+
selenium-webdriver (~> 2.0)
|
42
|
+
xpath (~> 0.1.4)
|
43
|
+
childprocess (0.3.1)
|
44
|
+
ffi (~> 1.0.6)
|
45
|
+
devise (2.0.4)
|
46
|
+
bcrypt-ruby (~> 3.0)
|
47
|
+
orm_adapter (~> 0.0.3)
|
48
|
+
railties (~> 3.1)
|
49
|
+
warden (~> 1.1.1)
|
50
|
+
erubis (2.7.0)
|
51
|
+
ffi (1.0.11)
|
52
|
+
git (1.2.5)
|
53
|
+
hike (1.2.1)
|
54
|
+
i18n (0.6.0)
|
55
|
+
jeweler (1.6.4)
|
56
|
+
bundler (~> 1.0)
|
57
|
+
git (>= 1.2.5)
|
58
|
+
rake
|
59
|
+
journey (1.0.3)
|
60
|
+
json (1.6.6)
|
61
|
+
launchy (2.1.0)
|
62
|
+
addressable (~> 2.2.6)
|
63
|
+
mail (2.4.4)
|
64
|
+
i18n (>= 0.4.0)
|
65
|
+
mime-types (~> 1.16)
|
66
|
+
treetop (~> 1.4.8)
|
67
|
+
mime-types (1.18)
|
68
|
+
multi_json (1.2.0)
|
69
|
+
nokogiri (1.5.2)
|
70
|
+
orm_adapter (0.0.7)
|
71
|
+
polyglot (0.3.3)
|
72
|
+
rack (1.4.1)
|
73
|
+
rack-cache (1.2)
|
74
|
+
rack (>= 0.4)
|
75
|
+
rack-ssl (1.3.2)
|
76
|
+
rack
|
77
|
+
rack-test (0.6.1)
|
78
|
+
rack (>= 1.0)
|
79
|
+
rails (3.2.3)
|
80
|
+
actionmailer (= 3.2.3)
|
81
|
+
actionpack (= 3.2.3)
|
82
|
+
activerecord (= 3.2.3)
|
83
|
+
activeresource (= 3.2.3)
|
84
|
+
activesupport (= 3.2.3)
|
85
|
+
bundler (~> 1.0)
|
86
|
+
railties (= 3.2.3)
|
87
|
+
railties (3.2.3)
|
88
|
+
actionpack (= 3.2.3)
|
89
|
+
activesupport (= 3.2.3)
|
90
|
+
rack-ssl (~> 1.3.2)
|
91
|
+
rake (>= 0.8.7)
|
92
|
+
rdoc (~> 3.4)
|
93
|
+
thor (~> 0.14.6)
|
94
|
+
rake (0.9.2.2)
|
95
|
+
rcov (1.0.0)
|
96
|
+
rdoc (3.12)
|
97
|
+
json (~> 1.4)
|
98
|
+
rubyzip (0.9.7)
|
99
|
+
selenium-webdriver (2.20.0)
|
100
|
+
childprocess (>= 0.2.5)
|
101
|
+
ffi (~> 1.0)
|
102
|
+
multi_json (~> 1.0)
|
103
|
+
rubyzip
|
104
|
+
simplecov (0.6.1)
|
105
|
+
multi_json (~> 1.0)
|
106
|
+
simplecov-html (~> 0.5.3)
|
107
|
+
simplecov-html (0.5.3)
|
108
|
+
sprockets (2.1.2)
|
109
|
+
hike (~> 1.2)
|
110
|
+
rack (~> 1.0)
|
111
|
+
tilt (~> 1.1, != 1.3.0)
|
112
|
+
sqlite3 (1.3.5)
|
113
|
+
thor (0.14.6)
|
114
|
+
tilt (1.3.3)
|
115
|
+
treetop (1.4.10)
|
116
|
+
polyglot
|
117
|
+
polyglot (>= 0.3.1)
|
118
|
+
tzinfo (0.3.33)
|
119
|
+
warden (1.1.1)
|
120
|
+
rack (>= 1.0)
|
121
|
+
xpath (0.1.4)
|
122
|
+
nokogiri (~> 1.3)
|
123
|
+
|
124
|
+
PLATFORMS
|
125
|
+
ruby
|
126
|
+
|
127
|
+
DEPENDENCIES
|
128
|
+
activesupport (>= 3.0.7)
|
129
|
+
bluecloth
|
130
|
+
bundler (>= 1.1.3)
|
131
|
+
capybara (>= 0.4.0)
|
132
|
+
devise
|
133
|
+
jeweler (~> 1.6.4)
|
134
|
+
launchy
|
135
|
+
rails (>= 3.0.7)
|
136
|
+
rcov
|
137
|
+
simplecov
|
138
|
+
sqlite3
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011 Schneems
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
## Stop, Read This
|
2
|
+
|
3
|
+
This is my first time writing and Oauth Provider, so there may be buggy or insecure code. If you want to use this, do so at your own risk. I'm vetting it on some development and production applications, when it is ready for consumption and contribution, i'll remove this. If you want to be notified when that happens let me know [@schneems](http://twitter.com/schneems). For now this should be considered a toy, and enjoyed as such :)
|
4
|
+
|
5
|
+
## Opro
|
6
|
+
|
7
|
+
A Rails Engine that turns your app into an [Oauth](http://oauth.net/2/) Provider.
|
8
|
+
|
9
|
+
|
10
|
+
## What is an Oauth Provider
|
11
|
+
|
12
|
+
Oauth is used all over the web by apps that need to authenticate users or restrict access to information in a secure fashion. Twitter and Facebook are the best known Oauth Providers. Users click "connect to Twitter" in an iPhone app, then they're sent over to Twitter's site where they can accept or deny access. From there they're sent back to the iPhone app where they can do anything through the API that they would be allowed to do in the website.
|
13
|
+
|
14
|
+
Most users understand the flow pretty well, it's a fairly standard process, and is secure. While there are plenty of Oauth client libraries unfortunately it's not super easy to implement from a provider standpoint. Since I hate writing code twice, I decided to take an Oauth Provider and turn it into a Rails Engine so anyone could implement an Oauth Provider on their site.
|
15
|
+
|
16
|
+
## Why would I use this?
|
17
|
+
|
18
|
+
Lets say you've built a Rails app, awesome. Now you want to build a mobile app on say, the iPhone; cool. You start throwing around `#to_json` like nobody's business, but then you realize you need to authenticate users somehow. "Basic Auth!!", you exclaim, but then you realize that's not the most secure solution. You also realize that some users already signed up with Facebook & Twitter so they don't have a username/password combo. What ever shall you do?
|
19
|
+
|
20
|
+
Wouldn't it be great if we could have a token exchange where the user goes to a mobile web view and grants permission, and then we return back an auth token just like the big boys (Facebook, Twitter, *cough* Foursquare *cough*). With Opro, we can add this functionality pretty easily. We'll use your existing authentication strategy and provide some end integration points for your clients to use out of the box.
|
21
|
+
|
22
|
+
## Sounds Hard
|
23
|
+
|
24
|
+
It's not, just follow the directions below. I'll add a screencast and example app when I get time. Any questions, open an issue or ping me on Twitter.
|
25
|
+
|
26
|
+
## Install
|
27
|
+
|
28
|
+
Gemfile
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
gem 'opro'
|
32
|
+
```
|
33
|
+
|
34
|
+
```shell
|
35
|
+
$ bundle install
|
36
|
+
```
|
37
|
+
|
38
|
+
```shell
|
39
|
+
$ opro:install
|
40
|
+
```
|
41
|
+
|
42
|
+
This will put a file in `initializers/opro.rb` and generate some migrations.
|
43
|
+
|
44
|
+
Go to `initializers/opro.rb` and configure your app for your authentication scheme.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
Opro.setup do |config|
|
48
|
+
config.auth_strategy = :devise
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
If you're not using devise you can manually configure your own auth strategy. In the future I plan on adding more auth strategies, ping me or submit a pull request for your desired authentication scheme.
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
Opro.setup do |config|
|
56
|
+
config.login_method { |controller, current_user| controller.sign_in(current_user, :bypass => true) }
|
57
|
+
config.logout_method { |controller, current_user| controller.sign_out(current_user) }
|
58
|
+
config.authenticate_user_method { |controller| controller.authenticate_user! }
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Now we're ready to migrate the database
|
63
|
+
|
64
|
+
```shell
|
65
|
+
$ rake db:migrate
|
66
|
+
````
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
That should be all you need to do to get setup, congrats you're now able to authenticate users using OAuth!!
|
71
|
+
|
72
|
+
|
73
|
+
## Use it
|
74
|
+
|
75
|
+
Opro comes with built in documentation, so if you start your server you can view them at `/docs/oauth`. If you're reading this on Github you can jump right to the [Quick Start](/app/views/docs/markdown/quick_start.md) guide. This guide will walk you through creating your first Oauth client application, giving access to that app as a logged in user, getting an access token for that user, and using that token to access the server as an authenticated user!
|
76
|
+
|
77
|
+
|
78
|
+
## Assumptions
|
79
|
+
|
80
|
+
* You have a user model and that is what your authenticating
|
81
|
+
* You're using Active::Record
|
82
|
+
|
83
|
+
If you submit a _good_ pull request for other adapters, or for generalizing the resource we're authenticating, you'll make me pretty happy.
|
84
|
+
|
85
|
+
|
86
|
+
## About
|
87
|
+
|
88
|
+
If you have a question file an issue or, find me on the Twitters [@schneems](http://twitter.com/schneems).
|
89
|
+
|
90
|
+
This project rocks and uses MIT-LICENSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development, :test)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'rake'
|
14
|
+
require 'rdoc/task'
|
15
|
+
|
16
|
+
require 'rake/testtask'
|
17
|
+
|
18
|
+
Rake::TestTask.new(:test) do |t|
|
19
|
+
t.libs << 'lib'
|
20
|
+
t.libs << 'test'
|
21
|
+
t.pattern = 'test/**/*_test.rb'
|
22
|
+
t.verbose = false
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => :test
|
26
|
+
|
27
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
28
|
+
rdoc.rdoc_dir = 'rdoc'
|
29
|
+
rdoc.title = 'Opro'
|
30
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
31
|
+
rdoc.rdoc_files.include('README.rdoc')
|
32
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
require 'jeweler'
|
37
|
+
Jeweler::Tasks.new do |gem|
|
38
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
39
|
+
gem.name = "opro"
|
40
|
+
gem.homepage = "http://github.com/schneems/opro"
|
41
|
+
gem.license = "MIT"
|
42
|
+
gem.summary = %Q{ Opro turns your Rails application into an OAuth Provider }
|
43
|
+
gem.description = %Q{ Enable oauth clients (iphone, android, web sites, etc.) to access and use your Rails application, what you do with it is up to you}
|
44
|
+
gem.email = "richard.schneeman@gmail.com"
|
45
|
+
gem.authors = ["schneems"]
|
46
|
+
# dependencies defined in Gemfile
|
47
|
+
end
|
48
|
+
Jeweler::RubygemsDotOrgTasks.new
|
49
|
+
|
50
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1.pre
|
@@ -0,0 +1,74 @@
|
|
1
|
+
class Oauth::AuthController < ApplicationController
|
2
|
+
before_filter :opro_authenticate_user!, :except => [:access_token]
|
3
|
+
skip_before_filter :verify_authenticity_token, :only => [:access_token, :user]
|
4
|
+
before_filter :ask_user!, :only => :authorize
|
5
|
+
|
6
|
+
def new
|
7
|
+
@redirect_uri = params[:redirect_uri]
|
8
|
+
@client_app = Oauth::ClientApplication.find_by_app_id(params[:client_id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def authorize
|
12
|
+
application = Oauth::ClientApplication.find_by_app_id(params[:client_id])
|
13
|
+
access_grant = Oauth::AccessGrant.where( :user_id => current_user.id, :application_id => application.id).first
|
14
|
+
access_grant ||= Oauth::AccessGrant.create(:user => current_user, :application => application)
|
15
|
+
redirect_to access_grant.redirect_uri_for(params[:redirect_uri])
|
16
|
+
end
|
17
|
+
|
18
|
+
def access_token
|
19
|
+
application = Oauth::ClientApplication.authenticate(params[:client_id], params[:client_secret])
|
20
|
+
|
21
|
+
if application.nil?
|
22
|
+
render :json => {:error => "Could not find application"}
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
access_grant = Oauth::AccessGrant.authenticate(params[:code], application.id)
|
27
|
+
|
28
|
+
if access_grant.nil?
|
29
|
+
render :json => {:error => "Could not authenticate access code"}
|
30
|
+
return
|
31
|
+
end
|
32
|
+
|
33
|
+
access_grant.start_expiry_period!
|
34
|
+
render :json => {:access_token => access_grant.access_token, :refresh_token => access_grant.refresh_token, :expires_in => access_grant.access_token_expires_at}
|
35
|
+
end
|
36
|
+
|
37
|
+
# When a user is sent to authorize an application they must first accept the authorization
|
38
|
+
# if they've already authed the app, they skip this section
|
39
|
+
def ask_user!
|
40
|
+
if user_granted_access_before?(current_user, params)
|
41
|
+
# Re-Authorize the application, do not ask the user
|
42
|
+
return true
|
43
|
+
elsif user_authorizes_the_request?(request)
|
44
|
+
# Authorize the application, do not ask the user
|
45
|
+
return true
|
46
|
+
else
|
47
|
+
# if the request did not come from a form within the application, render the user form
|
48
|
+
@redirect_uri ||= params[:redirect_uri]
|
49
|
+
@client_app ||= Oauth::ClientApplication.find_by_app_id(params[:client_id])
|
50
|
+
redirect_to oauth_new_path(params)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def user_granted_access_before?(user, params)
|
56
|
+
@client_app ||= Oauth::ClientApplication.find_by_app_id(params[:client_id])
|
57
|
+
Oauth::AccessGrant.where(:application_id => @client_app.id, :user_id => user.id).present?
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
# We're verifying that a post was made from our own site, indicating a user confirmed via form
|
62
|
+
def user_authorizes_the_request?(request)
|
63
|
+
request.post? && referrer_is_self?(request)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Ensures that the referrer is also the current host, to prevent spoofing
|
67
|
+
def referrer_is_self?(request)
|
68
|
+
return false if request.referrer.blank?
|
69
|
+
referrer_host = URI.parse(request.referrer).host
|
70
|
+
self_host = URI.parse(request.url).host
|
71
|
+
referrer_host == self_host
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Oauth::ClientApplicationController < ApplicationController
|
2
|
+
before_filter :opro_authenticate_user!
|
3
|
+
|
4
|
+
def new
|
5
|
+
@client_app = Oauth::ClientApplication.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
@client_app = Oauth::ClientApplication.create_with_user_and_name(current_user, params[:oauth_client_application][:name])
|
10
|
+
end
|
11
|
+
|
12
|
+
def index
|
13
|
+
@client_apps = Oauth::ClientApplication.where(:user_id => current_user.id)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'erb'
|
2
|
+
OPRO_MD_ROOT=File.join(File.dirname(__FILE__), '../../views/oauth/docs/markdown/')
|
3
|
+
|
4
|
+
|
5
|
+
class Oauth::DocsController < ApplicationController
|
6
|
+
helper_method :render_doc
|
7
|
+
|
8
|
+
def index
|
9
|
+
end
|
10
|
+
|
11
|
+
def show
|
12
|
+
@doc = params[:id]
|
13
|
+
end
|
14
|
+
|
15
|
+
def render_doc(name)
|
16
|
+
str = read_file(name.to_s)
|
17
|
+
str = parse_erb(str)
|
18
|
+
str = parse_markdown(str)
|
19
|
+
str.html_safe
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def parse_erb(str)
|
25
|
+
ERB.new(str).result(binding)
|
26
|
+
end
|
27
|
+
|
28
|
+
def parse_markdown(str)
|
29
|
+
BlueCloth.new(str).to_html
|
30
|
+
end
|
31
|
+
|
32
|
+
def read_file(name)
|
33
|
+
name = OPRO_MD_ROOT + name
|
34
|
+
File.open(name + '.md.erb' ).read.to_s
|
35
|
+
end
|
36
|
+
end
|