diff --git a/.env b/.env index 3182c16226..7ecc2646d5 100644 --- a/.env +++ b/.env @@ -42,14 +42,6 @@ SMTP_PASSWORD="f00d" # Javascript error reporting via Bugsnag. # BUGSNAG_JS_KEY="" -# SingleSignOn login for Discourse -# -# DISCOURSE_SSO_SECRET should be a random string. It must be the same as provided to your Discourse instance. -# DISCOURSE_SSO_SECRET="" -# -# DISCOURSE_URL must be the URL of your Discourse instance. -# DISCOURSE_URL="https://noticeboard.openfoodnetwork.org.au" - # see="https://developers.google.com/maps/documentation/javascript/get-api-key # GOOGLE_MAPS_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # see https://developers.google.com/maps/documentation/javascript/localization#Region diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a2c635f20a..bd71576ee1 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -6,11 +6,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 2 -Lint/DuplicateMethods: - Exclude: - - 'lib/discourse/single_sign_on.rb' - # Offense count: 16 # Configuration parameters: AllowComments, AllowEmptyLambdas. Lint/EmptyBlock: @@ -104,7 +99,6 @@ Metrics/AbcSize: - 'app/models/spree/order/checkout.rb' - 'app/models/spree/preferences/preferable_class_methods.rb' - 'app/models/spree/return_authorization.rb' - - 'lib/discourse/single_sign_on.rb' - 'lib/open_food_network/order_cycle_form_applicator.rb' - 'lib/open_food_network/order_cycle_permissions.rb' - 'lib/spree/core/controller_helpers/order.rb' @@ -205,7 +199,6 @@ Metrics/CyclomaticComplexity: - 'app/models/spree/tax_rate.rb' - 'app/models/spree/variant.rb' - 'app/models/spree/zone.rb' - - 'lib/discourse/single_sign_on.rb' - 'lib/open_food_network/enterprise_issue_validator.rb' - 'lib/reporting/reports/xero_invoices/base.rb' - 'lib/spree/core/controller_helpers/order.rb' @@ -227,7 +220,6 @@ Metrics/MethodLength: - 'app/models/spree/order/checkout.rb' - 'app/models/spree/payment/processing.rb' - 'app/models/spree/preferences/preferable_class_methods.rb' - - 'lib/discourse/single_sign_on.rb' - 'lib/open_food_network/order_cycle_form_applicator.rb' - 'lib/open_food_network/order_cycle_permissions.rb' - 'lib/reporting/reports/enterprise_fee_summary/scope.rb' @@ -1011,7 +1003,6 @@ Style/SlicingWithRange: - 'app/helpers/spree/admin/navigation_helper.rb' - 'app/services/embedded_page_service.rb' - 'engines/order_management/app/services/order_management/subscriptions/validator.rb' - - 'lib/discourse/single_sign_on.rb' # Offense count: 25 # This cop supports unsafe autocorrection (--autocorrect-all). @@ -1019,7 +1010,6 @@ Style/SlicingWithRange: Style/StringConcatenation: Exclude: - 'app/controllers/admin/stripe_connect_settings_controller.rb' - - 'app/helpers/discourse_helper.rb' - 'app/helpers/enterprises_helper.rb' - 'app/helpers/spree/admin/base_helper.rb' - 'app/mailers/spree/user_mailer.rb' diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f0bc1c0255..8c5675b217 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -28,7 +28,6 @@ class ApplicationController < ActionController::Base helper 'injection' helper 'markdown' helper 'footer_links' - helper 'discourse' helper 'checkout' helper 'link' helper 'terms_and_conditions' diff --git a/app/controllers/discourse_sso_controller.rb b/app/controllers/discourse_sso_controller.rb deleted file mode 100644 index 8ac609e931..0000000000 --- a/app/controllers/discourse_sso_controller.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'discourse/single_sign_on' - -class DiscourseSsoController < ApplicationController - include SharedHelper - include DiscourseHelper - - before_action :require_config - - def login - if require_activation? - redirect_to discourse_url - else - redirect_to discourse_login_url - end - end - - def sso - if spree_current_user - begin - redirect_to sso_url - rescue TypeError - render plain: "Bad SingleSignOn request.", status: :bad_request - end - else - redirect_to login_path - end - end - - private - - def sso_url - secret = discourse_sso_secret! - sso = Discourse::SingleSignOn.parse(request.query_string, secret) - sso.email = spree_current_user.email - sso.username = spree_current_user.login - sso.external_id = spree_current_user.id - sso.sso_secret = secret - sso.admin = admin_user? - sso.require_activation = require_activation? - sso.to_url(discourse_sso_url) - end - - def require_config - raise ActionController::RoutingError, 'Not Found' unless discourse_configured? - end - - def require_activation? - !admin_user? && !spree_current_user.confirmed? - end -end diff --git a/app/helpers/discourse_helper.rb b/app/helpers/discourse_helper.rb deleted file mode 100644 index 28b45209a2..0000000000 --- a/app/helpers/discourse_helper.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -module DiscourseHelper - def discourse_configured? - discourse_url.present? - end - - def discourse_url - ENV.fetch('DISCOURSE_URL', nil) - end - - def discourse_login_url - discourse_url + '/login' - end - - def discourse_sso_url - discourse_url + '/session/sso_login' - end - - def discourse_url! - discourse_url || raise('Missing Discourse URL') - end - - def discourse_sso_secret! - ENV['DISCOURSE_SSO_SECRET'] || raise('Missing SSO secret') - end -end diff --git a/app/views/shared/menu/_signed_in.html.haml b/app/views/shared/menu/_signed_in.html.haml index 34b7bcfc06..059580c1a2 100644 --- a/app/views/shared/menu/_signed_in.html.haml +++ b/app/views/shared/menu/_signed_in.html.haml @@ -1,9 +1,3 @@ -- if discourse_configured? - %li - %a{href: main_app.discourse_login_path, target: '_blank'} - %span.nav-primary - = t 'label_notices' - %li.user-menu.has-dropdown.not-click %a{href: "#", class: "top-bar--menu-item-with-icon"} diff --git a/app/views/shared/menu/_signed_in_offcanvas.html.haml b/app/views/shared/menu/_signed_in_offcanvas.html.haml index c6f0e6be8a..e5ec28bef4 100644 --- a/app/views/shared/menu/_signed_in_offcanvas.html.haml +++ b/app/views/shared/menu/_signed_in_offcanvas.html.haml @@ -1,10 +1,3 @@ -- if discourse_configured? - %li.li-menu - %a{href: main_app.discourse_login_path, target: '_blank'} - %span.nav-primary - %i.ofn-i_025-notepad - = t 'label_notices' - - if admin_user? or enterprise_user? %li %a{href: spree.admin_dashboard_path, target:'_blank'} diff --git a/config/locales/en.yml b/config/locales/en.yml index a705c300b8..78e9c8f25c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2188,7 +2188,6 @@ en: label_account: "Account" label_more: "Show more" label_less: "Show less" - label_notices: "Notices" cart_items: "items" cart_headline: "Your shopping cart" diff --git a/config/routes.rb b/config/routes.rb index ba182c9607..7537dd4615 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,9 +11,6 @@ Openfoodnetwork::Application.routes.draw do get "/login", to: redirect("/#/login") get '/unauthorized', :to => 'home#unauthorized', :as => :unauthorized - get "/discourse/login", to: "discourse_sso#login" - get "/discourse/sso", to: "discourse_sso#sso" - get "/map", to: "map#index", as: :map get "/sell", to: "home#sell", as: :sell diff --git a/lib/discourse/single_sign_on.rb b/lib/discourse/single_sign_on.rb deleted file mode 100644 index 5e2db79461..0000000000 --- a/lib/discourse/single_sign_on.rb +++ /dev/null @@ -1,107 +0,0 @@ -# frozen_string_literal: true - -# This class is the reference implementation of a SSO provider from Discourse. - -module Discourse - class SingleSignOn - ACCESSORS = [:nonce, :name, :username, :email, :avatar_url, :avatar_force_update, - :require_activation, :about_me, :external_id, :return_sso_url, :admin, :moderator, - :suppress_welcome_message].freeze - FIXNUMS = [].freeze - BOOLS = [:avatar_force_update, :admin, :moderator, :require_activation, - :suppress_welcome_message].freeze - NONCE_EXPIRY_TIME = 10.minutes - - attr_accessor(*ACCESSORS, :sso_secret, :sso_url) - - def self.sso_secret - raise "sso_secret not implemented on class, be sure to set it on instance" - end - - def self.sso_url - raise "sso_url not implemented on class, be sure to set it on instance" - end - - def self.parse(payload, sso_secret = nil) - sso = new - sso.sso_secret = sso_secret if sso_secret - - parsed = Rack::Utils.parse_query(payload) - if sso.sign(parsed["sso"]) != parsed["sig"] - diags = "\n\nsso: #{parsed['sso']}\n\nsig: #{parsed['sig']}\n\n" \ - "expected sig: #{sso.sign(parsed['sso'])}" - raise "Bad signature for payload #{diags}" unless parsed["sso"] =~ %r{[^a-zA-Z0-9=\r\n/+]}m - - raise "The SSO field should be Base64 encoded, using only A-Z, a-z, 0-9, +, /, " \ - "and = characters. Your input contains characters we don't understand as Base64, " \ - "see http://en.wikipedia.org/wiki/Base64 #{diags}" - - end - - decoded = Base64.decode64(parsed["sso"]) - decoded_hash = Rack::Utils.parse_query(decoded) - - ACCESSORS.each do |k| - val = decoded_hash[k.to_s] - val = val.to_i if FIXNUMS.include? k - if BOOLS.include? k - val = ["true", "false"].include?(val) ? val == "true" : nil - end - sso.public_send("#{k}=", val) - end - - decoded_hash.each do |k, v| - # 1234567 - # custom. - # - if k[0..6] == "custom." - field = k[7..-1] - sso.custom_fields[field] = v - end - end - - sso - end - - def sso_secret - @sso_secret || self.class.sso_secret - end - - def sso_url - @sso_url || self.class.sso_url - end - - def custom_fields - @custom_fields ||= {} - end - - def sign(payload) - OpenSSL::HMAC.hexdigest("sha256", sso_secret, payload) - end - - def to_url(base_url = nil) - base = (base_url || sso_url).to_s - "#{base}#{base.include?('?') ? '&' : '?'}#{payload}" - end - - def payload - payload = Base64.encode64(unsigned_payload) - "sso=#{CGI.escape(payload)}&sig=#{sign(payload)}" - end - - def unsigned_payload - payload = {} - ACCESSORS.each do |k| - next if (val = public_send k).nil? - - payload[k] = val - end - - @custom_fields&.each do |k, v| - payload["custom.#{k}"] = v.to_s - end - - Rack::Utils.build_query(payload) - end - end -end