Skip to content

Associate users to OAuth applications (ownership)

André Costa edited this page Nov 7, 2017 · 7 revisions

Let's say that you want to restrict the applications list/creation only to the users that are authenticated within your app. Doorkeeper provides a way to do that. However, it requires you to follow a few steps.

Database changes

The way doorkeeper provides this feature is via polymorphic associations. The first thing you need to do is install the migration:

rails generate doorkeeper:application_owner

And then

rake db:migrate

You've just upgraded the oauth_applications table with required fields.

Configuration

Uncomment (or add) the following line to the initializer:

Doorkeeper.configure do
  enable_application_owner :confirmation => false
end

You can optionally set the confirmation to true, if you want to require all applications to be related to an owner. Internally it just sets up presence: true to ownership validation into the Application model.

Sample application

Go to rails console and create a sample app:

app = Doorkeeper::Application.new :name => 'test', :redirect_uri => 'http://test.com'
app.owner = User.last # Or any owner class that you want to be associated
app.save

The application was just associated to that user. But if you want the relation to work the other way around, you'll have to change your User class to understand the association:

class User
  has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner
end

Now you can retrieve all applications for the given user:

User.last.oauth_applications
# => [#<Doorkeeper::Application id: ...>, ...]

Controllers

If you visit /oauth/applications you'll notice that all apps are being listed. Not only that, but the New Application form does not provide a way to associate the owner (and if you set :confirmation => true, the creation will fail altogether, because no owner was specified). Usually you want this owner to be the current_user. To do that you need to use a custom controller:

# app/controllers/oauth/applications_controller.rb
class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
  before_filter :authenticate_user! # use before_action instead if on Rails 5.1+

  def index
    @applications = current_user.oauth_applications
  end

  # only needed if each application must have some owner
  def create
    @application = Doorkeeper::Application.new(application_params)
    @application.owner = current_user if Doorkeeper.configuration.confirm_application_owner?
    if @application.save
      flash[:notice] = I18n.t(:notice, :scope => [:doorkeeper, :flash, :applications, :create])
      redirect_to oauth_application_url(@application)
    else
      render :new
    end
  end

  private

  def set_application
    @application = current_user.oauth_applications.find(params[:id])
  end

end

NOTE: inherit from Doorkeeper::ApplicationsController is optional and you might not want to do that since you'll end up customizing all actions from that controller.

Heads up: The authenticate_user! function is generated by Devise.

Later on, you need to point doorkeeper's routes to the correct controller:

YourApp::Application.routes.draw do
  use_doorkeeper do
    controllers :applications => 'oauth/applications'
  end
end

You can optionally skip the applications controller and create your own registration process. Remember that this controller is just a scaffold and should be used only to quick develop your OAuth provider.

You can’t perform that action at this time.