Permalink
Browse files

Merge branch 'password-credentials-flow'

Fix conflicts with old FactoryGirl creation methods
  • Loading branch information...
2 parents 614bea6 + 709557d commit 7ddf1c17ab882b352a0d5f12ff4880eb95414546 @felipeelias felipeelias committed Apr 30, 2012
@@ -21,6 +21,10 @@ def current_resource_owner
instance_exec(main_app, &Doorkeeper.configuration.authenticate_resource_owner)
end
+ def resource_owner_from_credentials
+ instance_exec(main_app, &Doorkeeper.configuration.resource_owner_from_credentials)
+ end
+
def authenticate_admin!
if block = Doorkeeper.configuration.authenticate_admin
instance_exec(main_app, &block)
@@ -17,6 +17,11 @@ def create
private
def token
- @token ||= Doorkeeper::OAuth::AccessTokenRequest.new(params)
+ if params[:grant_type] == 'password'
+ owner = resource_owner_from_credentials
+ @token ||= Doorkeeper::OAuth::PasswordAccessTokenRequest.new(owner, params)
+ else
+ @token ||= Doorkeeper::OAuth::AccessTokenRequest.new(params)
+ end
end
end
View
@@ -18,3 +18,6 @@ en:
invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.'
unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.'
+
+ # Password Access token errors
+ invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found'
View
@@ -22,4 +22,5 @@ Gem::Specification.new do |s|
s.add_development_dependency "factory_girl", "~> 2.6.4"
s.add_development_dependency "timecop", "~> 0.3.5"
s.add_development_dependency "database_cleaner", "~> 0.7.1"
+ s.add_development_dependency "bcrypt-ruby", "~> 3.0.1"
end
View
@@ -6,9 +6,10 @@ module Doorkeeper
autoload :Validations, "doorkeeper/validations"
module OAuth
- autoload :AuthorizationRequest, "doorkeeper/oauth/authorization_request"
- autoload :AccessTokenRequest, "doorkeeper/oauth/access_token_request"
- autoload :Authorization, "doorkeeper/oauth/authorization"
+ autoload :AuthorizationRequest, "doorkeeper/oauth/authorization_request"
+ autoload :AccessTokenRequest, "doorkeeper/oauth/access_token_request"
+ autoload :PasswordAccessTokenRequest, "doorkeeper/oauth/password_access_token_request"
+ autoload :Authorization, "doorkeeper/oauth/authorization"
module Helpers
autoload :ScopeChecker, "doorkeeper/oauth/helpers/scope_checker"
View
@@ -92,6 +92,7 @@ def extended(base)
option :resource_owner_authenticator, :as => :authenticate_resource_owner
option :admin_authenticator, :as => :authenticate_admin
+ option :resource_owner_from_credentials
option :access_token_expires_in, :default => 7200
option :authorization_scopes, :as => :scopes, :builder_class => ScopesBuilder, :default => Scopes.new
@@ -0,0 +1,139 @@
+# coding: utf-8
+
+# TODO: refactor to DRY up, this is very similar to AccessTokenRequest
+module Doorkeeper::OAuth
+ class PasswordAccessTokenRequest
+ include Doorkeeper::Validations
+
+ ATTRIBUTES = [
+ :client_id,
+ :client_secret,
+ :grant_type,
+ :username,
+ :password,
+ :scope,
+ :refresh_token
+ ]
+
+ validate :attributes, :error => :invalid_request
+ validate :grant_type, :error => :unsupported_grant_type
+ validate :client, :error => :invalid_client
+ validate :resource_owner, :error => :invalid_resource_owner
+ validate :scope, :error => :invalid_scope
+
+ attr_accessor *ATTRIBUTES
+ attr_accessor :resource_owner
+
+ def initialize(owner, attributes = {})
+ ATTRIBUTES.each { |attr| instance_variable_set("@#{attr}", attributes[attr]) }
+ @resource_owner = owner
+ @scope ||= Doorkeeper.configuration.default_scope_string
+ validate
+ end
+
+ def authorize
+ if valid?
+ find_or_create_access_token
+ end
+ end
+
+ def authorization
+ auth = {
+ 'access_token' => access_token.token,
+ 'token_type' => access_token.token_type,
+ 'expires_in' => access_token.expires_in,
+ }
+ auth.merge!({'refresh_token' => access_token.refresh_token}) if refresh_token_enabled?
+ auth
+ end
+
+ def valid?
+ self.error.nil?
+ end
+
+ def access_token
+ @access_token
+ end
+
+ def token_type
+ "bearer"
+ end
+
+ def error_response
+ {
+ 'error' => error.to_s,
+ 'error_description' => error_description
+ }
+ end
+
+ private
+
+ def find_or_create_access_token
+ if access_token
+ access_token.expired? ? revoke_and_create_access_token : access_token
+ else
+ create_access_token
+ end
+ end
+
+ def revoke_and_create_access_token
+ access_token.revoke
+ create_access_token
+ end
+
+ def revoke_base_token
+ base_token.revoke
+ end
+
+ def client
+ @client ||= Doorkeeper::Application.find_by_uid_and_secret(@client_id, @client_secret)
+ end
+
+ def create_access_token
+ @access_token = Doorkeeper::AccessToken.create!({
+ :application_id => client.id,
+ :resource_owner_id => resource_owner.id,
+ :scopes => @scope,
+ :expires_in => configuration.access_token_expires_in,
+ :use_refresh_token => refresh_token_enabled?
+ })
+ end
+
+ def has_scope?
+ Doorkeeper.configuration.scopes.all.present?
+ end
+
+ def validate_attributes
+ grant_type.present?
+ end
+
+ def refresh_token_enabled?
+ configuration.refresh_token_enabled?
+ end
+
+ def validate_client
+ !!client
+ end
+
+ def validate_scope
+ return true unless has_scope?
+ ScopeChecker.valid?(scope, configuration.scopes)
+ end
+
+ def validate_grant_type
+ grant_type == 'password'
+ end
+
+ def validate_resource_owner
+ !!resource_owner
+ end
+
+ def error_description
+ I18n.translate error, :scope => [:doorkeeper, :errors, :messages]
+ end
+
+ def configuration
+ Doorkeeper.configuration
+ end
+ end
+end
@@ -13,7 +13,7 @@ def translated_error_message(key)
end
let(:client) { FactoryGirl.create :application }
- let(:user) { User.create! }
+ let(:user) { User.create!(:name => "Joe", :password => "sekret") }
before do
controller.stub :current_resource_owner => user
@@ -4,7 +4,7 @@ def index
def sign_in
session[:user_id] = if Rails.env.development?
- User.first || User.create!
+ User.first || User.create!(:name => "Joe", :password => "sekret")
else
User.first
end
@@ -1,2 +1,9 @@
class User < ActiveRecord::Base
+ has_secure_password
+ validates_presence_of :password, :on => :create
+
+ def self.authenticate!(name, password)
+ owner = User.find_by_name(name)
+ owner.authenticate(password) if owner
+ end
end
@@ -0,0 +1,5 @@
+class AddPasswordToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :password_digest, :string
+ end
+end
View
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20111206151426) do
+ActiveRecord::Schema.define(:version => 20120312140401) do
create_table "oauth_access_grants", :force => true do |t|
t.integer "resource_owner_id", :null => false
@@ -40,14 +40,15 @@
t.string "uid", :null => false
t.string "secret", :null => false
t.string "redirect_uri", :null => false
- t.datetime "created_at"
- t.datetime "updated_at"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
end
create_table "users", :force => true do |t|
t.string "name"
- t.datetime "created_at"
- t.datetime "updated_at"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "password_digest"
end
end
Oops, something went wrong.

0 comments on commit 7ddf1c1

Please sign in to comment.