Skip to content

Commit

Permalink
Merge branch 'password-credentials-flow'
Browse files Browse the repository at this point in the history
Fix conflicts with old FactoryGirl creation methods
  • Loading branch information
felipeelias committed Apr 30, 2012
2 parents 614bea6 + 709557d commit 7ddf1c1
Show file tree
Hide file tree
Showing 19 changed files with 435 additions and 16 deletions.
4 changes: 4 additions & 0 deletions app/controllers/doorkeeper/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 6 additions & 1 deletion app/controllers/doorkeeper/tokens_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
1 change: 1 addition & 0 deletions doorkeeper.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -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
7 changes: 4 additions & 3 deletions lib/doorkeeper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions lib/doorkeeper/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
139 changes: 139 additions & 0 deletions lib/doorkeeper/oauth/password_access_token_request.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion spec/controllers/authorizations_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion spec/dummy/app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions spec/dummy/app/models/user.rb
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions spec/dummy/db/migrate/20120312140401_add_password_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddPasswordToUsers < ActiveRecord::Migration
def change
add_column :users, :password_digest, :string
end
end
11 changes: 6 additions & 5 deletions spec/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Loading

0 comments on commit 7ddf1c1

Please sign in to comment.