Drop support for OAuth 1
This commit is contained in:
parent
cee9818dfc
commit
17bc0853a0
48 changed files with 52 additions and 2395 deletions
2
Gemfile
2
Gemfile
|
@ -59,7 +59,6 @@ gem "dry-validation"
|
|||
gem "frozen_record"
|
||||
gem "http_accept_language", "~> 2.1.1"
|
||||
gem "i18n-js", "~> 3.9.2"
|
||||
gem "oauth-plugin", ">= 0.5.1"
|
||||
gem "openstreetmap-deadlock_retry", ">= 1.3.1", :require => "deadlock_retry"
|
||||
gem "rack-cors"
|
||||
gem "rails-i18n", "~> 7.0.0"
|
||||
|
@ -76,6 +75,7 @@ gem "addressable", "~> 2.8"
|
|||
gem "rack-uri_sanitizer"
|
||||
|
||||
# Omniauth for authentication
|
||||
gem "multi_json"
|
||||
gem "omniauth", "~> 2.0.2"
|
||||
gem "omniauth-facebook"
|
||||
gem "omniauth-github"
|
||||
|
|
|
@ -362,11 +362,6 @@ GEM
|
|||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
oauth (0.4.7)
|
||||
oauth-plugin (0.5.1)
|
||||
multi_json
|
||||
oauth (~> 0.4.4)
|
||||
oauth2 (>= 0.5.0)
|
||||
rack
|
||||
oauth2 (2.0.9)
|
||||
faraday (>= 0.17.3, < 3.0)
|
||||
jwt (>= 1.0, < 3.0)
|
||||
|
@ -672,8 +667,8 @@ DEPENDENCIES
|
|||
mini_racer (~> 0.9.0)
|
||||
minitest (~> 5.1)
|
||||
minitest-focus
|
||||
multi_json
|
||||
multi_xml (~> 0.6.0)
|
||||
oauth-plugin (>= 0.5.1)
|
||||
omniauth (~> 2.0.2)
|
||||
omniauth-facebook
|
||||
omniauth-github
|
||||
|
|
|
@ -12,7 +12,6 @@ class Ability
|
|||
can [:index, :permalink, :edit, :help, :fixthemap, :offline, :export, :about, :communities, :preview, :copyright, :key, :id], :site
|
||||
can [:finish, :embed], :export
|
||||
can [:search, :search_latlon, :search_osm_nominatim, :search_osm_nominatim_reverse], :geocoder
|
||||
can [:token, :request_token, :access_token, :test_request], :oauth
|
||||
|
||||
if Settings.status != "database_offline"
|
||||
can [:index, :feed, :show], Changeset
|
||||
|
@ -31,12 +30,10 @@ class Ability
|
|||
|
||||
if user&.active?
|
||||
can :welcome, :site
|
||||
can [:revoke, :authorize], :oauth
|
||||
can [:show], :deletion
|
||||
|
||||
if Settings.status != "database_offline"
|
||||
can [:subscribe, :unsubscribe], Changeset
|
||||
can [:index, :new, :create, :show, :edit, :update, :destroy], ClientApplication
|
||||
can [:index, :new, :create, :show, :edit, :update, :destroy], :oauth2_application
|
||||
can [:index, :destroy], :oauth2_authorized_application
|
||||
can [:new, :show, :create, :destroy], :oauth2_authorization
|
||||
|
|
|
@ -16,8 +16,6 @@ class AccountsController < ApplicationController
|
|||
allow_social_login :only => [:edit, :update]
|
||||
|
||||
def edit
|
||||
@tokens = current_user.oauth_tokens.authorized
|
||||
|
||||
if errors = session.delete(:user_errors)
|
||||
errors.each do |attribute, error|
|
||||
current_user.errors.add(attribute, error)
|
||||
|
@ -27,8 +25,6 @@ class AccountsController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
@tokens = current_user.oauth_tokens.authorized
|
||||
|
||||
user_params = params.require(:user).permit(:display_name, :new_email, :pass_crypt, :pass_crypt_confirmation, :auth_provider)
|
||||
|
||||
if params[:user][:auth_provider].blank? ||
|
||||
|
|
|
@ -385,7 +385,7 @@ module Api
|
|||
def add_comment(note, text, event, notify: true)
|
||||
attributes = { :visible => true, :event => event, :body => text }
|
||||
|
||||
if doorkeeper_token || current_token
|
||||
if doorkeeper_token
|
||||
author = current_user if scope_enabled?(:write_notes)
|
||||
else
|
||||
author = current_user
|
||||
|
|
|
@ -14,10 +14,8 @@ module Api
|
|||
def show
|
||||
@permissions = if doorkeeper_token.present?
|
||||
doorkeeper_token.scopes.map { |s| :"allow_#{s}" }
|
||||
elsif current_token.present?
|
||||
ClientApplication.all_permissions.select { |p| current_token.read_attribute(p) }
|
||||
elsif current_user
|
||||
ClientApplication.all_permissions
|
||||
Oauth.scopes.map { |s| :"allow_#{s.name}" }
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
|
|
@ -69,15 +69,13 @@ class ApiController < ApplicationController
|
|||
# Use capabilities from the oauth token if it exists and is a valid access token
|
||||
if doorkeeper_token&.accessible?
|
||||
ApiAbility.new(nil).merge(ApiCapability.new(doorkeeper_token))
|
||||
elsif Authenticator.new(self, [:token]).allow?
|
||||
ApiAbility.new(nil).merge(ApiCapability.new(current_token))
|
||||
else
|
||||
ApiAbility.new(current_user)
|
||||
end
|
||||
end
|
||||
|
||||
def deny_access(_exception)
|
||||
if doorkeeper_token || current_token
|
||||
if doorkeeper_token
|
||||
set_locale
|
||||
report_error t("oauth.permissions.missing"), :forbidden
|
||||
elsif current_user
|
||||
|
@ -107,13 +105,6 @@ class ApiController < ApplicationController
|
|||
# try and setup using OAuth
|
||||
if doorkeeper_token&.accessible?
|
||||
self.current_user = User.find(doorkeeper_token.resource_owner_id)
|
||||
elsif Authenticator.new(self, [:token]).allow?
|
||||
if Settings.oauth_10a_support
|
||||
# self.current_user setup by OAuth
|
||||
else
|
||||
report_error t("application.oauth_10a_disabled", :link => t("application.auth_disabled_link")), :forbidden
|
||||
self.current_user = nil
|
||||
end
|
||||
else
|
||||
username, passwd = auth_data # parse from headers
|
||||
# authenticate per-scheme
|
||||
|
|
|
@ -86,10 +86,6 @@ class ApplicationController < ActionController::Base
|
|||
@oauth_token = current_user.oauth_token(Settings.oauth_application) if current_user && Settings.key?(:oauth_application)
|
||||
end
|
||||
|
||||
def require_oauth_10a_support
|
||||
report_error t("application.oauth_10a_disabled", :link => t("application.auth_disabled_link")), :forbidden unless Settings.oauth_10a_support
|
||||
end
|
||||
|
||||
##
|
||||
# require the user to have cookies enabled in their browser
|
||||
def require_cookies
|
||||
|
@ -297,7 +293,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def deny_access(_exception)
|
||||
if doorkeeper_token || current_token
|
||||
if doorkeeper_token
|
||||
set_locale
|
||||
report_error t("oauth.permissions.missing"), :forbidden
|
||||
elsif current_user
|
||||
|
@ -341,9 +337,6 @@ class ApplicationController < ActionController::Base
|
|||
[user, pass]
|
||||
end
|
||||
|
||||
# override to stop oauth plugin sending errors
|
||||
def invalid_oauth_response; end
|
||||
|
||||
# clean any referer parameter
|
||||
def safe_referer(referer)
|
||||
begin
|
||||
|
@ -366,7 +359,7 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
def scope_enabled?(scope)
|
||||
doorkeeper_token&.includes_scope?(scope) || current_token&.includes_scope?(scope)
|
||||
doorkeeper_token&.includes_scope?(scope)
|
||||
end
|
||||
|
||||
helper_method :scope_enabled?
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
class OauthClientsController < ApplicationController
|
||||
layout "site"
|
||||
|
||||
before_action :authorize_web
|
||||
before_action :set_locale
|
||||
|
||||
authorize_resource :class => ClientApplication
|
||||
|
||||
def index
|
||||
@client_applications = current_user.client_applications
|
||||
@tokens = current_user.oauth_tokens.authorized
|
||||
end
|
||||
|
||||
def show
|
||||
@client_application = current_user.client_applications.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
@type = "client application"
|
||||
render :action => "not_found", :status => :not_found
|
||||
end
|
||||
|
||||
def new
|
||||
if Settings.oauth_10_registration
|
||||
@client_application = ClientApplication.new
|
||||
else
|
||||
flash[:error] = t ".disabled"
|
||||
redirect_to :action => "index"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@client_application = current_user.client_applications.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
@type = "client application"
|
||||
render :action => "not_found", :status => :not_found
|
||||
end
|
||||
|
||||
def create
|
||||
@client_application = current_user.client_applications.build(application_params)
|
||||
if @client_application.save
|
||||
flash[:notice] = t ".flash"
|
||||
redirect_to :action => "show", :id => @client_application.id
|
||||
else
|
||||
render :action => "new"
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@client_application = current_user.client_applications.find(params[:id])
|
||||
if @client_application.update(application_params)
|
||||
flash[:notice] = t ".flash"
|
||||
redirect_to :action => "show", :id => @client_application.id
|
||||
else
|
||||
render :action => "edit"
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
@type = "client application"
|
||||
render :action => "not_found", :status => :not_found
|
||||
end
|
||||
|
||||
def destroy
|
||||
@client_application = current_user.client_applications.find(params[:id])
|
||||
@client_application.destroy
|
||||
flash[:notice] = t ".flash"
|
||||
redirect_to :action => "index"
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
@type = "client application"
|
||||
render :action => "not_found", :status => :not_found
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def application_params
|
||||
params.require(:client_application).permit(:name, :url, :callback_url, :support_url, ClientApplication.all_permissions)
|
||||
end
|
||||
end
|
|
@ -1,80 +0,0 @@
|
|||
class OauthController < ApplicationController
|
||||
include OAuth::Controllers::ProviderController
|
||||
|
||||
# The ProviderController will call login_required for any action that needs
|
||||
# a login, but we want to check authorization on every action.
|
||||
authorize_resource :class => false
|
||||
|
||||
before_action :require_oauth_10a_support
|
||||
|
||||
layout "site"
|
||||
|
||||
allow_all_form_action :only => :oauth1_authorize
|
||||
|
||||
def revoke
|
||||
@token = current_user.oauth_tokens.find_by :token => params[:token]
|
||||
if @token
|
||||
@token.invalidate!
|
||||
flash[:notice] = t(".flash", :application => @token.client_application.name)
|
||||
end
|
||||
redirect_to oauth_clients_url(:display_name => @token.user.display_name)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def login_required
|
||||
authorize_web
|
||||
set_locale
|
||||
end
|
||||
|
||||
def user_authorizes_token?
|
||||
any_auth = false
|
||||
|
||||
@token.client_application.permissions.each do |pref|
|
||||
if params[pref].to_i.nonzero?
|
||||
@token.write_attribute(pref, true)
|
||||
any_auth ||= true
|
||||
else
|
||||
@token.write_attribute(pref, false)
|
||||
end
|
||||
end
|
||||
|
||||
any_auth
|
||||
end
|
||||
|
||||
def oauth1_authorize
|
||||
if @token.invalidated?
|
||||
@message = t "oauth.authorize_failure.invalid"
|
||||
render :action => "authorize_failure"
|
||||
elsif request.post?
|
||||
if user_authorizes_token?
|
||||
@token.authorize!(current_user)
|
||||
callback_url = if @token.oauth10?
|
||||
params[:oauth_callback] || @token.client_application.callback_url
|
||||
else
|
||||
@token.oob? ? @token.client_application.callback_url : @token.callback_url
|
||||
end
|
||||
@redirect_url = URI.parse(callback_url) if callback_url.present?
|
||||
|
||||
if @redirect_url.to_s.blank?
|
||||
render :action => "authorize_success"
|
||||
else
|
||||
@redirect_url.query = if @redirect_url.query.blank?
|
||||
"oauth_token=#{@token.token}"
|
||||
else
|
||||
@redirect_url.query +
|
||||
"&oauth_token=#{@token.token}"
|
||||
end
|
||||
|
||||
@redirect_url.query += "&oauth_verifier=#{@token.verifier}" unless @token.oauth10?
|
||||
|
||||
redirect_to @redirect_url.to_s, :allow_other_host => true
|
||||
end
|
||||
else
|
||||
@token.invalidate!
|
||||
@message = t("oauth.authorize_failure.denied", :app_name => @token.client_application.name)
|
||||
render :action => "authorize_failure"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,57 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: oauth_tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(20)
|
||||
# client_application_id :integer
|
||||
# token :string(50)
|
||||
# secret :string(50)
|
||||
# authorized_at :datetime
|
||||
# invalidated_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# allow_read_prefs :boolean default(FALSE), not null
|
||||
# allow_write_prefs :boolean default(FALSE), not null
|
||||
# allow_write_diary :boolean default(FALSE), not null
|
||||
# allow_write_api :boolean default(FALSE), not null
|
||||
# allow_read_gpx :boolean default(FALSE), not null
|
||||
# allow_write_gpx :boolean default(FALSE), not null
|
||||
# callback_url :string
|
||||
# verifier :string(20)
|
||||
# scope :string
|
||||
# valid_to :datetime
|
||||
# allow_write_notes :boolean default(FALSE), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_oauth_tokens_on_token (token) UNIQUE
|
||||
# index_oauth_tokens_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id)
|
||||
# oauth_tokens_user_id_fkey (user_id => users.id)
|
||||
#
|
||||
|
||||
class AccessToken < OauthToken
|
||||
belongs_to :user, :optional => true
|
||||
belongs_to :client_application, :optional => true
|
||||
|
||||
scope :valid, -> { where(:invalidated_at => nil) }
|
||||
|
||||
validates :user, :secret, :presence => true
|
||||
|
||||
before_create :set_authorized_at
|
||||
|
||||
def includes_scope?(scope)
|
||||
self[:"allow_#{scope}"]
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_authorized_at
|
||||
self.authorized_at = Time.now.utc
|
||||
end
|
||||
end
|
|
@ -1,109 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: client_applications
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string
|
||||
# url :string
|
||||
# support_url :string
|
||||
# callback_url :string
|
||||
# key :string(50)
|
||||
# secret :string(50)
|
||||
# user_id :integer
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# allow_read_prefs :boolean default(FALSE), not null
|
||||
# allow_write_prefs :boolean default(FALSE), not null
|
||||
# allow_write_diary :boolean default(FALSE), not null
|
||||
# allow_write_api :boolean default(FALSE), not null
|
||||
# allow_read_gpx :boolean default(FALSE), not null
|
||||
# allow_write_gpx :boolean default(FALSE), not null
|
||||
# allow_write_notes :boolean default(FALSE), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_client_applications_on_key (key) UNIQUE
|
||||
# index_client_applications_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# client_applications_user_id_fkey (user_id => users.id)
|
||||
#
|
||||
|
||||
class ClientApplication < ApplicationRecord
|
||||
belongs_to :user, :optional => true
|
||||
has_many :tokens, :class_name => "OauthToken", :dependent => :delete_all
|
||||
has_many :access_tokens
|
||||
has_many :oauth2_verifiers
|
||||
has_many :oauth_tokens
|
||||
|
||||
validates :key, :presence => true, :uniqueness => true
|
||||
validates :name, :url, :secret, :presence => true
|
||||
validates :url, :format => /\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/
|
||||
validates :support_url, :allow_blank => true, :format => /\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/
|
||||
validates :callback_url, :allow_blank => true, :format => /\A#{URI::DEFAULT_PARSER.make_regexp}\z/
|
||||
|
||||
before_validation :generate_keys, :on => :create
|
||||
|
||||
attr_accessor :token_callback_url
|
||||
|
||||
def self.find_token(token_key)
|
||||
token = OauthToken.includes(:client_application).find_by(:token => token_key)
|
||||
token if token&.authorized?
|
||||
end
|
||||
|
||||
def self.verify_request(request, options = {}, &block)
|
||||
signature = OAuth::Signature.build(request, options, &block)
|
||||
return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
|
||||
|
||||
signature.verify
|
||||
rescue OAuth::Signature::UnknownSignatureMethod
|
||||
false
|
||||
end
|
||||
|
||||
def self.all_permissions
|
||||
Oauth.scopes.collect { |s| :"allow_#{s.name}" }
|
||||
end
|
||||
|
||||
def oauth_server
|
||||
@oauth_server ||= OAuth::Server.new("https://#{Settings.server_url}")
|
||||
end
|
||||
|
||||
def credentials
|
||||
@credentials ||= OAuth::Consumer.new(key, secret)
|
||||
end
|
||||
|
||||
def create_request_token(_params = {})
|
||||
params = { :client_application => self, :callback_url => token_callback_url }
|
||||
permissions.each do |p|
|
||||
params[p] = true
|
||||
end
|
||||
RequestToken.create(params)
|
||||
end
|
||||
|
||||
def access_token_for_user(user)
|
||||
unless token = access_tokens.valid.find_by(:user_id => user)
|
||||
params = { :user => user }
|
||||
|
||||
permissions.each do |p|
|
||||
params[p] = true
|
||||
end
|
||||
|
||||
token = access_tokens.create(params)
|
||||
end
|
||||
|
||||
token
|
||||
end
|
||||
|
||||
# the permissions that this client would like from the user
|
||||
def permissions
|
||||
ClientApplication.all_permissions.select { |p| self[p] }
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def generate_keys
|
||||
self.key = OAuth::Helper.generate_key(40)[0, 40]
|
||||
self.secret = OAuth::Helper.generate_key(40)[0, 40]
|
||||
end
|
||||
end
|
|
@ -1,58 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: oauth_tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(20)
|
||||
# client_application_id :integer
|
||||
# token :string(50)
|
||||
# secret :string(50)
|
||||
# authorized_at :datetime
|
||||
# invalidated_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# allow_read_prefs :boolean default(FALSE), not null
|
||||
# allow_write_prefs :boolean default(FALSE), not null
|
||||
# allow_write_diary :boolean default(FALSE), not null
|
||||
# allow_write_api :boolean default(FALSE), not null
|
||||
# allow_read_gpx :boolean default(FALSE), not null
|
||||
# allow_write_gpx :boolean default(FALSE), not null
|
||||
# callback_url :string
|
||||
# verifier :string(20)
|
||||
# scope :string
|
||||
# valid_to :datetime
|
||||
# allow_write_notes :boolean default(FALSE), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_oauth_tokens_on_token (token) UNIQUE
|
||||
# index_oauth_tokens_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id)
|
||||
# oauth_tokens_user_id_fkey (user_id => users.id)
|
||||
#
|
||||
|
||||
class Oauth2Token < AccessToken
|
||||
attr_accessor :state
|
||||
|
||||
def as_json(_options = {})
|
||||
d = { :access_token => token, :token_type => "bearer" }
|
||||
d[:expires_in] = expires_in if expires_at
|
||||
d
|
||||
end
|
||||
|
||||
def to_query
|
||||
q = "access_token=#{token}&token_type=bearer"
|
||||
q << "&state=#{CGI.escape(state)}" if @state
|
||||
q << "&expires_in=#{expires_in}" if expires_at
|
||||
q << "&scope=#{CGI.escape(scope)}" if scope
|
||||
q
|
||||
end
|
||||
|
||||
def expires_in
|
||||
expires_at.to_i - Time.now.to_i
|
||||
end
|
||||
end
|
|
@ -1,72 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: oauth_tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(20)
|
||||
# client_application_id :integer
|
||||
# token :string(50)
|
||||
# secret :string(50)
|
||||
# authorized_at :datetime
|
||||
# invalidated_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# allow_read_prefs :boolean default(FALSE), not null
|
||||
# allow_write_prefs :boolean default(FALSE), not null
|
||||
# allow_write_diary :boolean default(FALSE), not null
|
||||
# allow_write_api :boolean default(FALSE), not null
|
||||
# allow_read_gpx :boolean default(FALSE), not null
|
||||
# allow_write_gpx :boolean default(FALSE), not null
|
||||
# callback_url :string
|
||||
# verifier :string(20)
|
||||
# scope :string
|
||||
# valid_to :datetime
|
||||
# allow_write_notes :boolean default(FALSE), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_oauth_tokens_on_token (token) UNIQUE
|
||||
# index_oauth_tokens_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id)
|
||||
# oauth_tokens_user_id_fkey (user_id => users.id)
|
||||
#
|
||||
|
||||
class Oauth2Verifier < OauthToken
|
||||
validates :user, :presence => true, :associated => true
|
||||
|
||||
attr_accessor :state
|
||||
|
||||
def exchange!(_params = {})
|
||||
OauthToken.transaction do
|
||||
token = Oauth2Token.create! :user => user, :client_application => client_application, :scope => scope
|
||||
invalidate!
|
||||
token
|
||||
end
|
||||
end
|
||||
|
||||
def code
|
||||
token
|
||||
end
|
||||
|
||||
def redirect_url
|
||||
callback_url
|
||||
end
|
||||
|
||||
def to_query
|
||||
q = "code=#{token}"
|
||||
q << "&state=#{CGI.escape(state)}" if @state
|
||||
q
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def generate_keys
|
||||
self.token = OAuth::Helper.generate_key(20)[0, 20]
|
||||
self.expires_at = 10.minutes.from_now
|
||||
self.authorized_at = Time.now.utc
|
||||
end
|
||||
end
|
|
@ -1,31 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: oauth_nonces
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# nonce :string
|
||||
# timestamp :integer
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_oauth_nonces_on_nonce_and_timestamp (nonce,timestamp) UNIQUE
|
||||
#
|
||||
|
||||
# Simple store of nonces. The OAuth Spec requires that any given pair of nonce and timestamps are unique.
|
||||
# Thus you can use the same nonce with a different timestamp and viceversa.
|
||||
class OauthNonce < ApplicationRecord
|
||||
validates :timestamp, :presence => true
|
||||
validates :nonce, :presence => true, :uniqueness => { :scope => :timestamp }
|
||||
|
||||
# Remembers a nonce and it's associated timestamp. It returns false if it has already been used
|
||||
def self.remember(nonce, timestamp)
|
||||
return false if Time.now.to_i - timestamp.to_i > 86400
|
||||
|
||||
oauth_nonce = OauthNonce.create(:nonce => nonce, :timestamp => timestamp.to_i)
|
||||
return false if oauth_nonce.new_record?
|
||||
|
||||
oauth_nonce
|
||||
end
|
||||
end
|
|
@ -1,72 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: oauth_tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(20)
|
||||
# client_application_id :integer
|
||||
# token :string(50)
|
||||
# secret :string(50)
|
||||
# authorized_at :datetime
|
||||
# invalidated_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# allow_read_prefs :boolean default(FALSE), not null
|
||||
# allow_write_prefs :boolean default(FALSE), not null
|
||||
# allow_write_diary :boolean default(FALSE), not null
|
||||
# allow_write_api :boolean default(FALSE), not null
|
||||
# allow_read_gpx :boolean default(FALSE), not null
|
||||
# allow_write_gpx :boolean default(FALSE), not null
|
||||
# callback_url :string
|
||||
# verifier :string(20)
|
||||
# scope :string
|
||||
# valid_to :datetime
|
||||
# allow_write_notes :boolean default(FALSE), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_oauth_tokens_on_token (token) UNIQUE
|
||||
# index_oauth_tokens_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id)
|
||||
# oauth_tokens_user_id_fkey (user_id => users.id)
|
||||
#
|
||||
|
||||
class OauthToken < ApplicationRecord
|
||||
belongs_to :client_application, :optional => true
|
||||
belongs_to :user, :optional => true
|
||||
|
||||
scope :authorized, -> { where("authorized_at IS NOT NULL and invalidated_at IS NULL") }
|
||||
|
||||
validates :token, :presence => true, :uniqueness => true
|
||||
validates :user, :associated => true
|
||||
validates :client_application, :presence => true
|
||||
|
||||
before_validation :generate_keys, :on => :create
|
||||
|
||||
def invalidated?
|
||||
invalidated_at != nil
|
||||
end
|
||||
|
||||
def invalidate!
|
||||
update(:invalidated_at => Time.now.utc)
|
||||
end
|
||||
|
||||
def authorized?
|
||||
!authorized_at.nil? && !invalidated?
|
||||
end
|
||||
|
||||
def to_query
|
||||
"oauth_token=#{token}&oauth_token_secret=#{secret}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def generate_keys
|
||||
self.token = OAuth::Helper.generate_key(40)[0, 40]
|
||||
self.secret = OAuth::Helper.generate_key(40)[0, 40]
|
||||
end
|
||||
end
|
|
@ -1,82 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: oauth_tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# type :string(20)
|
||||
# client_application_id :integer
|
||||
# token :string(50)
|
||||
# secret :string(50)
|
||||
# authorized_at :datetime
|
||||
# invalidated_at :datetime
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# allow_read_prefs :boolean default(FALSE), not null
|
||||
# allow_write_prefs :boolean default(FALSE), not null
|
||||
# allow_write_diary :boolean default(FALSE), not null
|
||||
# allow_write_api :boolean default(FALSE), not null
|
||||
# allow_read_gpx :boolean default(FALSE), not null
|
||||
# allow_write_gpx :boolean default(FALSE), not null
|
||||
# callback_url :string
|
||||
# verifier :string(20)
|
||||
# scope :string
|
||||
# valid_to :datetime
|
||||
# allow_write_notes :boolean default(FALSE), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_oauth_tokens_on_token (token) UNIQUE
|
||||
# index_oauth_tokens_on_user_id (user_id)
|
||||
#
|
||||
# Foreign Keys
|
||||
#
|
||||
# oauth_tokens_client_application_id_fkey (client_application_id => client_applications.id)
|
||||
# oauth_tokens_user_id_fkey (user_id => users.id)
|
||||
#
|
||||
|
||||
class RequestToken < OauthToken
|
||||
attr_accessor :provided_oauth_verifier
|
||||
|
||||
def authorize!(user)
|
||||
return false if authorized?
|
||||
|
||||
self.user = user
|
||||
self.authorized_at = Time.now.utc
|
||||
self.verifier = OAuth::Helper.generate_key(20)[0, 20] unless oauth10?
|
||||
save
|
||||
end
|
||||
|
||||
def exchange!
|
||||
return false unless authorized?
|
||||
return false unless oauth10? || verifier == provided_oauth_verifier
|
||||
|
||||
RequestToken.transaction do
|
||||
params = { :user => user, :client_application => client_application }
|
||||
# copy the permissions from the authorised request token to the access token
|
||||
client_application.permissions.each do |p|
|
||||
params[p] = self[p]
|
||||
end
|
||||
|
||||
access_token = AccessToken.create(params)
|
||||
invalidate!
|
||||
access_token
|
||||
end
|
||||
end
|
||||
|
||||
def to_query
|
||||
if oauth10?
|
||||
super
|
||||
else
|
||||
"#{super}&oauth_callback_confirmed=true"
|
||||
end
|
||||
end
|
||||
|
||||
def oob?
|
||||
callback_url.nil? || callback_url.casecmp?("oob")
|
||||
end
|
||||
|
||||
def oauth10?
|
||||
Settings.key?(:oauth_10_support) && Settings.oauth_10_support && callback_url.blank?
|
||||
end
|
||||
end
|
|
@ -66,9 +66,6 @@ class User < ApplicationRecord
|
|||
has_many :note_comments, :foreign_key => :author_id, :inverse_of => :author
|
||||
has_many :notes, :through => :note_comments
|
||||
|
||||
has_many :client_applications
|
||||
has_many :oauth_tokens, -> { order(:authorized_at => :desc).preload(:client_application) }, :class_name => "OauthToken", :inverse_of => :user
|
||||
|
||||
has_many :oauth2_applications, :class_name => Doorkeeper.config.application_model.name, :as => :owner
|
||||
has_many :access_grants, :class_name => Doorkeeper.config.access_grant_model.name, :foreign_key => :resource_owner_id
|
||||
has_many :access_tokens, :class_name => Doorkeeper.config.access_token_model.name, :foreign_key => :resource_owner_id
|
||||
|
@ -332,7 +329,6 @@ class User < ApplicationRecord
|
|||
##
|
||||
# revoke any authentication tokens
|
||||
def revoke_authentication_tokens
|
||||
oauth_tokens.authorized.each(&:invalidate!)
|
||||
access_tokens.not_expired.each(&:revoke)
|
||||
end
|
||||
|
||||
|
@ -377,12 +373,6 @@ class User < ApplicationRecord
|
|||
suspend! if may_suspend? && spam_score > Settings.spam_threshold
|
||||
end
|
||||
|
||||
##
|
||||
# return an oauth 1 access token for a specified application
|
||||
def access_token(application_key)
|
||||
ClientApplication.find_by(:key => application_key).access_token_for_user(self)
|
||||
end
|
||||
|
||||
##
|
||||
# return an oauth 2 access token for a specified application
|
||||
def oauth_token(application_id)
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
<li class="nav-item">
|
||||
<%= link_to t(".account_settings"), edit_account_path, :class => "nav-link #{'active' if %w[accounts deletions].include?(controller_name)}" %>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<%= link_to t(".oauth1_settings"), oauth_clients_path(current_user), :class => "nav-link #{'active' if controller_name == 'oauth_clients'}" %>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<%= link_to t(".oauth2_applications"), oauth_applications_path, :class => "nav-link #{'active' if controller_name == 'oauth2_applications'}" %>
|
||||
</li>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t ".title" %></h1>
|
||||
<% end %>
|
||||
|
||||
<p><%= t(".request_access_html", :app_name => link_to(@token.client_application.name, @token.client_application.url), :user => link_to(current_user.display_name, current_user)) %></p>
|
||||
|
||||
<%= bootstrap_form_tag do |f| %>
|
||||
<%= f.hidden_field :oauth_token, :value => @token.token %>
|
||||
<% if params[:oauth_callback] -%>
|
||||
<%= f.hidden_field :oauth_callback, :value => params[:oauth_callback] %>
|
||||
<% end -%>
|
||||
<%= f.form_group :permissions, :label => { :text => t(".allow_to") } do %>
|
||||
<% @token.client_application.permissions.each do |perm| -%>
|
||||
<%= f.check_box perm, :value => "yes", :checked => @token.read_attribute(perm), :label => t(".#{perm}") %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<%= f.primary t(".grant_access") %>
|
||||
<% end %>
|
|
@ -1,5 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t ".title" %></h1>
|
||||
<% end %>
|
||||
|
||||
<p><%= @message %></p>
|
|
@ -1,9 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t ".title" %></h1>
|
||||
<% end %>
|
||||
|
||||
<p><%= t(".allowed_html", :app_name => link_to(@token.client_application.name, @token.client_application.url)) %></p>
|
||||
|
||||
<% if @token.oob? and not @token.oauth10? %>
|
||||
<p><%= t ".verification", :code => @token.verifier %></p>
|
||||
<% end %>
|
|
@ -1,11 +0,0 @@
|
|||
<%= f.text_field :name %>
|
||||
<%= f.text_field :url %>
|
||||
<%= f.text_field :callback_url %>
|
||||
<%= f.text_field :support_url %>
|
||||
<div class='mb-3'>
|
||||
<p><%= t ".requests" %></p>
|
||||
<% ClientApplication.all_permissions.each do |perm| %>
|
||||
<%= f.check_box perm %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= f.primary %>
|
|
@ -1,9 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t ".title" %></h1>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "settings_menu" %>
|
||||
|
||||
<%= bootstrap_form_for @client_application, :url => oauth_client_path(@client_application.user.display_name, @client_application), :html => { :method => :put } do |f| %>
|
||||
<%= render :partial => "form", :locals => { :f => f } %>
|
||||
<% end %>
|
|
@ -1,47 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t ".title" %></h1>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "settings_menu" %>
|
||||
|
||||
<% unless @tokens.empty? %>
|
||||
<h3><%= t ".my_tokens" %></h3>
|
||||
<p><%= t ".list_tokens" %></p>
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><%= t ".application" %></th>
|
||||
<th><%= t ".issued_at" %></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<% @tokens.each do |token| %>
|
||||
<tr>
|
||||
<td><%= link_to token.client_application.name, token.client_application.url %></td>
|
||||
<td><%= token.authorized_at %></td>
|
||||
<td>
|
||||
<%= form_tag({ :controller => "oauth", :action => "revoke" }) do %>
|
||||
<%= hidden_field_tag "token", token.token, :autocomplete => "off" %>
|
||||
<%= submit_tag t(".revoke"), :class => "btn btn-sm btn-primary" %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
<h3><%= t ".my_apps" %></h3>
|
||||
<% if @client_applications.empty? %>
|
||||
<p><%= t(".no_apps_html", :oauth => link_to(t(".oauth"), "https://oauth.net")) %></p>
|
||||
<% else %>
|
||||
<p><%= t ".registered_apps" %></p>
|
||||
<ul>
|
||||
<% @client_applications.each do |client| %>
|
||||
<li class="client_application">
|
||||
<%= link_to client.name, :action => :show, :id => client.id %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% if Settings.oauth_10_registration -%>
|
||||
<%= link_to t(".register_new"), { :action => :new }, :class => "btn btn-outline-primary" %>
|
||||
<% end -%>
|
|
@ -1,9 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t ".title" %></h1>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "settings_menu" %>
|
||||
|
||||
<%= bootstrap_form_for @client_application, :url => { :action => :create } do |f| %>
|
||||
<%= render :partial => "form", :locals => { :f => f } %>
|
||||
<% end %>
|
|
@ -1 +0,0 @@
|
|||
<p><%= t('.sorry', :type => @type) %></p>
|
|
@ -1,33 +0,0 @@
|
|||
<% content_for :heading do %>
|
||||
<h1><%= t(".title", :app_name => @client_application.name) %></h1>
|
||||
<% end %>
|
||||
|
||||
<%= render :partial => "settings_menu" %>
|
||||
|
||||
<dl class="row">
|
||||
<dt class="col-sm-3"><%= t ".key" %></dt>
|
||||
<dd class="col-sm-9"><%= @client_application.key %></dt>
|
||||
<dt class="col-sm-3"><%= t ".secret" %></dt>
|
||||
<dd class="col-sm-9"><%= @client_application.secret %></dd>
|
||||
<dt class="col-sm-3"><%= t ".url" %></dt>
|
||||
<dd class="col-sm-9">http<%= "s" if request.ssl? %>://<%= request.host_with_port %><%= @client_application.oauth_server.request_token_path %></dd>
|
||||
<dt class="col-sm-3"><%= t ".access_url" %></dt>
|
||||
<dd class="col-sm-9">http<%= "s" if request.ssl? %>://<%= request.host_with_port %><%= @client_application.oauth_server.access_token_path %></dd>
|
||||
<dt class="col-sm-3"><%= t ".authorize_url" %></dt>
|
||||
<dd class="col-sm-9">http<%= "s" if request.ssl? %>://<%= request.host_with_port %><%= @client_application.oauth_server.authorize_path %></dd>
|
||||
</dl>
|
||||
|
||||
<div>
|
||||
<p><%= t ".requests" %></p>
|
||||
<ul>
|
||||
<% @client_application.permissions.each do |perm| %>
|
||||
<li><%= t("activerecord.attributes.client_application.#{perm}") %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<p><%= t ".support_notice" %></p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= link_to t(".edit"), edit_oauth_client_path(@client_application.user.display_name, @client_application), :method => :get, :class => "btn btn-outline-primary" %>
|
||||
<%= link_to t(".delete"), oauth_client_path(@client_application.user.display_name, @client_application), :method => :delete, :data => { :confirm => t(".confirm") }, :class => "btn btn-outline-danger" %>
|
||||
</div>
|
|
@ -1,90 +0,0 @@
|
|||
require "oauth/controllers/provider_controller"
|
||||
require "oauth/helper"
|
||||
require "oauth/rack/oauth_filter"
|
||||
|
||||
Rails.configuration.middleware.use OAuth::Rack::OAuthFilter
|
||||
|
||||
module OAuth
|
||||
module Helper
|
||||
def escape(value)
|
||||
value.to_s.gsub(OAuth::RESERVED_CHARACTERS) do |c|
|
||||
c.bytes.map do |b|
|
||||
format("%%%02X", b)
|
||||
end.join
|
||||
end.force_encoding(Encoding::US_ASCII)
|
||||
end
|
||||
|
||||
def unescape(value)
|
||||
value.to_s.gsub(/%\h{2}/) do |c|
|
||||
c[1..].to_i(16).chr
|
||||
end.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
end
|
||||
|
||||
module RequestProxy
|
||||
class RackRequest
|
||||
def method
|
||||
request.request_method
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module OpenStreetMap
|
||||
module ProviderController
|
||||
def self.prepended(mod)
|
||||
super
|
||||
mod.singleton_class.prepend(OpenStreetMap::ProviderController::ClassMethods)
|
||||
end
|
||||
|
||||
def render(options = {})
|
||||
text = options.delete(:text)
|
||||
if text
|
||||
super(options.merge(:plain => text))
|
||||
elsif options.delete(:nothing)
|
||||
status = options.delete(:status) || :ok
|
||||
head status, options
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
def included(controller)
|
||||
controller.class_eval do
|
||||
def self.before_filter(...)
|
||||
before_action(...)
|
||||
end
|
||||
|
||||
def self.skip_before_filter(...)
|
||||
skip_before_action(...)
|
||||
end
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module OAuthFilter
|
||||
def oauth1_verify(request, options = {}, &block)
|
||||
signature = OAuth::Signature.build(request, options, &block)
|
||||
return false unless OauthNonce.remember(signature.request.nonce, signature.request.timestamp)
|
||||
|
||||
value = signature.verify
|
||||
if request.ssl? && !value
|
||||
http_request = request.dup
|
||||
http_request.define_singleton_method(:scheme) { "http" }
|
||||
http_request.define_singleton_method(:port) { 80 }
|
||||
signature = OAuth::Signature.build(http_request, options, &block)
|
||||
value = signature.verify
|
||||
end
|
||||
value
|
||||
rescue OAuth::Signature::UnknownSignatureMethod
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
OAuth::Controllers::ProviderController.prepend(OpenStreetMap::ProviderController)
|
||||
OAuth::Rack::OAuthFilter.prepend(OpenStreetMap::OAuthFilter)
|
|
@ -2598,7 +2598,6 @@ en:
|
|||
need_to_see_terms: "Your access to the API is temporarily suspended. Please log-in to the web interface to view the Contributor Terms. You do not need to agree, but you must view them."
|
||||
settings_menu:
|
||||
account_settings: Account Settings
|
||||
oauth1_settings: OAuth 1 settings
|
||||
oauth2_applications: OAuth 2 applications
|
||||
oauth2_authorizations: OAuth 2 authorizations
|
||||
muted_users: Muted Users
|
||||
|
@ -2624,28 +2623,6 @@ en:
|
|||
title: Log in with Wikipedia
|
||||
alt: Wikipedia logo
|
||||
oauth:
|
||||
authorize:
|
||||
title: "Authorize access to your account"
|
||||
request_access_html: "The application %{app_name} is requesting access to your account, %{user}. Please check whether you would like the application to have the following capabilities. You may choose as many or as few as you like."
|
||||
allow_to: "Allow the client application to:"
|
||||
allow_read_prefs: "read your user preferences."
|
||||
allow_write_prefs: "modify your user preferences."
|
||||
allow_write_diary: "create diary entries, comments and make friends."
|
||||
allow_write_api: "modify the map."
|
||||
allow_read_gpx: "read your private GPS traces."
|
||||
allow_write_gpx: "upload GPS traces."
|
||||
allow_write_notes: "modify notes."
|
||||
grant_access: "Grant Access"
|
||||
authorize_success:
|
||||
title: "Authorization request allowed"
|
||||
allowed_html: "You have granted application %{app_name} access to your account."
|
||||
verification: "The verification code is %{code}."
|
||||
authorize_failure:
|
||||
title: "Authorization request failed"
|
||||
denied: "You have denied application %{app_name} access to your account."
|
||||
invalid: "The authorization token is not valid."
|
||||
revoke:
|
||||
flash: "You've revoked the token for %{application}"
|
||||
permissions:
|
||||
missing: "You have not permitted the application access to this facility"
|
||||
scopes:
|
||||
|
@ -2664,46 +2641,6 @@ en:
|
|||
skip_authorization: Auto approve application
|
||||
for_roles:
|
||||
moderator: This permission is for actions available only to moderators
|
||||
oauth_clients:
|
||||
new:
|
||||
title: "Register a new application"
|
||||
disabled: "Registration of OAuth 1 applications has been disabled"
|
||||
edit:
|
||||
title: "Edit your application"
|
||||
show:
|
||||
title: "OAuth details for %{app_name}"
|
||||
key: "Consumer Key:"
|
||||
secret: "Consumer Secret:"
|
||||
url: "Request Token URL:"
|
||||
access_url: "Access Token URL:"
|
||||
authorize_url: "Authorise URL:"
|
||||
support_notice: "We support HMAC-SHA1 (recommended) and RSA-SHA1 signatures."
|
||||
edit: "Edit Details"
|
||||
delete: "Delete Client"
|
||||
confirm: "Are you sure?"
|
||||
requests: "Requesting the following permissions from the user:"
|
||||
index:
|
||||
title: "My OAuth Details"
|
||||
my_tokens: "My Authorised Applications"
|
||||
list_tokens: "The following tokens have been issued to applications in your name:"
|
||||
application: "Application Name"
|
||||
issued_at: "Issued At"
|
||||
revoke: "Revoke!"
|
||||
my_apps: "My Client Applications"
|
||||
no_apps_html: "Do you have an application you would like to register for use with us using the %{oauth} standard? You must register your web application before it can make OAuth requests to this service."
|
||||
oauth: OAuth
|
||||
registered_apps: "You have the following client applications registered:"
|
||||
register_new: "Register your application"
|
||||
form:
|
||||
requests: "Request the following permissions from the user:"
|
||||
not_found:
|
||||
sorry: "Sorry, that %{type} could not be found."
|
||||
create:
|
||||
flash: "Registered the information successfully"
|
||||
update:
|
||||
flash: "Updated the client information successfully"
|
||||
destroy:
|
||||
flash: "Destroyed the client application registration"
|
||||
oauth2_applications:
|
||||
index:
|
||||
title: "My Client Applications"
|
||||
|
|
|
@ -323,17 +323,6 @@ OpenStreetMap::Application.routes.draw do
|
|||
end
|
||||
resources :user_mutes, :only => [:index]
|
||||
|
||||
# oauth admin pages (i.e: for setting up new clients, etc...)
|
||||
scope "/user/:display_name" do
|
||||
resources :oauth_clients
|
||||
end
|
||||
match "/oauth/revoke" => "oauth#revoke", :via => [:get, :post]
|
||||
match "/oauth/authorize" => "oauth#authorize", :via => [:get, :post], :as => :authorize
|
||||
get "/oauth/token" => "oauth#token", :as => :token
|
||||
match "/oauth/request_token" => "oauth#request_token", :via => [:get, :post], :as => :request_token
|
||||
match "/oauth/access_token" => "oauth#access_token", :via => [:get, :post], :as => :access_token
|
||||
get "/oauth/test_request" => "oauth#test_request", :as => :test_request
|
||||
|
||||
# roles and banning pages
|
||||
post "/user/:display_name/role/:role/grant" => "user_roles#grant", :as => "grant_role"
|
||||
post "/user/:display_name/role/:role/revoke" => "user_roles#revoke", :as => "revoke_role"
|
||||
|
|
|
@ -108,12 +108,6 @@ attachments_dir: ":rails_root/public/attachments"
|
|||
#memcache_servers: []
|
||||
# Enable HTTP basic authentication support
|
||||
basic_auth_support: true
|
||||
# Enable OAuth 1.0/1.0a registration
|
||||
oauth_10_registration: true
|
||||
# Enable legacy OAuth 1.0 support
|
||||
oauth_10_support: true
|
||||
# Enable OAuth 1.0a support
|
||||
oauth_10a_support: true
|
||||
# URL of Nominatim instance to use for geocoding
|
||||
nominatim_url: "https://nominatim.openstreetmap.org/"
|
||||
# Default editor
|
||||
|
|
38
db/migrate/20240724194738_drop_oauth1_tables.rb
Normal file
38
db/migrate/20240724194738_drop_oauth1_tables.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
class DropOauth1Tables < ActiveRecord::Migration[7.1]
|
||||
def change
|
||||
remove_index :oauth_nonces, [:nonce, :timestamp], :unique => true
|
||||
|
||||
drop_table :oauth_nonces do |t|
|
||||
t.string :nonce
|
||||
t.integer :timestamp
|
||||
|
||||
t.timestamps :null => true
|
||||
end
|
||||
|
||||
remove_index :oauth_tokens, :token, :unique => true
|
||||
|
||||
drop_table :oauth_tokens do |t|
|
||||
t.integer :user_id
|
||||
t.string :type, :limit => 20
|
||||
t.integer :client_application_id
|
||||
t.string :token, :limit => 50
|
||||
t.string :secret, :limit => 50
|
||||
t.timestamp :authorized_at, :invalidated_at
|
||||
t.timestamps :null => true
|
||||
end
|
||||
|
||||
remove_index :client_applications, :key, :unique => true
|
||||
|
||||
drop_table :client_applications do |t|
|
||||
t.string :name
|
||||
t.string :url
|
||||
t.string :support_url
|
||||
t.string :callback_url
|
||||
t.string :key, :limit => 50
|
||||
t.string :secret, :limit => 50
|
||||
t.integer :user_id
|
||||
|
||||
t.timestamps :null => true
|
||||
end
|
||||
end
|
||||
end
|
231
db/structure.sql
231
db/structure.sql
|
@ -472,51 +472,6 @@ CREATE TABLE public.changesets_subscribers (
|
|||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: client_applications; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.client_applications (
|
||||
id integer NOT NULL,
|
||||
name character varying,
|
||||
url character varying,
|
||||
support_url character varying,
|
||||
callback_url character varying,
|
||||
key character varying(50),
|
||||
secret character varying(50),
|
||||
user_id integer,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
allow_read_prefs boolean DEFAULT false NOT NULL,
|
||||
allow_write_prefs boolean DEFAULT false NOT NULL,
|
||||
allow_write_diary boolean DEFAULT false NOT NULL,
|
||||
allow_write_api boolean DEFAULT false NOT NULL,
|
||||
allow_read_gpx boolean DEFAULT false NOT NULL,
|
||||
allow_write_gpx boolean DEFAULT false NOT NULL,
|
||||
allow_write_notes boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: client_applications_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.client_applications_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: client_applications_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.client_applications_id_seq OWNED BY public.client_applications.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: current_node_tags; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1244,38 +1199,6 @@ CREATE SEQUENCE public.oauth_applications_id_seq
|
|||
ALTER SEQUENCE public.oauth_applications_id_seq OWNED BY public.oauth_applications.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_nonces; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.oauth_nonces (
|
||||
id bigint NOT NULL,
|
||||
nonce character varying,
|
||||
"timestamp" integer,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_nonces_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.oauth_nonces_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_nonces_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.oauth_nonces_id_seq OWNED BY public.oauth_nonces.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_openid_requests; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1306,55 +1229,6 @@ CREATE SEQUENCE public.oauth_openid_requests_id_seq
|
|||
ALTER SEQUENCE public.oauth_openid_requests_id_seq OWNED BY public.oauth_openid_requests.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.oauth_tokens (
|
||||
id integer NOT NULL,
|
||||
user_id integer,
|
||||
type character varying(20),
|
||||
client_application_id integer,
|
||||
token character varying(50),
|
||||
secret character varying(50),
|
||||
authorized_at timestamp without time zone,
|
||||
invalidated_at timestamp without time zone,
|
||||
created_at timestamp without time zone,
|
||||
updated_at timestamp without time zone,
|
||||
allow_read_prefs boolean DEFAULT false NOT NULL,
|
||||
allow_write_prefs boolean DEFAULT false NOT NULL,
|
||||
allow_write_diary boolean DEFAULT false NOT NULL,
|
||||
allow_write_api boolean DEFAULT false NOT NULL,
|
||||
allow_read_gpx boolean DEFAULT false NOT NULL,
|
||||
allow_write_gpx boolean DEFAULT false NOT NULL,
|
||||
callback_url character varying,
|
||||
verifier character varying(20),
|
||||
scope character varying,
|
||||
valid_to timestamp without time zone,
|
||||
allow_write_notes boolean DEFAULT false NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.oauth_tokens_id_seq
|
||||
AS integer
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.oauth_tokens_id_seq OWNED BY public.oauth_tokens.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: redactions; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1728,13 +1602,6 @@ ALTER TABLE ONLY public.changeset_comments ALTER COLUMN id SET DEFAULT nextval('
|
|||
ALTER TABLE ONLY public.changesets ALTER COLUMN id SET DEFAULT nextval('public.changesets_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: client_applications id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.client_applications ALTER COLUMN id SET DEFAULT nextval('public.client_applications_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: current_nodes id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1854,13 +1721,6 @@ ALTER TABLE ONLY public.oauth_access_tokens ALTER COLUMN id SET DEFAULT nextval(
|
|||
ALTER TABLE ONLY public.oauth_applications ALTER COLUMN id SET DEFAULT nextval('public.oauth_applications_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_nonces id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.oauth_nonces ALTER COLUMN id SET DEFAULT nextval('public.oauth_nonces_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_openid_requests id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1868,13 +1728,6 @@ ALTER TABLE ONLY public.oauth_nonces ALTER COLUMN id SET DEFAULT nextval('public
|
|||
ALTER TABLE ONLY public.oauth_openid_requests ALTER COLUMN id SET DEFAULT nextval('public.oauth_openid_requests_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.oauth_tokens ALTER COLUMN id SET DEFAULT nextval('public.oauth_tokens_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: redactions id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1981,14 +1834,6 @@ ALTER TABLE ONLY public.changesets
|
|||
ADD CONSTRAINT changesets_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: client_applications client_applications_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.client_applications
|
||||
ADD CONSTRAINT client_applications_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: current_node_tags current_node_tags_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2197,14 +2042,6 @@ ALTER TABLE ONLY public.oauth_applications
|
|||
ADD CONSTRAINT oauth_applications_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_nonces oauth_nonces_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.oauth_nonces
|
||||
ADD CONSTRAINT oauth_nonces_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_openid_requests oauth_openid_requests_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2213,14 +2050,6 @@ ALTER TABLE ONLY public.oauth_openid_requests
|
|||
ADD CONSTRAINT oauth_openid_requests_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens oauth_tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.oauth_tokens
|
||||
ADD CONSTRAINT oauth_tokens_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: redactions redactions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2585,20 +2414,6 @@ CREATE INDEX index_changesets_subscribers_on_changeset_id ON public.changesets_s
|
|||
CREATE UNIQUE INDEX index_changesets_subscribers_on_subscriber_id_and_changeset_id ON public.changesets_subscribers USING btree (subscriber_id, changeset_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_client_applications_on_key; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_client_applications_on_key ON public.client_applications USING btree (key);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_client_applications_on_user_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_client_applications_on_user_id ON public.client_applications USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_diary_entry_subscriptions_on_diary_entry_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2746,13 +2561,6 @@ CREATE INDEX index_oauth_applications_on_owner_type_and_owner_id ON public.oauth
|
|||
CREATE UNIQUE INDEX index_oauth_applications_on_uid ON public.oauth_applications USING btree (uid);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_oauth_nonces_on_nonce_and_timestamp; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_oauth_nonces_on_nonce_and_timestamp ON public.oauth_nonces USING btree (nonce, "timestamp");
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_oauth_openid_requests_on_access_grant_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2760,20 +2568,6 @@ CREATE UNIQUE INDEX index_oauth_nonces_on_nonce_and_timestamp ON public.oauth_no
|
|||
CREATE INDEX index_oauth_openid_requests_on_access_grant_id ON public.oauth_openid_requests USING btree (access_grant_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_oauth_tokens_on_token; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_oauth_tokens_on_token ON public.oauth_tokens USING btree (token);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_oauth_tokens_on_user_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_oauth_tokens_on_user_id ON public.oauth_tokens USING btree (user_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_reports_on_issue_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3032,14 +2826,6 @@ ALTER TABLE ONLY public.changesets
|
|||
ADD CONSTRAINT changesets_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: client_applications client_applications_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.client_applications
|
||||
ADD CONSTRAINT client_applications_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: current_node_tags current_node_tags_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3376,22 +3162,6 @@ ALTER TABLE ONLY public.note_comments
|
|||
ADD CONSTRAINT note_comments_note_id_fkey FOREIGN KEY (note_id) REFERENCES public.notes(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens oauth_tokens_client_application_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.oauth_tokens
|
||||
ADD CONSTRAINT oauth_tokens_client_application_id_fkey FOREIGN KEY (client_application_id) REFERENCES public.client_applications(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: oauth_tokens oauth_tokens_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.oauth_tokens
|
||||
ADD CONSTRAINT oauth_tokens_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: redactions redactions_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -3581,6 +3351,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('21'),
|
||||
('20240822121603'),
|
||||
('20240813070506'),
|
||||
('20240724194738'),
|
||||
('20240618193051'),
|
||||
('20240605134916'),
|
||||
('20240405083825'),
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
namespace :db do
|
||||
desc "Expire old tokens"
|
||||
task :expire_tokens => :environment do
|
||||
OauthNonce.where("timestamp < EXTRACT(EPOCH FROM NOW() - INTERVAL '1 day')").delete_all
|
||||
OauthToken.where("invalidated_at < NOW() - INTERVAL '28 days'").delete_all
|
||||
RequestToken.where("authorized_at IS NULL AND created_at < NOW() - INTERVAL '28 days'").delete_all
|
||||
Doorkeeper::AccessGrant.where("revoked_at < NOW() - INTERVAL '28 days' OR (created_at + expires_in * INTERVAL '1 second') < NOW() - INTERVAL '28 days'").delete_all
|
||||
Doorkeeper::AccessToken.where("revoked_at < NOW() - INTERVAL '28 days' OR (created_at + expires_in * INTERVAL '1 second') < NOW() - INTERVAL '28 days'").delete_all
|
||||
end
|
||||
|
|
|
@ -37,9 +37,9 @@ module Api
|
|||
get permissions_path, :headers => auth_header
|
||||
assert_response :success
|
||||
assert_select "osm > permissions", :count => 1 do
|
||||
assert_select "permission", :count => ClientApplication.all_permissions.size
|
||||
ClientApplication.all_permissions.each do |p|
|
||||
assert_select "permission[name='#{p}']", :count => 1
|
||||
assert_select "permission", :count => Oauth.scopes.size
|
||||
Oauth.scopes.each do |p|
|
||||
assert_select "permission[name='allow_#{p.name}']", :count => 1
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -50,24 +50,9 @@ module Api
|
|||
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
assert_equal ClientApplication.all_permissions.size, js["permissions"].count
|
||||
ClientApplication.all_permissions.each do |p|
|
||||
assert_includes js["permissions"], p.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def test_permissions_oauth1
|
||||
token = create(:access_token,
|
||||
:allow_read_prefs => true,
|
||||
:allow_write_api => true,
|
||||
:allow_read_gpx => false)
|
||||
signed_get permissions_path, :oauth => { :token => token }
|
||||
assert_response :success
|
||||
assert_select "osm > permissions", :count => 1 do
|
||||
assert_select "permission", :count => 2
|
||||
assert_select "permission[name='allow_read_prefs']", :count => 1
|
||||
assert_select "permission[name='allow_write_api']", :count => 1
|
||||
assert_select "permission[name='allow_read_gpx']", :count => 0
|
||||
assert_equal Oauth.scopes.size, js["permissions"].count
|
||||
Oauth.scopes.each do |p|
|
||||
assert_includes js["permissions"], "allow_#{p.name}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -75,80 +75,6 @@ module Api
|
|||
check_json_details(js, user, false, false)
|
||||
end
|
||||
|
||||
def test_show_oauth1
|
||||
user = create(:user,
|
||||
:home_lat => 12.1, :home_lon => 23.4,
|
||||
:languages => ["en"])
|
||||
good_token = create(:access_token,
|
||||
:user => user,
|
||||
:allow_read_prefs => true)
|
||||
bad_token = create(:access_token,
|
||||
:user => user)
|
||||
other_user = create(:user,
|
||||
:home_lat => 12.1, :home_lon => 23.4,
|
||||
:languages => ["en"])
|
||||
|
||||
# check that we can fetch our own details as XML with read_prefs
|
||||
signed_get api_user_path(:id => user.id), :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
|
||||
# check the data that is returned
|
||||
check_xml_details(user, true, false)
|
||||
|
||||
# check that we can fetch a different user's details as XML with read_prefs
|
||||
signed_get api_user_path(:id => other_user.id), :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
|
||||
# check the data that is returned
|
||||
check_xml_details(other_user, false, false)
|
||||
|
||||
# check that we can fetch our own details as XML without read_prefs
|
||||
signed_get api_user_path(:id => user.id), :oauth => { :token => bad_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
|
||||
# check the data that is returned
|
||||
check_xml_details(user, false, false)
|
||||
|
||||
# check that we can fetch our own details as JSON with read_prefs
|
||||
signed_get api_user_path(:id => user.id, :format => "json"), :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
|
||||
# parse the response
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
|
||||
# check the data that is returned
|
||||
check_json_details(js, user, true, false)
|
||||
|
||||
# check that we can fetch a different user's details as JSON with read_prefs
|
||||
signed_get api_user_path(:id => other_user.id, :format => "json"), :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
|
||||
# parse the response
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
|
||||
# check the data that is returned
|
||||
check_json_details(js, other_user, false, false)
|
||||
|
||||
# check that we can fetch our own details as JSON without read_prefs
|
||||
signed_get api_user_path(:id => other_user.id, :format => "json"), :oauth => { :token => bad_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
|
||||
# parse the response
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
|
||||
# check the data that is returned
|
||||
check_json_details(js, other_user, false, false)
|
||||
end
|
||||
|
||||
def test_show_oauth2
|
||||
user = create(:user,
|
||||
:home_lat => 12.1, :home_lon => 23.4,
|
||||
|
@ -260,45 +186,6 @@ module Api
|
|||
check_json_details(js, user, true, false)
|
||||
end
|
||||
|
||||
def test_details_oauth1
|
||||
user = create(:user,
|
||||
:home_lat => 12.1, :home_lon => 23.4,
|
||||
:languages => ["en"])
|
||||
good_token = create(:access_token,
|
||||
:user => user,
|
||||
:allow_read_prefs => true)
|
||||
bad_token = create(:access_token,
|
||||
:user => user)
|
||||
|
||||
# check that we can't fetch details as XML without read_prefs
|
||||
signed_get user_details_path, :oauth => { :token => bad_token }
|
||||
assert_response :forbidden
|
||||
|
||||
# check that we can fetch details as XML
|
||||
signed_get user_details_path, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
|
||||
# check the data that is returned
|
||||
check_xml_details(user, true, false)
|
||||
|
||||
# check that we can't fetch details as JSON without read_prefs
|
||||
signed_get user_details_path(:format => "json"), :oauth => { :token => bad_token }
|
||||
assert_response :forbidden
|
||||
|
||||
# check that we can fetch details as JSON
|
||||
signed_get user_details_path(:format => "json"), :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
|
||||
# parse the response
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
|
||||
# check the data that is returned
|
||||
check_json_details(js, user, true, false)
|
||||
end
|
||||
|
||||
def test_details_oauth2
|
||||
user = create(:user,
|
||||
:home_lat => 12.1, :home_lon => 23.4,
|
||||
|
@ -434,99 +321,6 @@ module Api
|
|||
assert_select "user", :count => 0
|
||||
end
|
||||
|
||||
def test_index_oauth1
|
||||
user1 = create(:user, :description => "test1", :terms_agreed => Date.yesterday)
|
||||
user2 = create(:user, :description => "test2", :terms_agreed => Date.yesterday)
|
||||
user3 = create(:user, :description => "test3", :terms_agreed => Date.yesterday)
|
||||
good_token = create(:access_token, :user => user1, :allow_read_prefs => true)
|
||||
bad_token = create(:access_token, :user => user1)
|
||||
|
||||
signed_get api_users_path, :params => { :users => user1.id }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 1 do
|
||||
check_xml_details(user1, true, false)
|
||||
assert_select "user[id='#{user2.id}']", :count => 0
|
||||
assert_select "user[id='#{user3.id}']", :count => 0
|
||||
end
|
||||
|
||||
signed_get api_users_path, :params => { :users => user2.id }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 1 do
|
||||
assert_select "user[id='#{user1.id}']", :count => 0
|
||||
check_xml_details(user2, false, false)
|
||||
assert_select "user[id='#{user3.id}']", :count => 0
|
||||
end
|
||||
|
||||
signed_get api_users_path, :params => { :users => "#{user1.id},#{user3.id}" }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 2 do
|
||||
check_xml_details(user1, true, false)
|
||||
assert_select "user[id='#{user2.id}']", :count => 0
|
||||
check_xml_details(user3, false, false)
|
||||
end
|
||||
|
||||
signed_get api_users_path, :params => { :users => "#{user1.id},#{user3.id}" }, :oauth => { :token => bad_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 2 do
|
||||
check_xml_details(user1, false, false)
|
||||
assert_select "user[id='#{user2.id}']", :count => 0
|
||||
check_xml_details(user3, false, false)
|
||||
end
|
||||
|
||||
signed_get api_users_path, :params => { :users => user1.id, :format => "json" }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
assert_equal 1, js["users"].count
|
||||
check_json_details(js["users"][0], user1, true, false)
|
||||
|
||||
signed_get api_users_path, :params => { :users => user2.id, :format => "json" }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
assert_equal 1, js["users"].count
|
||||
check_json_details(js["users"][0], user2, false, false)
|
||||
|
||||
signed_get api_users_path, :params => { :users => "#{user1.id},#{user3.id}", :format => "json" }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
assert_equal 2, js["users"].count
|
||||
check_json_details(js["users"][0], user1, true, false)
|
||||
check_json_details(js["users"][1], user3, false, false)
|
||||
|
||||
signed_get api_users_path, :params => { :users => "#{user1.id},#{user3.id}", :format => "json" }, :oauth => { :token => bad_token }
|
||||
assert_response :success
|
||||
assert_equal "application/json", response.media_type
|
||||
js = ActiveSupport::JSON.decode(@response.body)
|
||||
assert_not_nil js
|
||||
assert_equal 2, js["users"].count
|
||||
check_json_details(js["users"][0], user1, false, false)
|
||||
check_json_details(js["users"][1], user3, false, false)
|
||||
|
||||
signed_get api_users_path, :params => { :users => create(:user, :suspended).id }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 0
|
||||
|
||||
signed_get api_users_path, :params => { :users => create(:user, :deleted).id }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 0
|
||||
|
||||
signed_get api_users_path, :params => { :users => 0 }, :oauth => { :token => good_token }
|
||||
assert_response :success
|
||||
assert_equal "application/xml", response.media_type
|
||||
assert_select "user", :count => 0
|
||||
end
|
||||
|
||||
def test_index_oauth2
|
||||
user1 = create(:user, :description => "test1", :terms_agreed => Date.yesterday)
|
||||
user2 = create(:user, :description => "test2", :terms_agreed => Date.yesterday)
|
||||
|
|
|
@ -1,204 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class OauthClientsControllerTest < ActionDispatch::IntegrationTest
|
||||
##
|
||||
# test all routes which lead to this controller
|
||||
def test_routes
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients", :method => :get },
|
||||
{ :controller => "oauth_clients", :action => "index", :display_name => "username" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients/new", :method => :get },
|
||||
{ :controller => "oauth_clients", :action => "new", :display_name => "username" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients", :method => :post },
|
||||
{ :controller => "oauth_clients", :action => "create", :display_name => "username" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients/1", :method => :get },
|
||||
{ :controller => "oauth_clients", :action => "show", :display_name => "username", :id => "1" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients/1/edit", :method => :get },
|
||||
{ :controller => "oauth_clients", :action => "edit", :display_name => "username", :id => "1" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients/1", :method => :put },
|
||||
{ :controller => "oauth_clients", :action => "update", :display_name => "username", :id => "1" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/user/username/oauth_clients/1", :method => :delete },
|
||||
{ :controller => "oauth_clients", :action => "destroy", :display_name => "username", :id => "1" }
|
||||
)
|
||||
end
|
||||
|
||||
def test_index
|
||||
user = create(:user)
|
||||
create_list(:client_application, 2, :user => user)
|
||||
create_list(:access_token, 2, :user => user)
|
||||
|
||||
get oauth_clients_path(user)
|
||||
assert_redirected_to login_path(:referer => oauth_clients_path(user))
|
||||
|
||||
session_for(user)
|
||||
|
||||
get oauth_clients_path(user)
|
||||
assert_response :success
|
||||
assert_template "index"
|
||||
assert_select "li.client_application", 2
|
||||
end
|
||||
|
||||
def test_new
|
||||
user = create(:user)
|
||||
|
||||
get new_oauth_client_path(user)
|
||||
assert_redirected_to login_path(:referer => new_oauth_client_path(user))
|
||||
|
||||
session_for(user)
|
||||
|
||||
get new_oauth_client_path(user)
|
||||
assert_response :success
|
||||
assert_template "new"
|
||||
assert_select "form", 1 do
|
||||
assert_select "input#client_application_name", 1
|
||||
assert_select "input#client_application_url", 1
|
||||
assert_select "input#client_application_callback_url", 1
|
||||
assert_select "input#client_application_support_url", 1
|
||||
ClientApplication.all_permissions.each do |perm|
|
||||
assert_select "input#client_application_#{perm}", 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_new_disabled
|
||||
user = create(:user)
|
||||
|
||||
with_settings(:oauth_10_registration => false) do
|
||||
get new_oauth_client_path(user)
|
||||
assert_redirected_to login_path(:referer => new_oauth_client_path(user))
|
||||
|
||||
session_for(user)
|
||||
|
||||
get new_oauth_client_path(user)
|
||||
assert_redirected_to oauth_clients_path(user)
|
||||
end
|
||||
end
|
||||
|
||||
def test_create
|
||||
user = create(:user)
|
||||
|
||||
assert_difference "ClientApplication.count", 0 do
|
||||
post oauth_clients_path(user)
|
||||
end
|
||||
assert_response :forbidden
|
||||
|
||||
session_for(user)
|
||||
|
||||
assert_difference "ClientApplication.count", 0 do
|
||||
post oauth_clients_path(user, :client_application => { :name => "Test Application" })
|
||||
end
|
||||
assert_response :success
|
||||
assert_template "new"
|
||||
|
||||
assert_difference "ClientApplication.count", 1 do
|
||||
post oauth_clients_path(user, :client_application => { :name => "Test Application",
|
||||
:url => "http://test.example.com/" })
|
||||
end
|
||||
assert_redirected_to oauth_client_path(:id => ClientApplication.find_by(:name => "Test Application").id)
|
||||
end
|
||||
|
||||
def test_show
|
||||
user = create(:user)
|
||||
client = create(:client_application, :user => user)
|
||||
other_client = create(:client_application)
|
||||
|
||||
get oauth_client_path(user, client)
|
||||
assert_redirected_to login_path(:referer => oauth_client_path(user, client.id))
|
||||
|
||||
session_for(user)
|
||||
|
||||
get oauth_client_path(user, other_client)
|
||||
assert_response :not_found
|
||||
assert_template "not_found"
|
||||
|
||||
get oauth_client_path(user, client)
|
||||
assert_response :success
|
||||
assert_template "show"
|
||||
end
|
||||
|
||||
def test_edit
|
||||
user = create(:user)
|
||||
client = create(:client_application, :user => user)
|
||||
other_client = create(:client_application)
|
||||
|
||||
get edit_oauth_client_path(user, client)
|
||||
assert_redirected_to login_path(:referer => edit_oauth_client_path(user, client.id))
|
||||
|
||||
session_for(user)
|
||||
|
||||
get edit_oauth_client_path(user, other_client)
|
||||
assert_response :not_found
|
||||
assert_template "not_found"
|
||||
|
||||
get edit_oauth_client_path(user, client)
|
||||
assert_response :success
|
||||
assert_template "edit"
|
||||
assert_select "form", 1 do
|
||||
assert_select "input#client_application_name", 1
|
||||
assert_select "input#client_application_url", 1
|
||||
assert_select "input#client_application_callback_url", 1
|
||||
assert_select "input#client_application_support_url", 1
|
||||
ClientApplication.all_permissions.each do |perm|
|
||||
assert_select "input#client_application_#{perm}", 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_update
|
||||
user = create(:user)
|
||||
client = create(:client_application, :user => user)
|
||||
other_client = create(:client_application)
|
||||
|
||||
put oauth_client_path(user, client)
|
||||
assert_response :forbidden
|
||||
|
||||
session_for(user)
|
||||
|
||||
put oauth_client_path(user, other_client)
|
||||
assert_response :not_found
|
||||
assert_template "not_found"
|
||||
|
||||
put oauth_client_path(user, client, :client_application => { :name => "New Name", :url => nil })
|
||||
assert_response :success
|
||||
assert_template "edit"
|
||||
|
||||
put oauth_client_path(user, client, :client_application => { :name => "New Name", :url => "http://new.example.com/url" })
|
||||
assert_redirected_to oauth_client_path(:id => client.id)
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
user = create(:user)
|
||||
client = create(:client_application, :user => user)
|
||||
other_client = create(:client_application)
|
||||
|
||||
assert_difference "ClientApplication.count", 0 do
|
||||
delete oauth_client_path(user, client)
|
||||
end
|
||||
assert_response :forbidden
|
||||
|
||||
session_for(user)
|
||||
|
||||
assert_difference "ClientApplication.count", 0 do
|
||||
delete oauth_client_path(user, other_client)
|
||||
end
|
||||
assert_response :not_found
|
||||
assert_template "not_found"
|
||||
|
||||
assert_difference "ClientApplication.count", -1 do
|
||||
delete oauth_client_path(user, client)
|
||||
end
|
||||
assert_redirected_to oauth_clients_path(user)
|
||||
end
|
||||
end
|
|
@ -1,48 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class OauthControllerTest < ActionDispatch::IntegrationTest
|
||||
##
|
||||
# test all routes which lead to this controller
|
||||
def test_routes
|
||||
assert_routing(
|
||||
{ :path => "/oauth/revoke", :method => :get },
|
||||
{ :controller => "oauth", :action => "revoke" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/revoke", :method => :post },
|
||||
{ :controller => "oauth", :action => "revoke" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/authorize", :method => :get },
|
||||
{ :controller => "oauth", :action => "authorize" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/authorize", :method => :post },
|
||||
{ :controller => "oauth", :action => "authorize" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/token", :method => :get },
|
||||
{ :controller => "oauth", :action => "token" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/request_token", :method => :get },
|
||||
{ :controller => "oauth", :action => "request_token" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/request_token", :method => :post },
|
||||
{ :controller => "oauth", :action => "request_token" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/access_token", :method => :get },
|
||||
{ :controller => "oauth", :action => "access_token" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/access_token", :method => :post },
|
||||
{ :controller => "oauth", :action => "access_token" }
|
||||
)
|
||||
assert_routing(
|
||||
{ :path => "/oauth/test_request", :method => :get },
|
||||
{ :controller => "oauth", :action => "test_request" }
|
||||
)
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
FactoryBot.define do
|
||||
factory :client_application do
|
||||
sequence(:name) { |n| "Client application #{n}" }
|
||||
sequence(:url) { |n| "http://example.com/app/#{n}" }
|
||||
|
||||
user
|
||||
end
|
||||
end
|
|
@ -1,91 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class ClientApplicationsTest < ActionDispatch::IntegrationTest
|
||||
##
|
||||
# run through the procedure of creating a client application and checking
|
||||
# that it shows up on the user's account page.
|
||||
def test_create_application
|
||||
user = create(:user)
|
||||
|
||||
get "/login"
|
||||
assert_redirected_to login_path(:cookie_test => "true")
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
post "/login", :params => { "username" => user.email, "password" => "test", :referer => "/user/#{ERB::Util.u(user.display_name)}" }
|
||||
assert_response :redirect
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
assert_template "users/show"
|
||||
get "/account/edit"
|
||||
assert_response :success
|
||||
assert_template "accounts/edit"
|
||||
|
||||
# check that the form to allow new client application creations exists
|
||||
assert_in_heading do
|
||||
assert_select "ul.nav.nav-tabs li.nav-item a[href='/user/#{ERB::Util.u(user.display_name)}/oauth_clients']"
|
||||
end
|
||||
|
||||
# now we follow the link to the oauth client list
|
||||
get "/user/#{ERB::Util.u(user.display_name)}/oauth_clients"
|
||||
assert_response :success
|
||||
assert_in_body do
|
||||
assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/oauth_clients/new']"
|
||||
end
|
||||
|
||||
# now we follow the link to the new oauth client page
|
||||
get "/user/#{ERB::Util.u(user.display_name)}/oauth_clients/new"
|
||||
assert_response :success
|
||||
assert_in_heading do
|
||||
assert_select "h1", "Register a new application"
|
||||
end
|
||||
assert_in_body do
|
||||
assert_select "form[action='/user/#{ERB::Util.u(user.display_name)}/oauth_clients']" do
|
||||
[:name, :url, :callback_url, :support_url].each do |inp|
|
||||
assert_select "input[name=?]", "client_application[#{inp}]"
|
||||
end
|
||||
ClientApplication.all_permissions.each do |perm|
|
||||
assert_select "input[name=?]", "client_application[#{perm}]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
post "/user/#{ERB::Util.u(user.display_name)}/oauth_clients",
|
||||
:params => { "client_application[name]" => "My New App",
|
||||
"client_application[url]" => "http://my.new.app.org/",
|
||||
"client_application[callback_url]" => "http://my.new.app.org/callback",
|
||||
"client_application[support_url]" => "http://my.new.app.org/support" }
|
||||
assert_response :redirect
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
assert_template "oauth_clients/show"
|
||||
assert_equal "Registered the information successfully", flash[:notice]
|
||||
|
||||
# now go back to the account page and check its listed under this user
|
||||
get "/user/#{ERB::Util.u(user.display_name)}/oauth_clients"
|
||||
assert_response :success
|
||||
assert_template "oauth_clients/index"
|
||||
assert_in_body { assert_select "li>a", "My New App" }
|
||||
end
|
||||
|
||||
##
|
||||
# fake client workflow.
|
||||
# this acts like a 3rd party client trying to access the site.
|
||||
def test_3rd_party_token
|
||||
# apparently the oauth gem doesn't really support being used inside integration
|
||||
# tests, as its too tied into the HTTP headers and stuff that it signs.
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
##
|
||||
# utility method to make the HTML screening easier to read.
|
||||
def assert_in_heading(&block)
|
||||
assert_select("div.content-heading", &block)
|
||||
end
|
||||
|
||||
##
|
||||
# utility method to make the HTML screening easier to read.
|
||||
def assert_in_body(&block)
|
||||
assert_select("div#content", &block)
|
||||
end
|
||||
end
|
|
@ -1,421 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class OAuthTest < ActionDispatch::IntegrationTest
|
||||
include OAuth::Helper
|
||||
|
||||
def test_oauth10_web_app
|
||||
client = create(:client_application, :callback_url => "http://some.web.app.example.org/callback", :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
|
||||
user = create(:user)
|
||||
|
||||
session_for(user)
|
||||
|
||||
oauth10_without_callback(client)
|
||||
oauth10_with_callback(client, "http://another.web.app.example.org/callback")
|
||||
oauth10_refused(client)
|
||||
end
|
||||
|
||||
def test_oauth10_desktop_app
|
||||
client = create(:client_application, :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
|
||||
user = create(:user)
|
||||
|
||||
session_for(user)
|
||||
|
||||
oauth10_without_callback(client)
|
||||
oauth10_refused(client)
|
||||
end
|
||||
|
||||
def test_oauth10a_web_app
|
||||
client = create(:client_application, :callback_url => "http://some.web.app.example.org/callback", :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
|
||||
user = create(:user)
|
||||
|
||||
session_for(user)
|
||||
|
||||
oauth10a_without_callback(client)
|
||||
oauth10a_with_callback(client, "http://another.web.app.example.org/callback")
|
||||
oauth10a_refused(client)
|
||||
end
|
||||
|
||||
def test_oauth10a_desktop_app
|
||||
client = create(:client_application, :allow_read_prefs => true, :allow_write_api => true, :allow_read_gpx => true)
|
||||
user = create(:user)
|
||||
|
||||
session_for(user)
|
||||
|
||||
oauth10a_without_callback(client)
|
||||
oauth10a_refused(client)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def oauth10_without_callback(client)
|
||||
token = get_request_token(client)
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize
|
||||
|
||||
post "/oauth/authorize",
|
||||
:params => { :oauth_token => token.token,
|
||||
:allow_read_prefs => "1", :allow_write_prefs => "1" }
|
||||
if client.callback_url
|
||||
assert_redirected_to "#{client.callback_url}?oauth_token=#{token.token}"
|
||||
else
|
||||
assert_response :success
|
||||
assert_template :authorize_success
|
||||
end
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_read_prefs]
|
||||
|
||||
signed_get "/oauth/access_token", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
token = parse_token(response)
|
||||
assert_instance_of AccessToken, token
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_read_prefs]
|
||||
|
||||
post logout_path
|
||||
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
signed_get "/api/0.6/gpx/2", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.suspend!
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.hide!
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.unhide!
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
session_for(token.user)
|
||||
|
||||
post "/oauth/revoke", :params => { :token => token.token }
|
||||
assert_redirected_to oauth_clients_url(token.user.display_name)
|
||||
token = OauthToken.find_by(:token => token.token)
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
def oauth10_refused(client)
|
||||
token = get_request_token(client)
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize
|
||||
|
||||
post "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize_failure
|
||||
assert_select "p", "You have denied application #{client.name} access to your account."
|
||||
token.reload
|
||||
assert_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize_failure
|
||||
assert_select "p", "The authorization token is not valid."
|
||||
token.reload
|
||||
assert_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
post "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize_failure
|
||||
assert_select "p", "The authorization token is not valid."
|
||||
token.reload
|
||||
assert_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
end
|
||||
|
||||
def oauth10_with_callback(client, callback_url)
|
||||
token = get_request_token(client)
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize
|
||||
|
||||
post "/oauth/authorize",
|
||||
:params => { :oauth_token => token.token, :oauth_callback => callback_url,
|
||||
:allow_write_api => "1", :allow_read_gpx => "1" }
|
||||
assert_redirected_to "#{callback_url}?oauth_token=#{token.token}"
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_write_api, :allow_read_gpx]
|
||||
|
||||
signed_get "/oauth/access_token", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
token = parse_token(response)
|
||||
assert_instance_of AccessToken, token
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_write_api, :allow_read_gpx]
|
||||
|
||||
post logout_path
|
||||
|
||||
trace = create(:trace, :user => token.user)
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
signed_get "/api/0.6/user/details", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.suspend!
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.hide!
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.unhide!
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
session_for(token.user)
|
||||
|
||||
post "/oauth/revoke", :params => { :token => token.token }
|
||||
assert_redirected_to oauth_clients_url(token.user.display_name)
|
||||
token = OauthToken.find_by(:token => token.token)
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
signed_get "/api/0.6/gpx/2", :oauth => { :token => token }
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
def oauth10a_without_callback(client)
|
||||
token = get_request_token(client, :oauth_callback => "oob")
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize
|
||||
|
||||
post "/oauth/authorize",
|
||||
:params => { :oauth_token => token.token,
|
||||
:allow_read_prefs => "1", :allow_write_prefs => "1" }
|
||||
if client.callback_url
|
||||
assert_response :redirect
|
||||
verifier = parse_verifier(response)
|
||||
assert_redirected_to "http://some.web.app.example.org/callback?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
|
||||
else
|
||||
assert_response :success
|
||||
assert_template :authorize_success
|
||||
m = response.body.match("<p>The verification code is ([A-Za-z0-9]+).</p>")
|
||||
assert_not_nil m
|
||||
verifier = m[1]
|
||||
end
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_read_prefs]
|
||||
|
||||
signed_get "/oauth/access_token", :oauth => { :token => token }
|
||||
assert_response :unauthorized
|
||||
|
||||
signed_get "/oauth/access_token", :oauth => { :token => token, :oauth_verifier => verifier }
|
||||
assert_response :success
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
token = parse_token(response)
|
||||
assert_instance_of AccessToken, token
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_read_prefs]
|
||||
|
||||
post logout_path
|
||||
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
trace = create(:trace, :user => token.user)
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.suspend!
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.hide!
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.unhide!
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
session_for(token.user)
|
||||
|
||||
post "/oauth/revoke", :params => { :token => token.token }
|
||||
assert_redirected_to oauth_clients_url(token.user.display_name)
|
||||
token = OauthToken.find_by(:token => token.token)
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
signed_get "/api/0.6/user/preferences", :oauth => { :token => token }
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
def oauth10a_with_callback(client, callback_url)
|
||||
token = get_request_token(client, :oauth_callback => callback_url)
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize
|
||||
|
||||
post "/oauth/authorize",
|
||||
:params => { :oauth_token => token.token,
|
||||
:allow_write_api => "1", :allow_read_gpx => "1" }
|
||||
assert_response :redirect
|
||||
verifier = parse_verifier(response)
|
||||
assert_redirected_to "#{callback_url}?oauth_token=#{token.token}&oauth_verifier=#{verifier}"
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_write_api, :allow_read_gpx]
|
||||
|
||||
signed_get "/oauth/access_token", :oauth => { :token => token }
|
||||
assert_response :unauthorized
|
||||
|
||||
signed_get "/oauth/access_token", :oauth => { :token => token, :oauth_verifier => verifier }
|
||||
assert_response :success
|
||||
token.reload
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
token = parse_token(response)
|
||||
assert_instance_of AccessToken, token
|
||||
assert_not_nil token.created_at
|
||||
assert_not_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_allowed token, [:allow_write_api, :allow_read_gpx]
|
||||
|
||||
post logout_path
|
||||
|
||||
trace = create(:trace, :user => token.user)
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
signed_get "/api/0.6/user/details", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.suspend!
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.hide!
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :forbidden
|
||||
|
||||
token.user.unhide!
|
||||
signed_get "/api/0.6/gpx/#{trace.id}", :oauth => { :token => token }
|
||||
assert_response :success
|
||||
|
||||
session_for(token.user)
|
||||
|
||||
post "/oauth/revoke", :params => { :token => token.token }
|
||||
assert_redirected_to oauth_clients_url(token.user.display_name)
|
||||
token = OauthToken.find_by(:token => token.token)
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
signed_get "/api/0.6/gpx/2", :oauth => { :token => token }
|
||||
assert_response :unauthorized
|
||||
end
|
||||
|
||||
def oauth10a_refused(client)
|
||||
token = get_request_token(client, :oauth_callback => "oob")
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize
|
||||
|
||||
post "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize_failure
|
||||
assert_select "p", "You have denied application #{client.name} access to your account."
|
||||
token.reload
|
||||
assert_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
get "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize_failure
|
||||
assert_select "p", "The authorization token is not valid."
|
||||
token.reload
|
||||
assert_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
|
||||
post "/oauth/authorize", :params => { :oauth_token => token.token }
|
||||
assert_response :success
|
||||
assert_template :authorize_failure
|
||||
assert_select "p", "The authorization token is not valid."
|
||||
token.reload
|
||||
assert_nil token.authorized_at
|
||||
assert_not_nil token.invalidated_at
|
||||
end
|
||||
|
||||
def get_request_token(client, options = {})
|
||||
signed_get "/oauth/request_token", :oauth => options.merge(:consumer => client)
|
||||
assert_response :success
|
||||
token = parse_token(response)
|
||||
assert_instance_of RequestToken, token
|
||||
assert_not_nil token.created_at
|
||||
assert_nil token.authorized_at
|
||||
assert_nil token.invalidated_at
|
||||
assert_equal_allowing_nil options[:oauth_callback], token.callback_url
|
||||
assert_allowed token, client.permissions
|
||||
|
||||
token
|
||||
end
|
||||
|
||||
def parse_token(response)
|
||||
params = CGI.parse(response.body)
|
||||
|
||||
token = OauthToken.find_by(:token => params["oauth_token"].first)
|
||||
assert_equal token.secret, params["oauth_token_secret"].first
|
||||
|
||||
token
|
||||
end
|
||||
|
||||
def parse_verifier(response)
|
||||
params = CGI.parse(URI.parse(response.location).query)
|
||||
|
||||
assert_not_nil params["oauth_verifier"]
|
||||
assert_predicate params["oauth_verifier"].first, :present?
|
||||
|
||||
params["oauth_verifier"].first
|
||||
end
|
||||
|
||||
def assert_allowed(token, allowed)
|
||||
ClientApplication.all_permissions.each do |p|
|
||||
assert_equal allowed.include?(p), token.attributes[p.to_s]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,54 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class ClientApplicationTest < ActiveSupport::TestCase
|
||||
def test_url_valid
|
||||
ok = ["http://example.com/test", "https://example.com/test"]
|
||||
bad = ["", "ftp://example.com/test", "myapp://somewhere", "http://example.com\nhttp://example.net"]
|
||||
|
||||
ok.each do |url|
|
||||
app = build(:client_application)
|
||||
app.url = url
|
||||
assert_predicate app, :valid?, "#{url} is invalid, when it should be"
|
||||
end
|
||||
|
||||
bad.each do |url|
|
||||
app = build(:client_application)
|
||||
app.url = url
|
||||
assert_not_predicate app, :valid?, "#{url} is valid when it shouldn't be"
|
||||
end
|
||||
end
|
||||
|
||||
def test_support_url_valid
|
||||
ok = ["", "http://example.com/test", "https://example.com/test"]
|
||||
bad = ["ftp://example.com/test", "myapp://somewhere", "gibberish", "http://example.com\nhttp://example.net"]
|
||||
|
||||
ok.each do |url|
|
||||
app = build(:client_application)
|
||||
app.support_url = url
|
||||
assert_predicate app, :valid?, "#{url} is invalid, when it should be"
|
||||
end
|
||||
|
||||
bad.each do |url|
|
||||
app = build(:client_application)
|
||||
app.support_url = url
|
||||
assert_not_predicate app, :valid?, "#{url} is valid when it shouldn't be"
|
||||
end
|
||||
end
|
||||
|
||||
def test_callback_url_valid
|
||||
ok = ["", "http://example.com/test", "https://example.com/test", "ftp://example.com/test", "myapp://somewhere"]
|
||||
bad = ["gibberish", "http://example.com\nhttp://example.net"]
|
||||
|
||||
ok.each do |url|
|
||||
app = build(:client_application)
|
||||
app.callback_url = url
|
||||
assert_predicate app, :valid?, "#{url} is invalid, when it should be"
|
||||
end
|
||||
|
||||
bad.each do |url|
|
||||
app = build(:client_application)
|
||||
app.callback_url = url
|
||||
assert_not_predicate app, :valid?, "#{url} is valid when it shouldn't be"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,29 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class OauthNonceTest < ActiveSupport::TestCase
|
||||
##
|
||||
# the nonce has only one property, that it is a unique pair of
|
||||
# string and timestamp.
|
||||
def test_nonce_uniqueness
|
||||
string = "0123456789ABCDEF"
|
||||
timestamp = Time.now.to_i
|
||||
|
||||
nonce1 = OauthNonce.remember(string, timestamp)
|
||||
assert_not_equal false, nonce1, "First nonce should be unique. Check your test database is empty."
|
||||
|
||||
nonce2 = OauthNonce.remember(string, timestamp)
|
||||
assert_not nonce2, "Shouldn't be able to remember the same nonce twice."
|
||||
end
|
||||
|
||||
##
|
||||
# nonces that are not current should be rejected
|
||||
def test_nonce_not_current
|
||||
string = "0123456789ABCDEF"
|
||||
|
||||
nonce1 = OauthNonce.remember(string, Time.now.to_i - 86430)
|
||||
assert_not nonce1, "Nonces over a day in the past should be rejected"
|
||||
|
||||
nonce2 = OauthNonce.remember(string, Time.now.to_i - 86370)
|
||||
assert_not_equal false, nonce2, "Nonces under a day in the past should be rejected"
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class OauthTokenTest < ActiveSupport::TestCase
|
||||
##
|
||||
# check that after calling invalidate! on a token, it is invalid.
|
||||
def test_token_invalidation
|
||||
tok = OauthToken.new
|
||||
assert_not_predicate tok, :invalidated?, "Token should be created valid."
|
||||
tok.invalidate!
|
||||
assert_predicate tok, :invalidated?, "Token should now be invalid."
|
||||
end
|
||||
|
||||
##
|
||||
# check that an authorized token is authorised and can be invalidated
|
||||
def test_token_authorisation
|
||||
tok = RequestToken.create(:client_application => create(:client_application))
|
||||
assert_not_predicate tok, :authorized?, "Token should be created unauthorised."
|
||||
tok.authorize!(create(:user))
|
||||
assert_predicate tok, :authorized?, "Token should now be authorised."
|
||||
tok.invalidate!
|
||||
assert_not_predicate tok, :authorized?, "Token should now be invalid."
|
||||
end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
require "test_helper"
|
||||
|
||||
class RequestTokenTest < ActiveSupport::TestCase
|
||||
def test_oob
|
||||
assert_predicate RequestToken.new, :oob?
|
||||
assert_predicate RequestToken.new(:callback_url => "oob"), :oob?
|
||||
assert_predicate RequestToken.new(:callback_url => "OOB"), :oob?
|
||||
assert_not_predicate RequestToken.new(:callback_url => "http://test.host/"), :oob?
|
||||
end
|
||||
end
|
|
@ -304,18 +304,6 @@ class UserTest < ActiveSupport::TestCase
|
|||
assert_not_predicate user, :active?
|
||||
end
|
||||
|
||||
def test_soft_destroy_revokes_oauth1_tokens
|
||||
user = create(:user)
|
||||
access_token = create(:access_token, :user => user)
|
||||
assert_equal 1, user.oauth_tokens.authorized.count
|
||||
|
||||
user.soft_destroy
|
||||
|
||||
assert_equal 0, user.oauth_tokens.authorized.count
|
||||
access_token.reload
|
||||
assert_predicate access_token, :invalidated?
|
||||
end
|
||||
|
||||
def test_soft_destroy_revokes_oauth2_tokens
|
||||
user = create(:user)
|
||||
oauth_access_token = create(:oauth_access_token, :resource_owner_id => user.id)
|
||||
|
|
|
@ -145,43 +145,6 @@ module ActiveSupport
|
|||
{ "Authorization" => "Bearer #{token}" }
|
||||
end
|
||||
|
||||
##
|
||||
# make an OAuth signed request
|
||||
def signed_request(method, uri, options = {})
|
||||
uri = URI.parse(uri)
|
||||
uri.scheme ||= "http"
|
||||
uri.host ||= "www.example.com"
|
||||
|
||||
oauth = options.delete(:oauth)
|
||||
params = options.fetch(:params, {}).transform_keys(&:to_s)
|
||||
|
||||
oauth[:consumer] ||= oauth[:token].client_application
|
||||
|
||||
helper = OAuth::Client::Helper.new(nil, oauth)
|
||||
|
||||
request = OAuth::RequestProxy.proxy(
|
||||
"method" => method.to_s.upcase,
|
||||
"uri" => uri,
|
||||
"parameters" => params.merge(helper.oauth_parameters)
|
||||
)
|
||||
|
||||
request.sign!(oauth)
|
||||
|
||||
method(method).call(request.signed_uri, **options)
|
||||
end
|
||||
|
||||
##
|
||||
# make an OAuth signed GET request
|
||||
def signed_get(uri, options = {})
|
||||
signed_request(:get, uri, options)
|
||||
end
|
||||
|
||||
##
|
||||
# make an OAuth signed POST request
|
||||
def signed_post(uri, options = {})
|
||||
signed_request(:post, uri, options)
|
||||
end
|
||||
|
||||
##
|
||||
# return request header for HTTP Accept
|
||||
def accept_format_header(format)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue