return [user, pass]
end
+ # used by oauth plugin to get the current user
+ def current_user
+ @user
+ end
+
# used by oauth plugin to set the current user
def current_user=(user)
@user=user
+require 'oauth/controllers/provider_controller'
+
class OauthController < ApplicationController
+ include OAuth::Controllers::ProviderController
+
layout 'slim'
- before_filter :authorize_web, :only => [:oauthorize, :revoke]
- before_filter :set_locale, :only => [:oauthorize, :revoke]
- before_filter :require_user, :only => [:oauthorize]
- before_filter :verify_oauth_consumer_signature, :only => [:request_token]
- before_filter :verify_oauth_request_token, :only => [:access_token]
- # Uncomment the following if you are using restful_open_id_authentication
- # skip_before_filter :verify_authenticity_token
+ def login_required
+ authorize_web
+ set_locale
+ require_user
+ end
- def request_token
- @token = current_client_application.create_request_token
+ def user_authorizes_token?
+ any_auth = false
- if @token
- logger.info "request token params: #{params.inspect}"
- # 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.client_application.permissions.each do |pref|
+ if params[pref]
@token.write_attribute(pref, true)
+ any_auth ||= true
+ else
+ @token.write_attribute(pref, false)
end
- @token.save!
-
- render :text => @token.to_query
- else
- render :nothing => true, :status => 401
end
- end
- def access_token
- @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
+ any_auth
end
def revoke
- @token = @user.oauth_tokens.find_by_token params[:token]
+ @token = current_user.oauth_tokens.find_by_token params[:token]
if @token
@token.invalidate!
flash[:notice] = t('oauth.revoke.flash', :application => @token.client_application.name)
scope :valid, where(:invalidated_at => nil)
- validates_presence_of :user
+ validates_presence_of :user, :secret
before_create :set_authorized_at
belongs_to :user
has_many :tokens, :class_name => "OauthToken"
has_many :access_tokens
+ has_many :oauth2_verifiers
+ has_many :oauth_tokens
validates_presence_of :name, :url, :key, :secret
validates_uniqueness_of :key
def self.verify_request(request, options = {}, &block)
begin
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)
value = signature.verify
- logger.info "Signature verification returned: #{value.to_s}"
value
rescue OAuth::Signature::UnknownSignatureMethod => e
- logger.info "ERROR"+e.to_s
false
end
end
@oauth_client ||= OAuth::Consumer.new(key, secret)
end
- def create_request_token
- RequestToken.create :client_application => self, :callback_url => self.token_callback_url
+ def create_request_token(params={})
+ params = { :client_application => self, :callback_url => self.token_callback_url }
+ permissions.each do |p|
+ params[p] = true
+ end
+ RequestToken.create(params)
end
def access_token_for_user(user)
:allow_write_api, :allow_read_gpx, :allow_write_gpx ]
def generate_keys
- oauth_client = oauth_server.generate_consumer_credentials
- self.key = oauth_client.key
- self.secret = oauth_client.secret
+ self.key = OAuth::Helper.generate_key(40)[0,40]
+ self.secret = OAuth::Helper.generate_key(40)[0,40]
end
end
--- /dev/null
+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
--- /dev/null
+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
scope :authorized, where("authorized_at IS NOT NULL and invalidated_at IS NULL")
validates_uniqueness_of :token
- validates_presence_of :client_application, :token, :secret
+ validates_presence_of :client_application, :token
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?
invalidated_at != nil
end
protected
def generate_keys
- @oauth_token = client_application.oauth_server.generate_credentials
- self.token = @oauth_token[0]
- self.secret = @oauth_token[1]
+ self.token = OAuth::Helper.generate_key(40)[0,40]
+ self.secret = OAuth::Helper.generate_key(40)[0,40]
end
end
return false if authorized?
self.user = user
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
end
end
def oob?
- self.callback_url=='oob'
+ callback_url.nil? || callback_url.downcase == 'oob'
end
def oauth10?
<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 %>
<%= hidden_field_tag "oauth_token", @token.token %>
<%- if params[:oauth_callback] -%>
<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>
<% end %>
resources :oauth_clients
end
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/access_token' => 'oauth#access_token', :as => :access_token
match '/oauth/test_request' => 'oauth#test_request', :as => :test_request
--- /dev/null
+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
assert_equal false, tok.authorized?, "Token should now be invalid."
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