DEV: Introduce syntax_tree for ruby formatting (#75)
This commit is contained in:
		
							parent
							
								
									4a5259d81e
								
							
						
					
					
						commit
						ccf9d5d32c
					
				| 
						 | 
					@ -55,3 +55,12 @@ jobs:
 | 
				
			||||||
      - name: Rubocop
 | 
					      - name: Rubocop
 | 
				
			||||||
        if: ${{ !cancelled() }}
 | 
					        if: ${{ !cancelled() }}
 | 
				
			||||||
        run: bundle exec rubocop .
 | 
					        run: bundle exec rubocop .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      - name: Syntax Tree
 | 
				
			||||||
 | 
					        if: ${{ !cancelled() }}
 | 
				
			||||||
 | 
					        run: |
 | 
				
			||||||
 | 
					          if test -f .streerc; then
 | 
				
			||||||
 | 
					            bundle exec stree check Gemfile $(git ls-files '*.rb') $(git ls-files '*.rake')
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            echo "Stree config not detected for this repository. Skipping."
 | 
				
			||||||
 | 
					          fi
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ jobs:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Get yarn cache directory
 | 
					      - name: Get yarn cache directory
 | 
				
			||||||
        id: yarn-cache-dir
 | 
					        id: yarn-cache-dir
 | 
				
			||||||
        run: echo "::set-output name=dir::$(yarn cache dir)"
 | 
					        run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Yarn cache
 | 
					      - name: Yarn cache
 | 
				
			||||||
        uses: actions/cache@v3
 | 
					        uses: actions/cache@v3
 | 
				
			||||||
| 
						 | 
					@ -130,7 +130,7 @@ jobs:
 | 
				
			||||||
        shell: bash
 | 
					        shell: bash
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          if [ 0 -lt $(find plugins/${{ github.event.repository.name }}/spec -type f -name "*.rb" 2> /dev/null | wc -l) ]; then
 | 
					          if [ 0 -lt $(find plugins/${{ github.event.repository.name }}/spec -type f -name "*.rb" 2> /dev/null | wc -l) ]; then
 | 
				
			||||||
            echo "::set-output name=files_exist::true"
 | 
					            echo "files_exist=true" >> $GITHUB_OUTPUT
 | 
				
			||||||
          fi
 | 
					          fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Plugin RSpec
 | 
					      - name: Plugin RSpec
 | 
				
			||||||
| 
						 | 
					@ -142,7 +142,7 @@ jobs:
 | 
				
			||||||
        shell: bash
 | 
					        shell: bash
 | 
				
			||||||
        run: |
 | 
					        run: |
 | 
				
			||||||
          if [ 0 -lt $(find plugins/${{ github.event.repository.name }}/test/javascripts -type f \( -name "*.js" -or -name "*.es6" \) 2> /dev/null | wc -l) ]; then
 | 
					          if [ 0 -lt $(find plugins/${{ github.event.repository.name }}/test/javascripts -type f \( -name "*.js" -or -name "*.es6" \) 2> /dev/null | wc -l) ]; then
 | 
				
			||||||
            echo "::set-output name=files_exist::true"
 | 
					            echo "files_exist=true" >> $GITHUB_OUTPUT
 | 
				
			||||||
          fi
 | 
					          fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      - name: Plugin QUnit
 | 
					      - name: Plugin QUnit
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,2 @@
 | 
				
			||||||
inherit_gem:
 | 
					inherit_gem:
 | 
				
			||||||
  rubocop-discourse: default.yml
 | 
					  rubocop-discourse: stree-compat.yml
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								Gemfile
								
								
								
								
							
							
						
						
									
										5
									
								
								Gemfile
								
								
								
								
							| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
source 'https://rubygems.org'
 | 
					source "https://rubygems.org"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
group :development do
 | 
					group :development do
 | 
				
			||||||
  gem 'rubocop-discourse'
 | 
					  gem "rubocop-discourse"
 | 
				
			||||||
 | 
					  gem "syntax_tree"
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ GEM
 | 
				
			||||||
    parallel (1.22.1)
 | 
					    parallel (1.22.1)
 | 
				
			||||||
    parser (3.1.2.1)
 | 
					    parser (3.1.2.1)
 | 
				
			||||||
      ast (~> 2.4.1)
 | 
					      ast (~> 2.4.1)
 | 
				
			||||||
 | 
					    prettier_print (1.2.0)
 | 
				
			||||||
    rainbow (3.1.1)
 | 
					    rainbow (3.1.1)
 | 
				
			||||||
    regexp_parser (2.6.0)
 | 
					    regexp_parser (2.6.0)
 | 
				
			||||||
    rexml (3.2.5)
 | 
					    rexml (3.2.5)
 | 
				
			||||||
| 
						 | 
					@ -27,6 +28,8 @@ GEM
 | 
				
			||||||
    rubocop-rspec (2.13.2)
 | 
					    rubocop-rspec (2.13.2)
 | 
				
			||||||
      rubocop (~> 1.33)
 | 
					      rubocop (~> 1.33)
 | 
				
			||||||
    ruby-progressbar (1.11.0)
 | 
					    ruby-progressbar (1.11.0)
 | 
				
			||||||
 | 
					    syntax_tree (5.1.0)
 | 
				
			||||||
 | 
					      prettier_print (>= 1.2.0)
 | 
				
			||||||
    unicode-display_width (2.3.0)
 | 
					    unicode-display_width (2.3.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PLATFORMS
 | 
					PLATFORMS
 | 
				
			||||||
| 
						 | 
					@ -39,6 +42,7 @@ PLATFORMS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEPENDENCIES
 | 
					DEPENDENCIES
 | 
				
			||||||
  rubocop-discourse
 | 
					  rubocop-discourse
 | 
				
			||||||
 | 
					  syntax_tree
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BUNDLED WITH
 | 
					BUNDLED WITH
 | 
				
			||||||
   2.3.10
 | 
					   2.3.10
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										166
									
								
								plugin.rb
								
								
								
								
							
							
						
						
									
										166
									
								
								plugin.rb
								
								
								
								
							| 
						 | 
					@ -13,19 +13,19 @@ class ::OmniAuth::Strategies::Oauth2Basic < ::OmniAuth::Strategies::OAuth2
 | 
				
			||||||
  option :name, "oauth2_basic"
 | 
					  option :name, "oauth2_basic"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uid do
 | 
					  uid do
 | 
				
			||||||
    if path = SiteSetting.oauth2_callback_user_id_path.split('.')
 | 
					    if path = SiteSetting.oauth2_callback_user_id_path.split(".")
 | 
				
			||||||
      recurse(access_token, [*path]) if path.present?
 | 
					      recurse(access_token, [*path]) if path.present?
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  info do
 | 
					  info do
 | 
				
			||||||
    if paths = SiteSetting.oauth2_callback_user_info_paths.split('|')
 | 
					    if paths = SiteSetting.oauth2_callback_user_info_paths.split("|")
 | 
				
			||||||
      result = Hash.new
 | 
					      result = Hash.new
 | 
				
			||||||
      paths.each do |p|
 | 
					      paths.each do |p|
 | 
				
			||||||
        segments = p.split(':')
 | 
					        segments = p.split(":")
 | 
				
			||||||
        if segments.length == 2
 | 
					        if segments.length == 2
 | 
				
			||||||
          key = segments.first
 | 
					          key = segments.first
 | 
				
			||||||
          path = [*segments.last.split('.')]
 | 
					          path = [*segments.last.split(".")]
 | 
				
			||||||
          result[key] = recurse(access_token, path)
 | 
					          result[key] = recurse(access_token, path)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ class ::OmniAuth::Strategies::Oauth2Basic < ::OmniAuth::Strategies::OAuth2
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'faraday/logging/formatter'
 | 
					require "faraday/logging/formatter"
 | 
				
			||||||
class OAuth2FaradayFormatter < Faraday::Logging::Formatter
 | 
					class OAuth2FaradayFormatter < Faraday::Logging::Formatter
 | 
				
			||||||
  def request(env)
 | 
					  def request(env)
 | 
				
			||||||
    warn <<~LOG
 | 
					    warn <<~LOG
 | 
				
			||||||
| 
						 | 
					@ -76,7 +76,7 @@ DiscoursePluginRegistry.define_filtered_register :oauth2_basic_additional_json_p
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
					class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
  def name
 | 
					  def name
 | 
				
			||||||
    'oauth2_basic'
 | 
					    "oauth2_basic"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def can_revoke?
 | 
					  def can_revoke?
 | 
				
			||||||
| 
						 | 
					@ -90,52 +90,66 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
  def register_middleware(omniauth)
 | 
					  def register_middleware(omniauth)
 | 
				
			||||||
    omniauth.provider :oauth2_basic,
 | 
					    omniauth.provider :oauth2_basic,
 | 
				
			||||||
                      name: name,
 | 
					                      name: name,
 | 
				
			||||||
                      setup: lambda { |env|
 | 
					                      setup:
 | 
				
			||||||
                        opts = env['omniauth.strategy'].options
 | 
					                        lambda { |env|
 | 
				
			||||||
                        opts[:client_id] = SiteSetting.oauth2_client_id
 | 
					                          opts = env["omniauth.strategy"].options
 | 
				
			||||||
                        opts[:client_secret] = SiteSetting.oauth2_client_secret
 | 
					                          opts[:client_id] = SiteSetting.oauth2_client_id
 | 
				
			||||||
                        opts[:provider_ignores_state] = SiteSetting.oauth2_disable_csrf
 | 
					                          opts[:client_secret] = SiteSetting.oauth2_client_secret
 | 
				
			||||||
                        opts[:client_options] = {
 | 
					                          opts[:provider_ignores_state] = SiteSetting.oauth2_disable_csrf
 | 
				
			||||||
                          authorize_url: SiteSetting.oauth2_authorize_url,
 | 
					                          opts[:client_options] = {
 | 
				
			||||||
                          token_url: SiteSetting.oauth2_token_url,
 | 
					                            authorize_url: SiteSetting.oauth2_authorize_url,
 | 
				
			||||||
                          token_method: SiteSetting.oauth2_token_url_method.downcase.to_sym
 | 
					                            token_url: SiteSetting.oauth2_token_url,
 | 
				
			||||||
                        }
 | 
					                            token_method: SiteSetting.oauth2_token_url_method.downcase.to_sym,
 | 
				
			||||||
                        opts[:authorize_options] = SiteSetting.oauth2_authorize_options.split("|").map(&:to_sym)
 | 
					                          }
 | 
				
			||||||
 | 
					                          opts[:authorize_options] = SiteSetting
 | 
				
			||||||
 | 
					                            .oauth2_authorize_options
 | 
				
			||||||
 | 
					                            .split("|")
 | 
				
			||||||
 | 
					                            .map(&:to_sym)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        if SiteSetting.oauth2_authorize_signup_url.present? &&
 | 
					                          if SiteSetting.oauth2_authorize_signup_url.present? &&
 | 
				
			||||||
                            ActionDispatch::Request.new(env).params["signup"].present?
 | 
					                               ActionDispatch::Request.new(env).params["signup"].present?
 | 
				
			||||||
                          opts[:client_options][:authorize_url] = SiteSetting.oauth2_authorize_signup_url
 | 
					                            opts[:client_options][
 | 
				
			||||||
                        end
 | 
					                              :authorize_url
 | 
				
			||||||
 | 
					                            ] = SiteSetting.oauth2_authorize_signup_url
 | 
				
			||||||
                        if SiteSetting.oauth2_send_auth_header? && SiteSetting.oauth2_send_auth_body?
 | 
					 | 
				
			||||||
                          # For maximum compatibility we include both header and body auth by default
 | 
					 | 
				
			||||||
                          # This is a little unusual, and utilising multiple authentication methods
 | 
					 | 
				
			||||||
                          # is technically disallowed by the spec (RFC2749 Section 5.2)
 | 
					 | 
				
			||||||
                          opts[:client_options][:auth_scheme] = :request_body
 | 
					 | 
				
			||||||
                          opts[:token_params] = { headers: { 'Authorization' => basic_auth_header } }
 | 
					 | 
				
			||||||
                        elsif SiteSetting.oauth2_send_auth_header?
 | 
					 | 
				
			||||||
                          opts[:client_options][:auth_scheme] = :basic_auth
 | 
					 | 
				
			||||||
                        else
 | 
					 | 
				
			||||||
                          opts[:client_options][:auth_scheme] = :request_body
 | 
					 | 
				
			||||||
                        end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        unless SiteSetting.oauth2_scope.blank?
 | 
					 | 
				
			||||||
                          opts[:scope] = SiteSetting.oauth2_scope
 | 
					 | 
				
			||||||
                        end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        opts[:client_options][:connection_build] = lambda { |builder|
 | 
					 | 
				
			||||||
                          if SiteSetting.oauth2_debug_auth && defined? OAuth2FaradayFormatter
 | 
					 | 
				
			||||||
                            builder.response :logger, Rails.logger, { bodies: true, formatter: OAuth2FaradayFormatter }
 | 
					 | 
				
			||||||
                          end
 | 
					                          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                          builder.request :url_encoded                      # form-encode POST params
 | 
					                          if SiteSetting.oauth2_send_auth_header? &&
 | 
				
			||||||
                          builder.adapter FinalDestination::FaradayAdapter  # make requests with FinalDestination::HTTP
 | 
					                               SiteSetting.oauth2_send_auth_body?
 | 
				
			||||||
 | 
					                            # For maximum compatibility we include both header and body auth by default
 | 
				
			||||||
 | 
					                            # This is a little unusual, and utilising multiple authentication methods
 | 
				
			||||||
 | 
					                            # is technically disallowed by the spec (RFC2749 Section 5.2)
 | 
				
			||||||
 | 
					                            opts[:client_options][:auth_scheme] = :request_body
 | 
				
			||||||
 | 
					                            opts[:token_params] = {
 | 
				
			||||||
 | 
					                              headers: {
 | 
				
			||||||
 | 
					                                "Authorization" => basic_auth_header,
 | 
				
			||||||
 | 
					                              },
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                          elsif SiteSetting.oauth2_send_auth_header?
 | 
				
			||||||
 | 
					                            opts[:client_options][:auth_scheme] = :basic_auth
 | 
				
			||||||
 | 
					                          else
 | 
				
			||||||
 | 
					                            opts[:client_options][:auth_scheme] = :request_body
 | 
				
			||||||
 | 
					                          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                          unless SiteSetting.oauth2_scope.blank?
 | 
				
			||||||
 | 
					                            opts[:scope] = SiteSetting.oauth2_scope
 | 
				
			||||||
 | 
					                          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                          opts[:client_options][:connection_build] = lambda do |builder|
 | 
				
			||||||
 | 
					                            if SiteSetting.oauth2_debug_auth && defined?(OAuth2FaradayFormatter)
 | 
				
			||||||
 | 
					                              builder.response :logger,
 | 
				
			||||||
 | 
					                                               Rails.logger,
 | 
				
			||||||
 | 
					                                               { bodies: true, formatter: OAuth2FaradayFormatter }
 | 
				
			||||||
 | 
					                            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            builder.request :url_encoded # form-encode POST params
 | 
				
			||||||
 | 
					                            builder.adapter FinalDestination::FaradayAdapter # make requests with FinalDestination::HTTP
 | 
				
			||||||
 | 
					                          end
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                      }
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def basic_auth_header
 | 
					  def basic_auth_header
 | 
				
			||||||
    "Basic " + Base64.strict_encode64("#{SiteSetting.oauth2_client_id}:#{SiteSetting.oauth2_client_secret}")
 | 
					    "Basic " +
 | 
				
			||||||
 | 
					      Base64.strict_encode64("#{SiteSetting.oauth2_client_id}:#{SiteSetting.oauth2_client_secret}")
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def walk_path(fragment, segments, seg_index = 0)
 | 
					  def walk_path(fragment, segments, seg_index = 0)
 | 
				
			||||||
| 
						 | 
					@ -182,19 +196,21 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
    quoted = false
 | 
					    quoted = false
 | 
				
			||||||
    escaped = false
 | 
					    escaped = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    path.split("").each do |char|
 | 
					    path
 | 
				
			||||||
      next_char_escaped = false
 | 
					      .split("")
 | 
				
			||||||
      if !escaped && (char == '"')
 | 
					      .each do |char|
 | 
				
			||||||
        quoted = !quoted
 | 
					        next_char_escaped = false
 | 
				
			||||||
      elsif !escaped && !quoted && (char == '.')
 | 
					        if !escaped && (char == '"')
 | 
				
			||||||
        segments.append +""
 | 
					          quoted = !quoted
 | 
				
			||||||
      elsif !escaped && (char == '\\')
 | 
					        elsif !escaped && !quoted && (char == ".")
 | 
				
			||||||
        next_char_escaped = true
 | 
					          segments.append +""
 | 
				
			||||||
      else
 | 
					        elsif !escaped && (char == '\\')
 | 
				
			||||||
        segments.last << char
 | 
					          next_char_escaped = true
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          segments.last << char
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					        escaped = next_char_escaped
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
      escaped = next_char_escaped
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    segments
 | 
					    segments
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -204,14 +220,14 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def fetch_user_details(token, id)
 | 
					  def fetch_user_details(token, id)
 | 
				
			||||||
    user_json_url = SiteSetting.oauth2_user_json_url.sub(':token', token.to_s).sub(':id', id.to_s)
 | 
					    user_json_url = SiteSetting.oauth2_user_json_url.sub(":token", token.to_s).sub(":id", id.to_s)
 | 
				
			||||||
    user_json_method = SiteSetting.oauth2_user_json_url_method.downcase.to_sym
 | 
					    user_json_method = SiteSetting.oauth2_user_json_url_method.downcase.to_sym
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log("user_json_url: #{user_json_method} #{user_json_url}")
 | 
					    log("user_json_url: #{user_json_method} #{user_json_url}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bearer_token = "Bearer #{token}"
 | 
					    bearer_token = "Bearer #{token}"
 | 
				
			||||||
    connection = Faraday.new { |f| f.adapter FinalDestination::FaradayAdapter }
 | 
					    connection = Faraday.new { |f| f.adapter FinalDestination::FaradayAdapter }
 | 
				
			||||||
    headers = { 'Authorization' => bearer_token, 'Accept' => 'application/json' }
 | 
					    headers = { "Authorization" => bearer_token, "Accept" => "application/json" }
 | 
				
			||||||
    user_json_response = connection.run_request(user_json_method, user_json_url, nil, headers)
 | 
					    user_json_response = connection.run_request(user_json_method, user_json_url, nil, headers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log("user_json_response: #{user_json_response.inspect}")
 | 
					    log("user_json_response: #{user_json_response.inspect}")
 | 
				
			||||||
| 
						 | 
					@ -243,7 +259,7 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def primary_email_verified?(auth)
 | 
					  def primary_email_verified?(auth)
 | 
				
			||||||
    return true if SiteSetting.oauth2_email_verified
 | 
					    return true if SiteSetting.oauth2_email_verified
 | 
				
			||||||
    verified = auth['info']['email_verified']
 | 
					    verified = auth["info"]["email_verified"]
 | 
				
			||||||
    verified = true if verified == "true"
 | 
					    verified = true if verified == "true"
 | 
				
			||||||
    verified = false if verified == "false"
 | 
					    verified = false if verified == "false"
 | 
				
			||||||
    verified
 | 
					    verified
 | 
				
			||||||
| 
						 | 
					@ -254,19 +270,25 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def after_authenticate(auth, existing_account: nil)
 | 
					  def after_authenticate(auth, existing_account: nil)
 | 
				
			||||||
    log("after_authenticate response: \n\ncreds: #{auth['credentials'].to_hash}\nuid: #{auth['uid']}\ninfo: #{auth['info'].to_hash}\nextra: #{auth['extra'].to_hash}")
 | 
					    log(
 | 
				
			||||||
 | 
					      "after_authenticate response: \n\ncreds: #{auth["credentials"].to_hash}\nuid: #{auth["uid"]}\ninfo: #{auth["info"].to_hash}\nextra: #{auth["extra"].to_hash}",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if SiteSetting.oauth2_fetch_user_details?
 | 
					    if SiteSetting.oauth2_fetch_user_details?
 | 
				
			||||||
      if fetched_user_details = fetch_user_details(auth['credentials']['token'], auth['uid'])
 | 
					      if fetched_user_details = fetch_user_details(auth["credentials"]["token"], auth["uid"])
 | 
				
			||||||
        auth['uid'] = fetched_user_details[:user_id] if fetched_user_details[:user_id]
 | 
					        auth["uid"] = fetched_user_details[:user_id] if fetched_user_details[:user_id]
 | 
				
			||||||
        auth['info']['nickname'] = fetched_user_details[:username] if fetched_user_details[:username]
 | 
					        auth["info"]["nickname"] = fetched_user_details[:username] if fetched_user_details[
 | 
				
			||||||
        auth['info']['image'] = fetched_user_details[:avatar] if fetched_user_details[:avatar]
 | 
					          :username
 | 
				
			||||||
        ['name', 'email', 'email_verified'].each do |property|
 | 
					        ]
 | 
				
			||||||
          auth['info'][property] = fetched_user_details[property.to_sym] if fetched_user_details[property.to_sym]
 | 
					        auth["info"]["image"] = fetched_user_details[:avatar] if fetched_user_details[:avatar]
 | 
				
			||||||
 | 
					        %w[name email email_verified].each do |property|
 | 
				
			||||||
 | 
					          auth["info"][property] = fetched_user_details[property.to_sym] if fetched_user_details[
 | 
				
			||||||
 | 
					            property.to_sym
 | 
				
			||||||
 | 
					          ]
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail|
 | 
					        DiscoursePluginRegistry.oauth2_basic_additional_json_paths.each do |detail|
 | 
				
			||||||
          auth['extra'][detail] = fetched_user_details["extra:#{detail}"]
 | 
					          auth["extra"][detail] = fetched_user_details["extra:#{detail}"]
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
        result = Auth::Result.new
 | 
					        result = Auth::Result.new
 | 
				
			||||||
| 
						 | 
					@ -284,7 +306,9 @@ class ::OAuth2BasicAuthenticator < Auth::ManagedAuthenticator
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auth_provider title_setting: "oauth2_button_title",
 | 
					auth_provider title_setting: "oauth2_button_title", authenticator: OAuth2BasicAuthenticator.new
 | 
				
			||||||
              authenticator: OAuth2BasicAuthenticator.new
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
load File.expand_path("../lib/validators/oauth2_basic/oauth2_fetch_user_details_validator.rb", __FILE__)
 | 
					load File.expand_path(
 | 
				
			||||||
 | 
					       "../lib/validators/oauth2_basic/oauth2_fetch_user_details_validator.rb",
 | 
				
			||||||
 | 
					       __FILE__,
 | 
				
			||||||
 | 
					     )
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,9 @@ describe "OAuth2 Overrides Email", type: :request do
 | 
				
			||||||
  fab!(:initial_email) { "initial@example.com" }
 | 
					  fab!(:initial_email) { "initial@example.com" }
 | 
				
			||||||
  fab!(:new_email) { "new@example.com" }
 | 
					  fab!(:new_email) { "new@example.com" }
 | 
				
			||||||
  fab!(:user) { Fabricate(:user, email: initial_email) }
 | 
					  fab!(:user) { Fabricate(:user, email: initial_email) }
 | 
				
			||||||
  fab!(:uac) { UserAssociatedAccount.create!(user: user, provider_name: "oauth2_basic", provider_uid: "12345") }
 | 
					  fab!(:uac) do
 | 
				
			||||||
 | 
					    UserAssociatedAccount.create!(user: user, provider_name: "oauth2_basic", provider_uid: "12345")
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before do
 | 
					  before do
 | 
				
			||||||
    SiteSetting.oauth2_enabled = true
 | 
					    SiteSetting.oauth2_enabled = true
 | 
				
			||||||
| 
						 | 
					@ -16,17 +18,13 @@ describe "OAuth2 Overrides Email", type: :request do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    OmniAuth.config.test_mode = true
 | 
					    OmniAuth.config.test_mode = true
 | 
				
			||||||
    OmniAuth.config.mock_auth[:oauth2_basic] = OmniAuth::AuthHash.new(
 | 
					    OmniAuth.config.mock_auth[:oauth2_basic] = OmniAuth::AuthHash.new(
 | 
				
			||||||
      provider: 'oauth2_basic',
 | 
					      provider: "oauth2_basic",
 | 
				
			||||||
      uid: '12345',
 | 
					      uid: "12345",
 | 
				
			||||||
      info: OmniAuth::AuthHash::InfoHash.new(
 | 
					      info: OmniAuth::AuthHash::InfoHash.new(email: new_email),
 | 
				
			||||||
        email: new_email
 | 
					 | 
				
			||||||
      ),
 | 
					 | 
				
			||||||
      extra: {
 | 
					      extra: {
 | 
				
			||||||
        raw_info: OmniAuth::AuthHash.new(
 | 
					        raw_info: OmniAuth::AuthHash.new(email_verified: true),
 | 
				
			||||||
          email_verified: true
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      credentials: OmniAuth::AuthHash.new
 | 
					      credentials: OmniAuth::AuthHash.new,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +38,7 @@ describe "OAuth2 Overrides Email", type: :request do
 | 
				
			||||||
    expect(user.reload.email).to eq(initial_email)
 | 
					    expect(user.reload.email).to eq(initial_email)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'updates user email if enabled' do
 | 
					  it "updates user email if enabled" do
 | 
				
			||||||
    SiteSetting.oauth2_overrides_email = true
 | 
					    SiteSetting.oauth2_overrides_email = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    get "/auth/oauth2_basic/callback"
 | 
					    get "/auth/oauth2_basic/callback"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,31 +1,36 @@
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require 'rails_helper'
 | 
					require "rails_helper"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe OAuth2BasicAuthenticator do
 | 
					describe OAuth2BasicAuthenticator do
 | 
				
			||||||
  describe 'after_authenticate' do
 | 
					  describe "after_authenticate" do
 | 
				
			||||||
    let(:user) { Fabricate(:user) }
 | 
					    let(:user) { Fabricate(:user) }
 | 
				
			||||||
    let(:authenticator) { OAuth2BasicAuthenticator.new }
 | 
					    let(:authenticator) { OAuth2BasicAuthenticator.new }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let(:auth) do
 | 
					    let(:auth) do
 | 
				
			||||||
      OmniAuth::AuthHash.new('provider' => 'oauth2_basic',
 | 
					      OmniAuth::AuthHash.new(
 | 
				
			||||||
                             'credentials' => { 'token': 'token' },
 | 
					        "provider" => "oauth2_basic",
 | 
				
			||||||
                             'uid' => '123456789',
 | 
					        "credentials" => {
 | 
				
			||||||
                             'info' => { id: 'id' },
 | 
					          token: "token",
 | 
				
			||||||
                             'extra' => {})
 | 
					        },
 | 
				
			||||||
 | 
					        "uid" => "123456789",
 | 
				
			||||||
 | 
					        "info" => {
 | 
				
			||||||
 | 
					          id: "id",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "extra" => {
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(:each) do
 | 
					    before(:each) { SiteSetting.oauth2_email_verified = true }
 | 
				
			||||||
      SiteSetting.oauth2_email_verified = true
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'finds user by email' do
 | 
					    it "finds user by email" do
 | 
				
			||||||
      authenticator.expects(:fetch_user_details).returns(email: user.email)
 | 
					      authenticator.expects(:fetch_user_details).returns(email: user.email)
 | 
				
			||||||
      result = authenticator.after_authenticate(auth)
 | 
					      result = authenticator.after_authenticate(auth)
 | 
				
			||||||
      expect(result.user).to eq(user)
 | 
					      expect(result.user).to eq(user)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'validates user email if provider has verified' do
 | 
					    it "validates user email if provider has verified" do
 | 
				
			||||||
      SiteSetting.oauth2_email_verified = false
 | 
					      SiteSetting.oauth2_email_verified = false
 | 
				
			||||||
      authenticator.stubs(:fetch_user_details).returns(email: user.email, email_verified: true)
 | 
					      authenticator.stubs(:fetch_user_details).returns(email: user.email, email_verified: true)
 | 
				
			||||||
      result = authenticator.after_authenticate(auth)
 | 
					      result = authenticator.after_authenticate(auth)
 | 
				
			||||||
| 
						 | 
					@ -46,13 +51,13 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
      expect(result.email_valid).to eq(true)
 | 
					      expect(result.email_valid).to eq(true)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'handles true/false strings from identity provider' do
 | 
					    it "handles true/false strings from identity provider" do
 | 
				
			||||||
      SiteSetting.oauth2_email_verified = false
 | 
					      SiteSetting.oauth2_email_verified = false
 | 
				
			||||||
      authenticator.stubs(:fetch_user_details).returns(email: user.email, email_verified: 'true')
 | 
					      authenticator.stubs(:fetch_user_details).returns(email: user.email, email_verified: "true")
 | 
				
			||||||
      result = authenticator.after_authenticate(auth)
 | 
					      result = authenticator.after_authenticate(auth)
 | 
				
			||||||
      expect(result.email_valid).to eq(true)
 | 
					      expect(result.email_valid).to eq(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      authenticator.stubs(:fetch_user_details).returns(email: user.email, email_verified: 'false')
 | 
					      authenticator.stubs(:fetch_user_details).returns(email: user.email, email_verified: "false")
 | 
				
			||||||
      result = authenticator.after_authenticate(auth)
 | 
					      result = authenticator.after_authenticate(auth)
 | 
				
			||||||
      expect(result.email_valid).to eq(false)
 | 
					      expect(result.email_valid).to eq(false)
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					@ -61,21 +66,16 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
      before(:each) do
 | 
					      before(:each) do
 | 
				
			||||||
        SiteSetting.oauth2_fetch_user_details = true
 | 
					        SiteSetting.oauth2_fetch_user_details = true
 | 
				
			||||||
        SiteSetting.oauth2_user_json_url = "https://provider.com/user"
 | 
					        SiteSetting.oauth2_user_json_url = "https://provider.com/user"
 | 
				
			||||||
        SiteSetting.oauth2_user_json_url_method = 'GET'
 | 
					        SiteSetting.oauth2_user_json_url_method = "GET"
 | 
				
			||||||
        SiteSetting.oauth2_json_email_path = 'account.email'
 | 
					        SiteSetting.oauth2_json_email_path = "account.email"
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      let(:success_response) do
 | 
					      let(:success_response) do
 | 
				
			||||||
        {
 | 
					        { status: 200, body: '{"account":{"email":"newemail@example.com"}}' }
 | 
				
			||||||
          status: 200,
 | 
					 | 
				
			||||||
          body: '{"account":{"email":"newemail@example.com"}}'
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      let (:fail_response) do
 | 
					      let (:fail_response) do
 | 
				
			||||||
        {
 | 
					        { status: 403 }
 | 
				
			||||||
          status: 403
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it "works" do
 | 
					      it "works" do
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,7 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
        result = authenticator.after_authenticate(auth)
 | 
					        result = authenticator.after_authenticate(auth)
 | 
				
			||||||
        expect(result.email).to eq("newemail@example.com")
 | 
					        expect(result.email).to eq("newemail@example.com")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SiteSetting.oauth2_user_json_url_method = 'POST'
 | 
					        SiteSetting.oauth2_user_json_url_method = "POST"
 | 
				
			||||||
        stub_request(:post, SiteSetting.oauth2_user_json_url).to_return(success_response)
 | 
					        stub_request(:post, SiteSetting.oauth2_user_json_url).to_return(success_response)
 | 
				
			||||||
        result = authenticator.after_authenticate(auth)
 | 
					        result = authenticator.after_authenticate(auth)
 | 
				
			||||||
        expect(result.email).to eq("newemail@example.com")
 | 
					        expect(result.email).to eq("newemail@example.com")
 | 
				
			||||||
| 
						 | 
					@ -94,27 +94,27 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
        result = authenticator.after_authenticate(auth)
 | 
					        result = authenticator.after_authenticate(auth)
 | 
				
			||||||
        expect(result.failed).to eq(true)
 | 
					        expect(result.failed).to eq(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SiteSetting.oauth2_user_json_url_method = 'POST'
 | 
					        SiteSetting.oauth2_user_json_url_method = "POST"
 | 
				
			||||||
        stub_request(:post, SiteSetting.oauth2_user_json_url).to_return(fail_response)
 | 
					        stub_request(:post, SiteSetting.oauth2_user_json_url).to_return(fail_response)
 | 
				
			||||||
        result = authenticator.after_authenticate(auth)
 | 
					        result = authenticator.after_authenticate(auth)
 | 
				
			||||||
        expect(result.failed).to eq(true)
 | 
					        expect(result.failed).to eq(true)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      describe 'fetch custom attributes' do
 | 
					      describe "fetch custom attributes" do
 | 
				
			||||||
        after { DiscoursePluginRegistry.reset_register!(:oauth2_basic_additional_json_paths) }
 | 
					        after { DiscoursePluginRegistry.reset_register!(:oauth2_basic_additional_json_paths) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let(:response) do
 | 
					        let(:response) do
 | 
				
			||||||
          {
 | 
					          {
 | 
				
			||||||
            status: 200,
 | 
					            status: 200,
 | 
				
			||||||
            body: '{"account":{"email":"newemail@example.com","custom_attr":"received"}}'
 | 
					            body: '{"account":{"email":"newemail@example.com","custom_attr":"received"}}',
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it 'stores custom attributes in the user associated account' do
 | 
					        it "stores custom attributes in the user associated account" do
 | 
				
			||||||
          custom_path = 'account.custom_attr'
 | 
					          custom_path = "account.custom_attr"
 | 
				
			||||||
          DiscoursePluginRegistry.register_oauth2_basic_additional_json_path(
 | 
					          DiscoursePluginRegistry.register_oauth2_basic_additional_json_path(
 | 
				
			||||||
            custom_path,
 | 
					            custom_path,
 | 
				
			||||||
            Plugin::Instance.new
 | 
					            Plugin::Instance.new,
 | 
				
			||||||
          )
 | 
					          )
 | 
				
			||||||
          stub_request(:get, SiteSetting.oauth2_user_json_url).to_return(response)
 | 
					          stub_request(:get, SiteSetting.oauth2_user_json_url).to_return(response)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -126,7 +126,7 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    describe 'avatar downloading' do
 | 
					    describe "avatar downloading" do
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        SiteSetting.queue_jobs = true
 | 
					        SiteSetting.queue_jobs = true
 | 
				
			||||||
        SiteSetting.oauth2_fetch_user_details = true
 | 
					        SiteSetting.oauth2_fetch_user_details = true
 | 
				
			||||||
| 
						 | 
					@ -136,61 +136,66 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
      let(:job_klass) { Jobs::DownloadAvatarFromUrl }
 | 
					      let(:job_klass) { Jobs::DownloadAvatarFromUrl }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
        png = Base64.decode64("R0lGODlhAQABALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//wBiZCH5BAEAAA8ALAAAAAABAAEAAAQC8EUAOw==")
 | 
					        png =
 | 
				
			||||||
        stub_request(:get, "http://avatar.example.com/avatar.png").to_return(body: png, headers: { "Content-Type" => "image/png" })
 | 
					          Base64.decode64(
 | 
				
			||||||
 | 
					            "R0lGODlhAQABALMAAAAAAIAAAACAAICAAAAAgIAAgACAgMDAwICAgP8AAAD/AP//AAAA//8A/wD//wBiZCH5BAEAAA8ALAAAAAABAAEAAAQC8EUAOw==",
 | 
				
			||||||
 | 
					          )
 | 
				
			||||||
 | 
					        stub_request(:get, "http://avatar.example.com/avatar.png").to_return(
 | 
				
			||||||
 | 
					          body: png,
 | 
				
			||||||
 | 
					          headers: {
 | 
				
			||||||
 | 
					            "Content-Type" => "image/png",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it 'enqueues a download_avatar_from_url job for existing user' do
 | 
					      it "enqueues a download_avatar_from_url job for existing user" do
 | 
				
			||||||
        authenticator.expects(:fetch_user_details).returns(
 | 
					        authenticator.expects(:fetch_user_details).returns(
 | 
				
			||||||
          email: user.email,
 | 
					          email: user.email,
 | 
				
			||||||
          avatar: 'http://avatar.example.com/avatar.png'
 | 
					          avatar: "http://avatar.example.com/avatar.png",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        expect {
 | 
					        expect { authenticator.after_authenticate(auth) }.to change { job_klass.jobs.count }.by(1)
 | 
				
			||||||
          authenticator.after_authenticate(auth)
 | 
					 | 
				
			||||||
        }.to change { job_klass.jobs.count }.by(1)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        job_args = job_klass.jobs.last['args'].first
 | 
					        job_args = job_klass.jobs.last["args"].first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(job_args['url']).to eq("http://avatar.example.com/avatar.png")
 | 
					        expect(job_args["url"]).to eq("http://avatar.example.com/avatar.png")
 | 
				
			||||||
        expect(job_args['user_id']).to eq(user.id)
 | 
					        expect(job_args["user_id"]).to eq(user.id)
 | 
				
			||||||
        expect(job_args['override_gravatar']).to eq(false)
 | 
					        expect(job_args["override_gravatar"]).to eq(false)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it 'enqueues a download_avatar_from_url job for new user' do
 | 
					      it "enqueues a download_avatar_from_url job for new user" do
 | 
				
			||||||
        authenticator.expects(:fetch_user_details).returns(
 | 
					        authenticator.expects(:fetch_user_details).returns(
 | 
				
			||||||
          email: "unknown@user.com",
 | 
					          email: "unknown@user.com",
 | 
				
			||||||
          avatar: 'http://avatar.example.com/avatar.png'
 | 
					          avatar: "http://avatar.example.com/avatar.png",
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auth_result = nil
 | 
					        auth_result = nil
 | 
				
			||||||
        expect {
 | 
					        expect { auth_result = authenticator.after_authenticate(auth) }.not_to change {
 | 
				
			||||||
          auth_result = authenticator.after_authenticate(auth)
 | 
					          job_klass.jobs.count
 | 
				
			||||||
        }.not_to change { job_klass.jobs.count }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect {
 | 
					        expect { authenticator.after_create_account(user, auth_result) }.to change {
 | 
				
			||||||
          authenticator.after_create_account(user, auth_result)
 | 
					          job_klass.jobs.count
 | 
				
			||||||
        }.to change { job_klass.jobs.count }.by(1)
 | 
					        }.by(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        job_args = job_klass.jobs.last['args'].first
 | 
					        job_args = job_klass.jobs.last["args"].first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(job_args['url']).to eq("http://avatar.example.com/avatar.png")
 | 
					        expect(job_args["url"]).to eq("http://avatar.example.com/avatar.png")
 | 
				
			||||||
        expect(job_args['user_id']).to eq(user.id)
 | 
					        expect(job_args["user_id"]).to eq(user.id)
 | 
				
			||||||
        expect(job_args['override_gravatar']).to eq(false)
 | 
					        expect(job_args["override_gravatar"]).to eq(false)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'can walk json' do
 | 
					  it "can walk json" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"user":{"id":1234,"email":{"address":"test@example.com"}}}'
 | 
					    json_string = '{"user":{"id":1234,"email":{"address":"test@example.com"}}}'
 | 
				
			||||||
    SiteSetting.oauth2_json_email_path = 'user.email.address'
 | 
					    SiteSetting.oauth2_json_email_path = "user.email.address"
 | 
				
			||||||
    result = authenticator.json_walk({}, JSON.parse(json_string), :email)
 | 
					    result = authenticator.json_walk({}, JSON.parse(json_string), :email)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(result).to eq "test@example.com"
 | 
					    expect(result).to eq "test@example.com"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'allows keys containing dots, if wrapped in quotes' do
 | 
					  it "allows keys containing dots, if wrapped in quotes" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"www.example.com/uid": "myuid"}'
 | 
					    json_string = '{"www.example.com/uid": "myuid"}'
 | 
				
			||||||
    SiteSetting.oauth2_json_user_id_path = '"www.example.com/uid"'
 | 
					    SiteSetting.oauth2_json_user_id_path = '"www.example.com/uid"'
 | 
				
			||||||
| 
						 | 
					@ -199,7 +204,7 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
    expect(result).to eq "myuid"
 | 
					    expect(result).to eq "myuid"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'allows keys containing dots, if escaped' do
 | 
					  it "allows keys containing dots, if escaped" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"www.example.com/uid": "myuid"}'
 | 
					    json_string = '{"www.example.com/uid": "myuid"}'
 | 
				
			||||||
    SiteSetting.oauth2_json_user_id_path = 'www\.example\.com/uid'
 | 
					    SiteSetting.oauth2_json_user_id_path = 'www\.example\.com/uid'
 | 
				
			||||||
| 
						 | 
					@ -208,7 +213,7 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
    expect(result).to eq "myuid"
 | 
					    expect(result).to eq "myuid"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'allows keys containing literal backslashes, if escaped' do
 | 
					  it "allows keys containing literal backslashes, if escaped" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    # This 'single quoted heredoc' syntax means we don't have to escape backslashes in Ruby
 | 
					    # This 'single quoted heredoc' syntax means we don't have to escape backslashes in Ruby
 | 
				
			||||||
    # What you see is exactly what the user would enter in the site settings
 | 
					    # What you see is exactly what the user would enter in the site settings
 | 
				
			||||||
| 
						 | 
					@ -222,107 +227,109 @@ describe OAuth2BasicAuthenticator do
 | 
				
			||||||
    expect(result).to eq "myuid"
 | 
					    expect(result).to eq "myuid"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'can walk json that contains an array' do
 | 
					  it "can walk json that contains an array" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"email":"test@example.com","identities":[{"user_id":"123456789","provider":"auth0","isSocial":false}]}'
 | 
					    json_string =
 | 
				
			||||||
    SiteSetting.oauth2_json_user_id_path = 'identities.[].user_id'
 | 
					      '{"email":"test@example.com","identities":[{"user_id":"123456789","provider":"auth0","isSocial":false}]}'
 | 
				
			||||||
 | 
					    SiteSetting.oauth2_json_user_id_path = "identities.[].user_id"
 | 
				
			||||||
    result = authenticator.json_walk({}, JSON.parse(json_string), :user_id)
 | 
					    result = authenticator.json_walk({}, JSON.parse(json_string), :user_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(result).to eq "123456789"
 | 
					    expect(result).to eq "123456789"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'can walk json and handle an empty array' do
 | 
					  it "can walk json and handle an empty array" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"email":"test@example.com","identities":[]}'
 | 
					    json_string = '{"email":"test@example.com","identities":[]}'
 | 
				
			||||||
    SiteSetting.oauth2_json_user_id_path = 'identities.[].user_id'
 | 
					    SiteSetting.oauth2_json_user_id_path = "identities.[].user_id"
 | 
				
			||||||
    result = authenticator.json_walk({}, JSON.parse(json_string), :user_id)
 | 
					    result = authenticator.json_walk({}, JSON.parse(json_string), :user_id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(result).to eq nil
 | 
					    expect(result).to eq nil
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'can walk json and find values by index in an array' do
 | 
					  it "can walk json and find values by index in an array" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"emails":[{"value":"test@example.com"},{"value":"test2@example.com"}]}'
 | 
					    json_string = '{"emails":[{"value":"test@example.com"},{"value":"test2@example.com"}]}'
 | 
				
			||||||
    SiteSetting.oauth2_json_email_path = 'emails[1].value'
 | 
					    SiteSetting.oauth2_json_email_path = "emails[1].value"
 | 
				
			||||||
    result = authenticator.json_walk({}, JSON.parse(json_string), :email)
 | 
					    result = authenticator.json_walk({}, JSON.parse(json_string), :email)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(result).to eq "test2@example.com"
 | 
					    expect(result).to eq "test2@example.com"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  it 'can walk json and download avatar' do
 | 
					  it "can walk json and download avatar" do
 | 
				
			||||||
    authenticator = OAuth2BasicAuthenticator.new
 | 
					    authenticator = OAuth2BasicAuthenticator.new
 | 
				
			||||||
    json_string = '{"user":{"avatar":"http://example.com/1.png"}}'
 | 
					    json_string = '{"user":{"avatar":"http://example.com/1.png"}}'
 | 
				
			||||||
    SiteSetting.oauth2_json_avatar_path = 'user.avatar'
 | 
					    SiteSetting.oauth2_json_avatar_path = "user.avatar"
 | 
				
			||||||
    result = authenticator.json_walk({}, JSON.parse(json_string), :avatar)
 | 
					    result = authenticator.json_walk({}, JSON.parse(json_string), :avatar)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expect(result).to eq 'http://example.com/1.png'
 | 
					    expect(result).to eq "http://example.com/1.png"
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe 'token_callback' do
 | 
					  describe "token_callback" do
 | 
				
			||||||
    let(:user) { Fabricate(:user) }
 | 
					    let(:user) { Fabricate(:user) }
 | 
				
			||||||
    let(:strategy) { OmniAuth::Strategies::Oauth2Basic.new({}) }
 | 
					    let(:strategy) { OmniAuth::Strategies::Oauth2Basic.new({}) }
 | 
				
			||||||
    let(:authenticator) { OAuth2BasicAuthenticator.new }
 | 
					    let(:authenticator) { OAuth2BasicAuthenticator.new }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let(:auth) do
 | 
					    let(:auth) do
 | 
				
			||||||
      OmniAuth::AuthHash.new(
 | 
					      OmniAuth::AuthHash.new(
 | 
				
			||||||
        'provider' => 'oauth2_basic',
 | 
					        "provider" => "oauth2_basic",
 | 
				
			||||||
        'credentials' => {
 | 
					        "credentials" => {
 | 
				
			||||||
          'token' => 'token'
 | 
					          "token" => "token",
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        'uid' => 'e028b1b918853eca7fba208a9d7e9d29a6e93c57',
 | 
					        "uid" => "e028b1b918853eca7fba208a9d7e9d29a6e93c57",
 | 
				
			||||||
        'info' => {
 | 
					        "info" => {
 | 
				
			||||||
          "name" => 'Sammy the Shark',
 | 
					          "name" => "Sammy the Shark",
 | 
				
			||||||
          "email" => 'sammy@digitalocean.com'
 | 
					          "email" => "sammy@digitalocean.com",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "extra" => {
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        'extra' => {}
 | 
					 | 
				
			||||||
      )
 | 
					      )
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let(:access_token) do
 | 
					    let(:access_token) do
 | 
				
			||||||
      { "params" =>
 | 
					      {
 | 
				
			||||||
        { "info" =>
 | 
					        "params" => {
 | 
				
			||||||
          {
 | 
					          "info" => {
 | 
				
			||||||
            "name" => "Sammy the Shark",
 | 
					            "name" => "Sammy the Shark",
 | 
				
			||||||
            "email" => "sammy@digitalocean.com",
 | 
					            "email" => "sammy@digitalocean.com",
 | 
				
			||||||
            "uuid" => "e028b1b918853eca7fba208a9d7e9d29a6e93c57"
 | 
					            "uuid" => "e028b1b918853eca7fba208a9d7e9d29a6e93c57",
 | 
				
			||||||
          }
 | 
					          },
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(:each) do
 | 
					    before(:each) do
 | 
				
			||||||
      SiteSetting.oauth2_callback_user_id_path = 'params.info.uuid'
 | 
					      SiteSetting.oauth2_callback_user_id_path = "params.info.uuid"
 | 
				
			||||||
      SiteSetting.oauth2_callback_user_info_paths = 'name:params.info.name|email:params.info.email'
 | 
					      SiteSetting.oauth2_callback_user_info_paths = "name:params.info.name|email:params.info.email"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'can retrieve user id from access token callback' do
 | 
					    it "can retrieve user id from access token callback" do
 | 
				
			||||||
      strategy.stubs(:access_token).returns(access_token)
 | 
					      strategy.stubs(:access_token).returns(access_token)
 | 
				
			||||||
      expect(strategy.uid).to eq 'e028b1b918853eca7fba208a9d7e9d29a6e93c57'
 | 
					      expect(strategy.uid).to eq "e028b1b918853eca7fba208a9d7e9d29a6e93c57"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'can retrieve user properties from access token callback' do
 | 
					    it "can retrieve user properties from access token callback" do
 | 
				
			||||||
      strategy.stubs(:access_token).returns(access_token)
 | 
					      strategy.stubs(:access_token).returns(access_token)
 | 
				
			||||||
      expect(strategy.info['name']).to eq 'Sammy the Shark'
 | 
					      expect(strategy.info["name"]).to eq "Sammy the Shark"
 | 
				
			||||||
      expect(strategy.info['email']).to eq 'sammy@digitalocean.com'
 | 
					      expect(strategy.info["email"]).to eq "sammy@digitalocean.com"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'does apply user properties from access token callback in after_authenticate' do
 | 
					    it "does apply user properties from access token callback in after_authenticate" do
 | 
				
			||||||
      SiteSetting.oauth2_fetch_user_details = true
 | 
					      SiteSetting.oauth2_fetch_user_details = true
 | 
				
			||||||
      authenticator.stubs(:fetch_user_details).returns(email: 'sammy@digitalocean.com')
 | 
					      authenticator.stubs(:fetch_user_details).returns(email: "sammy@digitalocean.com")
 | 
				
			||||||
      result = authenticator.after_authenticate(auth)
 | 
					      result = authenticator.after_authenticate(auth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(result.extra_data[:uid]).to eq 'e028b1b918853eca7fba208a9d7e9d29a6e93c57'
 | 
					      expect(result.extra_data[:uid]).to eq "e028b1b918853eca7fba208a9d7e9d29a6e93c57"
 | 
				
			||||||
      expect(result.name).to eq 'Sammy the Shark'
 | 
					      expect(result.name).to eq "Sammy the Shark"
 | 
				
			||||||
      expect(result.email).to eq 'sammy@digitalocean.com'
 | 
					      expect(result.email).to eq "sammy@digitalocean.com"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'does work if user details are not fetched' do
 | 
					    it "does work if user details are not fetched" do
 | 
				
			||||||
      SiteSetting.oauth2_fetch_user_details = false
 | 
					      SiteSetting.oauth2_fetch_user_details = false
 | 
				
			||||||
      result = authenticator.after_authenticate(auth)
 | 
					      result = authenticator.after_authenticate(auth)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      expect(result.extra_data[:uid]).to eq 'e028b1b918853eca7fba208a9d7e9d29a6e93c57'
 | 
					      expect(result.extra_data[:uid]).to eq "e028b1b918853eca7fba208a9d7e9d29a6e93c57"
 | 
				
			||||||
      expect(result.name).to eq 'Sammy the Shark'
 | 
					      expect(result.name).to eq "Sammy the Shark"
 | 
				
			||||||
      expect(result.email).to eq 'sammy@digitalocean.com'
 | 
					      expect(result.email).to eq "sammy@digitalocean.com"
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue