Adding doorkeeper, adding a REST API
POST /api/statuses Params: status (text contents), in_reply_to_id (optional) GET /api/statuses/:id POST /api/statuses/:id/reblog GET /api/accounts/:id GET /api/accounts/:id/following GET /api/accounts/:id/followers POST /api/accounts/:id/follow POST /api/accounts/:id/unfollow POST /api/follows Params: uri (e.g. user@domain) OAuth authentication is currently disabled, but the API can be used with HTTP Auth.
This commit is contained in:
		
							
								
								
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Gemfile
									
									
									
									
									
								
							@@ -27,6 +27,9 @@ gem 'ostatus2'
 | 
				
			|||||||
gem 'goldfinger'
 | 
					gem 'goldfinger'
 | 
				
			||||||
gem 'devise'
 | 
					gem 'devise'
 | 
				
			||||||
gem 'rails_autolink'
 | 
					gem 'rails_autolink'
 | 
				
			||||||
 | 
					gem 'doorkeeper'
 | 
				
			||||||
 | 
					gem 'rabl'
 | 
				
			||||||
 | 
					gem 'oj'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
group :development, :test do
 | 
					group :development, :test do
 | 
				
			||||||
  gem 'rspec-rails'
 | 
					  gem 'rspec-rails'
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								Gemfile.lock
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								Gemfile.lock
									
									
									
									
									
								
							@@ -74,8 +74,10 @@ GEM
 | 
				
			|||||||
      warden (~> 1.2.3)
 | 
					      warden (~> 1.2.3)
 | 
				
			||||||
    diff-lcs (1.2.5)
 | 
					    diff-lcs (1.2.5)
 | 
				
			||||||
    docile (1.1.5)
 | 
					    docile (1.1.5)
 | 
				
			||||||
    domain_name (0.5.20160128)
 | 
					    domain_name (0.5.20160216)
 | 
				
			||||||
      unf (>= 0.0.5, < 1.0.0)
 | 
					      unf (>= 0.0.5, < 1.0.0)
 | 
				
			||||||
 | 
					    doorkeeper (3.1.0)
 | 
				
			||||||
 | 
					      railties (>= 3.2)
 | 
				
			||||||
    dotenv (2.1.0)
 | 
					    dotenv (2.1.0)
 | 
				
			||||||
    dotenv-rails (2.1.0)
 | 
					    dotenv-rails (2.1.0)
 | 
				
			||||||
      dotenv (= 2.1.0)
 | 
					      dotenv (= 2.1.0)
 | 
				
			||||||
@@ -90,7 +92,7 @@ GEM
 | 
				
			|||||||
      ruby-progressbar (~> 1.4)
 | 
					      ruby-progressbar (~> 1.4)
 | 
				
			||||||
    globalid (0.3.6)
 | 
					    globalid (0.3.6)
 | 
				
			||||||
      activesupport (>= 4.1.0)
 | 
					      activesupport (>= 4.1.0)
 | 
				
			||||||
    goldfinger (1.0.1)
 | 
					    goldfinger (1.0.2)
 | 
				
			||||||
      addressable (~> 2.4)
 | 
					      addressable (~> 2.4)
 | 
				
			||||||
      http (~> 1.0)
 | 
					      http (~> 1.0)
 | 
				
			||||||
      nokogiri (~> 1.6)
 | 
					      nokogiri (~> 1.6)
 | 
				
			||||||
@@ -139,6 +141,7 @@ GEM
 | 
				
			|||||||
    multi_json (1.11.2)
 | 
					    multi_json (1.11.2)
 | 
				
			||||||
    nokogiri (1.6.7.2)
 | 
					    nokogiri (1.6.7.2)
 | 
				
			||||||
      mini_portile2 (~> 2.0.0.rc2)
 | 
					      mini_portile2 (~> 2.0.0.rc2)
 | 
				
			||||||
 | 
					    oj (2.14.5)
 | 
				
			||||||
    orm_adapter (0.5.0)
 | 
					    orm_adapter (0.5.0)
 | 
				
			||||||
    ostatus2 (0.1.1)
 | 
					    ostatus2 (0.1.1)
 | 
				
			||||||
      addressable (~> 2.4)
 | 
					      addressable (~> 2.4)
 | 
				
			||||||
@@ -165,6 +168,8 @@ GEM
 | 
				
			|||||||
    puma (2.16.0)
 | 
					    puma (2.16.0)
 | 
				
			||||||
    quiet_assets (1.1.0)
 | 
					    quiet_assets (1.1.0)
 | 
				
			||||||
      railties (>= 3.1, < 5.0)
 | 
					      railties (>= 3.1, < 5.0)
 | 
				
			||||||
 | 
					    rabl (0.12.0)
 | 
				
			||||||
 | 
					      activesupport (>= 2.3.14)
 | 
				
			||||||
    rack (1.6.4)
 | 
					    rack (1.6.4)
 | 
				
			||||||
    rack-test (0.6.3)
 | 
					    rack-test (0.6.3)
 | 
				
			||||||
      rack (>= 1.0)
 | 
					      rack (>= 1.0)
 | 
				
			||||||
@@ -300,6 +305,7 @@ DEPENDENCIES
 | 
				
			|||||||
  binding_of_caller
 | 
					  binding_of_caller
 | 
				
			||||||
  coffee-rails (~> 4.1.0)
 | 
					  coffee-rails (~> 4.1.0)
 | 
				
			||||||
  devise
 | 
					  devise
 | 
				
			||||||
 | 
					  doorkeeper
 | 
				
			||||||
  dotenv-rails
 | 
					  dotenv-rails
 | 
				
			||||||
  fabrication
 | 
					  fabrication
 | 
				
			||||||
  font-awesome-sass
 | 
					  font-awesome-sass
 | 
				
			||||||
@@ -310,6 +316,7 @@ DEPENDENCIES
 | 
				
			|||||||
  jbuilder (~> 2.0)
 | 
					  jbuilder (~> 2.0)
 | 
				
			||||||
  jquery-rails
 | 
					  jquery-rails
 | 
				
			||||||
  nokogiri
 | 
					  nokogiri
 | 
				
			||||||
 | 
					  oj
 | 
				
			||||||
  ostatus2
 | 
					  ostatus2
 | 
				
			||||||
  paperclip (~> 4.3)
 | 
					  paperclip (~> 4.3)
 | 
				
			||||||
  paranoia (~> 2.0)
 | 
					  paranoia (~> 2.0)
 | 
				
			||||||
@@ -317,6 +324,7 @@ DEPENDENCIES
 | 
				
			|||||||
  pry-rails
 | 
					  pry-rails
 | 
				
			||||||
  puma
 | 
					  puma
 | 
				
			||||||
  quiet_assets
 | 
					  quiet_assets
 | 
				
			||||||
 | 
					  rabl
 | 
				
			||||||
  rails (= 4.2.5.1)
 | 
					  rails (= 4.2.5.1)
 | 
				
			||||||
  rails_12factor
 | 
					  rails_12factor
 | 
				
			||||||
  rails_autolink
 | 
					  rails_autolink
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								app/assets/javascripts/api/accounts.coffee
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/assets/javascripts/api/accounts.coffee
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Place all the behaviors and hooks related to the matching controller here.
 | 
				
			||||||
 | 
					# All this logic will automatically be available in application.js.
 | 
				
			||||||
 | 
					# You can use CoffeeScript in this file: http://coffeescript.org/
 | 
				
			||||||
							
								
								
									
										3
									
								
								app/assets/javascripts/api/follows.coffee
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/assets/javascripts/api/follows.coffee
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Place all the behaviors and hooks related to the matching controller here.
 | 
				
			||||||
 | 
					# All this logic will automatically be available in application.js.
 | 
				
			||||||
 | 
					# You can use CoffeeScript in this file: http://coffeescript.org/
 | 
				
			||||||
							
								
								
									
										3
									
								
								app/assets/javascripts/api/statuses.coffee
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/assets/javascripts/api/statuses.coffee
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Place all the behaviors and hooks related to the matching controller here.
 | 
				
			||||||
 | 
					# All this logic will automatically be available in application.js.
 | 
				
			||||||
 | 
					# You can use CoffeeScript in this file: http://coffeescript.org/
 | 
				
			||||||
							
								
								
									
										3
									
								
								app/assets/stylesheets/api/accounts.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/assets/stylesheets/api/accounts.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					// Place all the styles related to the Api::Accounts controller here.
 | 
				
			||||||
 | 
					// They will automatically be included in application.css.
 | 
				
			||||||
 | 
					// You can use Sass (SCSS) here: http://sass-lang.com/
 | 
				
			||||||
							
								
								
									
										3
									
								
								app/assets/stylesheets/api/follows.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/assets/stylesheets/api/follows.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					// Place all the styles related to the API::Follows controller here.
 | 
				
			||||||
 | 
					// They will automatically be included in application.css.
 | 
				
			||||||
 | 
					// You can use Sass (SCSS) here: http://sass-lang.com/
 | 
				
			||||||
							
								
								
									
										3
									
								
								app/assets/stylesheets/api/statuses.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								app/assets/stylesheets/api/statuses.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					// Place all the styles related to the API::Statuses controller here.
 | 
				
			||||||
 | 
					// They will automatically be included in application.css.
 | 
				
			||||||
 | 
					// You can use Sass (SCSS) here: http://sass-lang.com/
 | 
				
			||||||
@@ -3,7 +3,6 @@ class AccountsController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  before_action :set_account
 | 
					  before_action :set_account
 | 
				
			||||||
  before_action :set_webfinger_header
 | 
					  before_action :set_webfinger_header
 | 
				
			||||||
  before_action :authenticate_user!, only: [:follow, :unfollow]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    @statuses = @account.statuses.order('id desc').includes(thread: [:account], reblog: [:account], stream_entry: [])
 | 
					    @statuses = @account.statuses.order('id desc').includes(thread: [:account], reblog: [:account], stream_entry: [])
 | 
				
			||||||
@@ -14,16 +13,6 @@ class AccountsController < ApplicationController
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def follow
 | 
					 | 
				
			||||||
    current_user.account.follow!(@account)
 | 
					 | 
				
			||||||
    redirect_to root_path
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def unfollow
 | 
					 | 
				
			||||||
    current_user.account.unfollow!(@account)
 | 
					 | 
				
			||||||
    redirect_to root_path
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_account
 | 
					  def set_account
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										36
									
								
								app/controllers/api/accounts_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/controllers/api/accounts_controller.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					class Api::AccountsController < ApiController
 | 
				
			||||||
 | 
					  before_action :set_account
 | 
				
			||||||
 | 
					  before_action :authenticate_user!
 | 
				
			||||||
 | 
					  respond_to    :json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def show
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def following
 | 
				
			||||||
 | 
					    @following = @account.following
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def followers
 | 
				
			||||||
 | 
					    @followers = @account.followers
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def statuses
 | 
				
			||||||
 | 
					    @statuses = @account.statuses
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def follow
 | 
				
			||||||
 | 
					    @follow = current_user.account.follow!(@account)
 | 
				
			||||||
 | 
					    render action: :show
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def unfollow
 | 
				
			||||||
 | 
					    @unfollow = current_user.account.unfollow!(@account)
 | 
				
			||||||
 | 
					    render action: :show
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def set_account
 | 
				
			||||||
 | 
					    @account = Account.find(params[:id])
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										9
									
								
								app/controllers/api/follows_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/controllers/api/follows_controller.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					class Api::FollowsController < ApiController
 | 
				
			||||||
 | 
					  before_action :authenticate_user!
 | 
				
			||||||
 | 
					  respond_to    :json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def create
 | 
				
			||||||
 | 
					    @follow = FollowService.new.(current_user.account, params[:uri])
 | 
				
			||||||
 | 
					    render action: :show
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										18
									
								
								app/controllers/api/statuses_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/controllers/api/statuses_controller.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					class Api::StatusesController < ApiController
 | 
				
			||||||
 | 
					  before_action :authenticate_user!
 | 
				
			||||||
 | 
					  respond_to    :json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def show
 | 
				
			||||||
 | 
					    @status = Status.find(params[:id])
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def create
 | 
				
			||||||
 | 
					    @status = PostStatusService.new.(current_user.account, params[:status], params[:in_reply_to_id].blank? ? nil : Status.find(params[:in_reply_to_id]))
 | 
				
			||||||
 | 
					    render action: :show
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def reblog
 | 
				
			||||||
 | 
					    @status = ReblogService.new.(current_user.account, Status.find(params[:id]))
 | 
				
			||||||
 | 
					    render action: :show
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -1,3 +1,13 @@
 | 
				
			|||||||
class ApiController < ApplicationController
 | 
					class ApiController < ApplicationController
 | 
				
			||||||
  protect_from_forgery with: :null_session
 | 
					  protect_from_forgery with: :null_session
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def current_resource_owner
 | 
				
			||||||
 | 
					    User.find(doorkeeper_token.user_id) if doorkeeper_token
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def current_user
 | 
				
			||||||
 | 
					    super || current_resource_owner
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,6 @@ class StreamEntriesController < ApplicationController
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  before_action :set_account
 | 
					  before_action :set_account
 | 
				
			||||||
  before_action :set_stream_entry
 | 
					  before_action :set_stream_entry
 | 
				
			||||||
  before_action :authenticate_user!, only: [:reblog, :favourite]
 | 
					 | 
				
			||||||
  before_action :only_statuses!, only: [:reblog, :favourite]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    @type = @stream_entry.activity_type.downcase
 | 
					    @type = @stream_entry.activity_type.downcase
 | 
				
			||||||
@@ -15,16 +13,6 @@ class StreamEntriesController < ApplicationController
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def reblog
 | 
					 | 
				
			||||||
    ReblogService.new.(current_user.account, @stream_entry.activity)
 | 
					 | 
				
			||||||
    redirect_to root_path
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  def favourite
 | 
					 | 
				
			||||||
    FavouriteService.new.(current_user.account, @stream_entry.activity)
 | 
					 | 
				
			||||||
    redirect_to root_path
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_account
 | 
					  def set_account
 | 
				
			||||||
@@ -34,8 +22,4 @@ class StreamEntriesController < ApplicationController
 | 
				
			|||||||
  def set_stream_entry
 | 
					  def set_stream_entry
 | 
				
			||||||
    @stream_entry = @account.stream_entries.find(params[:id])
 | 
					    @stream_entry = @account.stream_entries.find(params[:id])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 | 
				
			||||||
  def only_statuses!
 | 
					 | 
				
			||||||
    redirect_to root_url unless @stream_entry.activity_type == 'Status'
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								app/helpers/api/accounts_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/helpers/api/accounts_helper.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					module Api::AccountsHelper
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										2
									
								
								app/helpers/api/follows_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/helpers/api/follows_helper.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					module Api::FollowsHelper
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										2
									
								
								app/helpers/api/statuses_helper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/helpers/api/statuses_helper.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					module Api::StatusesHelper
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -31,10 +31,10 @@ module StreamEntriesHelper
 | 
				
			|||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def reblogged_by_me_class(status)
 | 
					  def reblogged_by_me_class(status)
 | 
				
			||||||
    user_signed_in? && (status.reblog? ? status.reblog : status).reblogs.where(account: current_user.account).count == 1 ? 'reblogged' : ''
 | 
					    user_signed_in? && current_user.account.reblogged?(status) ? 'reblogged' : ''
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def favourited_by_me_class(status)
 | 
					  def favourited_by_me_class(status)
 | 
				
			||||||
    user_signed_in? && (status.reblog? ? status.reblog : status).favourites.where(account: current_user.account).count == 1 ? 'favourited' : ''
 | 
					    user_signed_in? && current_user.account.favourited?(status) ? 'favourited' : ''
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@ class Account < ActiveRecord::Base
 | 
				
			|||||||
  MENTION_RE = /(?:^|\W)@([a-z0-9_]+(?:@[a-z0-9\.\-]+)?)/i
 | 
					  MENTION_RE = /(?:^|\W)@([a-z0-9_]+(?:@[a-z0-9\.\-]+)?)/i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def follow!(other_account)
 | 
					  def follow!(other_account)
 | 
				
			||||||
    self.active_relationships.first_or_create!(target_account: other_account)
 | 
					    self.active_relationships.where(target_account: other_account).first_or_create!(target_account: other_account)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def unfollow!(other_account)
 | 
					  def unfollow!(other_account)
 | 
				
			||||||
@@ -59,6 +59,14 @@ class Account < ActiveRecord::Base
 | 
				
			|||||||
    !(self.secret.blank? || self.verify_token.blank?)
 | 
					    !(self.secret.blank? || self.verify_token.blank?)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def favourited?(status)
 | 
				
			||||||
 | 
					    (status.reblog? ? status.reblog : status).favourites.where(account: self).count == 1
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def reblogged?(status)
 | 
				
			||||||
 | 
					    (status.reblog? ? status.reblog : status).reblogs.where(account: self).count == 1
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def keypair
 | 
					  def keypair
 | 
				
			||||||
    self.private_key.nil? ? OpenSSL::PKey::RSA.new(self.public_key) : OpenSSL::PKey::RSA.new(self.private_key)
 | 
					    self.private_key.nil? ? OpenSSL::PKey::RSA.new(self.public_key) : OpenSSL::PKey::RSA.new(self.private_key)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,11 +5,12 @@ class FollowService < BaseService
 | 
				
			|||||||
  def call(source_account, uri)
 | 
					  def call(source_account, uri)
 | 
				
			||||||
    target_account = follow_remote_account_service.(uri)
 | 
					    target_account = follow_remote_account_service.(uri)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return if target_account.nil?
 | 
					    return nil if target_account.nil?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    follow = source_account.follow!(target_account)
 | 
					    follow = source_account.follow!(target_account)
 | 
				
			||||||
    send_interaction_service.(follow.stream_entry, target_account)
 | 
					    send_interaction_service.(follow.stream_entry, target_account)
 | 
				
			||||||
    source_account.ping!(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url])
 | 
					    source_account.ping!(account_url(source_account, format: 'atom'), [Rails.configuration.x.hub_url])
 | 
				
			||||||
 | 
					    follow
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								app/views/api/accounts/followers.rabl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/views/api/accounts/followers.rabl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					collection @followers
 | 
				
			||||||
 | 
					extends('api/accounts/show')
 | 
				
			||||||
							
								
								
									
										2
									
								
								app/views/api/accounts/following.rabl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/views/api/accounts/following.rabl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					collection @following
 | 
				
			||||||
 | 
					extends('api/accounts/show')
 | 
				
			||||||
							
								
								
									
										9
									
								
								app/views/api/accounts/show.rabl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								app/views/api/accounts/show.rabl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					object @account
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					attributes :id, :username, :acct, :display_name, :note
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					node(:url)       { |account| url_for_target(account) }
 | 
				
			||||||
 | 
					node(:avatar)    { |account| asset_url(account.avatar.url(:large, false)) }
 | 
				
			||||||
 | 
					node(:followers) { |account| account.followers.count }
 | 
				
			||||||
 | 
					node(:following) { |account| account.following.count }
 | 
				
			||||||
 | 
					node(:statuses)  { |account| account.statuses.count  }
 | 
				
			||||||
							
								
								
									
										2
									
								
								app/views/api/accounts/statuses.rabl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/views/api/accounts/statuses.rabl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					collection @statuses
 | 
				
			||||||
 | 
					extends('api/statuses/show')
 | 
				
			||||||
							
								
								
									
										5
									
								
								app/views/api/follows/show.rabl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/views/api/follows/show.rabl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					object @follow
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					child :target_account => :target_account do
 | 
				
			||||||
 | 
					  extends('api/accounts/show')
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										18
									
								
								app/views/api/statuses/show.rabl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/views/api/statuses/show.rabl
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					object @status
 | 
				
			||||||
 | 
					attributes :id, :created_at, :in_reply_to_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					node(:uri)        { |status| uri_for_target(status) }
 | 
				
			||||||
 | 
					node(:content)    { |status| status.local? ? linkify(status) : status.content }
 | 
				
			||||||
 | 
					node(:url)        { |status| url_for_target(status) }
 | 
				
			||||||
 | 
					node(:reblogs)    { |status| status.reblogs.count }
 | 
				
			||||||
 | 
					node(:favourites) { |status| status.favourites.count }
 | 
				
			||||||
 | 
					node(:favourited) { |status| current_user.account.favourited?(status) }
 | 
				
			||||||
 | 
					node(:reblogged)  { |status| current_user.account.reblogged?(status) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					child :reblog => :reblog do
 | 
				
			||||||
 | 
					  extends('api/statuses/show')
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					child :account do
 | 
				
			||||||
 | 
					  extends('api/accounts/show')
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										5
									
								
								app/views/doorkeeper/applications/_delete_form.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/views/doorkeeper/applications/_delete_form.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<%- submit_btn_css ||= 'btn btn-link' %>
 | 
				
			||||||
 | 
					<%= form_tag oauth_application_path(application) do %>
 | 
				
			||||||
 | 
					  <input type="hidden" name="_method" value="delete">
 | 
				
			||||||
 | 
					  <%= submit_tag t('doorkeeper.applications.buttons.destroy'), onclick: "return confirm('#{ t('doorkeeper.applications.confirmations.destroy') }')", class: submit_btn_css %>
 | 
				
			||||||
 | 
					<% end %>
 | 
				
			||||||
							
								
								
									
										47
									
								
								app/views/doorkeeper/applications/_form.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								app/views/doorkeeper/applications/_form.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					<%= form_for application, url: doorkeeper_submit_path(application), html: {class: 'form-horizontal', role: 'form'} do |f| %>
 | 
				
			||||||
 | 
					  <% if application.errors.any? %>
 | 
				
			||||||
 | 
					    <div class="alert alert-danger" data-alert><p><%= t('doorkeeper.applications.form.error') %></p></div>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do %>
 | 
				
			||||||
 | 
					    <%= f.label :name, class: 'col-sm-2 control-label' %>
 | 
				
			||||||
 | 
					    <div class="col-sm-10">
 | 
				
			||||||
 | 
					      <%= f.text_field :name, class: 'form-control' %>
 | 
				
			||||||
 | 
					      <%= doorkeeper_errors_for application, :name %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do %>
 | 
				
			||||||
 | 
					    <%= f.label :redirect_uri, class: 'col-sm-2 control-label' %>
 | 
				
			||||||
 | 
					    <div class="col-sm-10">
 | 
				
			||||||
 | 
					      <%= f.text_area :redirect_uri, class: 'form-control' %>
 | 
				
			||||||
 | 
					      <%= doorkeeper_errors_for application, :redirect_uri %>
 | 
				
			||||||
 | 
					      <span class="help-block">
 | 
				
			||||||
 | 
					        <%= t('doorkeeper.applications.help.redirect_uri') %>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					      <% if Doorkeeper.configuration.native_redirect_uri %>
 | 
				
			||||||
 | 
					          <span class="help-block">
 | 
				
			||||||
 | 
					            <%= raw t('doorkeeper.applications.help.native_redirect_uri', native_redirect_uri: "<code>#{ Doorkeeper.configuration.native_redirect_uri }</code>") %>
 | 
				
			||||||
 | 
					          </span>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <%= content_tag :div, class: "form-group#{' has-error' if application.errors[:scopes].present?}" do %>
 | 
				
			||||||
 | 
					    <%= f.label :scopes, class: 'col-sm-2 control-label' %>
 | 
				
			||||||
 | 
					    <div class="col-sm-10">
 | 
				
			||||||
 | 
					      <%= f.text_field :scopes, class: 'form-control' %>
 | 
				
			||||||
 | 
					      <%= doorkeeper_errors_for application, :scopes %>
 | 
				
			||||||
 | 
					      <span class="help-block">
 | 
				
			||||||
 | 
					        <%= t('doorkeeper.applications.help.scopes') %>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="form-group">
 | 
				
			||||||
 | 
					    <div class="col-sm-offset-2 col-sm-10">
 | 
				
			||||||
 | 
					      <%= f.submit t('doorkeeper.applications.buttons.submit'), class: "btn btn-primary" %>
 | 
				
			||||||
 | 
					      <%= link_to t('doorkeeper.applications.buttons.cancel'), oauth_applications_path, :class => "btn btn-default" %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					<% end %>
 | 
				
			||||||
							
								
								
									
										5
									
								
								app/views/doorkeeper/applications/edit.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/views/doorkeeper/applications/edit.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<div class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('.title') %></h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= render 'form', application: @application %>
 | 
				
			||||||
							
								
								
									
										26
									
								
								app/views/doorkeeper/applications/index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/views/doorkeeper/applications/index.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<div class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('.title') %></h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<p><%= link_to t('.new'), new_oauth_application_path, class: 'btn btn-success' %></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<table class="table table-striped">
 | 
				
			||||||
 | 
					  <thead>
 | 
				
			||||||
 | 
					  <tr>
 | 
				
			||||||
 | 
					    <th><%= t('.name') %></th>
 | 
				
			||||||
 | 
					    <th><%= t('.callback_url') %></th>
 | 
				
			||||||
 | 
					    <th></th>
 | 
				
			||||||
 | 
					    <th></th>
 | 
				
			||||||
 | 
					  </tr>
 | 
				
			||||||
 | 
					  </thead>
 | 
				
			||||||
 | 
					  <tbody>
 | 
				
			||||||
 | 
					  <% @applications.each do |application| %>
 | 
				
			||||||
 | 
					    <tr id="application_<%= application.id %>">
 | 
				
			||||||
 | 
					      <td><%= link_to application.name, oauth_application_path(application) %></td>
 | 
				
			||||||
 | 
					      <td><%= application.redirect_uri %></td>
 | 
				
			||||||
 | 
					      <td><%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'btn btn-link' %></td>
 | 
				
			||||||
 | 
					      <td><%= render 'delete_form', application: application %></td>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					  </tbody>
 | 
				
			||||||
 | 
					</table>
 | 
				
			||||||
							
								
								
									
										5
									
								
								app/views/doorkeeper/applications/new.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								app/views/doorkeeper/applications/new.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<div class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('.title') %></h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<%= render 'form', application: @application %>
 | 
				
			||||||
							
								
								
									
										39
									
								
								app/views/doorkeeper/applications/show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/views/doorkeeper/applications/show.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					<div class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('.title', name: @application.name) %></h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					  <div class="col-md-8">
 | 
				
			||||||
 | 
					    <h4><%= t('.application_id') %>:</h4>
 | 
				
			||||||
 | 
					    <p><code id="application_id"><%= @application.uid %></code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h4><%= t('.secret') %>:</h4>
 | 
				
			||||||
 | 
					    <p><code id="secret"><%= @application.secret %></code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h4><%= t('.scopes') %>:</h4>
 | 
				
			||||||
 | 
					    <p><code id="scopes"><%= @application.scopes %></code></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <h4><%= t('.callback_urls') %>:</h4>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <table>
 | 
				
			||||||
 | 
					      <% @application.redirect_uri.split.each do |uri| %>
 | 
				
			||||||
 | 
					        <tr>
 | 
				
			||||||
 | 
					          <td>
 | 
				
			||||||
 | 
					            <code><%= uri %></code>
 | 
				
			||||||
 | 
					          </td>
 | 
				
			||||||
 | 
					          <td>
 | 
				
			||||||
 | 
					            <%= link_to t('doorkeeper.applications.buttons.authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code'), class: 'btn btn-success', target: '_blank' %>
 | 
				
			||||||
 | 
					          </td>
 | 
				
			||||||
 | 
					        </tr>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="col-md-4">
 | 
				
			||||||
 | 
					    <h3><%= t('.actions') %></h3>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p><%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(@application), class: 'btn btn-primary' %></p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <p><%= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger' %></p>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										7
									
								
								app/views/doorkeeper/authorizations/error.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/views/doorkeeper/authorizations/error.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<div class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('doorkeeper.authorizations.error.title') %></h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<main role="main">
 | 
				
			||||||
 | 
					  <pre><%= @pre_auth.error_response.body[:error_description] %></pre>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
							
								
								
									
										40
									
								
								app/views/doorkeeper/authorizations/new.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								app/views/doorkeeper/authorizations/new.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					<header class="page-header" role="banner">
 | 
				
			||||||
 | 
					  <h1><%= t('.title') %></h1>
 | 
				
			||||||
 | 
					</header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<main role="main">
 | 
				
			||||||
 | 
					  <p class="h4">
 | 
				
			||||||
 | 
					    <%= raw t('.prompt', client_name: "<strong class=\"text-info\">#{ @pre_auth.client.name }</strong>") %>
 | 
				
			||||||
 | 
					  </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <% if @pre_auth.scopes.count > 0 %>
 | 
				
			||||||
 | 
					    <div id="oauth-permissions">
 | 
				
			||||||
 | 
					      <p><%= t('.able_to') %>:</p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      <ul class="text-info">
 | 
				
			||||||
 | 
					        <% @pre_auth.scopes.each do |scope| %>
 | 
				
			||||||
 | 
					          <li><%= t scope, scope: [:doorkeeper, :scopes] %></li>
 | 
				
			||||||
 | 
					        <% end %>
 | 
				
			||||||
 | 
					      </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  <% end %>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="actions">
 | 
				
			||||||
 | 
					    <%= form_tag oauth_authorization_path, method: :post do %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :state, @pre_auth.state %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :response_type, @pre_auth.response_type %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :scope, @pre_auth.scope %>
 | 
				
			||||||
 | 
					      <%= submit_tag t('doorkeeper.authorizations.buttons.authorize'), class: "btn btn-success btn-lg btn-block" %>
 | 
				
			||||||
 | 
					    <% end %>
 | 
				
			||||||
 | 
					    <%= form_tag oauth_authorization_path, method: :delete do %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :client_id, @pre_auth.client.uid %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :state, @pre_auth.state %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :response_type, @pre_auth.response_type %>
 | 
				
			||||||
 | 
					      <%= hidden_field_tag :scope, @pre_auth.scope %>
 | 
				
			||||||
 | 
					      <%= submit_tag t('doorkeeper.authorizations.buttons.deny'), class: "btn btn-danger btn-lg btn-block" %>
 | 
				
			||||||
 | 
					    <% end %>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
							
								
								
									
										7
									
								
								app/views/doorkeeper/authorizations/show.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								app/views/doorkeeper/authorizations/show.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					<header class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('.title') %>:</h1>
 | 
				
			||||||
 | 
					</header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<main role="main">
 | 
				
			||||||
 | 
					  <code id="authorization_code"><%= params[:code] %></code>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<%- submit_btn_css ||= 'btn btn-link' %>
 | 
				
			||||||
 | 
					<%= form_tag oauth_authorized_application_path(application) do %>
 | 
				
			||||||
 | 
					  <input type="hidden" name="_method" value="delete">
 | 
				
			||||||
 | 
					  <%= submit_tag t('doorkeeper.authorized_applications.buttons.revoke'), onclick: "return confirm('#{ t('doorkeeper.authorized_applications.confirmations.revoke') }')", class: submit_btn_css %>
 | 
				
			||||||
 | 
					<% end %>
 | 
				
			||||||
							
								
								
									
										25
									
								
								app/views/doorkeeper/authorized_applications/index.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								app/views/doorkeeper/authorized_applications/index.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<header class="page-header">
 | 
				
			||||||
 | 
					  <h1><%= t('doorkeeper.authorized_applications.index.title') %></h1>
 | 
				
			||||||
 | 
					</header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<main role="main">
 | 
				
			||||||
 | 
					  <table class="table table-striped">
 | 
				
			||||||
 | 
					    <thead>
 | 
				
			||||||
 | 
					    <tr>
 | 
				
			||||||
 | 
					      <th><%= t('doorkeeper.authorized_applications.index.application') %></th>
 | 
				
			||||||
 | 
					      <th><%= t('doorkeeper.authorized_applications.index.created_at') %></th>
 | 
				
			||||||
 | 
					      <th></th>
 | 
				
			||||||
 | 
					      <th></th>
 | 
				
			||||||
 | 
					    </tr>
 | 
				
			||||||
 | 
					    </thead>
 | 
				
			||||||
 | 
					    <tbody>
 | 
				
			||||||
 | 
					    <% @applications.each do |application| %>
 | 
				
			||||||
 | 
					      <tr>
 | 
				
			||||||
 | 
					        <td><%= application.name %></td>
 | 
				
			||||||
 | 
					        <td><%= application.created_at.strftime(t('doorkeeper.authorized_applications.index.date_format')) %></td>
 | 
				
			||||||
 | 
					        <td><%= render 'delete_form', application: application %></td>
 | 
				
			||||||
 | 
					      </tr>
 | 
				
			||||||
 | 
					    <% end %>
 | 
				
			||||||
 | 
					    </tbody>
 | 
				
			||||||
 | 
					  </table>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
							
								
								
									
										37
									
								
								app/views/layouts/doorkeeper/admin.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								app/views/layouts/doorkeeper/admin.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="utf-8">
 | 
				
			||||||
 | 
					  <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
				
			||||||
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					  <title>Doorkeeper</title>
 | 
				
			||||||
 | 
					  <%= stylesheet_link_tag "doorkeeper/admin/application" %>
 | 
				
			||||||
 | 
					  <%= csrf_meta_tags %>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div class="navbar navbar-inverse navbar-static-top" role="navigation">
 | 
				
			||||||
 | 
					  <div class="container-fluid">
 | 
				
			||||||
 | 
					    <div class="navbar-header">
 | 
				
			||||||
 | 
					      <%= link_to t('doorkeeper.layouts.admin.nav.oauth2_provider'), oauth_applications_path, class: 'navbar-brand' %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <ul class="nav navbar-nav">
 | 
				
			||||||
 | 
					      <%= content_tag :li, class: "#{'active' if request.path == oauth_applications_path}" do %>
 | 
				
			||||||
 | 
					        <%= link_to t('doorkeeper.layouts.admin.nav.applications'), oauth_applications_path %>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					      <%= content_tag :li do %>
 | 
				
			||||||
 | 
					        <%= link_to 'Home', root_path %>
 | 
				
			||||||
 | 
					      <% end %>
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="container">
 | 
				
			||||||
 | 
					  <%- if flash[:notice].present? %>
 | 
				
			||||||
 | 
					    <div class="alert alert-info">
 | 
				
			||||||
 | 
					      <%= flash[:notice] %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  <% end -%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <%= yield %>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										23
									
								
								app/views/layouts/doorkeeper/application.html.erb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								app/views/layouts/doorkeeper/application.html.erb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <title><%= t('doorkeeper.layouts.application.title') %></title>
 | 
				
			||||||
 | 
					  <meta charset="utf-8">
 | 
				
			||||||
 | 
					  <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
				
			||||||
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <%= stylesheet_link_tag "doorkeeper/application" %>
 | 
				
			||||||
 | 
					  <%= csrf_meta_tags %>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<div id="container">
 | 
				
			||||||
 | 
					  <%- if flash[:notice].present? %>
 | 
				
			||||||
 | 
					    <div class="alert alert-info">
 | 
				
			||||||
 | 
					      <%= flash[:notice] %>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  <% end -%>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <%= yield %>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
@@ -27,5 +27,10 @@ module Mastodon
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
 | 
					    config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
 | 
				
			||||||
    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
 | 
					    config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config.to_prepare do
 | 
				
			||||||
 | 
					      Doorkeeper::AuthorizationsController.layout 'auth'
 | 
				
			||||||
 | 
					      Doorkeeper::AuthorizedApplicationsController.layout 'auth'
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ Devise.setup do |config|
 | 
				
			|||||||
  # given strategies, for example, `config.http_authenticatable = [:database]` will
 | 
					  # given strategies, for example, `config.http_authenticatable = [:database]` will
 | 
				
			||||||
  # enable it only for database authentication. The supported strategies are:
 | 
					  # enable it only for database authentication. The supported strategies are:
 | 
				
			||||||
  # :database      = Support basic authentication with authentication key + password
 | 
					  # :database      = Support basic authentication with authentication key + password
 | 
				
			||||||
  # config.http_authenticatable = false
 | 
					  config.http_authenticatable = [:database]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # If 401 status code should be returned for AJAX requests. True by default.
 | 
					  # If 401 status code should be returned for AJAX requests. True by default.
 | 
				
			||||||
  # config.http_authenticatable_on_xhr = true
 | 
					  # config.http_authenticatable_on_xhr = true
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										104
									
								
								config/initializers/doorkeeper.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								config/initializers/doorkeeper.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					Doorkeeper.configure do
 | 
				
			||||||
 | 
					  # Change the ORM that doorkeeper will use (needs plugins)
 | 
				
			||||||
 | 
					  orm :active_record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # This block will be called to check whether the resource owner is authenticated or not.
 | 
				
			||||||
 | 
					  resource_owner_authenticator do
 | 
				
			||||||
 | 
					    current_user || redirect_to(new_user_session_url)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # If you want to restrict access to the web interface for adding oauth authorized applications, you need to declare the block below.
 | 
				
			||||||
 | 
					  # admin_authenticator do
 | 
				
			||||||
 | 
					  #   # Put your admin authentication logic here.
 | 
				
			||||||
 | 
					  #   # Example implementation:
 | 
				
			||||||
 | 
					  #   Admin.find_by_id(session[:admin_id]) || redirect_to(new_admin_session_url)
 | 
				
			||||||
 | 
					  # end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Authorization Code expiration time (default 10 minutes).
 | 
				
			||||||
 | 
					  # authorization_code_expires_in 10.minutes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Access token expiration time (default 2 hours).
 | 
				
			||||||
 | 
					  # If you want to disable expiration, set this to nil.
 | 
				
			||||||
 | 
					  # access_token_expires_in 2.hours
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Assign a custom TTL for implicit grants.
 | 
				
			||||||
 | 
					  # custom_access_token_expires_in do |oauth_client|
 | 
				
			||||||
 | 
					  #   oauth_client.application.additional_settings.implicit_oauth_expiration
 | 
				
			||||||
 | 
					  # end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Use a custom class for generating the access token.
 | 
				
			||||||
 | 
					  # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
 | 
				
			||||||
 | 
					  # access_token_generator "::Doorkeeper::JWT"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Reuse access token for the same resource owner within an application (disabled by default)
 | 
				
			||||||
 | 
					  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
 | 
				
			||||||
 | 
					  # reuse_access_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Issue access tokens with refresh token (disabled by default)
 | 
				
			||||||
 | 
					  # use_refresh_token
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Provide support for an owner to be assigned to each registered application (disabled by default)
 | 
				
			||||||
 | 
					  # Optional parameter :confirmation => true (default false) if you want to enforce ownership of
 | 
				
			||||||
 | 
					  # a registered application
 | 
				
			||||||
 | 
					  # Note: you must also run the rails g doorkeeper:application_owner generator to provide the necessary support
 | 
				
			||||||
 | 
					  # enable_application_owner :confirmation => false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Define access token scopes for your provider
 | 
				
			||||||
 | 
					  # For more information go to
 | 
				
			||||||
 | 
					  # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
 | 
				
			||||||
 | 
					  # default_scopes  :public
 | 
				
			||||||
 | 
					  # optional_scopes :write, :update
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Change the way client credentials are retrieved from the request object.
 | 
				
			||||||
 | 
					  # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
 | 
				
			||||||
 | 
					  # falls back to the `:client_id` and `:client_secret` params from the `params` object.
 | 
				
			||||||
 | 
					  # Check out the wiki for more information on customization
 | 
				
			||||||
 | 
					  # client_credentials :from_basic, :from_params
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Change the way access token is authenticated from the request object.
 | 
				
			||||||
 | 
					  # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
 | 
				
			||||||
 | 
					  # falls back to the `:access_token` or `:bearer_token` params from the `params` object.
 | 
				
			||||||
 | 
					  # Check out the wiki for more information on customization
 | 
				
			||||||
 | 
					  # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Change the native redirect uri for client apps
 | 
				
			||||||
 | 
					  # When clients register with the following redirect uri, they won't be redirected to any server and the authorization code will be displayed within the provider
 | 
				
			||||||
 | 
					  # The value can be any string. Use nil to disable this feature. When disabled, clients must provide a valid URL
 | 
				
			||||||
 | 
					  # (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # native_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
 | 
				
			||||||
 | 
					  # by default in non-development environments). OAuth2 delegates security in
 | 
				
			||||||
 | 
					  # communication to the HTTPS protocol so it is wise to keep this enabled.
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # force_ssl_in_redirect_uri !Rails.env.development?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Specify what grant flows are enabled in array of Strings. The valid
 | 
				
			||||||
 | 
					  # strings and the flows they enable are:
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # "authorization_code" => Authorization Code Grant Flow
 | 
				
			||||||
 | 
					  # "implicit"           => Implicit Grant Flow
 | 
				
			||||||
 | 
					  # "password"           => Resource Owner Password Credentials Grant Flow
 | 
				
			||||||
 | 
					  # "client_credentials" => Client Credentials Grant Flow
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # If not specified, Doorkeeper enables authorization_code and
 | 
				
			||||||
 | 
					  # client_credentials.
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # implicit and password grant flows have risks that you should understand
 | 
				
			||||||
 | 
					  # before enabling:
 | 
				
			||||||
 | 
					  #   http://tools.ietf.org/html/rfc6819#section-4.4.2
 | 
				
			||||||
 | 
					  #   http://tools.ietf.org/html/rfc6819#section-4.4.3
 | 
				
			||||||
 | 
					  #
 | 
				
			||||||
 | 
					  # grant_flows %w(authorization_code client_credentials)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # Under some circumstances you might want to have applications auto-approved,
 | 
				
			||||||
 | 
					  # so that the user skips the authorization step.
 | 
				
			||||||
 | 
					  # For example if dealing with a trusted application.
 | 
				
			||||||
 | 
					  # skip_authorization do |resource_owner, client|
 | 
				
			||||||
 | 
					  #   client.superapp? or resource_owner.admin?
 | 
				
			||||||
 | 
					  # end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # WWW-Authenticate Realm (default "Doorkeeper").
 | 
				
			||||||
 | 
					  # realm "Doorkeeper"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										3
									
								
								config/initializers/rabl_init.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								config/initializers/rabl_init.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					Rabl.configure do |config|
 | 
				
			||||||
 | 
					  config.include_json_root = false
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
if Rails.env.development?
 | 
					 | 
				
			||||||
  ActiveSupport::Dependencies.explicitly_unloadable_constants << 'Twitter::API'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  api_files = Dir[Rails.root.join('app', 'api', '**', '*.rb')]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  api_reloader = ActiveSupport::FileUpdateChecker.new(api_files) do
 | 
					 | 
				
			||||||
    Rails.application.reload_routes!
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ActionDispatch::Callbacks.to_prepare do
 | 
					 | 
				
			||||||
    api_reloader.execute_if_updated
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
							
								
								
									
										123
									
								
								config/locales/doorkeeper.en.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								config/locales/doorkeeper.en.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,123 @@
 | 
				
			|||||||
 | 
					en:
 | 
				
			||||||
 | 
					  activerecord:
 | 
				
			||||||
 | 
					    attributes:
 | 
				
			||||||
 | 
					      doorkeeper/application:
 | 
				
			||||||
 | 
					        name: 'Name'
 | 
				
			||||||
 | 
					        redirect_uri: 'Redirect URI'
 | 
				
			||||||
 | 
					    errors:
 | 
				
			||||||
 | 
					      models:
 | 
				
			||||||
 | 
					        doorkeeper/application:
 | 
				
			||||||
 | 
					          attributes:
 | 
				
			||||||
 | 
					            redirect_uri:
 | 
				
			||||||
 | 
					              fragment_present: 'cannot contain a fragment.'
 | 
				
			||||||
 | 
					              invalid_uri: 'must be a valid URI.'
 | 
				
			||||||
 | 
					              relative_uri: 'must be an absolute URI.'
 | 
				
			||||||
 | 
					              secured_uri: 'must be an HTTPS/SSL URI.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  doorkeeper:
 | 
				
			||||||
 | 
					    applications:
 | 
				
			||||||
 | 
					      confirmations:
 | 
				
			||||||
 | 
					        destroy: 'Are you sure?'
 | 
				
			||||||
 | 
					      buttons:
 | 
				
			||||||
 | 
					        edit: 'Edit'
 | 
				
			||||||
 | 
					        destroy: 'Destroy'
 | 
				
			||||||
 | 
					        submit: 'Submit'
 | 
				
			||||||
 | 
					        cancel: 'Cancel'
 | 
				
			||||||
 | 
					        authorize: 'Authorize'
 | 
				
			||||||
 | 
					      form:
 | 
				
			||||||
 | 
					        error: 'Whoops! Check your form for possible errors'
 | 
				
			||||||
 | 
					      help:
 | 
				
			||||||
 | 
					        redirect_uri: 'Use one line per URI'
 | 
				
			||||||
 | 
					        native_redirect_uri: 'Use %{native_redirect_uri} for local tests'
 | 
				
			||||||
 | 
					        scopes: 'Separate scopes with spaces. Leave blank to use the default scopes.'
 | 
				
			||||||
 | 
					      edit:
 | 
				
			||||||
 | 
					        title: 'Edit application'
 | 
				
			||||||
 | 
					      index:
 | 
				
			||||||
 | 
					        title: 'Your applications'
 | 
				
			||||||
 | 
					        new: 'New Application'
 | 
				
			||||||
 | 
					        name: 'Name'
 | 
				
			||||||
 | 
					        callback_url: 'Callback URL'
 | 
				
			||||||
 | 
					      new:
 | 
				
			||||||
 | 
					        title: 'New Application'
 | 
				
			||||||
 | 
					      show:
 | 
				
			||||||
 | 
					        title: 'Application: %{name}'
 | 
				
			||||||
 | 
					        application_id: 'Application Id'
 | 
				
			||||||
 | 
					        secret: 'Secret'
 | 
				
			||||||
 | 
					        scopes: 'Scopes'
 | 
				
			||||||
 | 
					        callback_urls: 'Callback urls'
 | 
				
			||||||
 | 
					        actions: 'Actions'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    authorizations:
 | 
				
			||||||
 | 
					      buttons:
 | 
				
			||||||
 | 
					        authorize: 'Authorize'
 | 
				
			||||||
 | 
					        deny: 'Deny'
 | 
				
			||||||
 | 
					      error:
 | 
				
			||||||
 | 
					        title: 'An error has occurred'
 | 
				
			||||||
 | 
					      new:
 | 
				
			||||||
 | 
					        title: 'Authorization required'
 | 
				
			||||||
 | 
					        prompt: 'Authorize %{client_name} to use your account?'
 | 
				
			||||||
 | 
					        able_to: 'This application will be able to'
 | 
				
			||||||
 | 
					      show:
 | 
				
			||||||
 | 
					        title: 'Authorization code'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    authorized_applications:
 | 
				
			||||||
 | 
					      confirmations:
 | 
				
			||||||
 | 
					        revoke: 'Are you sure?'
 | 
				
			||||||
 | 
					      buttons:
 | 
				
			||||||
 | 
					        revoke: 'Revoke'
 | 
				
			||||||
 | 
					      index:
 | 
				
			||||||
 | 
					        title: 'Your authorized applications'
 | 
				
			||||||
 | 
					        application: 'Application'
 | 
				
			||||||
 | 
					        created_at: 'Created At'
 | 
				
			||||||
 | 
					        date_format: '%Y-%m-%d %H:%M:%S'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    errors:
 | 
				
			||||||
 | 
					      messages:
 | 
				
			||||||
 | 
					        # Common error messages
 | 
				
			||||||
 | 
					        invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
 | 
				
			||||||
 | 
					        invalid_redirect_uri: 'The redirect uri included is not valid.'
 | 
				
			||||||
 | 
					        unauthorized_client: 'The client is not authorized to perform this request using this method.'
 | 
				
			||||||
 | 
					        access_denied: 'The resource owner or authorization server denied the request.'
 | 
				
			||||||
 | 
					        invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
 | 
				
			||||||
 | 
					        server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
 | 
				
			||||||
 | 
					        temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #configuration error messages
 | 
				
			||||||
 | 
					        credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.'
 | 
				
			||||||
 | 
					        resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Access grant errors
 | 
				
			||||||
 | 
					        unsupported_response_type: 'The authorization server does not support this response type.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Access token errors
 | 
				
			||||||
 | 
					        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'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        invalid_token:
 | 
				
			||||||
 | 
					          revoked: "The access token was revoked"
 | 
				
			||||||
 | 
					          expired: "The access token expired"
 | 
				
			||||||
 | 
					          unknown: "The access token is invalid"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    flash:
 | 
				
			||||||
 | 
					      applications:
 | 
				
			||||||
 | 
					        create:
 | 
				
			||||||
 | 
					          notice: 'Application created.'
 | 
				
			||||||
 | 
					        destroy:
 | 
				
			||||||
 | 
					          notice: 'Application deleted.'
 | 
				
			||||||
 | 
					        update:
 | 
				
			||||||
 | 
					          notice: 'Application updated.'
 | 
				
			||||||
 | 
					      authorized_applications:
 | 
				
			||||||
 | 
					        destroy:
 | 
				
			||||||
 | 
					          notice: 'Application revoked.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    layouts:
 | 
				
			||||||
 | 
					      admin:
 | 
				
			||||||
 | 
					        nav:
 | 
				
			||||||
 | 
					          oauth2_provider: 'OAuth2 Provider'
 | 
				
			||||||
 | 
					          applications: 'Applications'
 | 
				
			||||||
 | 
					      application:
 | 
				
			||||||
 | 
					        title: 'OAuth authorization required'
 | 
				
			||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
Rails.application.routes.draw do
 | 
					Rails.application.routes.draw do
 | 
				
			||||||
 | 
					  use_doorkeeper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta
 | 
					  get '.well-known/host-meta', to: 'xrd#host_meta', as: :host_meta
 | 
				
			||||||
  get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger
 | 
					  get '.well-known/webfinger', to: 'xrd#webfinger', as: :webfinger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,24 +11,37 @@ Rails.application.routes.draw do
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  resources :accounts, path: 'users', only: [:show], param: :username do
 | 
					  resources :accounts, path: 'users', only: [:show], param: :username do
 | 
				
			||||||
    member do
 | 
					    resources :stream_entries, path: 'updates', only: [:show]
 | 
				
			||||||
      post :follow
 | 
					  end
 | 
				
			||||||
      post :unfollow
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resources :stream_entries, path: 'updates', only: [:show] do
 | 
					  namespace :api do
 | 
				
			||||||
 | 
					    # PubSubHubbub
 | 
				
			||||||
 | 
					    resources :subscriptions, only: [:show]
 | 
				
			||||||
 | 
					    post '/subscriptions/:id', to: 'subscriptions#update'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Salmon
 | 
				
			||||||
 | 
					    post '/salmon/:id', to: 'salmon#update', as: :salmon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # JSON / REST API
 | 
				
			||||||
 | 
					    resources :statuses, only: [:create, :show] do
 | 
				
			||||||
      member do
 | 
					      member do
 | 
				
			||||||
        post :reblog
 | 
					        post :reblog
 | 
				
			||||||
        post :favourite
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resources :follows,  only: [:create]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resources :accounts, only: [:show] do
 | 
				
			||||||
 | 
					      member do
 | 
				
			||||||
 | 
					        get :statuses
 | 
				
			||||||
 | 
					        get :followers
 | 
				
			||||||
 | 
					        get :following
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        post :follow
 | 
				
			||||||
 | 
					        post :unfollow
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  namespace :api do
 | 
					 | 
				
			||||||
    resources :subscriptions, only: [:show]
 | 
					 | 
				
			||||||
    post '/subscriptions/:id', to: 'subscriptions#update'
 | 
					 | 
				
			||||||
    post '/salmon/:id', to: 'salmon#update', as: :salmon
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  root 'home#index'
 | 
					  root 'home#index'
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								db/migrate/20160306172223_create_doorkeeper_tables.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								db/migrate/20160306172223_create_doorkeeper_tables.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					class CreateDoorkeeperTables < ActiveRecord::Migration
 | 
				
			||||||
 | 
					  def change
 | 
				
			||||||
 | 
					    create_table :oauth_applications do |t|
 | 
				
			||||||
 | 
					      t.string  :name,         null: false
 | 
				
			||||||
 | 
					      t.string  :uid,          null: false
 | 
				
			||||||
 | 
					      t.string  :secret,       null: false
 | 
				
			||||||
 | 
					      t.text    :redirect_uri, null: false
 | 
				
			||||||
 | 
					      t.string  :scopes,       null: false, default: ''
 | 
				
			||||||
 | 
					      t.timestamps
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_index :oauth_applications, :uid, unique: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    create_table :oauth_access_grants do |t|
 | 
				
			||||||
 | 
					      t.integer  :user_id,           null: false
 | 
				
			||||||
 | 
					      t.integer  :application_id,    null: false
 | 
				
			||||||
 | 
					      t.string   :token,             null: false
 | 
				
			||||||
 | 
					      t.integer  :expires_in,        null: false
 | 
				
			||||||
 | 
					      t.text     :redirect_uri,      null: false
 | 
				
			||||||
 | 
					      t.datetime :created_at,        null: false
 | 
				
			||||||
 | 
					      t.datetime :revoked_at
 | 
				
			||||||
 | 
					      t.string   :scopes
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_index :oauth_access_grants, :token, unique: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    create_table :oauth_access_tokens do |t|
 | 
				
			||||||
 | 
					      t.integer  :resource_owner_id
 | 
				
			||||||
 | 
					      t.integer  :application_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      # If you use a custom token generator you may need to change this column
 | 
				
			||||||
 | 
					      # from string to text, so that it accepts tokens larger than 255
 | 
				
			||||||
 | 
					      # characters. More info on custom token generators in:
 | 
				
			||||||
 | 
					      # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator
 | 
				
			||||||
 | 
					      #
 | 
				
			||||||
 | 
					      # t.text     :token,             null: false
 | 
				
			||||||
 | 
					      t.string   :token,             null: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      t.string   :refresh_token
 | 
				
			||||||
 | 
					      t.integer  :expires_in
 | 
				
			||||||
 | 
					      t.datetime :revoked_at
 | 
				
			||||||
 | 
					      t.datetime :created_at,        null: false
 | 
				
			||||||
 | 
					      t.string   :scopes
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_index :oauth_access_tokens, :token, unique: true
 | 
				
			||||||
 | 
					    add_index :oauth_access_tokens, :resource_owner_id
 | 
				
			||||||
 | 
					    add_index :oauth_access_tokens, :refresh_token, unique: true
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										42
									
								
								db/schema.rb
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								db/schema.rb
									
									
									
									
									
								
							@@ -11,7 +11,7 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# It's strongly recommended that you check this file into your version control system.
 | 
					# It's strongly recommended that you check this file into your version control system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ActiveRecord::Schema.define(version: 20160305115639) do
 | 
					ActiveRecord::Schema.define(version: 20160306172223) do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # These are extensions that must be enabled in order to support this database
 | 
					  # These are extensions that must be enabled in order to support this database
 | 
				
			||||||
  enable_extension "plpgsql"
 | 
					  enable_extension "plpgsql"
 | 
				
			||||||
@@ -67,6 +67,46 @@ ActiveRecord::Schema.define(version: 20160305115639) do
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  add_index "mentions", ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree
 | 
					  add_index "mentions", ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  create_table "oauth_access_grants", force: :cascade do |t|
 | 
				
			||||||
 | 
					    t.integer  "user_id",        null: false
 | 
				
			||||||
 | 
					    t.integer  "application_id", null: false
 | 
				
			||||||
 | 
					    t.string   "token",          null: false
 | 
				
			||||||
 | 
					    t.integer  "expires_in",     null: false
 | 
				
			||||||
 | 
					    t.text     "redirect_uri",   null: false
 | 
				
			||||||
 | 
					    t.datetime "created_at",     null: false
 | 
				
			||||||
 | 
					    t.datetime "revoked_at"
 | 
				
			||||||
 | 
					    t.string   "scopes"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  create_table "oauth_access_tokens", force: :cascade do |t|
 | 
				
			||||||
 | 
					    t.integer  "resource_owner_id"
 | 
				
			||||||
 | 
					    t.integer  "application_id"
 | 
				
			||||||
 | 
					    t.string   "token",             null: false
 | 
				
			||||||
 | 
					    t.string   "refresh_token"
 | 
				
			||||||
 | 
					    t.integer  "expires_in"
 | 
				
			||||||
 | 
					    t.datetime "revoked_at"
 | 
				
			||||||
 | 
					    t.datetime "created_at",        null: false
 | 
				
			||||||
 | 
					    t.string   "scopes"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
 | 
				
			||||||
 | 
					  add_index "oauth_access_tokens", ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id", using: :btree
 | 
				
			||||||
 | 
					  add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  create_table "oauth_applications", force: :cascade do |t|
 | 
				
			||||||
 | 
					    t.string   "name",                      null: false
 | 
				
			||||||
 | 
					    t.string   "uid",                       null: false
 | 
				
			||||||
 | 
					    t.string   "secret",                    null: false
 | 
				
			||||||
 | 
					    t.text     "redirect_uri",              null: false
 | 
				
			||||||
 | 
					    t.string   "scopes",       default: "", null: false
 | 
				
			||||||
 | 
					    t.datetime "created_at"
 | 
				
			||||||
 | 
					    t.datetime "updated_at"
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  create_table "statuses", force: :cascade do |t|
 | 
					  create_table "statuses", force: :cascade do |t|
 | 
				
			||||||
    t.string   "uri"
 | 
					    t.string   "uri"
 | 
				
			||||||
    t.integer  "account_id",                  null: false
 | 
					    t.integer  "account_id",                  null: false
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										5
									
								
								spec/controllers/api/accounts_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/controllers/api/accounts_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RSpec.describe Api::AccountsController, type: :controller do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										5
									
								
								spec/controllers/api/follows_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/controllers/api/follows_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RSpec.describe Api::FollowsController, type: :controller do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										5
									
								
								spec/controllers/api/statuses_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								spec/controllers/api/statuses_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RSpec.describe Api::StatusesController, type: :controller do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										15
									
								
								spec/helpers/api/accounts_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								spec/helpers/api/accounts_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Specs in this file have access to a helper object that includes
 | 
				
			||||||
 | 
					# the Api::AccountsHelper. For example:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# describe Api::AccountsHelper do
 | 
				
			||||||
 | 
					#   describe "string concat" do
 | 
				
			||||||
 | 
					#     it "concats two strings with spaces" do
 | 
				
			||||||
 | 
					#       expect(helper.concat_strings("this","that")).to eq("this that")
 | 
				
			||||||
 | 
					#     end
 | 
				
			||||||
 | 
					#   end
 | 
				
			||||||
 | 
					# end
 | 
				
			||||||
 | 
					RSpec.describe Api::AccountsHelper, type: :helper do
 | 
				
			||||||
 | 
					  pending "add some examples to (or delete) #{__FILE__}"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										15
									
								
								spec/helpers/api/follows_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								spec/helpers/api/follows_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Specs in this file have access to a helper object that includes
 | 
				
			||||||
 | 
					# the Api::FollowsHelper. For example:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# describe Api::FollowsHelper do
 | 
				
			||||||
 | 
					#   describe "string concat" do
 | 
				
			||||||
 | 
					#     it "concats two strings with spaces" do
 | 
				
			||||||
 | 
					#       expect(helper.concat_strings("this","that")).to eq("this that")
 | 
				
			||||||
 | 
					#     end
 | 
				
			||||||
 | 
					#   end
 | 
				
			||||||
 | 
					# end
 | 
				
			||||||
 | 
					RSpec.describe Api::FollowsHelper, type: :helper do
 | 
				
			||||||
 | 
					  pending "add some examples to (or delete) #{__FILE__}"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										15
									
								
								spec/helpers/api/statuses_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								spec/helpers/api/statuses_helper_spec.rb
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Specs in this file have access to a helper object that includes
 | 
				
			||||||
 | 
					# the Api::StatusesHelper. For example:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# describe Api::StatusesHelper do
 | 
				
			||||||
 | 
					#   describe "string concat" do
 | 
				
			||||||
 | 
					#     it "concats two strings with spaces" do
 | 
				
			||||||
 | 
					#       expect(helper.concat_strings("this","that")).to eq("this that")
 | 
				
			||||||
 | 
					#     end
 | 
				
			||||||
 | 
					#   end
 | 
				
			||||||
 | 
					# end
 | 
				
			||||||
 | 
					RSpec.describe Api::StatusesHelper, type: :helper do
 | 
				
			||||||
 | 
					  pending "add some examples to (or delete) #{__FILE__}"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
		Reference in New Issue
	
	Block a user