Make OAuth work again
This commit is contained in:
parent
87d38efbb0
commit
7b89dc6349
13 changed files with 109 additions and 109 deletions
|
@ -366,6 +366,11 @@ private
|
||||||
return [user, pass]
|
return [user, pass]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# used by oauth plugin to get the current user
|
||||||
|
def current_user
|
||||||
|
@user
|
||||||
|
end
|
||||||
|
|
||||||
# used by oauth plugin to set the current user
|
# used by oauth plugin to set the current user
|
||||||
def current_user=(user)
|
def current_user=(user)
|
||||||
@user=user
|
@user=user
|
||||||
|
|
|
@ -1,83 +1,33 @@
|
||||||
|
require 'oauth/controllers/provider_controller'
|
||||||
|
|
||||||
class OauthController < ApplicationController
|
class OauthController < ApplicationController
|
||||||
|
include OAuth::Controllers::ProviderController
|
||||||
|
|
||||||
layout 'slim'
|
layout 'slim'
|
||||||
|
|
||||||
before_filter :authorize_web, :only => [:oauthorize, :revoke]
|
def login_required
|
||||||
before_filter :set_locale, :only => [:oauthorize, :revoke]
|
authorize_web
|
||||||
before_filter :require_user, :only => [:oauthorize]
|
set_locale
|
||||||
before_filter :verify_oauth_consumer_signature, :only => [:request_token]
|
require_user
|
||||||
before_filter :verify_oauth_request_token, :only => [:access_token]
|
end
|
||||||
# Uncomment the following if you are using restful_open_id_authentication
|
|
||||||
# skip_before_filter :verify_authenticity_token
|
|
||||||
|
|
||||||
def request_token
|
def user_authorizes_token?
|
||||||
@token = current_client_application.create_request_token
|
any_auth = false
|
||||||
|
|
||||||
if @token
|
@token.client_application.permissions.each do |pref|
|
||||||
logger.info "request token params: #{params.inspect}"
|
if params[pref]
|
||||||
# request tokens indicate what permissions the client *wants*, not
|
|
||||||
# necessarily the same as those which the user allows.
|
|
||||||
current_client_application.permissions.each do |pref|
|
|
||||||
@token.write_attribute(pref, true)
|
@token.write_attribute(pref, true)
|
||||||
|
any_auth ||= true
|
||||||
|
else
|
||||||
|
@token.write_attribute(pref, false)
|
||||||
end
|
end
|
||||||
@token.save!
|
|
||||||
|
|
||||||
render :text => @token.to_query
|
|
||||||
else
|
|
||||||
render :nothing => true, :status => 401
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
def access_token
|
any_auth
|
||||||
@token = current_token && current_token.exchange!
|
|
||||||
if @token
|
|
||||||
render :text => @token.to_query
|
|
||||||
else
|
|
||||||
render :nothing => true, :status => 401
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def oauthorize
|
|
||||||
@token = RequestToken.find_by_token params[:oauth_token]
|
|
||||||
unless @token.nil? or @token.invalidated?
|
|
||||||
if request.post?
|
|
||||||
any_auth = false
|
|
||||||
@token.client_application.permissions.each do |pref|
|
|
||||||
if params[pref]
|
|
||||||
@token.write_attribute(pref, true)
|
|
||||||
any_auth ||= true
|
|
||||||
else
|
|
||||||
@token.write_attribute(pref, false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if any_auth
|
|
||||||
@token.authorize!(@user)
|
|
||||||
if @token.oauth10?
|
|
||||||
redirect_url = params[:oauth_callback] || @token.client_application.callback_url
|
|
||||||
else
|
|
||||||
redirect_url = @token.oob? ? @token.client_application.callback_url : @token.callback_url
|
|
||||||
end
|
|
||||||
if redirect_url and not redirect_url.empty?
|
|
||||||
if @token.oauth10?
|
|
||||||
redirect_to "#{redirect_url}?oauth_token=#{@token.token}"
|
|
||||||
else
|
|
||||||
redirect_to "#{redirect_url}?oauth_token=#{@token.token}&oauth_verifier=#{@token.verifier}"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
render :action => "authorize_success"
|
|
||||||
end
|
|
||||||
else
|
|
||||||
@token.invalidate!
|
|
||||||
render :action => "authorize_failure"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
render :action => "authorize_failure"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def revoke
|
def revoke
|
||||||
@token = @user.oauth_tokens.find_by_token params[:token]
|
@token = current_user.oauth_tokens.find_by_token params[:token]
|
||||||
if @token
|
if @token
|
||||||
@token.invalidate!
|
@token.invalidate!
|
||||||
flash[:notice] = t('oauth.revoke.flash', :application => @token.client_application.name)
|
flash[:notice] = t('oauth.revoke.flash', :application => @token.client_application.name)
|
||||||
|
|
|
@ -4,7 +4,7 @@ class AccessToken < OauthToken
|
||||||
|
|
||||||
scope :valid, where(:invalidated_at => nil)
|
scope :valid, where(:invalidated_at => nil)
|
||||||
|
|
||||||
validates_presence_of :user
|
validates_presence_of :user, :secret
|
||||||
|
|
||||||
before_create :set_authorized_at
|
before_create :set_authorized_at
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ class ClientApplication < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
has_many :tokens, :class_name => "OauthToken"
|
has_many :tokens, :class_name => "OauthToken"
|
||||||
has_many :access_tokens
|
has_many :access_tokens
|
||||||
|
has_many :oauth2_verifiers
|
||||||
|
has_many :oauth_tokens
|
||||||
|
|
||||||
validates_presence_of :name, :url, :key, :secret
|
validates_presence_of :name, :url, :key, :secret
|
||||||
validates_uniqueness_of :key
|
validates_uniqueness_of :key
|
||||||
|
@ -27,15 +29,10 @@ class ClientApplication < ActiveRecord::Base
|
||||||
def self.verify_request(request, options = {}, &block)
|
def self.verify_request(request, options = {}, &block)
|
||||||
begin
|
begin
|
||||||
signature = OAuth::Signature.build(request, options, &block)
|
signature = OAuth::Signature.build(request, options, &block)
|
||||||
logger.info "Signature Base String: #{signature.signature_base_string}"
|
|
||||||
logger.info "Consumer: #{signature.send :consumer_key}"
|
|
||||||
logger.info "Token: #{signature.send :token}"
|
|
||||||
return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
|
return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
|
||||||
value = signature.verify
|
value = signature.verify
|
||||||
logger.info "Signature verification returned: #{value.to_s}"
|
|
||||||
value
|
value
|
||||||
rescue OAuth::Signature::UnknownSignatureMethod => e
|
rescue OAuth::Signature::UnknownSignatureMethod => e
|
||||||
logger.info "ERROR"+e.to_s
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -52,8 +49,12 @@ class ClientApplication < ActiveRecord::Base
|
||||||
@oauth_client ||= OAuth::Consumer.new(key, secret)
|
@oauth_client ||= OAuth::Consumer.new(key, secret)
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_request_token
|
def create_request_token(params={})
|
||||||
RequestToken.create :client_application => self, :callback_url => self.token_callback_url
|
params = { :client_application => self, :callback_url => self.token_callback_url }
|
||||||
|
permissions.each do |p|
|
||||||
|
params[p] = true
|
||||||
|
end
|
||||||
|
RequestToken.create(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
def access_token_for_user(user)
|
def access_token_for_user(user)
|
||||||
|
@ -84,8 +85,7 @@ protected
|
||||||
:allow_write_api, :allow_read_gpx, :allow_write_gpx ]
|
:allow_write_api, :allow_read_gpx, :allow_write_gpx ]
|
||||||
|
|
||||||
def generate_keys
|
def generate_keys
|
||||||
oauth_client = oauth_server.generate_consumer_credentials
|
self.key = OAuth::Helper.generate_key(40)[0,40]
|
||||||
self.key = oauth_client.key
|
self.secret = OAuth::Helper.generate_key(40)[0,40]
|
||||||
self.secret = oauth_client.secret
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
21
app/models/oauth2_token.rb
Normal file
21
app/models/oauth2_token.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
class Oauth2Token < AccessToken
|
||||||
|
attr_accessor :state
|
||||||
|
|
||||||
|
def as_json(options={})
|
||||||
|
d = {:access_token=>token, :token_type => 'bearer'}
|
||||||
|
d[:expires_in] = expires_in if expires_at
|
||||||
|
d
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_query
|
||||||
|
q = "access_token=#{token}&token_type=bearer"
|
||||||
|
q << "&state=#{URI.escape(state)}" if @state
|
||||||
|
q << "&expires_in=#{expires_in}" if expires_at
|
||||||
|
q << "&scope=#{URI.escape(scope)}" if scope
|
||||||
|
q
|
||||||
|
end
|
||||||
|
|
||||||
|
def expires_in
|
||||||
|
expires_at.to_i - Time.now.to_i
|
||||||
|
end
|
||||||
|
end
|
34
app/models/oauth2_verifier.rb
Normal file
34
app/models/oauth2_verifier.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
class Oauth2Verifier < OauthToken
|
||||||
|
validates_presence_of :user
|
||||||
|
attr_accessor :state
|
||||||
|
|
||||||
|
def exchange!(params={})
|
||||||
|
OauthToken.transaction do
|
||||||
|
token = Oauth2Token.create! :user=>user,:client_application=>client_application, :scope => scope
|
||||||
|
invalidate!
|
||||||
|
token
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def code
|
||||||
|
token
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirect_url
|
||||||
|
callback_url
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_query
|
||||||
|
q = "code=#{token}"
|
||||||
|
q << "&state=#{URI.escape(state)}" if @state
|
||||||
|
q
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def generate_keys
|
||||||
|
self.token = OAuth::Helper.generate_key(20)[0,20]
|
||||||
|
self.expires_at = 10.minutes.from_now
|
||||||
|
self.authorized_at = Time.now
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,20 +5,10 @@ class OauthToken < ActiveRecord::Base
|
||||||
scope :authorized, where("authorized_at IS NOT NULL and invalidated_at IS NULL")
|
scope :authorized, where("authorized_at IS NOT NULL and invalidated_at IS NULL")
|
||||||
|
|
||||||
validates_uniqueness_of :token
|
validates_uniqueness_of :token
|
||||||
validates_presence_of :client_application, :token, :secret
|
validates_presence_of :client_application, :token
|
||||||
|
|
||||||
before_validation :generate_keys, :on => :create
|
before_validation :generate_keys, :on => :create
|
||||||
|
|
||||||
def self.find_token(token_key)
|
|
||||||
token = OauthToken.find_by_token(token_key, :include => :client_application)
|
|
||||||
if token && token.authorized?
|
|
||||||
logger.info "Loaded #{token.token} which was authorized by (user_id=#{token.user_id}) on the #{token.authorized_at}"
|
|
||||||
token
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def invalidated?
|
def invalidated?
|
||||||
invalidated_at != nil
|
invalidated_at != nil
|
||||||
end
|
end
|
||||||
|
@ -38,8 +28,7 @@ class OauthToken < ActiveRecord::Base
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def generate_keys
|
def generate_keys
|
||||||
@oauth_token = client_application.oauth_server.generate_credentials
|
self.token = OAuth::Helper.generate_key(40)[0,40]
|
||||||
self.token = @oauth_token[0]
|
self.secret = OAuth::Helper.generate_key(40)[0,40]
|
||||||
self.secret = @oauth_token[1]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ class RequestToken < OauthToken
|
||||||
return false if authorized?
|
return false if authorized?
|
||||||
self.user = user
|
self.user = user
|
||||||
self.authorized_at = Time.now
|
self.authorized_at = Time.now
|
||||||
self.verifier = OAuth::Helper.generate_key(16)[0,20] unless oauth10?
|
self.verifier = OAuth::Helper.generate_key(20)[0,20] unless oauth10?
|
||||||
self.save
|
self.save
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class RequestToken < OauthToken
|
||||||
end
|
end
|
||||||
|
|
||||||
def oob?
|
def oob?
|
||||||
self.callback_url=='oob'
|
callback_url.nil? || callback_url.downcase == 'oob'
|
||||||
end
|
end
|
||||||
|
|
||||||
def oauth10?
|
def oauth10?
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<h1>Authorize access to your account</h1>
|
<h1>Authorize access to your account</h1>
|
||||||
<p><%= t('oauth.oauthorize.request_access', :app_name => link_to(@token.client_application.name, @token.client_application.url), :user => link_to(@user.display_name, :controller => :user, :action => :view, :display_name => @user.display_name)) %></p>
|
<p><%= raw t('oauth.oauthorize.request_access', :app_name => link_to(@token.client_application.name, @token.client_application.url), :user => link_to(@user.display_name, :controller => :user, :action => :view, :display_name => @user.display_name)) %></p>
|
||||||
<%= form_tag authorize_url do %>
|
<%= form_tag authorize_url do %>
|
||||||
<%= hidden_field_tag "oauth_token", @token.token %>
|
<%= hidden_field_tag "oauth_token", @token.token %>
|
||||||
<%- if params[:oauth_callback] -%>
|
<%- if params[:oauth_callback] -%>
|
|
@ -1,5 +1,5 @@
|
||||||
<h1>You have allowed this request</h1>
|
<h1>You have allowed this request</h1>
|
||||||
|
|
||||||
<% if @token.oob? %>
|
<% if @token.oob? and not @token.oauth10? %>
|
||||||
<p>The verification code is <%= @token.verifier %></p>
|
<p>The verification code is <%= @token.verifier %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
|
@ -213,7 +213,8 @@ OpenStreetMap::Application.routes.draw do
|
||||||
resources :oauth_clients
|
resources :oauth_clients
|
||||||
end
|
end
|
||||||
match '/oauth/revoke' => 'oauth#revoke'
|
match '/oauth/revoke' => 'oauth#revoke'
|
||||||
match '/oauth/authorize' => 'oauth#oauthorize', :as => :authorize
|
match '/oauth/authorize' => 'oauth#authorize', :as => :authorize
|
||||||
|
match '/oauth/token' => 'oauth#token', :as => :token
|
||||||
match '/oauth/request_token' => 'oauth#request_token', :as => :request_token
|
match '/oauth/request_token' => 'oauth#request_token', :as => :request_token
|
||||||
match '/oauth/access_token' => 'oauth#access_token', :as => :access_token
|
match '/oauth/access_token' => 'oauth#access_token', :as => :access_token
|
||||||
match '/oauth/test_request' => 'oauth#test_request', :as => :test_request
|
match '/oauth/test_request' => 'oauth#test_request', :as => :test_request
|
||||||
|
|
11
db/migrate/20111116184519_update_oauth.rb
Normal file
11
db/migrate/20111116184519_update_oauth.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class UpdateOauth < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :oauth_tokens, :scope, :string
|
||||||
|
add_column :oauth_tokens, :valid_to, :timestamp
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :oauth_tokens, :valid_to
|
||||||
|
remove_column :oauth_tokens, :scope
|
||||||
|
end
|
||||||
|
end
|
|
@ -23,15 +23,4 @@ class OauthTokenTest < ActiveSupport::TestCase
|
||||||
assert_equal false, tok.authorized?, "Token should now be invalid."
|
assert_equal false, tok.authorized?, "Token should now be invalid."
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
|
||||||
# test that tokens can't be found unless they're authorised
|
|
||||||
def test_find_token
|
|
||||||
tok = client_applications(:oauth_web_app).create_request_token
|
|
||||||
assert_equal false, tok.authorized?, "Token should be created unauthorised."
|
|
||||||
assert_equal nil, OauthToken.find_token(tok.token), "Shouldn't be able to find unauthorised token"
|
|
||||||
tok.authorize!(users(:public_user))
|
|
||||||
assert_equal true, tok.authorized?, "Token should now be authorised."
|
|
||||||
assert_not_equal nil, OauthToken.find_token(tok.token), "Should be able to find authorised token"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue