Skip to content

Instantly share code, notes, and snippets.

@thibaudgg
Last active October 27, 2021 06:22

Revisions

  1. thibaudgg renamed this gist Feb 16, 2016. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion HTTP example → HTTP.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    ``` http
    POST /oauth/token HTTP/1.1
    Content-Type: application/json
    @@ -8,8 +9,9 @@ Content-Type: application/json
    "username": "OWNER_EMAIL",
    "password": "OWNER_PASSWORD"
    }
    ```


    ``` http
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    @@ -22,3 +24,4 @@ Content-Type: application/json; charset=utf-8
    "owner_id": "OWNER_ID",
    "owner_type": "OWNER_TYPE"
    }
    ```
  2. thibaudgg revised this gist Feb 16, 2016. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion access_token.rb
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ class AccessToken < ActiveRecord::Base
    def as_json(*)
    super.except!(:resource_owner_id).merge!(
    owner: {
    id: resource_owner&.owner_external_id,
    id: resource_owner&.owner_id,
    type: resource_owner&.owner_type&.tableize
    }
    )
    2 changes: 1 addition & 1 deletion token_response_body_with_resource_owner.rb
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@ module OAuth
    module TokenResponseBodyWithResourceOwner
    def body
    super.merge({
    'owner_id' => token.resource_owner&.owner_external_id,
    'owner_id' => token.resource_owner&.owner_id,
    'owner_type' => token.resource_owner&.owner_type&.tableize
    }.compact)
    end
  3. thibaudgg created this gist Feb 16, 2016.
    24 changes: 24 additions & 0 deletions HTTP example
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@
    POST /oauth/token HTTP/1.1
    Content-Type: application/json

    {
    "grant_type": "password",
    "client_id": "CLIENT_ID",
    "owner_type": "OWNER_TYPE",
    "username": "OWNER_EMAIL",
    "password": "OWNER_PASSWORD"
    }


    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8

    {
    "access_token": "e2892936f4...3a0d3171b0",
    "token_type": "bearer",
    "expires_in": 7200,
    "refresh_token": "6231777801...735af7da27",
    "created_at": 1430921359,
    "owner_id": "OWNER_ID",
    "owner_type": "OWNER_TYPE"
    }
    16 changes: 16 additions & 0 deletions access_token.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    # app/models/doorkeeper/access_token.rb

    module Doorkeeper
    class AccessToken < ActiveRecord::Base
    belongs_to :resource_owner, class_name: 'OauthResourceOwner'

    def as_json(*)
    super.except!(:resource_owner_id).merge!(
    owner: {
    id: resource_owner&.owner_external_id,
    type: resource_owner&.owner_type&.tableize
    }
    )
    end
    end
    end
    14 changes: 14 additions & 0 deletions doorkeeper.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    # config/doorkeeper.rb

    Doorkeeper.configure do
    orm :active_record

    # ...

    resource_owner_from_credentials do |_routes|
    app = Doorkeeper::Application.by_uid(params[:client_id])
    OauthResourceOwnerAuthenticator.authenticate(app, request) if app
    end

    # ...
    end
    5 changes: 5 additions & 0 deletions oauth_resource_owner.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,5 @@
    # app/models/oauth_resource_owner.rb

    class OauthResourceOwner < ActiveRecord::Base
    belongs_to :owner, polymorphic: true
    end
    48 changes: 48 additions & 0 deletions oauth_resource_owner_authenticator.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,48 @@
    # app/services/oauth_resource_owner_authenticator.rb

    class OauthResourceOwnerAuthenticator
    attr_reader :application, :request
    delegate :params, to: :request

    def self.authenticate(*args)
    new(*args).authenticate
    end

    def initialize(application, request)
    @application = application
    @request = request
    end

    def authenticate
    return unless owner_class

    owner = authenticate_owner
    OauthResourceOwner.find_or_create_by(owner: owner) if owner
    end

    private

    def authenticate_owner
    owner = owner_class.find_for_database_authentication(
    email: params[:username]
    )
    return unless owner&.valid_password?(params[:password])

    update_tracked_fields(owner)
    owner
    end

    # Update Devise tracked fields
    def update_tracked_fields(owner)
    if owner.respond_to?(:update_tracked_fields!)
    owner.update_tracked_fields!(request)
    end
    end

    def owner_class
    case params[:owner_type]
    when /admin/i then Admin
    when /user/i then User
    end
    end
    end
    16 changes: 16 additions & 0 deletions token_response_body_with_resource_owner.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,16 @@
    # lib/doorkeeper/oauth/token_response_body_with_resource_owner.rb

    module Doorkeeper
    module OAuth
    module TokenResponseBodyWithResourceOwner
    def body
    super.merge({
    'owner_id' => token.resource_owner&.owner_external_id,
    'owner_type' => token.resource_owner&.owner_type&.tableize
    }.compact)
    end
    end

    TokenResponse.prepend(TokenResponseBodyWithResourceOwner)
    end
    end