From: Tom Hughes Date: Wed, 24 Jul 2024 18:12:14 +0000 (+0100) Subject: Drop support for OAuth 1 X-Git-Tag: live~207^2 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/17bc0853a05cc392c335cc8637e901fa33dd75bd?ds=sidebyside Drop support for OAuth 1 --- diff --git a/Gemfile b/Gemfile index ac056cd83..27f295eb6 100644 --- a/Gemfile +++ b/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" diff --git a/Gemfile.lock b/Gemfile.lock index 764281285..a34976cd6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index f98b1b24a..c8d18b9aa 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -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 diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index d45dce66a..085d1bfea 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -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? || diff --git a/app/controllers/api/notes_controller.rb b/app/controllers/api/notes_controller.rb index be36421d9..3352c1f69 100644 --- a/app/controllers/api/notes_controller.rb +++ b/app/controllers/api/notes_controller.rb @@ -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 diff --git a/app/controllers/api/permissions_controller.rb b/app/controllers/api/permissions_controller.rb index 717bbfa6f..d7fb92ae6 100644 --- a/app/controllers/api/permissions_controller.rb +++ b/app/controllers/api/permissions_controller.rb @@ -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 diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index ae1bc8755..1a8185a3e 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -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 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c6223fb9d..cc006c19c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -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? diff --git a/app/controllers/oauth_clients_controller.rb b/app/controllers/oauth_clients_controller.rb deleted file mode 100644 index 42b0921f1..000000000 --- a/app/controllers/oauth_clients_controller.rb +++ /dev/null @@ -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 diff --git a/app/controllers/oauth_controller.rb b/app/controllers/oauth_controller.rb deleted file mode 100644 index 62a68b533..000000000 --- a/app/controllers/oauth_controller.rb +++ /dev/null @@ -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 diff --git a/app/models/access_token.rb b/app/models/access_token.rb deleted file mode 100644 index d2c0dba1c..000000000 --- a/app/models/access_token.rb +++ /dev/null @@ -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 diff --git a/app/models/client_application.rb b/app/models/client_application.rb deleted file mode 100644 index d9d6b2df8..000000000 --- a/app/models/client_application.rb +++ /dev/null @@ -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 diff --git a/app/models/oauth2_token.rb b/app/models/oauth2_token.rb deleted file mode 100644 index 3435b25a3..000000000 --- a/app/models/oauth2_token.rb +++ /dev/null @@ -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 diff --git a/app/models/oauth2_verifier.rb b/app/models/oauth2_verifier.rb deleted file mode 100644 index 1613eabeb..000000000 --- a/app/models/oauth2_verifier.rb +++ /dev/null @@ -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 diff --git a/app/models/oauth_nonce.rb b/app/models/oauth_nonce.rb deleted file mode 100644 index e08121cfc..000000000 --- a/app/models/oauth_nonce.rb +++ /dev/null @@ -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 diff --git a/app/models/oauth_token.rb b/app/models/oauth_token.rb deleted file mode 100644 index ae15dc658..000000000 --- a/app/models/oauth_token.rb +++ /dev/null @@ -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 diff --git a/app/models/request_token.rb b/app/models/request_token.rb deleted file mode 100644 index ec38f7421..000000000 --- a/app/models/request_token.rb +++ /dev/null @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 4241a9e56..ceeefd40f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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) diff --git a/app/views/application/_settings_menu.html.erb b/app/views/application/_settings_menu.html.erb index 8477a11a0..14f1c2927 100644 --- a/app/views/application/_settings_menu.html.erb +++ b/app/views/application/_settings_menu.html.erb @@ -5,9 +5,6 @@ - diff --git a/app/views/oauth/authorize.html.erb b/app/views/oauth/authorize.html.erb deleted file mode 100644 index b8fe11f75..000000000 --- a/app/views/oauth/authorize.html.erb +++ /dev/null @@ -1,18 +0,0 @@ -<% content_for :heading do %> -

<%= t ".title" %>

-<% end %> - -

<%= 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)) %>

- -<%= 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 %> diff --git a/app/views/oauth/authorize_failure.html.erb b/app/views/oauth/authorize_failure.html.erb deleted file mode 100644 index 7142a71a0..000000000 --- a/app/views/oauth/authorize_failure.html.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% content_for :heading do %> -

<%= t ".title" %>

-<% end %> - -

<%= @message %>

diff --git a/app/views/oauth/authorize_success.html.erb b/app/views/oauth/authorize_success.html.erb deleted file mode 100644 index 63239a386..000000000 --- a/app/views/oauth/authorize_success.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -<% content_for :heading do %> -

<%= t ".title" %>

-<% end %> - -

<%= t(".allowed_html", :app_name => link_to(@token.client_application.name, @token.client_application.url)) %>

- -<% if @token.oob? and not @token.oauth10? %> -

<%= t ".verification", :code => @token.verifier %>

-<% end %> diff --git a/app/views/oauth_clients/_form.html.erb b/app/views/oauth_clients/_form.html.erb deleted file mode 100644 index e13f4110f..000000000 --- a/app/views/oauth_clients/_form.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -<%= f.text_field :name %> -<%= f.text_field :url %> -<%= f.text_field :callback_url %> -<%= f.text_field :support_url %> -
-

<%= t ".requests" %>

- <% ClientApplication.all_permissions.each do |perm| %> - <%= f.check_box perm %> - <% end %> -
-<%= f.primary %> diff --git a/app/views/oauth_clients/edit.html.erb b/app/views/oauth_clients/edit.html.erb deleted file mode 100644 index b0299689a..000000000 --- a/app/views/oauth_clients/edit.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -<% content_for :heading do %> -

<%= t ".title" %>

-<% 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 %> diff --git a/app/views/oauth_clients/index.html.erb b/app/views/oauth_clients/index.html.erb deleted file mode 100644 index b4c2558cf..000000000 --- a/app/views/oauth_clients/index.html.erb +++ /dev/null @@ -1,47 +0,0 @@ -<% content_for :heading do %> -

<%= t ".title" %>

-<% end %> - -<%= render :partial => "settings_menu" %> - -<% unless @tokens.empty? %> -

<%= t ".my_tokens" %>

-

<%= t ".list_tokens" %>

- - - - - - - - - <% @tokens.each do |token| %> - - - - - - <% end %> -
<%= t ".application" %><%= t ".issued_at" %> 
<%= link_to token.client_application.name, token.client_application.url %><%= token.authorized_at %> - <%= 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 %> -
-<% end %> -

<%= t ".my_apps" %>

-<% if @client_applications.empty? %> -

<%= t(".no_apps_html", :oauth => link_to(t(".oauth"), "https://oauth.net")) %>

-<% else %> -

<%= t ".registered_apps" %>

- -<% end %> -<% if Settings.oauth_10_registration -%> -<%= link_to t(".register_new"), { :action => :new }, :class => "btn btn-outline-primary" %> -<% end -%> diff --git a/app/views/oauth_clients/new.html.erb b/app/views/oauth_clients/new.html.erb deleted file mode 100644 index a048f3da1..000000000 --- a/app/views/oauth_clients/new.html.erb +++ /dev/null @@ -1,9 +0,0 @@ -<% content_for :heading do %> -

<%= t ".title" %>

-<% end %> - -<%= render :partial => "settings_menu" %> - -<%= bootstrap_form_for @client_application, :url => { :action => :create } do |f| %> - <%= render :partial => "form", :locals => { :f => f } %> -<% end %> diff --git a/app/views/oauth_clients/not_found.erb b/app/views/oauth_clients/not_found.erb deleted file mode 100644 index fda9ab06d..000000000 --- a/app/views/oauth_clients/not_found.erb +++ /dev/null @@ -1 +0,0 @@ -

<%= t('.sorry', :type => @type) %>

diff --git a/app/views/oauth_clients/show.html.erb b/app/views/oauth_clients/show.html.erb deleted file mode 100644 index c7b10f137..000000000 --- a/app/views/oauth_clients/show.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -<% content_for :heading do %> -

<%= t(".title", :app_name => @client_application.name) %>

-<% end %> - -<%= render :partial => "settings_menu" %> - -
-
<%= t ".key" %>
-
<%= @client_application.key %> -
<%= t ".secret" %>
-
<%= @client_application.secret %>
-
<%= t ".url" %>
-
http<%= "s" if request.ssl? %>://<%= request.host_with_port %><%= @client_application.oauth_server.request_token_path %>
-
<%= t ".access_url" %>
-
http<%= "s" if request.ssl? %>://<%= request.host_with_port %><%= @client_application.oauth_server.access_token_path %>
-
<%= t ".authorize_url" %>
-
http<%= "s" if request.ssl? %>://<%= request.host_with_port %><%= @client_application.oauth_server.authorize_path %>
-
- -
-

<%= t ".requests" %>

- -

<%= t ".support_notice" %>

-
- -
- <%= 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" %> -
diff --git a/config/initializers/oauth.rb b/config/initializers/oauth.rb deleted file mode 100644 index 812e6610d..000000000 --- a/config/initializers/oauth.rb +++ /dev/null @@ -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) diff --git a/config/locales/en.yml b/config/locales/en.yml index dfad0230e..2aa69699f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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" diff --git a/config/routes.rb b/config/routes.rb index 676afc0fb..22c4ad642 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -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" diff --git a/config/settings.yml b/config/settings.yml index 71df9ad3d..e2ff88a41 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -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 diff --git a/db/migrate/20240724194738_drop_oauth1_tables.rb b/db/migrate/20240724194738_drop_oauth1_tables.rb new file mode 100644 index 000000000..ace4c82e7 --- /dev/null +++ b/db/migrate/20240724194738_drop_oauth1_tables.rb @@ -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 diff --git a/db/structure.sql b/db/structure.sql index 49cd4b9fb..f9e588b3c 100644 --- a/db/structure.sql +++ b/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'), diff --git a/lib/tasks/cleanup.rake b/lib/tasks/cleanup.rake index 8c95a1783..2cfc7e46d 100644 --- a/lib/tasks/cleanup.rake +++ b/lib/tasks/cleanup.rake @@ -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 diff --git a/test/controllers/api/permissions_controller_test.rb b/test/controllers/api/permissions_controller_test.rb index cca85b404..3bc13cc04 100644 --- a/test/controllers/api/permissions_controller_test.rb +++ b/test/controllers/api/permissions_controller_test.rb @@ -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 diff --git a/test/controllers/api/users_controller_test.rb b/test/controllers/api/users_controller_test.rb index 8e7079b85..4ed7e7f77 100644 --- a/test/controllers/api/users_controller_test.rb +++ b/test/controllers/api/users_controller_test.rb @@ -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) diff --git a/test/controllers/oauth_clients_controller_test.rb b/test/controllers/oauth_clients_controller_test.rb deleted file mode 100644 index c4dd4a181..000000000 --- a/test/controllers/oauth_clients_controller_test.rb +++ /dev/null @@ -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 diff --git a/test/controllers/oauth_controller_test.rb b/test/controllers/oauth_controller_test.rb deleted file mode 100644 index da01ba9c3..000000000 --- a/test/controllers/oauth_controller_test.rb +++ /dev/null @@ -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 diff --git a/test/factories/client_applications.rb b/test/factories/client_applications.rb deleted file mode 100644 index c2dbf7fa2..000000000 --- a/test/factories/client_applications.rb +++ /dev/null @@ -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 diff --git a/test/integration/client_applications_test.rb b/test/integration/client_applications_test.rb deleted file mode 100644 index e7e5b7575..000000000 --- a/test/integration/client_applications_test.rb +++ /dev/null @@ -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 diff --git a/test/integration/oauth_test.rb b/test/integration/oauth_test.rb deleted file mode 100644 index dfe2552bb..000000000 --- a/test/integration/oauth_test.rb +++ /dev/null @@ -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("

The verification code is ([A-Za-z0-9]+).

") - 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 diff --git a/test/models/client_application_test.rb b/test/models/client_application_test.rb deleted file mode 100644 index 9dc5ab5fc..000000000 --- a/test/models/client_application_test.rb +++ /dev/null @@ -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 diff --git a/test/models/oauth_nonce_test.rb b/test/models/oauth_nonce_test.rb deleted file mode 100644 index 56178fb5f..000000000 --- a/test/models/oauth_nonce_test.rb +++ /dev/null @@ -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 diff --git a/test/models/oauth_token_test.rb b/test/models/oauth_token_test.rb deleted file mode 100644 index 73dd6258f..000000000 --- a/test/models/oauth_token_test.rb +++ /dev/null @@ -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 diff --git a/test/models/request_token_test.rb b/test/models/request_token_test.rb deleted file mode 100644 index 65d17d442..000000000 --- a/test/models/request_token_test.rb +++ /dev/null @@ -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 diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 10fd3d97e..6836c4f70 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -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) diff --git a/test/test_helper.rb b/test/test_helper.rb index 1d04f57da..c45c73465 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -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)