From c7f2d960b2a9385366270bb53c171d8c0175ae5e Mon Sep 17 00:00:00 2001 From: youzik Date: Mon, 3 Oct 2016 10:57:19 +0700 Subject: [PATCH 01/46] add slack --- lib/sorcery/providers/slack.rb | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 lib/sorcery/providers/slack.rb diff --git a/lib/sorcery/providers/slack.rb b/lib/sorcery/providers/slack.rb new file mode 100644 index 00000000..55f33881 --- /dev/null +++ b/lib/sorcery/providers/slack.rb @@ -0,0 +1,60 @@ +module Sorcery + module Providers + # This class adds support for OAuth with github.com. + # + # config.slack.key = + # config.slack.secret = + # ... + # + class Slack < Base + + include Protocols::Oauth2 + + attr_accessor :auth_path, :scope, :token_url, :user_info_path + + def initialize + super + + @scope = nil + @site = 'https://slack.com/' + @user_info_path = 'https://api.github.com/user' + @auth_path = '/oauth/authorize' + @token_url = '/api/oauth.access' + end + + def get_user_hash(access_token) + response = access_token.get(user_info_path) + + auth_hash(access_token).tap do |h| + h[:user_info] = JSON.parse(response.body).tap do |uih| + uih['email'] = primary_email(access_token) if scope =~ /user/ + end + h[:uid] = h[:user_info]['id'] + end + end + + # calculates and returns the url to which the user should be redirected, + # to get authenticated at the external provider's site. + def login_url(params, session) + authorize_url({ authorize_url: auth_path }) + end + + # tries to login the user from access token + def process_callback(params, session) + args = {}.tap do |a| + a[:code] = params[:code] if params[:code] + end + + get_access_token(args, token_url: token_url, token_method: :post) + end + + def primary_email(access_token) + response = access_token.get(user_info_path + "/emails") + emails = JSON.parse(response.body) + primary = emails.find{|i| i['primary'] } + primary && primary['email'] || emails.first && emails.first['email'] + end + + end + end +end From e04b12f6038620af345d144d7e4aa5a81c26c3fc Mon Sep 17 00:00:00 2001 From: youzik Date: Mon, 3 Oct 2016 15:22:29 +0700 Subject: [PATCH 02/46] add slack auth --- .../sorcery/templates/initializer.rb | 5 ++ lib/sorcery/controller/submodules/external.rb | 1 + lib/sorcery/providers/slack.rb | 14 ++-- sorcery.gemspec | 82 ++++++++++++------- 4 files changed, 66 insertions(+), 36 deletions(-) diff --git a/lib/generators/sorcery/templates/initializer.rb b/lib/generators/sorcery/templates/initializer.rb index 8a736c3f..5dc99476 100644 --- a/lib/generators/sorcery/templates/initializer.rb +++ b/lib/generators/sorcery/templates/initializer.rb @@ -144,6 +144,11 @@ # config.vk.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=vk" # config.vk.user_info_mapping = {:login => "domain", :name => "full_name"} # + #config.slack.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=slack" + #config.slack.key = '' + #config.slack.secret = '' + #config.slack.user_info_mapping = {email: 'email'} + # # To use liveid in development mode you have to replace mydomain.com with # a valid domain even in development. To use a valid domain in development # simply add your domain in your /etc/hosts file in front of 127.0.0.1 diff --git a/lib/sorcery/controller/submodules/external.rb b/lib/sorcery/controller/submodules/external.rb index e7988dfd..8688039e 100644 --- a/lib/sorcery/controller/submodules/external.rb +++ b/lib/sorcery/controller/submodules/external.rb @@ -20,6 +20,7 @@ def self.included(base) require 'sorcery/providers/jira' require 'sorcery/providers/salesforce' require 'sorcery/providers/paypal' + require 'sorcery/providers/slack' Config.module_eval do class << self diff --git a/lib/sorcery/providers/slack.rb b/lib/sorcery/providers/slack.rb index 55f33881..e20e19eb 100644 --- a/lib/sorcery/providers/slack.rb +++ b/lib/sorcery/providers/slack.rb @@ -15,21 +15,19 @@ class Slack < Base def initialize super - @scope = nil + @scope = 'identity.basic, identity.email' @site = 'https://slack.com/' - @user_info_path = 'https://api.github.com/user' + @user_info_path = 'https://slack.com/api/users.identity' @auth_path = '/oauth/authorize' @token_url = '/api/oauth.access' end def get_user_hash(access_token) - response = access_token.get(user_info_path) - + response = access_token.get(user_info_path, params: { token: access_token.token }) auth_hash(access_token).tap do |h| - h[:user_info] = JSON.parse(response.body).tap do |uih| - uih['email'] = primary_email(access_token) if scope =~ /user/ - end - h[:uid] = h[:user_info]['id'] + h[:user_info] = JSON.parse(response.body) + h[:user_info]['email'] = h[:user_info]['user']['email'] + h[:uid] = h[:user_info]['user']['id'] end end diff --git a/sorcery.gemspec b/sorcery.gemspec index 638094ef..43c44ac0 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -1,37 +1,63 @@ -lib = File.expand_path('../lib', __FILE__) -$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'sorcery/version' +# -*- encoding: utf-8 -*- +# stub: sorcery 0.9.1 ruby lib Gem::Specification.new do |s| s.name = "sorcery" - s.version = Sorcery::VERSION + s.version = "0.9.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] s.authors = ["Noam Ben Ari", "Kir Shatrov", "Grzegorz Witek"] - s.email = "nbenari@gmail.com" + s.date = "2016-10-03" s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password." - s.summary = "Magical authentication for Rails 3 & 4 applications" + s.email = "nbenari@gmail.com" + s.files = [".document", ".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "gemfiles/active_record-rails40.gemfile", "gemfiles/active_record-rails41.gemfile", "gemfiles/active_record-rails42.gemfile", "lib/generators/sorcery/USAGE", "lib/generators/sorcery/helpers.rb", "lib/generators/sorcery/install_generator.rb", "lib/generators/sorcery/templates/initializer.rb", "lib/generators/sorcery/templates/migration/activity_logging.rb", "lib/generators/sorcery/templates/migration/brute_force_protection.rb", "lib/generators/sorcery/templates/migration/core.rb", "lib/generators/sorcery/templates/migration/external.rb", "lib/generators/sorcery/templates/migration/remember_me.rb", "lib/generators/sorcery/templates/migration/reset_password.rb", "lib/generators/sorcery/templates/migration/user_activation.rb", "lib/sorcery.rb", "lib/sorcery/adapters/active_record_adapter.rb", "lib/sorcery/adapters/base_adapter.rb", "lib/sorcery/controller.rb", "lib/sorcery/controller/config.rb", "lib/sorcery/controller/submodules/activity_logging.rb", "lib/sorcery/controller/submodules/brute_force_protection.rb", "lib/sorcery/controller/submodules/external.rb", "lib/sorcery/controller/submodules/http_basic_auth.rb", "lib/sorcery/controller/submodules/remember_me.rb", "lib/sorcery/controller/submodules/session_timeout.rb", "lib/sorcery/crypto_providers/aes256.rb", "lib/sorcery/crypto_providers/bcrypt.rb", "lib/sorcery/crypto_providers/common.rb", "lib/sorcery/crypto_providers/md5.rb", "lib/sorcery/crypto_providers/sha1.rb", "lib/sorcery/crypto_providers/sha256.rb", "lib/sorcery/crypto_providers/sha512.rb", "lib/sorcery/engine.rb", "lib/sorcery/model.rb", "lib/sorcery/model/config.rb", "lib/sorcery/model/submodules/activity_logging.rb", "lib/sorcery/model/submodules/brute_force_protection.rb", "lib/sorcery/model/submodules/external.rb", "lib/sorcery/model/submodules/remember_me.rb", "lib/sorcery/model/submodules/reset_password.rb", "lib/sorcery/model/submodules/user_activation.rb", "lib/sorcery/model/temporary_token.rb", "lib/sorcery/protocols/certs/ca-bundle.crt", "lib/sorcery/protocols/oauth.rb", "lib/sorcery/protocols/oauth2.rb", "lib/sorcery/providers/base.rb", "lib/sorcery/providers/facebook.rb", "lib/sorcery/providers/github.rb", "lib/sorcery/providers/google.rb", "lib/sorcery/providers/heroku.rb", "lib/sorcery/providers/jira.rb", "lib/sorcery/providers/linkedin.rb", "lib/sorcery/providers/liveid.rb", "lib/sorcery/providers/paypal.rb", "lib/sorcery/providers/salesforce.rb", "lib/sorcery/providers/slack.rb", "lib/sorcery/providers/twitter.rb", "lib/sorcery/providers/vk.rb", "lib/sorcery/providers/xing.rb", "lib/sorcery/test_helpers/internal.rb", "lib/sorcery/test_helpers/internal/rails.rb", "lib/sorcery/test_helpers/rails/controller.rb", "lib/sorcery/test_helpers/rails/integration.rb", "lib/sorcery/version.rb", "sorcery.gemspec", "spec/active_record/user_activation_spec.rb", "spec/active_record/user_activity_logging_spec.rb", "spec/active_record/user_brute_force_protection_spec.rb", "spec/active_record/user_oauth_spec.rb", "spec/active_record/user_remember_me_spec.rb", "spec/active_record/user_reset_password_spec.rb", "spec/active_record/user_spec.rb", "spec/controllers/controller_activity_logging_spec.rb", "spec/controllers/controller_brute_force_protection_spec.rb", "spec/controllers/controller_http_basic_auth_spec.rb", "spec/controllers/controller_oauth2_spec.rb", "spec/controllers/controller_oauth_spec.rb", "spec/controllers/controller_remember_me_spec.rb", "spec/controllers/controller_session_timeout_spec.rb", "spec/controllers/controller_spec.rb", "spec/orm/active_record.rb", "spec/rails_app/app/active_record/authentication.rb", "spec/rails_app/app/active_record/user.rb", "spec/rails_app/app/active_record/user_provider.rb", "spec/rails_app/app/controllers/sorcery_controller.rb", "spec/rails_app/app/helpers/application_helper.rb", "spec/rails_app/app/mailers/sorcery_mailer.rb", "spec/rails_app/app/views/application/index.html.erb", "spec/rails_app/app/views/layouts/application.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb", "spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb", "spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb", "spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb", "spec/rails_app/config.ru", "spec/rails_app/config/application.rb", "spec/rails_app/config/boot.rb", "spec/rails_app/config/database.yml", "spec/rails_app/config/environment.rb", "spec/rails_app/config/environments/test.rb", "spec/rails_app/config/initializers/backtrace_silencers.rb", "spec/rails_app/config/initializers/inflections.rb", "spec/rails_app/config/initializers/mime_types.rb", "spec/rails_app/config/initializers/secret_token.rb", "spec/rails_app/config/initializers/session_store.rb", "spec/rails_app/config/locales/en.yml", "spec/rails_app/config/routes.rb", "spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb", "spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb", "spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb", "spec/rails_app/db/migrate/core/20101224223620_create_users.rb", "spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb", "spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb", "spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb", "spec/rails_app/db/schema.rb", "spec/rails_app/db/seeds.rb", "spec/shared_examples/user_activation_shared_examples.rb", "spec/shared_examples/user_activity_logging_shared_examples.rb", "spec/shared_examples/user_brute_force_protection_shared_examples.rb", "spec/shared_examples/user_oauth_shared_examples.rb", "spec/shared_examples/user_remember_me_shared_examples.rb", "spec/shared_examples/user_reset_password_shared_examples.rb", "spec/shared_examples/user_shared_examples.rb", "spec/sorcery_crypto_providers_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"] s.homepage = "http://github.com/NoamB/sorcery" - s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled\n" - s.post_install_message += "you need to add those dependencies to your Gemfile" - - s.files = `git ls-files`.split($/) - s.require_paths = ["lib"] - s.licenses = ["MIT"] + s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled\nyou need to add those dependencies to your Gemfile" + s.required_ruby_version = Gem::Requirement.new(">= 2.0.0") + s.rubygems_version = "2.5.1" + s.summary = "Magical authentication for Rails 3 & 4 applications" - s.required_ruby_version = '>= 2.0.0' - - s.add_dependency "oauth", "~> 0.4", ">= 0.4.4" - s.add_dependency "oauth2", ">= 0.8.0" - s.add_dependency "bcrypt", "~> 3.1" - - s.add_development_dependency "abstract", ">= 1.0.0" - s.add_development_dependency "json", ">= 1.7.7" - s.add_development_dependency "yard", "~> 0.6.0" - - s.add_development_dependency "timecop" - s.add_development_dependency "simplecov", ">= 0.3.8" - s.add_development_dependency "rspec", "~> 3.1.0" - s.add_development_dependency "rspec-rails", "~> 3.1.0" - s.add_development_dependency "test-unit", "~> 3.1.0" + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q, [">= 0.4.4", "~> 0.4"]) + s.add_runtime_dependency(%q, [">= 0.8.0"]) + s.add_runtime_dependency(%q, ["~> 3.1"]) + s.add_development_dependency(%q, [">= 1.0.0"]) + s.add_development_dependency(%q, [">= 1.7.7"]) + s.add_development_dependency(%q, ["~> 0.6.0"]) + s.add_development_dependency(%q, [">= 0"]) + s.add_development_dependency(%q, [">= 0.3.8"]) + s.add_development_dependency(%q, ["~> 3.1.0"]) + s.add_development_dependency(%q, ["~> 3.1.0"]) + s.add_development_dependency(%q, ["~> 3.1.0"]) + else + s.add_dependency(%q, [">= 0.4.4", "~> 0.4"]) + s.add_dependency(%q, [">= 0.8.0"]) + s.add_dependency(%q, ["~> 3.1"]) + s.add_dependency(%q, [">= 1.0.0"]) + s.add_dependency(%q, [">= 1.7.7"]) + s.add_dependency(%q, ["~> 0.6.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0.3.8"]) + s.add_dependency(%q, ["~> 3.1.0"]) + s.add_dependency(%q, ["~> 3.1.0"]) + s.add_dependency(%q, ["~> 3.1.0"]) + end + else + s.add_dependency(%q, [">= 0.4.4", "~> 0.4"]) + s.add_dependency(%q, [">= 0.8.0"]) + s.add_dependency(%q, ["~> 3.1"]) + s.add_dependency(%q, [">= 1.0.0"]) + s.add_dependency(%q, [">= 1.7.7"]) + s.add_dependency(%q, ["~> 0.6.0"]) + s.add_dependency(%q, [">= 0"]) + s.add_dependency(%q, [">= 0.3.8"]) + s.add_dependency(%q, ["~> 3.1.0"]) + s.add_dependency(%q, ["~> 3.1.0"]) + s.add_dependency(%q, ["~> 3.1.0"]) + end end - From dacd843e86d6dbc6f794a20e592de836c8c4160b Mon Sep 17 00:00:00 2001 From: youzik Date: Mon, 3 Oct 2016 16:35:35 +0700 Subject: [PATCH 03/46] tests --- .../sorcery/templates/initializer.rb | 2 +- lib/sorcery/providers/github.rb | 1 - lib/sorcery/providers/slack.rb | 16 ++-------- spec/controllers/controller_oauth2_spec.rb | 29 ++++++++++++++----- .../app/controllers/sorcery_controller.rb | 20 +++++++++++++ spec/rails_app/config/routes.rb | 3 ++ spec/shared_examples/user_shared_examples.rb | 6 ++-- 7 files changed, 51 insertions(+), 26 deletions(-) diff --git a/lib/generators/sorcery/templates/initializer.rb b/lib/generators/sorcery/templates/initializer.rb index 5dc99476..36623bb3 100644 --- a/lib/generators/sorcery/templates/initializer.rb +++ b/lib/generators/sorcery/templates/initializer.rb @@ -73,7 +73,7 @@ # -- external -- - # What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid, :salesforce] . + # What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid, :salesforce, :slack] . # Default: `[]` # # config.external_providers = diff --git a/lib/sorcery/providers/github.rb b/lib/sorcery/providers/github.rb index d91640d3..cd939157 100644 --- a/lib/sorcery/providers/github.rb +++ b/lib/sorcery/providers/github.rb @@ -24,7 +24,6 @@ def initialize def get_user_hash(access_token) response = access_token.get(user_info_path) - auth_hash(access_token).tap do |h| h[:user_info] = JSON.parse(response.body).tap do |uih| uih['email'] = primary_email(access_token) if scope =~ /user/ diff --git a/lib/sorcery/providers/slack.rb b/lib/sorcery/providers/slack.rb index e20e19eb..129cf5c3 100644 --- a/lib/sorcery/providers/slack.rb +++ b/lib/sorcery/providers/slack.rb @@ -1,11 +1,7 @@ module Sorcery module Providers - # This class adds support for OAuth with github.com. - # - # config.slack.key = - # config.slack.secret = - # ... - # + # This class adds support for OAuth with slack.com. + class Slack < Base include Protocols::Oauth2 @@ -45,14 +41,6 @@ def process_callback(params, session) get_access_token(args, token_url: token_url, token_method: :post) end - - def primary_email(access_token) - response = access_token.get(user_info_path + "/emails") - emails = JSON.parse(response.body) - primary = emails.find{|i| i['primary'] } - primary && primary['email'] || emails.first && emails.first['email'] - end - end end end diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index 73b09ee7..8e8d9455 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -152,7 +152,7 @@ expect(flash[:notice]).to eq "Success!" end - [:github, :google, :liveid, :vk, :salesforce, :paypal].each do |provider| + [:github, :google, :liveid, :vk, :salesforce, :paypal, :slack].each do |provider| describe "with #{provider}" do @@ -205,7 +205,7 @@ end sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer) - sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal]) + sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack]) sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w") sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") @@ -228,8 +228,13 @@ sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w") sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com") end + + after(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation") @@ -287,7 +292,7 @@ end end - %w(facebook github google liveid vk salesforce).each do |provider| + %w(facebook github google liveid vk salesforce slack).each do |provider| context "when #{provider}" do before(:each) do sorcery_controller_property_set(:register_login_time, true) @@ -327,7 +332,7 @@ let(:user) { double('user', id: 42) } - %w(facebook github google liveid vk salesforce).each do |provider| + %w(facebook github google liveid vk salesforce slack).each do |provider| context "when #{provider}" do before(:each) do sorcery_model_property_set(:authentications_class, Authentication) @@ -389,7 +394,13 @@ def stub_all_oauth2_requests! "first_name"=>"Noam", "last_name"=>"Ben Ari" } - ]}.to_json } + ], + "user": { + "name": "Sonny Whether", + "id": "123", + "email": "bobby@example.com" + } + }.to_json } allow(access_token).to receive(:get) { response } allow(access_token).to receive(:token) { "187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3" } # access_token params for VK auth @@ -398,7 +409,7 @@ def stub_all_oauth2_requests! end def set_external_property - sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal]) + sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack]) sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w") sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com") @@ -420,6 +431,9 @@ def set_external_property sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w") sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com") end def provider_url(provider) @@ -429,7 +443,8 @@ def provider_url(provider) google: "https://accounts.google.com/o/oauth2/auth?client_id=#{::Sorcery::Controller::Config.google.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state", liveid: "https://oauth.live.com/authorize?client_id=#{::Sorcery::Controller::Config.liveid.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=wl.basic+wl.emails+wl.offline_access&state", vk: "https://oauth.vk.com/authorize?client_id=#{::Sorcery::Controller::Config.vk.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.vk.scope}&state", - salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope#{'=' + ::Sorcery::Controller::Config.salesforce.scope unless ::Sorcery::Controller::Config.salesforce.scope.nil?}&state" + salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope#{'=' + ::Sorcery::Controller::Config.salesforce.scope unless ::Sorcery::Controller::Config.salesforce.scope.nil?}&state", + slack: "https://slack.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.slack.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=identity.basic%2C+identity.email&state" }[provider] end end diff --git a/spec/rails_app/app/controllers/sorcery_controller.rb b/spec/rails_app/app/controllers/sorcery_controller.rb index d5857871..8f1f3c78 100644 --- a/spec/rails_app/app/controllers/sorcery_controller.rb +++ b/spec/rails_app/app/controllers/sorcery_controller.rb @@ -121,6 +121,10 @@ def login_at_test_salesforce login_at(:salesforce) end + def login_at_test_slack + login_at(:slack) + end + def login_at_test_with_state login_at(:facebook, {state: 'bla'}) end @@ -199,6 +203,14 @@ def test_login_from_salesforce end end + def test_login_from_slack + if @user = login_from(:slack) + redirect_to 'bla', notice: 'Success!' + else + redirect_to 'blu', alert: 'Failed!' + end + end + def test_return_to_with_external_twitter if @user = login_from(:twitter) redirect_back_or_to 'bla', notice: 'Success!' @@ -273,6 +285,14 @@ def test_return_to_with_external_salesforce end end + def test_return_to_with_external_slack + if @user = login_from(:slack) + redirect_back_or_to 'bla', notice: 'Success!' + else + redirect_to 'blu', alert: 'Failed!' + end + end + def test_create_from_provider provider = params[:provider] login_from(provider) diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index 20a56290..c75eb535 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -26,6 +26,7 @@ get :test_login_from_vk get :test_login_from_jira get :test_login_from_salesforce + get :test_login_from_slack get :login_at_test get :login_at_test_twitter get :login_at_test_facebook @@ -36,6 +37,7 @@ get :login_at_test_vk get :login_at_test_jira get :login_at_test_salesforce + get :login_at_test_slack get :test_return_to_with_external get :test_return_to_with_external_twitter get :test_return_to_with_external_facebook @@ -46,6 +48,7 @@ get :test_return_to_with_external_vk get :test_return_to_with_external_jira get :test_return_to_with_external_salesforce + get :test_return_to_with_external_slack get :test_http_basic_auth get :some_action_making_a_non_persisted_change_to_the_user post :test_login_with_remember diff --git a/spec/shared_examples/user_shared_examples.rb b/spec/shared_examples/user_shared_examples.rb index 242aef7d..27522b3e 100644 --- a/spec/shared_examples/user_shared_examples.rb +++ b/spec/shared_examples/user_shared_examples.rb @@ -262,11 +262,11 @@ class Admin2 < User; end let(:user_with_pass) { create_new_user({:username => 'foo_bar', :email => "foo@bar.com", :password => 'foobar'})} specify { expect(user_with_pass).to respond_to :valid_password? } - + it "returns true if password is correct" do expect(user_with_pass.valid_password?("foobar")).to be true end - + it "returns false if password is incorrect" do expect(user_with_pass.valid_password?("foobug")).to be false end @@ -541,7 +541,7 @@ def self.matches?(crypted,*tokens) User.sorcery_adapter.delete_all end - [:facebook, :github, :google, :liveid].each do |provider| + [:facebook, :github, :google, :liveid, :slack].each do |provider| it "does not send activation email to external users" do old_size = ActionMailer::Base.deliveries.size From 63a01dbb0271cc20cbd96b00b721cdfd5fe277a0 Mon Sep 17 00:00:00 2001 From: youzik Date: Mon, 3 Oct 2016 16:39:15 +0700 Subject: [PATCH 04/46] fix --- lib/sorcery/providers/github.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sorcery/providers/github.rb b/lib/sorcery/providers/github.rb index cd939157..4c8778b9 100644 --- a/lib/sorcery/providers/github.rb +++ b/lib/sorcery/providers/github.rb @@ -24,6 +24,7 @@ def initialize def get_user_hash(access_token) response = access_token.get(user_info_path) + auth_hash(access_token).tap do |h| h[:user_info] = JSON.parse(response.body).tap do |uih| uih['email'] = primary_email(access_token) if scope =~ /user/ From bfe4a5df37b1d94c0aadfd5b7024bdb1022d6de1 Mon Sep 17 00:00:00 2001 From: youzik Date: Mon, 3 Oct 2016 17:46:54 +0700 Subject: [PATCH 05/46] fix to work with pre 2.2 ruby versions --- lib/sorcery/providers/github.rb | 2 +- spec/controllers/controller_oauth2_spec.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/sorcery/providers/github.rb b/lib/sorcery/providers/github.rb index 4c8778b9..d91640d3 100644 --- a/lib/sorcery/providers/github.rb +++ b/lib/sorcery/providers/github.rb @@ -24,7 +24,7 @@ def initialize def get_user_hash(access_token) response = access_token.get(user_info_path) - + auth_hash(access_token).tap do |h| h[:user_info] = JSON.parse(response.body).tap do |uih| uih['email'] = primary_email(access_token) if scope =~ /user/ diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index 8e8d9455..c238219a 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -395,10 +395,10 @@ def stub_all_oauth2_requests! "last_name"=>"Ben Ari" } ], - "user": { - "name": "Sonny Whether", - "id": "123", - "email": "bobby@example.com" + "user"=> { + "name"=>"Sonny Whether", + "id"=>"123", + "email"=>"bobby@example.com" } }.to_json } allow(access_token).to receive(:get) { response } From bb256f0ad656fc98cdf20618d2b629fa640e0ad1 Mon Sep 17 00:00:00 2001 From: youzik Date: Mon, 17 Oct 2016 12:05:55 +0700 Subject: [PATCH 06/46] fix sorcery.gemspec --- sorcery.gemspec | 79 ++++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 53 deletions(-) diff --git a/sorcery.gemspec b/sorcery.gemspec index 43c44ac0..cc4d4fb7 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -1,63 +1,36 @@ -# -*- encoding: utf-8 -*- -# stub: sorcery 0.9.1 ruby lib +lib = File.expand_path('../lib', __FILE__) +$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) +require 'sorcery/version' Gem::Specification.new do |s| s.name = "sorcery" - s.version = "0.9.1" - - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.require_paths = ["lib"] + s.version = Sorcery::VERSION s.authors = ["Noam Ben Ari", "Kir Shatrov", "Grzegorz Witek"] - s.date = "2016-10-03" - s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password." s.email = "nbenari@gmail.com" - s.files = [".document", ".gitignore", ".rspec", ".travis.yml", "CHANGELOG.md", "Gemfile", "LICENSE.txt", "README.md", "Rakefile", "gemfiles/active_record-rails40.gemfile", "gemfiles/active_record-rails41.gemfile", "gemfiles/active_record-rails42.gemfile", "lib/generators/sorcery/USAGE", "lib/generators/sorcery/helpers.rb", "lib/generators/sorcery/install_generator.rb", "lib/generators/sorcery/templates/initializer.rb", "lib/generators/sorcery/templates/migration/activity_logging.rb", "lib/generators/sorcery/templates/migration/brute_force_protection.rb", "lib/generators/sorcery/templates/migration/core.rb", "lib/generators/sorcery/templates/migration/external.rb", "lib/generators/sorcery/templates/migration/remember_me.rb", "lib/generators/sorcery/templates/migration/reset_password.rb", "lib/generators/sorcery/templates/migration/user_activation.rb", "lib/sorcery.rb", "lib/sorcery/adapters/active_record_adapter.rb", "lib/sorcery/adapters/base_adapter.rb", "lib/sorcery/controller.rb", "lib/sorcery/controller/config.rb", "lib/sorcery/controller/submodules/activity_logging.rb", "lib/sorcery/controller/submodules/brute_force_protection.rb", "lib/sorcery/controller/submodules/external.rb", "lib/sorcery/controller/submodules/http_basic_auth.rb", "lib/sorcery/controller/submodules/remember_me.rb", "lib/sorcery/controller/submodules/session_timeout.rb", "lib/sorcery/crypto_providers/aes256.rb", "lib/sorcery/crypto_providers/bcrypt.rb", "lib/sorcery/crypto_providers/common.rb", "lib/sorcery/crypto_providers/md5.rb", "lib/sorcery/crypto_providers/sha1.rb", "lib/sorcery/crypto_providers/sha256.rb", "lib/sorcery/crypto_providers/sha512.rb", "lib/sorcery/engine.rb", "lib/sorcery/model.rb", "lib/sorcery/model/config.rb", "lib/sorcery/model/submodules/activity_logging.rb", "lib/sorcery/model/submodules/brute_force_protection.rb", "lib/sorcery/model/submodules/external.rb", "lib/sorcery/model/submodules/remember_me.rb", "lib/sorcery/model/submodules/reset_password.rb", "lib/sorcery/model/submodules/user_activation.rb", "lib/sorcery/model/temporary_token.rb", "lib/sorcery/protocols/certs/ca-bundle.crt", "lib/sorcery/protocols/oauth.rb", "lib/sorcery/protocols/oauth2.rb", "lib/sorcery/providers/base.rb", "lib/sorcery/providers/facebook.rb", "lib/sorcery/providers/github.rb", "lib/sorcery/providers/google.rb", "lib/sorcery/providers/heroku.rb", "lib/sorcery/providers/jira.rb", "lib/sorcery/providers/linkedin.rb", "lib/sorcery/providers/liveid.rb", "lib/sorcery/providers/paypal.rb", "lib/sorcery/providers/salesforce.rb", "lib/sorcery/providers/slack.rb", "lib/sorcery/providers/twitter.rb", "lib/sorcery/providers/vk.rb", "lib/sorcery/providers/xing.rb", "lib/sorcery/test_helpers/internal.rb", "lib/sorcery/test_helpers/internal/rails.rb", "lib/sorcery/test_helpers/rails/controller.rb", "lib/sorcery/test_helpers/rails/integration.rb", "lib/sorcery/version.rb", "sorcery.gemspec", "spec/active_record/user_activation_spec.rb", "spec/active_record/user_activity_logging_spec.rb", "spec/active_record/user_brute_force_protection_spec.rb", "spec/active_record/user_oauth_spec.rb", "spec/active_record/user_remember_me_spec.rb", "spec/active_record/user_reset_password_spec.rb", "spec/active_record/user_spec.rb", "spec/controllers/controller_activity_logging_spec.rb", "spec/controllers/controller_brute_force_protection_spec.rb", "spec/controllers/controller_http_basic_auth_spec.rb", "spec/controllers/controller_oauth2_spec.rb", "spec/controllers/controller_oauth_spec.rb", "spec/controllers/controller_remember_me_spec.rb", "spec/controllers/controller_session_timeout_spec.rb", "spec/controllers/controller_spec.rb", "spec/orm/active_record.rb", "spec/rails_app/app/active_record/authentication.rb", "spec/rails_app/app/active_record/user.rb", "spec/rails_app/app/active_record/user_provider.rb", "spec/rails_app/app/controllers/sorcery_controller.rb", "spec/rails_app/app/helpers/application_helper.rb", "spec/rails_app/app/mailers/sorcery_mailer.rb", "spec/rails_app/app/views/application/index.html.erb", "spec/rails_app/app/views/layouts/application.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_email.text.erb", "spec/rails_app/app/views/sorcery_mailer/activation_needed_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_success_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/activation_success_email.text.erb", "spec/rails_app/app/views/sorcery_mailer/reset_password_email.html.erb", "spec/rails_app/app/views/sorcery_mailer/reset_password_email.text.erb", "spec/rails_app/app/views/sorcery_mailer/send_unlock_token_email.text.erb", "spec/rails_app/config.ru", "spec/rails_app/config/application.rb", "spec/rails_app/config/boot.rb", "spec/rails_app/config/database.yml", "spec/rails_app/config/environment.rb", "spec/rails_app/config/environments/test.rb", "spec/rails_app/config/initializers/backtrace_silencers.rb", "spec/rails_app/config/initializers/inflections.rb", "spec/rails_app/config/initializers/mime_types.rb", "spec/rails_app/config/initializers/secret_token.rb", "spec/rails_app/config/initializers/session_store.rb", "spec/rails_app/config/locales/en.yml", "spec/rails_app/config/routes.rb", "spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb", "spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb", "spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb", "spec/rails_app/db/migrate/core/20101224223620_create_users.rb", "spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb", "spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb", "spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb", "spec/rails_app/db/schema.rb", "spec/rails_app/db/seeds.rb", "spec/shared_examples/user_activation_shared_examples.rb", "spec/shared_examples/user_activity_logging_shared_examples.rb", "spec/shared_examples/user_brute_force_protection_shared_examples.rb", "spec/shared_examples/user_oauth_shared_examples.rb", "spec/shared_examples/user_remember_me_shared_examples.rb", "spec/shared_examples/user_reset_password_shared_examples.rb", "spec/shared_examples/user_shared_examples.rb", "spec/sorcery_crypto_providers_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"] + s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password." + s.summary = "Magical authentication for Rails 3 & 4 applications" s.homepage = "http://github.com/NoamB/sorcery" + s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled\n" + s.post_install_message += "you need to add those dependencies to your Gemfile" + + s.files = `git ls-files`.split($/) + s.require_paths = ["lib"] + s.licenses = ["MIT"] - s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled\nyou need to add those dependencies to your Gemfile" - s.required_ruby_version = Gem::Requirement.new(">= 2.0.0") - s.rubygems_version = "2.5.1" - s.summary = "Magical authentication for Rails 3 & 4 applications" - if s.respond_to? :specification_version then - s.specification_version = 4 + s.required_ruby_version = '>= 2.0.0' + + s.add_dependency "oauth", "~> 0.4", ">= 0.4.4" + s.add_dependency "oauth2", ">= 0.8.0" + s.add_dependency "bcrypt", "~> 3.1" + + s.add_development_dependency "abstract", ">= 1.0.0" + s.add_development_dependency "json", ">= 1.7.7" + s.add_development_dependency "yard", "~> 0.6.0" - if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_runtime_dependency(%q, [">= 0.4.4", "~> 0.4"]) - s.add_runtime_dependency(%q, [">= 0.8.0"]) - s.add_runtime_dependency(%q, ["~> 3.1"]) - s.add_development_dependency(%q, [">= 1.0.0"]) - s.add_development_dependency(%q, [">= 1.7.7"]) - s.add_development_dependency(%q, ["~> 0.6.0"]) - s.add_development_dependency(%q, [">= 0"]) - s.add_development_dependency(%q, [">= 0.3.8"]) - s.add_development_dependency(%q, ["~> 3.1.0"]) - s.add_development_dependency(%q, ["~> 3.1.0"]) - s.add_development_dependency(%q, ["~> 3.1.0"]) - else - s.add_dependency(%q, [">= 0.4.4", "~> 0.4"]) - s.add_dependency(%q, [">= 0.8.0"]) - s.add_dependency(%q, ["~> 3.1"]) - s.add_dependency(%q, [">= 1.0.0"]) - s.add_dependency(%q, [">= 1.7.7"]) - s.add_dependency(%q, ["~> 0.6.0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0.3.8"]) - s.add_dependency(%q, ["~> 3.1.0"]) - s.add_dependency(%q, ["~> 3.1.0"]) - s.add_dependency(%q, ["~> 3.1.0"]) - end - else - s.add_dependency(%q, [">= 0.4.4", "~> 0.4"]) - s.add_dependency(%q, [">= 0.8.0"]) - s.add_dependency(%q, ["~> 3.1"]) - s.add_dependency(%q, [">= 1.0.0"]) - s.add_dependency(%q, [">= 1.7.7"]) - s.add_dependency(%q, ["~> 0.6.0"]) - s.add_dependency(%q, [">= 0"]) - s.add_dependency(%q, [">= 0.3.8"]) - s.add_dependency(%q, ["~> 3.1.0"]) - s.add_dependency(%q, ["~> 3.1.0"]) - s.add_dependency(%q, ["~> 3.1.0"]) - end + s.add_development_dependency "timecop" + s.add_development_dependency "simplecov", ">= 0.3.8" + s.add_development_dependency "rspec", "~> 3.1.0" + s.add_development_dependency "rspec-rails", "~> 3.1.0" + s.add_development_dependency "test-unit", "~> 3.1.0" end From 3f1d8c9ea626edb7951891a68fab65fcdc637b02 Mon Sep 17 00:00:00 2001 From: yamada Date: Sun, 6 Nov 2016 17:49:49 +0900 Subject: [PATCH 07/46] Update sorcery.gemspec --- sorcery.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sorcery.gemspec b/sorcery.gemspec index cc4d4fb7..cc3c507e 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -9,7 +9,7 @@ Gem::Specification.new do |s| s.email = "nbenari@gmail.com" s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password." s.summary = "Magical authentication for Rails 3 & 4 applications" - s.homepage = "http://github.com/NoamB/sorcery" + s.homepage = "https://github.com/Sorcery/sorcery" s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled\n" s.post_install_message += "you need to add those dependencies to your Gemfile" From 54c5400fe28bda2d5b0d97b72dc208c364834e37 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 21:00:23 +0900 Subject: [PATCH 08/46] [rubocop] Removes prefix _ for a variable --- lib/sorcery/model.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/sorcery/model.rb b/lib/sorcery/model.rb index b4b90095..56382c08 100644 --- a/lib/sorcery/model.rb +++ b/lib/sorcery/model.rb @@ -148,12 +148,12 @@ def external? # Calls the configured encryption provider to compare the supplied password with the encrypted one. def valid_password?(pass) - _crypted = self.send(sorcery_config.crypted_password_attribute_name) - return _crypted == pass if sorcery_config.encryption_provider.nil? + crypted = self.send(sorcery_config.crypted_password_attribute_name) + return crypted == pass if sorcery_config.encryption_provider.nil? - _salt = self.send(sorcery_config.salt_attribute_name) unless sorcery_config.salt_attribute_name.nil? + salt = self.send(sorcery_config.salt_attribute_name) unless sorcery_config.salt_attribute_name.nil? - sorcery_config.encryption_provider.matches?(_crypted, pass, _salt) + sorcery_config.encryption_provider.matches?(crypted, pass, salt) end protected From c96c11711359525e9b2c35fff43a166e042a446c Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 21:08:46 +0900 Subject: [PATCH 09/46] [rubocop] Removes unused block argument --- lib/sorcery/engine.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sorcery/engine.rb b/lib/sorcery/engine.rb index 1aa7591c..84a2a97c 100644 --- a/lib/sorcery/engine.rb +++ b/lib/sorcery/engine.rb @@ -6,8 +6,8 @@ module Sorcery # With the plugin logic. class Engine < Rails::Engine config.sorcery = ::Sorcery::Controller::Config - - initializer "extend Controller with sorcery" do |app| + + initializer "extend Controller with sorcery" do ActionController::Base.send(:include, Sorcery::Controller) ActionController::Base.helper_method :current_user ActionController::Base.helper_method :logged_in? From 9e04c7c2d3dfd1fe37bfc029808bf51439648792 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 21:32:31 +0900 Subject: [PATCH 10/46] [rubocop] Changes and to &&, or to || --- lib/sorcery/controller/submodules/http_basic_auth.rb | 2 +- lib/sorcery/model.rb | 2 +- lib/sorcery/model/submodules/activity_logging.rb | 4 ++-- lib/sorcery/model/submodules/remember_me.rb | 4 ++-- lib/sorcery/model/submodules/reset_password.rb | 2 +- lib/sorcery/model/submodules/user_activation.rb | 2 +- lib/sorcery/providers/linkedin.rb | 2 +- lib/sorcery/test_helpers/internal/rails.rb | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/sorcery/controller/submodules/http_basic_auth.rb b/lib/sorcery/controller/submodules/http_basic_auth.rb index 200fd7f1..c18b4fb9 100644 --- a/lib/sorcery/controller/submodules/http_basic_auth.rb +++ b/lib/sorcery/controller/submodules/http_basic_auth.rb @@ -37,7 +37,7 @@ module InstanceMethods # To overcome this, we set a session when requesting the password, which logout will # reset, and that's how we know if we need to request for HTTP auth again. def require_login_from_http_basic - (request_http_basic_authentication(realm_name_by_controller) and (session[:http_authentication_used] = true) and return) if (request.authorization.nil? || session[:http_authentication_used].nil?) + (request_http_basic_authentication(realm_name_by_controller) && (session[:http_authentication_used] = true) && return) if (request.authorization.nil? || session[:http_authentication_used].nil?) require_login session[:http_authentication_used] = nil unless logged_in? end diff --git a/lib/sorcery/model.rb b/lib/sorcery/model.rb index 56382c08..4c22d6d0 100644 --- a/lib/sorcery/model.rb +++ b/lib/sorcery/model.rb @@ -180,7 +180,7 @@ def clear_virtual_password def generic_send_email(method, mailer) config = sorcery_config mail = config.send(mailer).send(config.send(method),self) - if defined?(ActionMailer) and config.send(mailer).kind_of?(Class) and config.send(mailer) < ActionMailer::Base + if defined?(ActionMailer) && config.send(mailer).kind_of?(Class) && config.send(mailer) < ActionMailer::Base mail.send(config.email_delivery_method) end end diff --git a/lib/sorcery/model/submodules/activity_logging.rb b/lib/sorcery/model/submodules/activity_logging.rb index 7cd31bec..1548abb6 100644 --- a/lib/sorcery/model/submodules/activity_logging.rb +++ b/lib/sorcery/model/submodules/activity_logging.rb @@ -53,13 +53,13 @@ def set_last_ip_address(ip_address) def online? return false if self.send(sorcery_config.last_activity_at_attribute_name).nil? - logged_in? and self.send(sorcery_config.last_activity_at_attribute_name) > sorcery_config.activity_timeout.seconds.ago + logged_in? && self.send(sorcery_config.last_activity_at_attribute_name) > sorcery_config.activity_timeout.seconds.ago end # shows if user is logged in, but it not show if user is online - see online? def logged_in? return false if self.send(sorcery_config.last_login_at_attribute_name).nil? - return true if self.send(sorcery_config.last_login_at_attribute_name).present? and self.send(sorcery_config.last_logout_at_attribute_name).nil? + return true if self.send(sorcery_config.last_login_at_attribute_name).present? && self.send(sorcery_config.last_logout_at_attribute_name).nil? self.send(sorcery_config.last_login_at_attribute_name) > self.send(sorcery_config.last_logout_at_attribute_name) end diff --git a/lib/sorcery/model/submodules/remember_me.rb b/lib/sorcery/model/submodules/remember_me.rb index 9d297d89..b0bb766b 100644 --- a/lib/sorcery/model/submodules/remember_me.rb +++ b/lib/sorcery/model/submodules/remember_me.rb @@ -46,7 +46,7 @@ def remember_me! update_options = { config.remember_me_token_expires_at_attribute_name => Time.now.in_time_zone + config.remember_me_for } - unless config.remember_me_token_persist_globally and has_remember_me_token? + unless config.remember_me_token_persist_globally && has_remember_me_token? update_options.merge!(config.remember_me_token_attribute_name => TemporaryToken.generate_random_token) end @@ -60,7 +60,7 @@ def has_remember_me_token? # You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method. # We only clear the token value if remember_me_token_persist_globally = true. def forget_me! - sorcery_config.remember_me_token_persist_globally or force_forget_me! + sorcery_config.remember_me_token_persist_globally || force_forget_me! end # You shouldn't really use this one yourself - it's called by the controller's 'force_forget_me!' method. diff --git a/lib/sorcery/model/submodules/reset_password.rb b/lib/sorcery/model/submodules/reset_password.rb index 00e8de48..0acd8b65 100644 --- a/lib/sorcery/model/submodules/reset_password.rb +++ b/lib/sorcery/model/submodules/reset_password.rb @@ -71,7 +71,7 @@ def load_from_reset_password_token(token) # when reset_password_mailer_disabled is false def validate_mailer_defined msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)." - raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil and @sorcery_config.reset_password_mailer_disabled == false + raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil && @sorcery_config.reset_password_mailer_disabled == false end def define_reset_password_fields diff --git a/lib/sorcery/model/submodules/user_activation.rb b/lib/sorcery/model/submodules/user_activation.rb index 5c5bd5fa..b04bf55e 100644 --- a/lib/sorcery/model/submodules/user_activation.rb +++ b/lib/sorcery/model/submodules/user_activation.rb @@ -82,7 +82,7 @@ def load_from_activation_token(token) # when activation_mailer_disabled is false def validate_mailer_defined msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)." - raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil and @sorcery_config.activation_mailer_disabled == false + raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil && @sorcery_config.activation_mailer_disabled == false end def define_user_activation_fields diff --git a/lib/sorcery/providers/linkedin.rb b/lib/sorcery/providers/linkedin.rb index 9ac12e36..1dee7c5b 100644 --- a/lib/sorcery/providers/linkedin.rb +++ b/lib/sorcery/providers/linkedin.rb @@ -26,7 +26,7 @@ def initialize # Override included get_consumer method to provide authorize_path def get_consumer # Add access permissions to request token path - @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? or @configuration[:request_token_path].include? '?scope=' + @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? || @configuration[:request_token_path].include? '?scope=' ::OAuth::Consumer.new(@key, @secret, @configuration) end diff --git a/lib/sorcery/test_helpers/internal/rails.rb b/lib/sorcery/test_helpers/internal/rails.rb index 1a53d42c..07b5671c 100644 --- a/lib/sorcery/test_helpers/internal/rails.rb +++ b/lib/sorcery/test_helpers/internal/rails.rb @@ -40,7 +40,7 @@ def sorcery_reload!(submodules = [], options = {}) end end User.authenticates_with_sorcery! - if defined?(DataMapper) and User.ancestors.include?(DataMapper::Resource) + if defined?(DataMapper) && User.ancestors.include?(DataMapper::Resource) DataMapper.auto_migrate! User.finalize Authentication.finalize From f19f8ef32de19fe4b1e796802c5b440d0d96fe82 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 21:36:47 +0900 Subject: [PATCH 11/46] [rubocop] Removes non-ascii character --- lib/sorcery/controller/submodules/external.rb | 2 +- lib/sorcery/model/submodules/brute_force_protection.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sorcery/controller/submodules/external.rb b/lib/sorcery/controller/submodules/external.rb index 8688039e..9b6babdd 100644 --- a/lib/sorcery/controller/submodules/external.rb +++ b/lib/sorcery/controller/submodules/external.rb @@ -141,7 +141,7 @@ def add_provider_to_user(provider_name) current_user.add_provider_to_user(provider_name.to_s, @user_hash[:uid].to_s) end - # Initialize new user from provider informations. + # Initialize new user from provider informations. # If a provider doesn't give required informations or username/email is already taken, # we store provider/user infos into a session and can be rendered into registration form def create_and_validate_from(provider_name) diff --git a/lib/sorcery/model/submodules/brute_force_protection.rb b/lib/sorcery/model/submodules/brute_force_protection.rb index e176c471..eb2cebef 100644 --- a/lib/sorcery/model/submodules/brute_force_protection.rb +++ b/lib/sorcery/model/submodules/brute_force_protection.rb @@ -18,7 +18,7 @@ def self.included(base) :unlock_token_attribute_name, # Unlock token attribute name :unlock_token_email_method_name, # Mailer method name :unlock_token_mailer_disabled, # When true, dont send unlock token via email - :unlock_token_mailer # Mailer class + :unlock_token_mailer # Mailer class end base.sorcery_config.instance_eval do From 4d45c8efcbff61926cc0b411301fbab83c841b95 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 21:50:05 +0900 Subject: [PATCH 12/46] [rubocop] Changes :: to . for method calls --- lib/sorcery/providers/facebook.rb | 4 ++-- spec/controllers/controller_http_basic_auth_spec.rb | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/sorcery/providers/facebook.rb b/lib/sorcery/providers/facebook.rb index b80c0aac..6b5738ec 100644 --- a/lib/sorcery/providers/facebook.rb +++ b/lib/sorcery/providers/facebook.rb @@ -50,8 +50,8 @@ def authorize_url # Fix: replace default oauth2 options, specially to prevent the Faraday gem which # concatenates with "/", removing the Facebook api version options = { - site: File::join(@site, api_version.to_s), - authorize_url: File::join(@auth_site, api_version.to_s, auth_path), + site: File.join(@site, api_version.to_s), + authorize_url: File.join(@auth_site, api_version.to_s, auth_path), token_url: token_url } diff --git a/spec/controllers/controller_http_basic_auth_spec.rb b/spec/controllers/controller_http_basic_auth_spec.rb index 4dec045b..e0705dcf 100644 --- a/spec/controllers/controller_http_basic_auth_spec.rb +++ b/spec/controllers/controller_http_basic_auth_spec.rb @@ -25,7 +25,7 @@ # dirty hack for rails 4 allow(subject).to receive(:register_last_activity_time_to_db) - @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64::encode64("#{user.email}:secret")}" + @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{user.email}:secret")}" expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user) get :test_http_basic_auth, nil, http_authentication_used: true @@ -33,7 +33,7 @@ end it "fails authentication if credentials are wrong" do - @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64::encode64("#{user.email}:wrong!")}" + @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{user.email}:wrong!")}" expect(User).to receive('authenticate').with('bla@bla.com', 'wrong!').and_return(nil) get :test_http_basic_auth, nil, http_authentication_used: true @@ -57,7 +57,7 @@ # dirty hack for rails 4 allow(controller).to receive(:register_last_activity_time_to_db) - @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64::encode64("#{user.email}:secret")}" + @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{user.email}:secret")}" expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user) get :test_http_basic_auth, nil, http_authentication_used: true From 6f550238a445f9708986e171d670e59bc3ba5b93 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 21:54:12 +0900 Subject: [PATCH 13/46] [rubocop] Removes () from define non-arg method --- lib/sorcery/model.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sorcery/model.rb b/lib/sorcery/model.rb index 4c22d6d0..6aba267d 100644 --- a/lib/sorcery/model.rb +++ b/lib/sorcery/model.rb @@ -113,7 +113,7 @@ def encrypt(*tokens) protected - def set_encryption_attributes() + def set_encryption_attributes @sorcery_config.encryption_provider.stretches = @sorcery_config.stretches if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches @sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token end From 50f7ee14b83c256a47f22aea0ecf222b2fd9c3aa Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 22:04:06 +0900 Subject: [PATCH 14/46] [rubocop] Removes extra lines --- lib/sorcery/adapters/active_record_adapter.rb | 1 - lib/sorcery/model/config.rb | 1 - lib/sorcery/model/submodules/user_activation.rb | 1 - lib/sorcery/providers/jira.rb | 1 - lib/sorcery/providers/xing.rb | 1 - 5 files changed, 5 deletions(-) diff --git a/lib/sorcery/adapters/active_record_adapter.rb b/lib/sorcery/adapters/active_record_adapter.rb index 41a5e41b..5c97fe65 100644 --- a/lib/sorcery/adapters/active_record_adapter.rb +++ b/lib/sorcery/adapters/active_record_adapter.rb @@ -106,6 +106,5 @@ def transaction(&blk) end end - end end diff --git a/lib/sorcery/model/config.rb b/lib/sorcery/model/config.rb index 4d111e4d..9f4be0da 100644 --- a/lib/sorcery/model/config.rb +++ b/lib/sorcery/model/config.rb @@ -34,7 +34,6 @@ class Config # Default: :deliver (Rails version < 4.2) or :deliver_now (Rails version 4.2+) # method to send email related - :after_config # an array of method names to call after configuration by user. # used internally. diff --git a/lib/sorcery/model/submodules/user_activation.rb b/lib/sorcery/model/submodules/user_activation.rb index b04bf55e..52e5183c 100644 --- a/lib/sorcery/model/submodules/user_activation.rb +++ b/lib/sorcery/model/submodules/user_activation.rb @@ -64,7 +64,6 @@ def self.included(base) base.extend(ClassMethods) base.send(:include, InstanceMethods) - end module ClassMethods diff --git a/lib/sorcery/providers/jira.rb b/lib/sorcery/providers/jira.rb index faed807a..f65f2bac 100644 --- a/lib/sorcery/providers/jira.rb +++ b/lib/sorcery/providers/jira.rb @@ -13,7 +13,6 @@ class Jira < Base attr_accessor :access_token_path, :authorize_path, :request_token_path, :user_info_path, :site, :signature_method, :private_key_file, :callback_url - def initialize @configuration = { authorize_path: '/authorize', diff --git a/lib/sorcery/providers/xing.rb b/lib/sorcery/providers/xing.rb index a2048453..ba487bb3 100644 --- a/lib/sorcery/providers/xing.rb +++ b/lib/sorcery/providers/xing.rb @@ -13,7 +13,6 @@ class Xing < Base attr_accessor :access_token_path, :authorize_path, :request_token_path, :user_info_path - def initialize @configuration = { site: 'https://api.xing.com/v1', From 576d437e6ce1a84976115dca19ef798ac9fd229d Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Tue, 8 Nov 2016 22:31:39 +0900 Subject: [PATCH 15/46] Fixes wrong use of include?() --- lib/sorcery/providers/linkedin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sorcery/providers/linkedin.rb b/lib/sorcery/providers/linkedin.rb index 1dee7c5b..1a3dbaa4 100644 --- a/lib/sorcery/providers/linkedin.rb +++ b/lib/sorcery/providers/linkedin.rb @@ -26,7 +26,7 @@ def initialize # Override included get_consumer method to provide authorize_path def get_consumer # Add access permissions to request token path - @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? || @configuration[:request_token_path].include? '?scope=' + @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? || @configuration[:request_token_path].include?('?scope=') ::OAuth::Consumer.new(@key, @secret, @configuration) end From 26a0eab52e347a376168a27919ae841180c37e0f Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Wed, 9 Nov 2016 00:13:16 +0900 Subject: [PATCH 16/46] [rubocop] Removes trailing whitespaces --- .../controller/submodules/http_basic_auth.rb | 18 +++++++------- lib/sorcery/crypto_providers/aes256.rb | 18 +++++++------- lib/sorcery/crypto_providers/bcrypt.rb | 24 +++++++++---------- lib/sorcery/crypto_providers/md5.rb | 6 ++--- lib/sorcery/crypto_providers/sha1.rb | 4 ++-- lib/sorcery/crypto_providers/sha256.rb | 2 +- lib/sorcery/crypto_providers/sha512.rb | 2 +- lib/sorcery/model.rb | 2 +- lib/sorcery/test_helpers/rails/integration.rb | 2 +- spec/rails_app/app/mailers/sorcery_mailer.rb | 8 +++---- ...224223624_add_activity_logging_to_users.rb | 4 ++-- ...24223623_add_remember_me_token_to_users.rb | 4 ++-- .../user_remember_me_shared_examples.rb | 10 ++++---- .../user_reset_password_shared_examples.rb | 2 +- 14 files changed, 53 insertions(+), 53 deletions(-) diff --git a/lib/sorcery/controller/submodules/http_basic_auth.rb b/lib/sorcery/controller/submodules/http_basic_auth.rb index c18b4fb9..a6dd30b4 100644 --- a/lib/sorcery/controller/submodules/http_basic_auth.rb +++ b/lib/sorcery/controller/submodules/http_basic_auth.rb @@ -4,7 +4,7 @@ module Submodules # This submodule integrates HTTP Basic authentication into sorcery. # You are provided with a before action, require_login_from_http_basic, # which requests the browser for authentication. - # Then the rest of the submodule takes care of logging the user in + # Then the rest of the submodule takes care of logging the user in # into the session, so that the next requests will keep him logged in. module HttpBasicAuth def self.included(base) @@ -12,7 +12,7 @@ def self.included(base) Config.module_eval do class << self attr_accessor :controller_to_realm_map # What realm to display for which controller name. - + def merge_http_basic_auth_defaults! @defaults.merge!(:@controller_to_realm_map => {"application" => "Application"}) end @@ -21,18 +21,18 @@ def merge_http_basic_auth_defaults! end Config.login_sources << :login_from_basic_auth end - + module InstanceMethods protected - + # to be used as a before_action. # The method sets a session when requesting the user's credentials. # This is a trick to overcome the way HTTP authentication works (explained below): # - # Once the user fills the credentials once, the browser will always send it to the + # Once the user fills the credentials once, the browser will always send it to the # server when visiting the website, until the browser is closed. - # This causes wierd behaviour if the user logs out. The session is reset, yet the + # This causes wierd behaviour if the user logs out. The session is reset, yet the # user is re-logged in by the before_action calling 'login_from_basic_auth'. # To overcome this, we set a session when requesting the password, which logout will # reset, and that's how we know if we need to request for HTTP auth again. @@ -41,7 +41,7 @@ def require_login_from_http_basic require_login session[:http_authentication_used] = nil unless logged_in? end - + # given to main controller module as a login source callback def login_from_basic_auth authenticate_with_http_basic do |username, password| @@ -50,7 +50,7 @@ def login_from_basic_auth @current_user end end - + # Sets the realm name by searching the controller name in the hash given at configuration time. def realm_name_by_controller if defined?(ActionController::Base) @@ -65,7 +65,7 @@ def realm_name_by_controller Config.controller_to_realm_map["application"] end end - + end end diff --git a/lib/sorcery/crypto_providers/aes256.rb b/lib/sorcery/crypto_providers/aes256.rb index cd06d79b..42705f68 100644 --- a/lib/sorcery/crypto_providers/aes256.rb +++ b/lib/sorcery/crypto_providers/aes256.rb @@ -2,45 +2,45 @@ module Sorcery module CryptoProviders - # This encryption method is reversible if you have the supplied key. + # This encryption method is reversible if you have the supplied key. # So in order to use this encryption method you must supply it with a key first. # In an initializer, or before your application initializes, you should do the following: # # Sorcery::Model::ConfigAES256.key = "my 32 bytes long key" # - # My final comment is that this is a strong encryption method, + # My final comment is that this is a strong encryption method, # but its main weakness is that its reversible. If you do not need to reverse the hash # then you should consider Sha512 or BCrypt instead. # # Keep your key in a safe place, some even say the key should be stored on a separate server. - # This won't hurt performance because the only time it will try and access the key on the + # This won't hurt performance because the only time it will try and access the key on the # separate server is during initialization, which only - # happens once. The reasoning behind this is if someone does compromise your server they + # happens once. The reasoning behind this is if someone does compromise your server they # won't have the key also. Basically, you don't want to store the key with the lock. class AES256 class << self attr_writer :key - + def encrypt(*tokens) aes.encrypt aes.key = @key [aes.update(tokens.join) + aes.final].pack("m").chomp end - + def matches?(crypted, *tokens) decrypt(crypted) == tokens.join rescue OpenSSL::CipherError false end - + def decrypt(crypted) aes.decrypt aes.key = @key (aes.update(crypted.unpack("m").first) + aes.final) end - + private - + def aes raise ArgumentError.new("#{name} expects a 32 bytes long key. Please use Sorcery::Model::Config.encryption_key to set it.") if ( @key.nil? || @key == "" ) @aes ||= OpenSSL::Cipher::Cipher.new("AES-256-ECB") diff --git a/lib/sorcery/crypto_providers/bcrypt.rb b/lib/sorcery/crypto_providers/bcrypt.rb index 2e01d746..816f452b 100644 --- a/lib/sorcery/crypto_providers/bcrypt.rb +++ b/lib/sorcery/crypto_providers/bcrypt.rb @@ -2,9 +2,9 @@ module Sorcery module CryptoProviders - # For most apps Sha512 is plenty secure, but if you are building an app that stores nuclear + # For most apps Sha512 is plenty secure, but if you are building an app that stores nuclear # launch codes you might want to consier BCrypt. This is an extremely - # secure hashing algorithm, mainly because it is slow. + # secure hashing algorithm, mainly because it is slow. # A brute force attack on a BCrypt encrypted password would take much longer than a brute force attack on a # password encrypted with a Sha algorithm. Keep in mind you are sacrificing performance by using this, # generating a password takes exponentially longer than any @@ -40,9 +40,9 @@ module CryptoProviders # You are good to go! class BCrypt class << self - # This is the :cost option for the BCrpyt library. + # This is the :cost option for the BCrpyt library. # The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10. - # Set this to whatever you want, play around with it to get that perfect balance between + # Set this to whatever you want, play around with it to get that perfect balance between # security and performance. def cost @cost ||= 10 @@ -50,20 +50,20 @@ def cost attr_writer :cost alias :stretches :cost alias :stretches= :cost= - + # Creates a BCrypt hash for the password passed. def encrypt(*tokens) ::BCrypt::Password.create(join_tokens(tokens), :cost => cost) end - + # Does the hash match the tokens? Uses the same tokens that were used to encrypt. def matches?(hash, *tokens) hash = new_from_hash(hash) return false if hash.nil? || hash == {} hash == join_tokens(tokens) end - - # This method is used as a flag to tell Sorcery to "resave" the password + + # This method is used as a flag to tell Sorcery to "resave" the password # upon a successful login, using the new cost def cost_matches?(hash) hash = new_from_hash(hash) @@ -73,17 +73,17 @@ def cost_matches?(hash) hash.cost == cost end end - + def reset! @cost = 10 end - + private - + def join_tokens(tokens) tokens.flatten.join end - + def new_from_hash(hash) begin ::BCrypt::Password.new(hash) diff --git a/lib/sorcery/crypto_providers/md5.rb b/lib/sorcery/crypto_providers/md5.rb index f359e561..5dbfcc6c 100644 --- a/lib/sorcery/crypto_providers/md5.rb +++ b/lib/sorcery/crypto_providers/md5.rb @@ -1,9 +1,9 @@ require "digest/md5" - + module Sorcery module CryptoProviders - # This class was made for the users transitioning from md5 based systems. - # I highly discourage using this crypto provider as it superbly inferior + # This class was made for the users transitioning from md5 based systems. + # I highly discourage using this crypto provider as it superbly inferior # to your other options. # # Please use any other provider offered by Sorcery. diff --git a/lib/sorcery/crypto_providers/sha1.rb b/lib/sorcery/crypto_providers/sha1.rb index 266ef703..91cc14a7 100644 --- a/lib/sorcery/crypto_providers/sha1.rb +++ b/lib/sorcery/crypto_providers/sha1.rb @@ -10,7 +10,7 @@ class << self def join_token @join_token ||= "--" end - + # Turns your raw password into a Sha1 hash. def encrypt(*tokens) tokens = tokens.flatten @@ -18,7 +18,7 @@ def encrypt(*tokens) stretches.times { digest = secure_digest([digest, *tokens].join(join_token)) } digest end - + def secure_digest(digest) Digest::SHA1.hexdigest(digest) end diff --git a/lib/sorcery/crypto_providers/sha256.rb b/lib/sorcery/crypto_providers/sha256.rb index a979adc3..df525e69 100644 --- a/lib/sorcery/crypto_providers/sha256.rb +++ b/lib/sorcery/crypto_providers/sha256.rb @@ -1,7 +1,7 @@ require "digest/sha2" module Sorcery - # The activate_sorcery method has a custom_crypto_provider configuration option. + # The activate_sorcery method has a custom_crypto_provider configuration option. # This allows you to use any type of encryption you like. # Just create a class with a class level encrypt and matches? method. See example below. # diff --git a/lib/sorcery/crypto_providers/sha512.rb b/lib/sorcery/crypto_providers/sha512.rb index 58f7d079..51ba6523 100644 --- a/lib/sorcery/crypto_providers/sha512.rb +++ b/lib/sorcery/crypto_providers/sha512.rb @@ -1,7 +1,7 @@ require "digest/sha2" module Sorcery - # The activate_sorcery method has a custom_crypto_provider configuration option. + # The activate_sorcery method has a custom_crypto_provider configuration option. # This allows you to use any type of encryption you like. # Just create a class with a class level encrypt and matches? method. See example below. # diff --git a/lib/sorcery/model.rb b/lib/sorcery/model.rb index 6aba267d..371e7cd1 100644 --- a/lib/sorcery/model.rb +++ b/lib/sorcery/model.rb @@ -117,7 +117,7 @@ def set_encryption_attributes @sorcery_config.encryption_provider.stretches = @sorcery_config.stretches if @sorcery_config.encryption_provider.respond_to?(:stretches) && @sorcery_config.stretches @sorcery_config.encryption_provider.join_token = @sorcery_config.salt_join_token if @sorcery_config.encryption_provider.respond_to?(:join_token) && @sorcery_config.salt_join_token end - + def add_config_inheritance self.class_eval do def self.inherited(subclass) diff --git a/lib/sorcery/test_helpers/rails/integration.rb b/lib/sorcery/test_helpers/rails/integration.rb index 1f243f86..eb64dfad 100644 --- a/lib/sorcery/test_helpers/rails/integration.rb +++ b/lib/sorcery/test_helpers/rails/integration.rb @@ -2,7 +2,7 @@ module Sorcery module TestHelpers module Rails module Integration - + #Accepts arguments for user to login, route to use and HTTP method #Defaults - @user, 'sessions_url' and POST def login_user(user = nil, route = nil, http_method = :post) diff --git a/spec/rails_app/app/mailers/sorcery_mailer.rb b/spec/rails_app/app/mailers/sorcery_mailer.rb index 7b0236e9..2692755a 100644 --- a/spec/rails_app/app/mailers/sorcery_mailer.rb +++ b/spec/rails_app/app/mailers/sorcery_mailer.rb @@ -1,21 +1,21 @@ class SorceryMailer < ActionMailer::Base - + default :from => "notifications@example.com" - + def activation_needed_email(user) @user = user @url = "http://example.com/login" mail(:to => user.email, :subject => "Welcome to My Awesome Site") end - + def activation_success_email(user) @user = user @url = "http://example.com/login" mail(:to => user.email, :subject => "Your account is now activated") end - + def reset_password_email(user) @user = user @url = "http://example.com/login" diff --git a/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb b/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb index ffc64aa4..603fb2dd 100644 --- a/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +++ b/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb @@ -4,13 +4,13 @@ def self.up add_column :users, :last_logout_at, :datetime, :default => nil add_column :users, :last_activity_at, :datetime, :default => nil add_column :users, :last_login_from_ip_address, :string, :default => nil - + add_index :users, [:last_logout_at, :last_activity_at] end def self.down remove_index :users, [:last_logout_at, :last_activity_at] - + remove_column :users, :last_activity_at remove_column :users, :last_logout_at remove_column :users, :last_login_at diff --git a/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb b/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb index df8b986d..30b33e0f 100644 --- a/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +++ b/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb @@ -2,13 +2,13 @@ class AddRememberMeTokenToUsers < ActiveRecord::Migration def self.up add_column :users, :remember_me_token, :string, :default => nil add_column :users, :remember_me_token_expires_at, :datetime, :default => nil - + add_index :users, :remember_me_token end def self.down remove_index :users, :remember_me_token - + remove_column :users, :remember_me_token_expires_at remove_column :users, :remember_me_token end diff --git a/spec/shared_examples/user_remember_me_shared_examples.rb b/spec/shared_examples/user_remember_me_shared_examples.rb index db1a9671..8c89e6d3 100644 --- a/spec/shared_examples/user_remember_me_shared_examples.rb +++ b/spec/shared_examples/user_remember_me_shared_examples.rb @@ -6,11 +6,11 @@ before(:all) do sorcery_reload!([:remember_me]) end - + after(:each) do User.sorcery_config.reset! end - + it "allows configuration option 'remember_me_token_attribute_name'" do sorcery_model_property_set(:remember_me_token_attribute_name, :my_token) @@ -28,13 +28,13 @@ expect(User.sorcery_config.remember_me_token_persist_globally).to eq true end - + specify { expect(user).to respond_to :remember_me! } specify { expect(user).to respond_to :forget_me! } specify { expect(user).to respond_to :force_forget_me! } - + it "sets an expiration based on 'remember_me_for' attribute" do sorcery_model_property_set(:remember_me_for, 2 * 60 * 60 * 24) @@ -45,7 +45,7 @@ expect(user.remember_me_token_expires_at.utc.to_s).to eq (ts + 2 * 60 * 60 * 24).utc.to_s end - + context "when not persisting globally" do before { sorcery_model_property_set(:remember_me_token_persist_globally, false) } diff --git a/spec/shared_examples/user_reset_password_shared_examples.rb b/spec/shared_examples/user_reset_password_shared_examples.rb index 02a2b786..c0e96bda 100644 --- a/spec/shared_examples/user_reset_password_shared_examples.rb +++ b/spec/shared_examples/user_reset_password_shared_examples.rb @@ -142,7 +142,7 @@ it "'deliver_reset_password_instructions! returns a Mail::Message object" do expect(user.deliver_reset_password_instructions!).to be_an_instance_of Mail::Message - end + end it "the reset_password_token is random" do sorcery_model_property_set(:reset_password_time_between_emails, 0) From 6ad0d221f404145e7d77015f4fe4ed7c0836d5cc Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Wed, 9 Nov 2016 13:16:39 +0900 Subject: [PATCH 17/46] [rubocop] Removes comma from last element in hash --- lib/sorcery/model/config.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sorcery/model/config.rb b/lib/sorcery/model/config.rb index 9f4be0da..5774f0d8 100644 --- a/lib/sorcery/model/config.rb +++ b/lib/sorcery/model/config.rb @@ -59,7 +59,7 @@ def initialize :@subclasses_inherit_config => false, :@before_authenticate => [], :@after_config => [], - :@email_delivery_method => default_email_delivery_method, + :@email_delivery_method => default_email_delivery_method } reset! end From 38e247aabb628c572f46a333d7494490e45d3a24 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Wed, 9 Nov 2016 13:29:28 +0900 Subject: [PATCH 18/46] [rubocop] Fixes pass arg to map instead of block --- lib/sorcery/controller.rb | 2 +- lib/sorcery/model.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sorcery/controller.rb b/lib/sorcery/controller.rb index cc790e25..6cfb5600 100644 --- a/lib/sorcery/controller.rb +++ b/lib/sorcery/controller.rb @@ -5,7 +5,7 @@ def self.included(klass) include InstanceMethods Config.submodules.each do |mod| begin - include Submodules.const_get(mod.to_s.split('_').map { |p| p.capitalize }.join) + include Submodules.const_get(mod.to_s.split('_').map(&:capitalize).join) rescue NameError # don't stop on a missing submodule. end diff --git a/lib/sorcery/model.rb b/lib/sorcery/model.rb index 371e7cd1..43053e3d 100644 --- a/lib/sorcery/model.rb +++ b/lib/sorcery/model.rb @@ -49,7 +49,7 @@ def include_required_submodules! @sorcery_config.submodules = ::Sorcery::Controller::Config.submodules @sorcery_config.submodules.each do |mod| begin - include Submodules.const_get(mod.to_s.split('_').map {|p| p.capitalize}.join) + include Submodules.const_get(mod.to_s.split('_').map(&:capitalize).join) rescue NameError # don't stop on a missing submodule. Needed because some submodules are only defined # in the controller side. From ea6d46f1992c5000b9980303dd8ee4c935479d28 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Wed, 9 Nov 2016 14:07:36 +0900 Subject: [PATCH 19/46] [rubocop] Removes spaces inside square brackets --- spec/rails_app/config/application.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/rails_app/config/application.rb b/spec/rails_app/config/application.rb index f28835f3..2066817c 100644 --- a/spec/rails_app/config/application.rb +++ b/spec/rails_app/config/application.rb @@ -16,7 +16,7 @@ module AppRoot class Application < Rails::Application config.autoload_paths.reject!{ |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers mailers views).include?($1) } - config.autoload_paths += [ "#{config.root}/app/#{SORCERY_ORM}" ] + config.autoload_paths += ["#{config.root}/app/#{SORCERY_ORM}"] # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers From 2a0c406a1d7075407732c1a7abae97110c218e04 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Wed, 9 Nov 2016 14:18:49 +0900 Subject: [PATCH 20/46] [rubocop] Removes parentheses around the condition of an if --- lib/sorcery/controller/submodules/external.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sorcery/controller/submodules/external.rb b/lib/sorcery/controller/submodules/external.rb index 9b6babdd..946c5128 100644 --- a/lib/sorcery/controller/submodules/external.rb +++ b/lib/sorcery/controller/submodules/external.rb @@ -101,7 +101,7 @@ def sorcery_fixup_callback_url(provider) uri = URI.parse(request.url.gsub(/\?.*$/,'')) uri.path = '' uri.query = nil - uri.scheme = 'https' if(request.env['HTTP_X_FORWARDED_PROTO'] == 'https') + uri.scheme = 'https' if request.env['HTTP_X_FORWARDED_PROTO'] == 'https' host = uri.to_s provider.callback_url = "#{host}#{@provider.original_callback_url}" end From ae7d146f7355dba36a5e7a0c683ec7f931ba4564 Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Wed, 9 Nov 2016 14:20:37 +0900 Subject: [PATCH 21/46] [rubocop] Fixes spaces missing in default value assignment --- lib/sorcery/adapters/active_record_adapter.rb | 4 ++-- lib/sorcery/protocols/oauth.rb | 2 +- lib/sorcery/providers/base.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/sorcery/adapters/active_record_adapter.rb b/lib/sorcery/adapters/active_record_adapter.rb index 5c97fe65..89bd7c3e 100644 --- a/lib/sorcery/adapters/active_record_adapter.rb +++ b/lib/sorcery/adapters/active_record_adapter.rb @@ -29,11 +29,11 @@ def find_authentication_by_oauth_credentials(relation_name, provider, uid) end class << self - def define_field(name, type, options={}) + def define_field(name, type, options = {}) # AR fields are defined through migrations, only validator here end - def define_callback(time, event, method_name, options={}) + def define_callback(time, event, method_name, options = {}) @klass.send "#{time}_#{event}", method_name, options.slice(:if) end diff --git a/lib/sorcery/protocols/oauth.rb b/lib/sorcery/protocols/oauth.rb index b30355ce..3ee7f7a7 100644 --- a/lib/sorcery/protocols/oauth.rb +++ b/lib/sorcery/protocols/oauth.rb @@ -8,7 +8,7 @@ def oauth_version '1.0' end - def get_request_token(token=nil,secret=nil) + def get_request_token(token = nil,secret = nil) return ::OAuth::RequestToken.new(get_consumer, token, secret) if token && secret get_consumer.get_request_token(oauth_callback: @callback_url) end diff --git a/lib/sorcery/providers/base.rb b/lib/sorcery/providers/base.rb index c3fce2ad..eca67367 100644 --- a/lib/sorcery/providers/base.rb +++ b/lib/sorcery/providers/base.rb @@ -13,7 +13,7 @@ def initialize @user_info_mapping = {} end - def auth_hash(access_token, hash={}) + def auth_hash(access_token, hash = {}) return hash if access_token.nil? token_hash = hash.dup From d11b46dad9186f42f14c29a2fb409a33d093c38e Mon Sep 17 00:00:00 2001 From: Yusuke Ebihara Date: Fri, 11 Nov 2016 17:41:38 +0900 Subject: [PATCH 22/46] Fix the bug that after running specs there remains the table, users and version in schema_migrations. --- spec/controllers/controller_oauth2_spec.rb | 1 + spec/shared_examples/user_shared_examples.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index c238219a..3a960e55 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -237,6 +237,7 @@ after(:all) do if SORCERY_ORM == :active_record + ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external") ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation") end end diff --git a/spec/shared_examples/user_shared_examples.rb b/spec/shared_examples/user_shared_examples.rb index 27522b3e..b242c168 100644 --- a/spec/shared_examples/user_shared_examples.rb +++ b/spec/shared_examples/user_shared_examples.rb @@ -532,8 +532,8 @@ def self.matches?(crypted,*tokens) after(:all) do if SORCERY_ORM == :active_record - ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation") ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external") + ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation") end end From 428534c9f7385cf7d2b7c0818a5469579366839e Mon Sep 17 00:00:00 2001 From: kyuden Date: Tue, 15 Nov 2016 00:34:59 +0900 Subject: [PATCH 23/46] Use urlsafe_base64 for url sensitive chars --- lib/sorcery/model/temporary_token.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sorcery/model/temporary_token.rb b/lib/sorcery/model/temporary_token.rb index 44854ffd..23c6712b 100644 --- a/lib/sorcery/model/temporary_token.rb +++ b/lib/sorcery/model/temporary_token.rb @@ -12,7 +12,7 @@ def self.included(base) # Random code, used for salt and temporary tokens. def self.generate_random_token - SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz') + SecureRandom.urlsafe_base64(15).tr('lIO0', 'sxyz') end module ClassMethods From 244e8ad5ea0838c6e8186a11c2fe500e96f4d82f Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 27 Nov 2016 22:07:24 +0900 Subject: [PATCH 24/46] Test against rails 5 by default --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index ed7c959b..7e86869a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ source 'https://rubygems.org' -gem 'rails', '~> 4.0' +gem 'rails', '~> 5.0.0' gem 'sqlite3' gem 'pry' From 154d1c29d85f8b0e16f3ac736dd32e0f1950338b Mon Sep 17 00:00:00 2001 From: asmsuechan Date: Mon, 5 Dec 2016 22:24:26 +0900 Subject: [PATCH 25/46] Fixes wrong use of include?() --- lib/sorcery/providers/linkedin.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sorcery/providers/linkedin.rb b/lib/sorcery/providers/linkedin.rb index 9ac12e36..380782b0 100644 --- a/lib/sorcery/providers/linkedin.rb +++ b/lib/sorcery/providers/linkedin.rb @@ -26,7 +26,7 @@ def initialize # Override included get_consumer method to provide authorize_path def get_consumer # Add access permissions to request token path - @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? or @configuration[:request_token_path].include? '?scope=' + @configuration[:request_token_path] += '?scope=' + access_permissions.join('+') unless access_permissions.blank? or @configuration[:request_token_path].include?('?scope=') ::OAuth::Consumer.new(@key, @secret, @configuration) end From 78d363ae28c1dc5db75742f4f9ca88dcbc0aa198 Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 27 Nov 2016 22:52:36 +0900 Subject: [PATCH 26/46] Use rails-controller-testing gem because `assigns` was deleted on rails5 Failure/Error: expect(cookies.signed["remember_me_token"]).to eq assigns[:current_user].remember_me_token NoMethodError: assigns has been extracted to a gem. To continue using it, add `gem 'rails-controller-testing'` to your Gemfile. ./spec/controllers/controller_remember_me_spec.rb:32:in `block (3 levels) in --- Gemfile | 1 + spec/controllers/controller_activity_logging_spec.rb | 2 +- spec/controllers/controller_brute_force_protection_spec.rb | 2 +- spec/controllers/controller_http_basic_auth_spec.rb | 2 +- spec/controllers/controller_oauth2_spec.rb | 2 +- spec/controllers/controller_oauth_spec.rb | 2 +- spec/controllers/controller_remember_me_spec.rb | 2 +- spec/controllers/controller_session_timeout_spec.rb | 2 +- spec/controllers/controller_spec.rb | 2 +- spec/spec_helper.rb | 6 ++++++ 10 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index 7e86869a..7d2e1a5b 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,7 @@ source 'https://rubygems.org' gem 'rails', '~> 5.0.0' +gem 'rails-controller-testing' gem 'sqlite3' gem 'pry' diff --git a/spec/controllers/controller_activity_logging_spec.rb b/spec/controllers/controller_activity_logging_spec.rb index 307a2c9a..42360f49 100644 --- a/spec/controllers/controller_activity_logging_spec.rb +++ b/spec/controllers/controller_activity_logging_spec.rb @@ -2,7 +2,7 @@ # require 'shared_examples/controller_activity_logging_shared_examples' -describe SorceryController do +describe SorceryController, :type => :controller do after(:all) do sorcery_controller_property_set(:register_login_time, true) sorcery_controller_property_set(:register_logout_time, true) diff --git a/spec/controllers/controller_brute_force_protection_spec.rb b/spec/controllers/controller_brute_force_protection_spec.rb index cc71ccc9..fce5c7fd 100644 --- a/spec/controllers/controller_brute_force_protection_spec.rb +++ b/spec/controllers/controller_brute_force_protection_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SorceryController do +describe SorceryController, :type => :controller do let(:user) { double('user', id: 42, email: 'bla@bla.com') } diff --git a/spec/controllers/controller_http_basic_auth_spec.rb b/spec/controllers/controller_http_basic_auth_spec.rb index 4dec045b..0bb5072e 100644 --- a/spec/controllers/controller_http_basic_auth_spec.rb +++ b/spec/controllers/controller_http_basic_auth_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SorceryController do +describe SorceryController, :type => :controller do let(:user) { double("user", id: 42, email: 'bla@bla.com') } diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index c238219a..090b2d65 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -2,7 +2,7 @@ # require 'shared_examples/controller_oauth2_shared_examples' -describe SorceryController, :active_record => true do +describe SorceryController, :active_record => true, :type => :controller do before(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external") diff --git a/spec/controllers/controller_oauth_spec.rb b/spec/controllers/controller_oauth_spec.rb index 24e14099..39331b22 100644 --- a/spec/controllers/controller_oauth_spec.rb +++ b/spec/controllers/controller_oauth_spec.rb @@ -21,7 +21,7 @@ def stub_all_oauth_requests! allow(acc_token).to receive(:get) { response } end -describe SorceryController do +describe SorceryController, :type => :controller do let(:user) { double('user', id: 42) } diff --git a/spec/controllers/controller_remember_me_spec.rb b/spec/controllers/controller_remember_me_spec.rb index ba262328..4cf11916 100644 --- a/spec/controllers/controller_remember_me_spec.rb +++ b/spec/controllers/controller_remember_me_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SorceryController do +describe SorceryController, :type => :controller do let!(:user) { double('user', id: 42) } diff --git a/spec/controllers/controller_session_timeout_spec.rb b/spec/controllers/controller_session_timeout_spec.rb index b445bba9..8dcbcdca 100644 --- a/spec/controllers/controller_session_timeout_spec.rb +++ b/spec/controllers/controller_session_timeout_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SorceryController do +describe SorceryController, :type => :controller do let!(:user) { double('user', id: 42) } diff --git a/spec/controllers/controller_spec.rb b/spec/controllers/controller_spec.rb index 4f32afc4..795bb25e 100644 --- a/spec/controllers/controller_spec.rb +++ b/spec/controllers/controller_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SorceryController do +describe SorceryController, :type => :controller do describe "plugin configuration" do before(:all) do sorcery_reload! diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 702b60f2..c8530841 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -38,4 +38,10 @@ class TestMailer < ActionMailer::Base;end config.include ::Sorcery::TestHelpers::Internal config.include ::Sorcery::TestHelpers::Internal::Rails + + if ((Module.const_defined?('::Rails::Controller::Testing') rescue false)) + config.include ::Rails::Controller::Testing::TestProcess, :type => :controller + config.include ::Rails::Controller::Testing::TemplateAssertions, :type => :controller + config.include ::Rails::Controller::Testing::Integration, :type => :controller + end end From 4da8ca3e7ae571fe1f90eaa69342f31dcb88720a Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 27 Nov 2016 23:06:27 +0900 Subject: [PATCH 27/46] Fix warning of `:nothing` option DEPRECATION WARNING: `:nothing` option is deprecated and will be removed in Rails 5.1. Use `head` method to respond with empty response body. (called from test_auto_login at /Users/kyuden/go/src/github.com/kyuden/sorcery/spec/rails_app/app/controllers/sorcery_controller.rb:30) --- .../app/controllers/sorcery_controller.rb | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec/rails_app/app/controllers/sorcery_controller.rb b/spec/rails_app/app/controllers/sorcery_controller.rb index 8f1f3c78..95bba6b4 100644 --- a/spec/rails_app/app/controllers/sorcery_controller.rb +++ b/spec/rails_app/app/controllers/sorcery_controller.rb @@ -10,24 +10,24 @@ def index end def some_action - render nothing: true + head :ok end def some_action_making_a_non_persisted_change_to_the_user current_user.email = 'to_be_ignored' - render nothing: true + head :ok end def test_login @user = login(params[:email], params[:password]) - render nothing: true + head :ok end def test_auto_login @user = User.first auto_login(@user) @result = current_user - render nothing: true + head :ok end def test_return_to @@ -37,38 +37,38 @@ def test_return_to def test_logout logout - render nothing: true + head :ok end def test_logout_with_remember remember_me! logout - render nothing: true + head :ok end def test_logout_with_force_forget_me remember_me! force_forget_me! logout - render nothing: true + head :ok end def test_login_with_remember @user = login(params[:email], params[:password]) remember_me! - render nothing: true + head :ok end def test_login_with_remember_in_login @user = login(params[:email], params[:password], params[:remember]) - render nothing: true + head :ok end def test_login_from_cookie @user = current_user - render nothing: true + head :ok end def test_not_authenticated_action @@ -76,7 +76,7 @@ def test_not_authenticated_action end def test_should_be_logged_in - render nothing: true + head :ok end def test_http_basic_auth From 6e7a49f43a86ee7705c07b67ad2220f544418d1f Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 27 Nov 2016 23:43:15 +0900 Subject: [PATCH 28/46] Fix warning of HTTP request methods DEPRECATION WARNING: ActionController::TestCase HTTP request methods will accept only keyword arguments in future Rails versions. --- lib/sorcery/test_helpers/internal/rails.rb | 8 ++++++++ .../controller_brute_force_protection_spec.rb | 4 ++-- .../controller_http_basic_auth_spec.rb | 6 +++--- spec/controllers/controller_oauth2_spec.rb | 12 ++++++------ spec/controllers/controller_oauth_spec.rb | 16 ++++++++-------- spec/controllers/controller_remember_me_spec.rb | 8 ++++---- .../controller_session_timeout_spec.rb | 6 +++--- spec/controllers/controller_spec.rb | 6 +++--- 8 files changed, 37 insertions(+), 29 deletions(-) diff --git a/lib/sorcery/test_helpers/internal/rails.rb b/lib/sorcery/test_helpers/internal/rails.rb index 1a53d42c..e5619036 100644 --- a/lib/sorcery/test_helpers/internal/rails.rb +++ b/lib/sorcery/test_helpers/internal/rails.rb @@ -62,6 +62,14 @@ def sorcery_controller_external_property_set(provider, property, value) def clear_user_without_logout subject.instance_variable_set(:@current_user,nil) end + + if ::Rails.version < '5.0.0' + %w( get post put ).each do |method| + define_method(method) do |action, options={}| + super action, options[:params] || {}, options[:session] + end + end + end end end end diff --git a/spec/controllers/controller_brute_force_protection_spec.rb b/spec/controllers/controller_brute_force_protection_spec.rb index fce5c7fd..392b09e0 100644 --- a/spec/controllers/controller_brute_force_protection_spec.rb +++ b/spec/controllers/controller_brute_force_protection_spec.rb @@ -5,7 +5,7 @@ let(:user) { double('user', id: 42, email: 'bla@bla.com') } def request_test_login - get :test_login, email: 'bla@bla.com', password: 'blabla' + get :test_login, :params => { email: 'bla@bla.com', password: 'blabla' } end # ----------------- SESSION TIMEOUT ----------------------- @@ -37,7 +37,7 @@ def request_test_login allow(User).to receive(:authenticate).and_return(user) expect(user).to receive_message_chain(:sorcery_adapter, :update_attribute).with(:failed_logins_count, 0) - get :test_login, email: 'bla@bla.com', password: 'secret' + get :test_login, :params => { email: 'bla@bla.com', password: 'secret' } end end end diff --git a/spec/controllers/controller_http_basic_auth_spec.rb b/spec/controllers/controller_http_basic_auth_spec.rb index 0bb5072e..262a494f 100644 --- a/spec/controllers/controller_http_basic_auth_spec.rb +++ b/spec/controllers/controller_http_basic_auth_spec.rb @@ -27,7 +27,7 @@ @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64::encode64("#{user.email}:secret")}" expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user) - get :test_http_basic_auth, nil, http_authentication_used: true + get :test_http_basic_auth, :params => {}, session: { :http_authentication_used => true } expect(response).to be_a_success end @@ -35,7 +35,7 @@ it "fails authentication if credentials are wrong" do @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64::encode64("#{user.email}:wrong!")}" expect(User).to receive('authenticate').with('bla@bla.com', 'wrong!').and_return(nil) - get :test_http_basic_auth, nil, http_authentication_used: true + get :test_http_basic_auth, :params => {}, session: { :http_authentication_used => true } expect(response).to redirect_to root_url end @@ -60,7 +60,7 @@ @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64::encode64("#{user.email}:secret")}" expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user) - get :test_http_basic_auth, nil, http_authentication_used: true + get :test_http_basic_auth, :params => {}, session: { :http_authentication_used => true } expect(session[:user_id]).to eq "42" end diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index 090b2d65..176f44b8 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -29,7 +29,7 @@ sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name' }) expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}) - get :test_create_from_provider, provider: 'facebook' + get :test_create_from_provider, :params => { provider: 'facebook' } end it 'supports nested attributes' do @@ -37,7 +37,7 @@ sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'hometown/name' }) expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Haifa, Israel'}) - get :test_create_from_provider, provider: 'facebook' + get :test_create_from_provider, :params => { provider: 'facebook' } end it 'does not crash on missing nested attributes' do @@ -46,7 +46,7 @@ expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}) - get :test_create_from_provider, provider: 'facebook' + get :test_create_from_provider, :params => { provider: 'facebook' } end describe 'with a block' do @@ -57,7 +57,7 @@ u = double('user') expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}).and_return(u).and_yield(u) # test_create_from_provider_with_block in controller will check for uniqueness of username - get :test_create_from_provider_with_block, provider: 'facebook' + get :test_create_from_provider_with_block, :params => { provider: 'facebook' } end end end @@ -146,7 +146,7 @@ sorcery_model_property_set(:authentications_class, Authentication) expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user) - get :test_return_to_with_external_facebook, {}, :return_to_url => "fuu" + get :test_return_to_with_external_facebook, :params => {}, session: { :return_to_url => "fuu" } expect(response).to redirect_to("fuu") expect(flash[:notice]).to eq "Success!" @@ -188,7 +188,7 @@ sorcery_model_property_set(:authentications_class, Authentication) expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user) - get :"test_return_to_with_external_#{provider}", {}, :return_to_url => "fuu" + get :"test_return_to_with_external_#{provider}", :params => {}, session: { :return_to_url => "fuu" } expect(response).to redirect_to "fuu" expect(flash[:notice]).to eq "Success!" diff --git a/spec/controllers/controller_oauth_spec.rb b/spec/controllers/controller_oauth_spec.rb index 39331b22..8305d98c 100644 --- a/spec/controllers/controller_oauth_spec.rb +++ b/spec/controllers/controller_oauth_spec.rb @@ -72,20 +72,20 @@ def stub_all_oauth_requests! it "logins if user exists" do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(user) - get :test_login_from, :oauth_verifier => "blablaRERASDFcxvSDFA" + get :test_login_from, :params => { :oauth_verifier => "blablaRERASDFcxvSDFA" } expect(flash[:notice]).to eq "Success!" end it "'login_from' fails if user doesn't exist" do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(nil) - get :test_login_from, :oauth_verifier => "blablaRERASDFcxvSDFA" + get :test_login_from, :params => { :oauth_verifier => "blablaRERASDFcxvSDFA" } expect(flash[:alert]).to eq "Failed!" end it "on successful 'login_from' the user is redirected to the url he originally wanted" do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(user) - get :test_return_to_with_external, {}, :return_to_url => "fuu" + get :test_return_to_with_external, params: {}, :session => { :return_to_url => "fuu" } expect(response).to redirect_to("fuu") expect(flash[:notice]).to eq "Success!" end @@ -111,7 +111,7 @@ def stub_all_oauth_requests! expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'nbenari'}).and_return(user) - get :test_create_from_provider, :provider => "twitter" + get :test_create_from_provider, :params => { :provider => "twitter" } end it "supports nested attributes" do @@ -119,7 +119,7 @@ def stub_all_oauth_requests! expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'coming soon to sorcery gem: twitter and facebook authentication support.'}).and_return(user) - get :test_create_from_provider, :provider => "twitter" + get :test_create_from_provider, :params => { :provider => "twitter" } end it "does not crash on missing nested attributes" do @@ -127,7 +127,7 @@ def stub_all_oauth_requests! expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'coming soon to sorcery gem: twitter and facebook authentication support.'}).and_return(user) - get :test_create_from_provider, :provider => "twitter" + get :test_create_from_provider, :params => { :provider => "twitter" } end it "binds new provider" do @@ -138,7 +138,7 @@ def stub_all_oauth_requests! login_user(user) expect(user).to receive(:add_provider_to_user).with('twitter', '123') - get :test_add_second_provider, :provider => "twitter" + get :test_add_second_provider, :params => { :provider => "twitter" } end describe "with a block" do @@ -150,7 +150,7 @@ def stub_all_oauth_requests! expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'nbenari'}).and_return(u).and_yield(u) - get :test_create_from_provider_with_block, :provider => "twitter" + get :test_create_from_provider_with_block, :params => { :provider => "twitter" } end end diff --git a/spec/controllers/controller_remember_me_spec.rb b/spec/controllers/controller_remember_me_spec.rb index 4cf11916..447da320 100644 --- a/spec/controllers/controller_remember_me_spec.rb +++ b/spec/controllers/controller_remember_me_spec.rb @@ -27,7 +27,7 @@ expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) expect(user).to receive(:remember_me!) - post :test_login_with_remember, :email => 'bla@bla.com', :password => 'secret' + post :test_login_with_remember, :params => { :email => 'bla@bla.com', :password => 'secret' } expect(cookies.signed["remember_me_token"]).to eq assigns[:current_user].remember_me_token end @@ -51,7 +51,7 @@ expect(user).to receive(:remember_me!) expect(user).to receive(:remember_me_token).and_return('abracadabra').twice - post :test_login_with_remember_in_login, :email => 'bla@bla.com', :password => 'secret', :remember => "1" + post :test_login_with_remember_in_login, :params => { :email => 'bla@bla.com', :password => 'secret', :remember => "1" } expect(cookies.signed["remember_me_token"]).not_to be_nil expect(cookies.signed["remember_me_token"]).to eq assigns[:user].remember_me_token @@ -88,13 +88,13 @@ end it "doest not remember_me! when not asked to, even if third parameter is used" do - post :test_login_with_remember_in_login, :email => 'bla@bla.com', :password => 'secret', :remember => "0" + post :test_login_with_remember_in_login, :params => { :email => 'bla@bla.com', :password => 'secret', :remember => "0" } expect(cookies["remember_me_token"]).to be_nil end it "doest not remember_me! when not asked to" do - post :test_login, :email => 'bla@bla.com', :password => 'secret' + post :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } expect(cookies["remember_me_token"]).to be_nil end diff --git a/spec/controllers/controller_session_timeout_spec.rb b/spec/controllers/controller_session_timeout_spec.rb index 8dcbcdca..b5a6f374 100644 --- a/spec/controllers/controller_session_timeout_spec.rb +++ b/spec/controllers/controller_session_timeout_spec.rb @@ -42,7 +42,7 @@ # TODO: ??? expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) - get :test_login, :email => 'bla@bla.com', :password => 'secret' + get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } expect(session[:user_id]).not_to be_nil expect(response).to be_a_success @@ -53,7 +53,7 @@ sorcery_controller_property_set(:session_timeout_from_last_action, true) expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) - get :test_login, :email => 'bla@bla.com', :password => 'secret' + get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } Timecop.travel(Time.now.in_time_zone+0.3) get :test_should_be_logged_in @@ -68,7 +68,7 @@ it "with 'session_timeout_from_last_action' logs out if there was no activity" do sorcery_controller_property_set(:session_timeout_from_last_action, true) - get :test_login, :email => 'bla@bla.com', :password => 'secret' + get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } Timecop.travel(Time.now.in_time_zone+0.6) get :test_should_be_logged_in diff --git a/spec/controllers/controller_spec.rb b/spec/controllers/controller_spec.rb index 795bb25e..640c649a 100644 --- a/spec/controllers/controller_spec.rb +++ b/spec/controllers/controller_spec.rb @@ -55,7 +55,7 @@ context "when succeeds" do before do expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) - get :test_login, :email => 'bla@bla.com', :password => 'secret' + get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } end it "assigns user to @user variable" do @@ -75,7 +75,7 @@ context "when fails" do before do expect(User).to receive(:authenticate).with('bla@bla.com', 'opensesame!').and_return(nil) - get :test_login, :email => 'bla@bla.com', :password => 'opensesame!' + get :test_login, :params => { :email => 'bla@bla.com', :password => 'opensesame!' } end it "sets @user variable to nil" do @@ -156,7 +156,7 @@ it "on successful login the user is redirected to the url he originally wanted" do session[:return_to_url] = "http://test.host/some_action" - post :test_return_to, :email => 'bla@bla.com', :password => 'secret' + post :test_return_to, :params => { :email => 'bla@bla.com', :password => 'secret' } expect(response).to redirect_to("http://test.host/some_action") expect(flash[:notice]).to eq "haha!" From 2edeaa7e8a35942a68547ee7eda1e68866650656 Mon Sep 17 00:00:00 2001 From: kyuden Date: Mon, 28 Nov 2016 01:20:00 +0900 Subject: [PATCH 29/46] Fix warning of ActiveRecord::Migration DEPRECATION WARNING: Directly inheriting from ActiveRecord::Migration is deprecated. Please specify the Rails release the migration was written for: class CreateAuthenticationsAndUserProviders < ActiveRecord::Migration[4.2] (called from block (3 levels) in at /Users/kyuden/go/src/github.com/kyuden/sorcery/spec/controllers/controller_oauth_spec.rb:207) --- .../initializers/compatible_legacy_migration.rb | 11 +++++++++++ .../20101224223622_add_activation_to_users.rb | 2 +- .../20101224223624_add_activity_logging_to_users.rb | 2 +- ...01224223626_add_brute_force_protection_to_users.rb | 2 +- .../db/migrate/core/20101224223620_create_users.rb | 2 +- ...23628_create_authentications_and_user_providers.rb | 2 +- .../20101224223623_add_remember_me_token_to_users.rb | 2 +- .../20101224223622_add_reset_password_to_users.rb | 2 +- 8 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 spec/rails_app/config/initializers/compatible_legacy_migration.rb diff --git a/spec/rails_app/config/initializers/compatible_legacy_migration.rb b/spec/rails_app/config/initializers/compatible_legacy_migration.rb new file mode 100644 index 00000000..7a8b6a2c --- /dev/null +++ b/spec/rails_app/config/initializers/compatible_legacy_migration.rb @@ -0,0 +1,11 @@ +module ActiveRecord + module CompatibleLegacyMigration + def self.migration_class + if Rails::VERSION::MAJOR >= 5 + ActiveRecord::Migration::Current + else + ActiveRecord::Migration + end + end + end +end diff --git a/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb b/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb index 14dd8669..a6592696 100644 --- a/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +++ b/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb @@ -1,4 +1,4 @@ -class AddActivationToUsers < ActiveRecord::Migration +class AddActivationToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up add_column :users, :activation_state, :string, :default => nil add_column :users, :activation_token, :string, :default => nil diff --git a/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb b/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb index ffc64aa4..de2b2dae 100644 --- a/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +++ b/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb @@ -1,4 +1,4 @@ -class AddActivityLoggingToUsers < ActiveRecord::Migration +class AddActivityLoggingToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up add_column :users, :last_login_at, :datetime, :default => nil add_column :users, :last_logout_at, :datetime, :default => nil diff --git a/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb b/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb index 50011bb2..be210206 100644 --- a/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +++ b/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb @@ -1,4 +1,4 @@ -class AddBruteForceProtectionToUsers < ActiveRecord::Migration +class AddBruteForceProtectionToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up add_column :users, :failed_logins_count, :integer, :default => 0 add_column :users, :lock_expires_at, :datetime, :default => nil diff --git a/spec/rails_app/db/migrate/core/20101224223620_create_users.rb b/spec/rails_app/db/migrate/core/20101224223620_create_users.rb index a2fba774..20b00e1d 100644 --- a/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +++ b/spec/rails_app/db/migrate/core/20101224223620_create_users.rb @@ -1,4 +1,4 @@ -class CreateUsers < ActiveRecord::Migration +class CreateUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up create_table :users do |t| t.string :username, :null => false diff --git a/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb b/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb index 16ce83c3..6528cf8f 100644 --- a/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb +++ b/spec/rails_app/db/migrate/external/20101224223628_create_authentications_and_user_providers.rb @@ -1,4 +1,4 @@ -class CreateAuthenticationsAndUserProviders < ActiveRecord::Migration +class CreateAuthenticationsAndUserProviders < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up create_table :authentications do |t| t.integer :user_id, null: false diff --git a/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb b/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb index df8b986d..ea101a77 100644 --- a/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +++ b/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb @@ -1,4 +1,4 @@ -class AddRememberMeTokenToUsers < ActiveRecord::Migration +class AddRememberMeTokenToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up add_column :users, :remember_me_token, :string, :default => nil add_column :users, :remember_me_token_expires_at, :datetime, :default => nil diff --git a/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb b/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb index 215425aa..14a45cfb 100644 --- a/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +++ b/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb @@ -1,4 +1,4 @@ -class AddResetPasswordToUsers < ActiveRecord::Migration +class AddResetPasswordToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up add_column :users, :reset_password_token, :string, :default => nil add_column :users, :reset_password_token_expires_at, :datetime, :default => nil From e086058897617d39cffdc463485b30f35faaa969 Mon Sep 17 00:00:00 2001 From: kyuden Date: Mon, 28 Nov 2016 01:22:58 +0900 Subject: [PATCH 30/46] Fix warning of `render :text` DEPRECATION WARNING: `render :text` is deprecated because it does not actually render a `text/plain` response. Switch to `render plain: 'plain text'` to render as `text/plain`, `render html: 'HTML'` to render as `text/html`, or `render body: 'raw'` to match the deprecated behavior and render with the default Content-Type, which is `text/plain`. (called from test_not_authenticated_action at /Users/kyuden/go/src/github.com/kyuden/sorcery/spec/rails_app/app/controllers/sorcery_controller.rb:75) --- spec/controllers/controller_spec.rb | 2 +- spec/rails_app/app/controllers/sorcery_controller.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/controllers/controller_spec.rb b/spec/controllers/controller_spec.rb index 640c649a..a0e202b8 100644 --- a/spec/controllers/controller_spec.rb +++ b/spec/controllers/controller_spec.rb @@ -136,7 +136,7 @@ sorcery_controller_property_set(:not_authenticated_action, :test_not_authenticated_action) get :test_logout - expect(response.body).to eq "test_not_authenticated_action" + expect(response).to be_a_success end it "require_login before_action saves the url that the user originally wanted" do diff --git a/spec/rails_app/app/controllers/sorcery_controller.rb b/spec/rails_app/app/controllers/sorcery_controller.rb index 95bba6b4..bc0d9f8c 100644 --- a/spec/rails_app/app/controllers/sorcery_controller.rb +++ b/spec/rails_app/app/controllers/sorcery_controller.rb @@ -72,7 +72,7 @@ def test_login_from_cookie end def test_not_authenticated_action - render text: 'test_not_authenticated_action' + head :ok end def test_should_be_logged_in @@ -80,7 +80,7 @@ def test_should_be_logged_in end def test_http_basic_auth - render text: 'HTTP Basic Auth' + head :ok end def login_at_test_twitter From c3f60998d1e03dfe183ac68b15ae238e555018fe Mon Sep 17 00:00:00 2001 From: kyuden Date: Mon, 28 Nov 2016 01:53:10 +0900 Subject: [PATCH 31/46] Fix warning of use_transactional_fixtures= with latest rspec-rails gem" DEPRECATION WARNING: use_transactional_fixtures= is deprecated and will be removed from Rails 5.1 (use use_transactional_tests= instead) (called from at /Users/kyuden/go/src/github.com/kyuden/sorcery/spec/active_record/user_activation_spec.rb:6) --- sorcery.gemspec | 3 +-- spec/spec_helper.rb | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sorcery.gemspec b/sorcery.gemspec index cc4d4fb7..fb584b2e 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -30,7 +30,6 @@ Gem::Specification.new do |s| s.add_development_dependency "timecop" s.add_development_dependency "simplecov", ">= 0.3.8" - s.add_development_dependency "rspec", "~> 3.1.0" - s.add_development_dependency "rspec-rails", "~> 3.1.0" + s.add_development_dependency "rspec-rails", "~> 3.5.0" s.add_development_dependency "test-unit", "~> 3.1.0" end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c8530841..2c9a488c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -8,9 +8,6 @@ # require 'simplecov' # SimpleCov.root File.join(File.dirname(__FILE__), '..', 'lib') # SimpleCov.start - -require 'rspec' - require 'rails/all' require 'rspec/rails' require 'timecop' From 3c8e74209c4479edd6d64837cc4bef243f81244a Mon Sep 17 00:00:00 2001 From: kyuden Date: Mon, 28 Nov 2016 05:12:31 +0900 Subject: [PATCH 32/46] Exclude ruby 2.0.0 and 2.1 on rails 5 --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 7011aa8b..f4a34b11 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,6 +31,12 @@ matrix: - rvm: 2.0.0 gemfile: gemfiles/active_record-rails42.gemfile + - rvm: 2.0.0 + gemfile: Gemfile + + - rvm: 2.1 + gemfile: Gemfile + - rvm: jruby gemfile: Gemfile From 444800997ec9f6aa35e90b6322dc6841e06fc3dc Mon Sep 17 00:00:00 2001 From: kyuden Date: Mon, 28 Nov 2016 05:27:06 +0900 Subject: [PATCH 33/46] Use latest ruby --- .travis.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index f4a34b11..ca6f782d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,9 +2,9 @@ language: ruby rvm: - jruby - 2.0.0 - - 2.1 - - 2.2 - - 2.3.0 + - 2.1.10 + - 2.2.6 + - 2.3.3 env: global: @@ -34,14 +34,14 @@ matrix: - rvm: 2.0.0 gemfile: Gemfile - - rvm: 2.1 + - rvm: 2.1.10 gemfile: Gemfile - - rvm: jruby - gemfile: Gemfile - - - rvm: 2.2 + - rvm: 2.2.6 gemfile: gemfiles/active_record-rails40.gemfile - - rvm: 2.3.0 + - rvm: 2.3.3 gemfile: gemfiles/active_record-rails40.gemfile + + - rvm: jruby + gemfile: Gemfile From 6519d60fa6ed705e76cc62ff0daf4170f57df29f Mon Sep 17 00:00:00 2001 From: kyuden Date: Wed, 7 Dec 2016 00:44:24 +0900 Subject: [PATCH 34/46] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad7a8edc..256eb954 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * Deprecated Rails 3 * Deprecated using `callback_filter` in favor of `callback_action` * Added null: false to migrations +* Added support for Rails 5 by @kyuden ## 0.9.1 From 1ba1c8ab3740d8fbc6ec782309dc563e4b7b36a4 Mon Sep 17 00:00:00 2001 From: Dan Kim Date: Mon, 12 Dec 2016 23:36:46 +0300 Subject: [PATCH 35/46] Fix code style --- Rakefile | 4 +- lib/generators/sorcery/helpers.rb | 8 +-- .../sorcery/templates/initializer.rb | 63 ++----------------- lib/sorcery.rb | 3 - lib/sorcery/adapters/active_record_adapter.rb | 11 ++-- .../controller/submodules/activity_logging.rb | 7 +-- .../controller/submodules/remember_me.rb | 17 +++-- lib/sorcery/crypto_providers/aes256.rb | 12 ++-- lib/sorcery/crypto_providers/common.rb | 2 +- lib/sorcery/crypto_providers/md5.rb | 4 +- lib/sorcery/crypto_providers/sha1.rb | 6 +- lib/sorcery/crypto_providers/sha256.rb | 2 +- lib/sorcery/crypto_providers/sha512.rb | 4 +- lib/sorcery/engine.rb | 2 +- lib/sorcery/model/submodules/external.rb | 10 +-- lib/sorcery/protocols/oauth.rb | 12 +--- lib/sorcery/protocols/oauth2.rb | 2 - lib/sorcery/providers/base.rb | 6 +- lib/sorcery/version.rb | 2 +- spec/active_record/user_oauth_spec.rb | 7 +-- spec/active_record/user_remember_me_spec.rb | 7 +-- .../active_record/user_reset_password_spec.rb | 5 +- spec/active_record/user_spec.rb | 14 ++--- .../controller_activity_logging_spec.rb | 25 ++++---- .../controller_brute_force_protection_spec.rb | 14 ++--- .../controller_http_basic_auth_spec.rb | 39 ++++++------ .../user_activity_logging_shared_examples.rb | 5 +- ..._brute_force_protection_shared_examples.rb | 37 +++++------ .../user_oauth_shared_examples.rb | 17 +++-- .../user_remember_me_shared_examples.rb | 18 +++--- 30 files changed, 137 insertions(+), 228 deletions(-) diff --git a/Rakefile b/Rakefile index 087ed954..2470119d 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,6 @@ -require "bundler/gem_tasks" +require 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) -task :default => :spec +task default: :spec diff --git a/lib/generators/sorcery/helpers.rb b/lib/generators/sorcery/helpers.rb index 057ce278..f0830785 100644 --- a/lib/generators/sorcery/helpers.rb +++ b/lib/generators/sorcery/helpers.rb @@ -4,16 +4,16 @@ module Helpers private def sorcery_config_path - "config/initializers/sorcery.rb" + 'config/initializers/sorcery.rb' end # Either return the model passed in a classified form or return the default "User". def model_class_name - options[:model] ? options[:model].classify : "User" + options[:model] ? options[:model].classify : 'User' end def model_path - @model_path ||= File.join("app", "models", "#{file_path}.rb") + @model_path ||= File.join('app', 'models', "#{file_path}.rb") end def file_path @@ -33,7 +33,7 @@ def model_name [namespace.to_s] + [model_class_name] else [model_class_name] - end.join("::") + end.join('::') end end end diff --git a/lib/generators/sorcery/templates/initializer.rb b/lib/generators/sorcery/templates/initializer.rb index 36623bb3..cd7074f8 100644 --- a/lib/generators/sorcery/templates/initializer.rb +++ b/lib/generators/sorcery/templates/initializer.rb @@ -13,79 +13,67 @@ # # config.not_authenticated_action = - # When a non logged in user tries to enter a page that requires login, save # the URL he wanted to reach, and send him there after login, using 'redirect_back_or_to'. # Default: `true` # # config.save_return_to_url = - # Set domain option for cookies; Useful for remember_me submodule. # Default: `nil` # # config.cookie_domain = - # Allow the remember_me cookie to be set through AJAX # Default: `true` # # config.remember_me_httponly = - # -- session timeout -- # How long in seconds to keep the session alive. # Default: `3600` # # config.session_timeout = - # Use the last action as the beginning of session timeout. # Default: `false` # # config.session_timeout_from_last_action = - # -- http_basic_auth -- # What realm to display for which controller name. For example {"My App" => "Application"} # Default: `{"application" => "Application"}` # # config.controller_to_realm_map = - # -- activity logging -- # will register the time of last user login, every login. # Default: `true` # # config.register_login_time = - # will register the time of last user logout, every logout. # Default: `true` # # config.register_logout_time = - # will register the time of last user action, every action. # Default: `true` # # config.register_last_activity_time = - # -- external -- # What providers are supported by this app, i.e. [:twitter, :facebook, :github, :linkedin, :xing, :google, :liveid, :salesforce, :slack] . # Default: `[]` # # config.external_providers = - # You can change it by your local ca_file. i.e. '/etc/pki/tls/certs/ca-bundle.crt' # Path to ca_file. By default use a internal ca-bundle.crt. # Default: `'path/to/ca_file'` # # config.ca_file = - # For information about LinkedIn API: # - user info fields go to https://developer.linkedin.com/documents/profile-fields # - access permissions go to https://developer.linkedin.com/documents/authentication#granting @@ -144,10 +132,10 @@ # config.vk.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=vk" # config.vk.user_info_mapping = {:login => "domain", :name => "full_name"} # - #config.slack.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=slack" - #config.slack.key = '' - #config.slack.secret = '' - #config.slack.user_info_mapping = {email: 'email'} + # config.slack.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=slack" + # config.slack.key = '' + # config.slack.secret = '' + # config.slack.user_info_mapping = {email: 'email'} # # To use liveid in development mode you have to replace mydomain.com with # a valid domain even in development. To use a valid domain in development @@ -190,119 +178,100 @@ # # user.username_attribute_names = - # change *virtual* password attribute, the one which is used until an encrypted one is generated. # Default: `:password` # # user.password_attribute_name = - # downcase the username before trying to authenticate, default is false # Default: `false` # # user.downcase_username_before_authenticating = - # change default email attribute. # Default: `:email` # # user.email_attribute_name = - # change default crypted_password attribute. # Default: `:crypted_password` # # user.crypted_password_attribute_name = - # what pattern to use to join the password with the salt # Default: `""` # # user.salt_join_token = - # change default salt attribute. # Default: `:salt` # # user.salt_attribute_name = - # how many times to apply encryption to the password. # Default: `nil` # # user.stretches = - # encryption key used to encrypt reversible encryptions such as AES256. # WARNING: If used for users' passwords, changing this key will leave passwords undecryptable! # Default: `nil` # # user.encryption_key = - # use an external encryption class. # Default: `nil` # # user.custom_encryption_provider = - # encryption algorithm name. See 'encryption_algorithm=' for available options. # Default: `:bcrypt` # # user.encryption_algorithm = - # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI. # Default: `false` # # user.subclasses_inherit_config = - # -- remember_me -- # How long in seconds the session length will be # Default: `604800` # # user.remember_me_for = - # when true sorcery will persist a single remember me token for all # logins/logouts (supporting remembering on multiple browsers simultaneously). # Default: false # # user.remember_me_token_persist_globally = - # -- user_activation -- # the attribute name to hold activation state (active/pending). # Default: `:activation_state` # # user.activation_state_attribute_name = - # the attribute name to hold activation code (sent by email). # Default: `:activation_token` # # user.activation_token_attribute_name = - # the attribute name to hold activation code expiration date. # Default: `:activation_token_expires_at` # # user.activation_token_expires_at_attribute_name = - # how many seconds before the activation code expires. nil for never expires. # Default: `nil` # # user.activation_token_expiration_period = - # your mailer class. Required. # Default: `nil` # # user.user_activation_mailer = - # when true sorcery will not automatically # email activation details and allow you to # manually handle how and when email is sent. @@ -316,56 +285,47 @@ # # user.email_delivery_method = - # activation needed email method on your mailer class. # Default: `:activation_needed_email` # # user.activation_needed_email_method_name = - # activation success email method on your mailer class. # Default: `:activation_success_email` # # user.activation_success_email_method_name = - # do you want to prevent or allow users that did not activate by email to login? # Default: `true` # # user.prevent_non_active_users_to_login = - # -- reset_password -- # reset password code attribute name. # Default: `:reset_password_token` # # user.reset_password_token_attribute_name = - # expires at attribute name. # Default: `:reset_password_token_expires_at` # # user.reset_password_token_expires_at_attribute_name = - # when was email sent, used for hammering protection. # Default: `:reset_password_email_sent_at` # # user.reset_password_email_sent_at_attribute_name = - # mailer class. Needed. # Default: `nil` # # user.reset_password_mailer = - # reset password email method on your mailer class. # Default: `:reset_password_email` # # user.reset_password_email_method_name = - # when true sorcery will not automatically # email password reset details and allow you to # manually handle how and when email is sent @@ -373,38 +333,32 @@ # # user.reset_password_mailer_disabled = - # how many seconds before the reset request expires. nil for never expires. # Default: `nil` # # user.reset_password_expiration_period = - # hammering protection, how long in seconds to wait before allowing another email to be sent. # Default: `5 * 60` # # user.reset_password_time_between_emails = - # -- brute_force_protection -- # Failed logins attribute name. # Default: `:failed_logins_count` # # user.failed_logins_count_attribute_name = - # This field indicates whether user is banned and when it will be active again. # Default: `:lock_expires_at` # # user.lock_expires_at_attribute_name = - # How many failed logins allowed. # Default: `50` # # user.consecutive_login_retries_amount_limit = - # How long the user should be banned. in seconds. 0 for permanent. # Default: `60 * 60` # @@ -437,44 +391,37 @@ # # user.last_login_at_attribute_name = - # Last logout attribute name. # Default: `:last_logout_at` # # user.last_logout_at_attribute_name = - # Last activity attribute name. # Default: `:last_activity_at` # # user.last_activity_at_attribute_name = - # How long since last activity is the user defined logged out? # Default: `10 * 60` # # user.activity_timeout = - # -- external -- # Class which holds the various external provider data for this user. # Default: `nil` # # user.authentications_class = - # User's identifier in authentications class. # Default: `:user_id` # # user.authentications_user_id_attribute_name = - # Provider's identifier in authentications class. # Default: `:provider` # # user.provider_attribute_name = - # User's external unique identifier in authentications class. # Default: `:uid` # @@ -483,5 +430,5 @@ # This line must come after the 'user config' block. # Define which model authenticates with sorcery. - config.user_class = "<%= model_class_name %>" + config.user_class = '<%= model_class_name %>' end diff --git a/lib/sorcery.rb b/lib/sorcery.rb index e9e90d8e..be4796d3 100644 --- a/lib/sorcery.rb +++ b/lib/sorcery.rb @@ -1,7 +1,6 @@ require 'sorcery/version' module Sorcery - require 'sorcery/model' module Adapters @@ -12,7 +11,6 @@ module Model require 'sorcery/model/temporary_token' require 'sorcery/model/config' - module Submodules require 'sorcery/model/submodules/user_activation' require 'sorcery/model/submodules/reset_password' @@ -63,7 +61,6 @@ module Rails module Internal require 'sorcery/test_helpers/internal/rails' end - end require 'sorcery/adapters/base_adapter' diff --git a/lib/sorcery/adapters/active_record_adapter.rb b/lib/sorcery/adapters/active_record_adapter.rb index 89bd7c3e..266031e7 100644 --- a/lib/sorcery/adapters/active_record_adapter.rb +++ b/lib/sorcery/adapters/active_record_adapter.rb @@ -61,11 +61,11 @@ def find_by_credentials(credentials) condition = @klass.arel_table[attribute].eq(credentials[0]) end - if relation.nil? - relation = condition - else - relation = relation.or(condition) - end + relation = if relation.nil? + condition + else + relation.or(condition) + end end @klass.where(relation).first @@ -105,6 +105,5 @@ def transaction(&blk) end end end - end end diff --git a/lib/sorcery/controller/submodules/activity_logging.rb b/lib/sorcery/controller/submodules/activity_logging.rb index 44d61504..5aaf578c 100644 --- a/lib/sorcery/controller/submodules/activity_logging.rb +++ b/lib/sorcery/controller/submodules/activity_logging.rb @@ -25,8 +25,7 @@ def merge_activity_logging_defaults! @defaults.merge!(:@register_login_time => true, :@register_logout_time => true, :@register_last_activity_time => true, - :@register_last_ip_address => true - ) + :@register_last_ip_address => true) end end merge_activity_logging_defaults! @@ -42,7 +41,7 @@ module InstanceMethods # registers last login time on every login. # This runs as a hook just after a successful login. - def register_login_time_to_db(user, credentials) + def register_login_time_to_db(user, _credentials) return unless Config.register_login_time user.set_last_login_at(Time.now.in_time_zone) end @@ -64,7 +63,7 @@ def register_last_activity_time_to_db # Updates IP address on every login. # This runs as a hook just after a successful login. - def register_last_ip_address(user, credentials) + def register_last_ip_address(_user, _credentials) return unless Config.register_last_ip_address current_user.set_last_ip_address(request.remote_ip) end diff --git a/lib/sorcery/controller/submodules/remember_me.rb b/lib/sorcery/controller/submodules/remember_me.rb index 5bbe7866..48ccce9e 100644 --- a/lib/sorcery/controller/submodules/remember_me.rb +++ b/lib/sorcery/controller/submodules/remember_me.rb @@ -32,13 +32,13 @@ def remember_me! # Clears the cookie, and depending on the value of remember_me_token_persist_globally, may clear the token value. def forget_me! current_user.forget_me! - cookies.delete(:remember_me_token, :domain => Config.cookie_domain) + cookies.delete(:remember_me_token, domain: Config.cookie_domain) end # Clears the cookie, and clears the token value. def force_forget_me! current_user.force_forget_me! - cookies.delete(:remember_me_token, :domain => Config.cookie_domain) + cookies.delete(:remember_me_token, domain: Config.cookie_domain) end # Override. @@ -53,8 +53,8 @@ def auto_login(user, should_remember = false) # calls remember_me! if a third credential was passed to the login method. # Runs as a hook after login. - def remember_me_if_asked_to(user, credentials) - remember_me! if ( credentials.size == 3 && credentials[2] && credentials[2] != "0" ) + def remember_me_if_asked_to(_user, credentials) + remember_me! if credentials.size == 3 && credentials[2] && credentials[2] != '0' end # Checks the cookie for a remember me token, tried to find a user with that token @@ -73,14 +73,13 @@ def login_from_cookie def set_remember_me_cookie!(user) cookies.signed[:remember_me_token] = { - :value => user.send(user.sorcery_config.remember_me_token_attribute_name), - :expires => user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name), - :httponly => Config.remember_me_httponly, - :domain => Config.cookie_domain + value: user.send(user.sorcery_config.remember_me_token_attribute_name), + expires: user.send(user.sorcery_config.remember_me_token_expires_at_attribute_name), + httponly: Config.remember_me_httponly, + domain: Config.cookie_domain } end end - end end end diff --git a/lib/sorcery/crypto_providers/aes256.rb b/lib/sorcery/crypto_providers/aes256.rb index 42705f68..c11c8d04 100644 --- a/lib/sorcery/crypto_providers/aes256.rb +++ b/lib/sorcery/crypto_providers/aes256.rb @@ -1,4 +1,4 @@ -require "openssl" +require 'openssl' module Sorcery module CryptoProviders @@ -24,7 +24,7 @@ class << self def encrypt(*tokens) aes.encrypt aes.key = @key - [aes.update(tokens.join) + aes.final].pack("m").chomp + [aes.update(tokens.join) + aes.final].pack('m').chomp end def matches?(crypted, *tokens) @@ -36,16 +36,16 @@ def matches?(crypted, *tokens) def decrypt(crypted) aes.decrypt aes.key = @key - (aes.update(crypted.unpack("m").first) + aes.final) + (aes.update(crypted.unpack('m').first) + aes.final) end private def aes - raise ArgumentError.new("#{name} expects a 32 bytes long key. Please use Sorcery::Model::Config.encryption_key to set it.") if ( @key.nil? || @key == "" ) - @aes ||= OpenSSL::Cipher::Cipher.new("AES-256-ECB") + raise ArgumentError, "#{name} expects a 32 bytes long key. Please use Sorcery::Model::Config.encryption_key to set it." if @key.nil? || @key == '' + @aes ||= OpenSSL::Cipher::Cipher.new('AES-256-ECB') end end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/crypto_providers/common.rb b/lib/sorcery/crypto_providers/common.rb index 5f916d8a..40477ab7 100644 --- a/lib/sorcery/crypto_providers/common.rb +++ b/lib/sorcery/crypto_providers/common.rb @@ -32,4 +32,4 @@ def reset! end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/crypto_providers/md5.rb b/lib/sorcery/crypto_providers/md5.rb index 5dbfcc6c..7f213945 100644 --- a/lib/sorcery/crypto_providers/md5.rb +++ b/lib/sorcery/crypto_providers/md5.rb @@ -1,4 +1,4 @@ -require "digest/md5" +require 'digest/md5' module Sorcery module CryptoProviders @@ -16,4 +16,4 @@ def secure_digest(digest) end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/crypto_providers/sha1.rb b/lib/sorcery/crypto_providers/sha1.rb index 91cc14a7..71bea732 100644 --- a/lib/sorcery/crypto_providers/sha1.rb +++ b/lib/sorcery/crypto_providers/sha1.rb @@ -1,4 +1,4 @@ -require "digest/sha1" +require 'digest/sha1' module Sorcery module CryptoProviders @@ -8,7 +8,7 @@ class SHA1 include Common class << self def join_token - @join_token ||= "--" + @join_token ||= '--' end # Turns your raw password into a Sha1 hash. @@ -25,4 +25,4 @@ def secure_digest(digest) end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/crypto_providers/sha256.rb b/lib/sorcery/crypto_providers/sha256.rb index df525e69..0bed919e 100644 --- a/lib/sorcery/crypto_providers/sha256.rb +++ b/lib/sorcery/crypto_providers/sha256.rb @@ -1,4 +1,4 @@ -require "digest/sha2" +require 'digest/sha2' module Sorcery # The activate_sorcery method has a custom_crypto_provider configuration option. diff --git a/lib/sorcery/crypto_providers/sha512.rb b/lib/sorcery/crypto_providers/sha512.rb index 51ba6523..5ea25042 100644 --- a/lib/sorcery/crypto_providers/sha512.rb +++ b/lib/sorcery/crypto_providers/sha512.rb @@ -1,4 +1,4 @@ -require "digest/sha2" +require 'digest/sha2' module Sorcery # The activate_sorcery method has a custom_crypto_provider configuration option. @@ -33,4 +33,4 @@ def secure_digest(digest) end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/engine.rb b/lib/sorcery/engine.rb index 84a2a97c..8042cf9a 100644 --- a/lib/sorcery/engine.rb +++ b/lib/sorcery/engine.rb @@ -7,7 +7,7 @@ module Sorcery class Engine < Rails::Engine config.sorcery = ::Sorcery::Controller::Config - initializer "extend Controller with sorcery" do + initializer 'extend Controller with sorcery' do ActionController::Base.send(:include, Sorcery::Controller) ActionController::Base.helper_method :current_user ActionController::Base.helper_method :logged_in? diff --git a/lib/sorcery/model/submodules/external.rb b/lib/sorcery/model/submodules/external.rb index 04dd7d7d..2f2babfd 100644 --- a/lib/sorcery/model/submodules/external.rb +++ b/lib/sorcery/model/submodules/external.rb @@ -20,7 +20,6 @@ def self.included(base) :authentications_user_id_attribute_name, :provider_attribute_name, :provider_uid_attribute_name - end base.sorcery_config.instance_eval do @@ -34,12 +33,11 @@ def self.included(base) base.send(:include, InstanceMethods) base.extend(ClassMethods) - end module ClassMethods # takes a provider and uid and finds a user by them. - def load_from_provider(provider,uid) + def load_from_provider(provider, uid) config = sorcery_config authentication = config.authentications_class.sorcery_adapter.find_by_oauth_credentials(provider, uid) user = sorcery_adapter.find_by_id(authentication.send(config.authentications_user_id_attribute_name)) if authentication @@ -57,7 +55,7 @@ def create_and_validate_from_provider(provider, uid, attrs) def create_from_provider(provider, uid, attrs) user = new - attrs.each do |k,v| + attrs.each do |k, v| user.send(:"#{k}=", v) end @@ -66,7 +64,7 @@ def create_from_provider(provider, uid, attrs) end sorcery_adapter.transaction do - user.sorcery_adapter.save(:validate => false) + user.sorcery_adapter.save(validate: false) sorcery_config.authentications_class.create!( sorcery_config.authentications_user_id_attribute_name => user.id, sorcery_config.provider_attribute_name => provider, @@ -91,9 +89,7 @@ def add_provider_to_user(provider, uid) user end - end - end end end diff --git a/lib/sorcery/protocols/oauth.rb b/lib/sorcery/protocols/oauth.rb index 3ee7f7a7..448602cf 100644 --- a/lib/sorcery/protocols/oauth.rb +++ b/lib/sorcery/protocols/oauth.rb @@ -3,12 +3,11 @@ module Sorcery module Protocols module Oauth - def oauth_version '1.0' end - def get_request_token(token = nil,secret = nil) + def get_request_token(token = nil, secret = nil) return ::OAuth::RequestToken.new(get_consumer, token, secret) if token && secret get_consumer.get_request_token(oauth_callback: @callback_url) end @@ -17,18 +16,14 @@ def authorize_url(args) get_request_token( args[:request_token], args[:request_token_secret] - ).authorize_url({ - oauth_callback: @callback_url - }) + ).authorize_url(oauth_callback: @callback_url) end def get_access_token(args) get_request_token( args[:request_token], args[:request_token_secret] - ).get_access_token({ - oauth_verifier: args[:oauth_verifier] - }) + ).get_access_token(oauth_verifier: args[:oauth_verifier]) end protected @@ -36,7 +31,6 @@ def get_access_token(args) def get_consumer ::OAuth::Consumer.new(@key, @secret, site: @site) end - end end end diff --git a/lib/sorcery/protocols/oauth2.rb b/lib/sorcery/protocols/oauth2.rb index 594d4888..9bba11dd 100644 --- a/lib/sorcery/protocols/oauth2.rb +++ b/lib/sorcery/protocols/oauth2.rb @@ -3,7 +3,6 @@ module Sorcery module Protocols module Oauth2 - def oauth_version '2.0' end @@ -41,7 +40,6 @@ def build_client(options = {}) defaults.merge!(options) ) end - end end end diff --git a/lib/sorcery/providers/base.rb b/lib/sorcery/providers/base.rb index eca67367..3996f689 100644 --- a/lib/sorcery/providers/base.rb +++ b/lib/sorcery/providers/base.rb @@ -1,13 +1,14 @@ module Sorcery module Providers class Base - attr_reader :access_token attr_accessor :callback_url, :key, :original_callback_url, :secret, :site, :state, :user_info_mapping - def has_callback?; true; end + def has_callback? + true + end def initialize @user_info_mapping = {} @@ -32,7 +33,6 @@ def self.name def self.descendants ObjectSpace.each_object(Class).select { |klass| klass < self } end - end end end diff --git a/lib/sorcery/version.rb b/lib/sorcery/version.rb index 362ffb71..ce33bf6f 100644 --- a/lib/sorcery/version.rb +++ b/lib/sorcery/version.rb @@ -1,3 +1,3 @@ module Sorcery - VERSION = "0.9.1" + VERSION = '0.9.1' end diff --git a/spec/active_record/user_oauth_spec.rb b/spec/active_record/user_oauth_spec.rb index 480716fe..33a751be 100644 --- a/spec/active_record/user_oauth_spec.rb +++ b/spec/active_record/user_oauth_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'shared_examples/user_oauth_shared_examples' -describe User, "with oauth submodule", :active_record => true do +describe User, 'with oauth submodule', active_record: true do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external") User.reset_column_information @@ -11,6 +11,5 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external") end - it_behaves_like "rails_3_oauth_model" - -end \ No newline at end of file + it_behaves_like 'rails_3_oauth_model' +end diff --git a/spec/active_record/user_remember_me_spec.rb b/spec/active_record/user_remember_me_spec.rb index c31fc4d8..948b3c08 100644 --- a/spec/active_record/user_remember_me_spec.rb +++ b/spec/active_record/user_remember_me_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'shared_examples/user_remember_me_shared_examples' -describe User, "with remember_me submodule", :active_record => true do +describe User, 'with remember_me submodule', active_record: true do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/remember_me") User.reset_column_information @@ -11,6 +11,5 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/remember_me") end - it_behaves_like "rails_3_remember_me_model" - -end \ No newline at end of file + it_behaves_like 'rails_3_remember_me_model' +end diff --git a/spec/active_record/user_reset_password_spec.rb b/spec/active_record/user_reset_password_spec.rb index 5c0a01ef..1af1f266 100644 --- a/spec/active_record/user_reset_password_spec.rb +++ b/spec/active_record/user_reset_password_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'shared_examples/user_reset_password_shared_examples' -describe User, "with reset_password submodule", :active_record => true do +describe User, 'with reset_password submodule', active_record: true do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/reset_password") User.reset_column_information @@ -11,6 +11,5 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/reset_password") end - it_behaves_like "rails_3_reset_password_model" - + it_behaves_like 'rails_3_reset_password_model' end diff --git a/spec/active_record/user_spec.rb b/spec/active_record/user_spec.rb index f1487ccf..407eeef1 100644 --- a/spec/active_record/user_spec.rb +++ b/spec/active_record/user_spec.rb @@ -2,26 +2,26 @@ require 'rails_app/app/mailers/sorcery_mailer' require 'shared_examples/user_shared_examples' -describe User, "with no submodules (core)", :active_record => true do +describe User, 'with no submodules (core)', active_record: true do before(:all) do sorcery_reload! end - context "when app has plugin loaded" do - it "responds to the plugin activation class method" do + context 'when app has plugin loaded' do + it 'responds to the plugin activation class method' do expect(ActiveRecord::Base).to respond_to :authenticates_with_sorcery! end - it "User responds to .authenticates_with_sorcery!" do + it 'User responds to .authenticates_with_sorcery!' do expect(User).to respond_to :authenticates_with_sorcery! end end # ----------------- PLUGIN CONFIGURATION ----------------------- - it_should_behave_like "rails_3_core_model" + it_should_behave_like 'rails_3_core_model' - describe "external users" do + describe 'external users' do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external") User.reset_column_information @@ -32,6 +32,6 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external") end - it_should_behave_like "external_user" + it_should_behave_like 'external_user' end end diff --git a/spec/controllers/controller_activity_logging_spec.rb b/spec/controllers/controller_activity_logging_spec.rb index 42360f49..bee7cae1 100644 --- a/spec/controllers/controller_activity_logging_spec.rb +++ b/spec/controllers/controller_activity_logging_spec.rb @@ -2,7 +2,7 @@ # require 'shared_examples/controller_activity_logging_shared_examples' -describe SorceryController, :type => :controller do +describe SorceryController, type: :controller do after(:all) do sorcery_controller_property_set(:register_login_time, true) sorcery_controller_property_set(:register_logout_time, true) @@ -11,8 +11,7 @@ end # ----------------- ACTIVITY LOGGING ----------------------- - context "with activity logging features" do - + context 'with activity logging features' do let(:adapter) { double('sorcery_adapter') } let(:user) { double('user', id: 42, sorcery_adapter: adapter) } @@ -31,8 +30,7 @@ sorcery_controller_property_set(:register_last_activity_time, false) end - - it "logs login time on login" do + it 'logs login time on login' do now = Time.now.in_time_zone Timecop.freeze(now) @@ -43,7 +41,7 @@ Timecop.return end - it "logs logout time on logout" do + it 'logs logout time on logout' do login_user(user) now = Time.now.in_time_zone Timecop.freeze(now) @@ -54,7 +52,7 @@ Timecop.return end - it "logs last activity time when logged in" do + it 'logs last activity time when logged in' do sorcery_controller_property_set(:register_last_activity_time, true) login_user(user) @@ -67,14 +65,14 @@ Timecop.return end - it "logs last IP address when logged in" do + it 'logs last IP address when logged in' do sorcery_controller_property_set(:register_last_ip_address, true) expect(user).to receive(:set_last_ip_address).with('0.0.0.0') login_user(user) end - it "updates nothing but activity fields" do + it 'updates nothing but activity fields' do pending 'Move to model' original_user_name = User.last.username login_user(user) @@ -83,14 +81,14 @@ expect(User.last.username).to eq original_user_name end - it "does not register login time if configured so" do + it 'does not register login time if configured so' do sorcery_controller_property_set(:register_login_time, false) expect(user).to receive(:set_last_login_at).never login_user(user) end - it "does not register logout time if configured so" do + it 'does not register logout time if configured so' do sorcery_controller_property_set(:register_logout_time, false) login_user(user) @@ -98,19 +96,18 @@ logout_user end - it "does not register last activity time if configured so" do + it 'does not register last activity time if configured so' do sorcery_controller_property_set(:register_last_activity_time, false) expect(user).to receive(:set_last_activity_at).never login_user(user) end - it "does not register last IP address if configured so" do + it 'does not register last IP address if configured so' do sorcery_controller_property_set(:register_last_ip_address, false) expect(user).to receive(:set_last_ip_address).never login_user(user) end - end end diff --git a/spec/controllers/controller_brute_force_protection_spec.rb b/spec/controllers/controller_brute_force_protection_spec.rb index 392b09e0..e395a956 100644 --- a/spec/controllers/controller_brute_force_protection_spec.rb +++ b/spec/controllers/controller_brute_force_protection_spec.rb @@ -1,16 +1,14 @@ require 'spec_helper' -describe SorceryController, :type => :controller do - +describe SorceryController, type: :controller do let(:user) { double('user', id: 42, email: 'bla@bla.com') } def request_test_login - get :test_login, :params => { email: 'bla@bla.com', password: 'blabla' } + get :test_login, params: { email: 'bla@bla.com', password: 'blabla' } end # ----------------- SESSION TIMEOUT ----------------------- - describe "brute force protection features" do - + describe 'brute force protection features' do before(:all) do sorcery_reload!([:brute_force_protection]) end @@ -21,7 +19,7 @@ def request_test_login Timecop.return end - it "counts login retries" do + it 'counts login retries' do allow(User).to receive(:authenticate) allow(User.sorcery_adapter).to receive(:find_by_credentials).with(['bla@bla.com', 'blabla']).and_return(user) @@ -30,14 +28,14 @@ def request_test_login 3.times { request_test_login } end - it "resets the counter on a good login" do + it 'resets the counter on a good login' do # dirty hack for rails 4 allow(@controller).to receive(:register_last_activity_time_to_db) allow(User).to receive(:authenticate).and_return(user) expect(user).to receive_message_chain(:sorcery_adapter, :update_attribute).with(:failed_logins_count, 0) - get :test_login, :params => { email: 'bla@bla.com', password: 'secret' } + get :test_login, params: { email: 'bla@bla.com', password: 'secret' } end end end diff --git a/spec/controllers/controller_http_basic_auth_spec.rb b/spec/controllers/controller_http_basic_auth_spec.rb index 201fe598..7a633a2c 100644 --- a/spec/controllers/controller_http_basic_auth_spec.rb +++ b/spec/controllers/controller_http_basic_auth_spec.rb @@ -1,68 +1,67 @@ require 'spec_helper' -describe SorceryController, :type => :controller do +describe SorceryController, type: :controller do + let(:user) { double('user', id: 42, email: 'bla@bla.com') } - let(:user) { double("user", id: 42, email: 'bla@bla.com') } - - describe "with http basic auth features" do + describe 'with http basic auth features' do before(:all) do sorcery_reload!([:http_basic_auth]) - sorcery_controller_property_set(:controller_to_realm_map, {"sorcery" => "sorcery"}) + sorcery_controller_property_set(:controller_to_realm_map, 'sorcery' => 'sorcery') end after(:each) do logout_user end - it "requests basic authentication when before_action is used" do + it 'requests basic authentication when before_action is used' do get :test_http_basic_auth expect(response.status).to eq 401 end - it "authenticates from http basic if credentials are sent" do + it 'authenticates from http basic if credentials are sent' do # dirty hack for rails 4 allow(subject).to receive(:register_last_activity_time_to_db) - @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{user.email}:secret")}" + @request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64("#{user.email}:secret")}" expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user) - get :test_http_basic_auth, :params => {}, session: { :http_authentication_used => true } + get :test_http_basic_auth, params: {}, session: { http_authentication_used: true } expect(response).to be_a_success end - it "fails authentication if credentials are wrong" do - @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{user.email}:wrong!")}" + it 'fails authentication if credentials are wrong' do + @request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64("#{user.email}:wrong!")}" expect(User).to receive('authenticate').with('bla@bla.com', 'wrong!').and_return(nil) - get :test_http_basic_auth, :params => {}, session: { :http_authentication_used => true } + get :test_http_basic_auth, params: {}, session: { http_authentication_used: true } expect(response).to redirect_to root_url end it "allows configuration option 'controller_to_realm_map'" do - sorcery_controller_property_set(:controller_to_realm_map, {"1" => "2"}) + sorcery_controller_property_set(:controller_to_realm_map, '1' => '2') - expect(Sorcery::Controller::Config.controller_to_realm_map).to eq({"1" => "2"}) + expect(Sorcery::Controller::Config.controller_to_realm_map).to eq('1' => '2') end - it "displays the correct realm name configured for the controller" do - sorcery_controller_property_set(:controller_to_realm_map, {"sorcery" => "Salad"}) + it 'displays the correct realm name configured for the controller' do + sorcery_controller_property_set(:controller_to_realm_map, 'sorcery' => 'Salad') get :test_http_basic_auth - expect(response.headers["WWW-Authenticate"]).to eq "Basic realm=\"Salad\"" + expect(response.headers['WWW-Authenticate']).to eq 'Basic realm="Salad"' end it "signs in the user's session on successful login" do # dirty hack for rails 4 allow(controller).to receive(:register_last_activity_time_to_db) - @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{user.email}:secret")}" + @request.env['HTTP_AUTHORIZATION'] = "Basic #{Base64.encode64("#{user.email}:secret")}" expect(User).to receive('authenticate').with('bla@bla.com', 'secret').and_return(user) - get :test_http_basic_auth, :params => {}, session: { :http_authentication_used => true } + get :test_http_basic_auth, params: {}, session: { http_authentication_used: true } - expect(session[:user_id]).to eq "42" + expect(session[:user_id]).to eq '42' end end end diff --git a/spec/shared_examples/user_activity_logging_shared_examples.rb b/spec/shared_examples/user_activity_logging_shared_examples.rb index ed3ac44f..5e049870 100644 --- a/spec/shared_examples/user_activity_logging_shared_examples.rb +++ b/spec/shared_examples/user_activity_logging_shared_examples.rb @@ -1,5 +1,5 @@ -shared_examples_for "rails_3_activity_logging_model" do - context "loaded plugin configuration" do +shared_examples_for 'rails_3_activity_logging_model' do + context 'loaded plugin configuration' do before(:all) do sorcery_reload!([:activity_logging]) end @@ -102,6 +102,5 @@ user.set_last_logout_at(now) expect(user.online?).to eq(false) end - end end diff --git a/spec/shared_examples/user_brute_force_protection_shared_examples.rb b/spec/shared_examples/user_brute_force_protection_shared_examples.rb index 51df6d90..b267dcc2 100644 --- a/spec/shared_examples/user_brute_force_protection_shared_examples.rb +++ b/spec/shared_examples/user_brute_force_protection_shared_examples.rb @@ -1,12 +1,10 @@ -shared_examples_for "rails_3_brute_force_protection_model" do +shared_examples_for 'rails_3_brute_force_protection_model' do let(:user) { create_new_user } before(:each) do User.sorcery_adapter.delete_all end - - context "loaded plugin configuration" do - + context 'loaded plugin configuration' do let(:config) { User.sorcery_config } before(:all) do @@ -40,8 +38,8 @@ expect(config.login_lock_time_period).to eq 2.hours end - describe "#locked?" do - it "is locked" do + describe '#locked?' do + it 'is locked' do user.send("#{config.lock_expires_at_attribute_name}=", Time.now + 5.days) expect(user).to be_locked end @@ -53,8 +51,8 @@ end end - describe "#register_failed_login!" do - it "locks user when number of retries reached the limit" do + describe '#register_failed_login!' do + it 'locks user when number of retries reached the limit' do expect(user.lock_expires_at).to be_nil sorcery_model_property_set(:consecutive_login_retries_amount_limit, 1) @@ -64,8 +62,8 @@ expect(lock_expires_at).not_to be_nil end - context "unlock_token_mailer_disabled is true" do - it "does not automatically send unlock email" do + context 'unlock_token_mailer_disabled is true' do + it 'does not automatically send unlock email' do sorcery_model_property_set(:unlock_token_mailer_disabled, true) sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2) sorcery_model_property_set(:login_lock_time_period, 0) @@ -74,11 +72,10 @@ 3.times { user.register_failed_login! } expect(ActionMailer::Base.deliveries.size).to eq 0 - end end - context "unlock_token_mailer_disabled is false" do + context 'unlock_token_mailer_disabled is false' do before do sorcery_model_property_set(:unlock_token_mailer_disabled, false) sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2) @@ -86,13 +83,13 @@ sorcery_model_property_set(:unlock_token_mailer, SorceryMailer) end - it "does not automatically send unlock email" do + it 'does not automatically send unlock email' do 3.times { user.register_failed_login! } expect(ActionMailer::Base.deliveries.size).to eq 1 end - it "generates unlock token before mail is sent" do + it 'generates unlock token before mail is sent' do 3.times { user.register_failed_login! } expect(ActionMailer::Base.deliveries.last.body.to_s.match(user.unlock_token)).not_to be_nil @@ -100,9 +97,8 @@ end end - context ".authenticate" do - - it "unlocks after lock time period passes" do + context '.authenticate' do + it 'unlocks after lock time period passes' do sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2) sorcery_model_property_set(:login_lock_time_period, 0.2) 2.times { user.register_failed_login! } @@ -118,7 +114,7 @@ Timecop.return end - it "doest not unlock if time period is 0 (permanent lock)" do + it 'doest not unlock if time period is 0 (permanent lock)' do sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2) sorcery_model_property_set(:login_lock_time_period, 0) @@ -132,11 +128,10 @@ expect(user.lock_expires_at.to_s).to eq unlock_date.to_s Timecop.return end - end - describe "#unlock!" do - it "unlocks after entering unlock token" do + describe '#unlock!' do + it 'unlocks after entering unlock token' do sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2) sorcery_model_property_set(:login_lock_time_period, 0) sorcery_model_property_set(:unlock_token_mailer, SorceryMailer) diff --git a/spec/shared_examples/user_oauth_shared_examples.rb b/spec/shared_examples/user_oauth_shared_examples.rb index 1c7a024e..f06bbab8 100644 --- a/spec/shared_examples/user_oauth_shared_examples.rb +++ b/spec/shared_examples/user_oauth_shared_examples.rb @@ -1,10 +1,9 @@ -shared_examples_for "rails_3_oauth_model" do +shared_examples_for 'rails_3_oauth_model' do # ----------------- PLUGIN CONFIGURATION ----------------------- let(:external_user) { create_new_external_user :twitter } - describe "loaded plugin configuration" do - + describe 'loaded plugin configuration' do before(:all) do Authentication.sorcery_adapter.delete_all User.sorcery_adapter.delete_all @@ -12,9 +11,9 @@ sorcery_reload!([:external]) sorcery_controller_property_set(:external_providers, [:twitter]) sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_external_property_set(:twitter, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:twitter, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:twitter, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:twitter, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:twitter, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:twitter, :callback_url, 'http://blabla.com') end it "responds to 'load_from_provider'" do @@ -23,14 +22,12 @@ it "'load_from_provider' loads user if exists" do external_user - expect(User.load_from_provider :twitter, 123).to eq external_user + expect(User.load_from_provider(:twitter, 123)).to eq external_user end it "'load_from_provider' returns nil if user doesn't exist" do external_user - expect(User.load_from_provider :twitter, 980342).to be_nil + expect(User.load_from_provider(:twitter, 980342)).to be_nil end - end - end diff --git a/spec/shared_examples/user_remember_me_shared_examples.rb b/spec/shared_examples/user_remember_me_shared_examples.rb index 8c89e6d3..e7448d31 100644 --- a/spec/shared_examples/user_remember_me_shared_examples.rb +++ b/spec/shared_examples/user_remember_me_shared_examples.rb @@ -1,8 +1,7 @@ -shared_examples_for "rails_3_remember_me_model" do +shared_examples_for 'rails_3_remember_me_model' do let(:user) { create_new_user } - describe "loaded plugin configuration" do - + describe 'loaded plugin configuration' do before(:all) do sorcery_reload!([:remember_me]) end @@ -46,7 +45,7 @@ expect(user.remember_me_token_expires_at.utc.to_s).to eq (ts + 2 * 60 * 60 * 24).utc.to_s end - context "when not persisting globally" do + context 'when not persisting globally' do before { sorcery_model_property_set(:remember_me_token_persist_globally, false) } it "generates a new token on 'remember_me!' when a token doesn't exist" do @@ -57,11 +56,11 @@ end it "generates a new token on 'remember_me!' when a token exists" do - user.remember_me_token = "abc123" + user.remember_me_token = 'abc123' user.remember_me! expect(user.remember_me_token).not_to be_nil - expect(user.remember_me_token).not_to eq("abc123") + expect(user.remember_me_token).not_to eq('abc123') end it "deletes the token and expiration on 'forget_me!'" do @@ -87,7 +86,7 @@ end end - context "when persisting globally" do + context 'when persisting globally' do before { sorcery_model_property_set(:remember_me_token_persist_globally, true) } it "generates a new token on 'remember_me!' when a token doesn't exist" do @@ -98,10 +97,10 @@ end it "keeps existing token on 'remember_me!' when a token exists" do - user.remember_me_token = "abc123" + user.remember_me_token = 'abc123' user.remember_me! - expect(user.remember_me_token).to eq("abc123") + expect(user.remember_me_token).to eq('abc123') end it "keeps the token and expiration on 'forget_me!'" do @@ -126,6 +125,5 @@ expect(user.remember_me_token_expires_at).to be_nil end end - end end From 3993b00f55061bf227a407edec39e534b721d912 Mon Sep 17 00:00:00 2001 From: Dan Kim Date: Tue, 13 Dec 2016 00:16:17 +0300 Subject: [PATCH 36/46] Fix code style --- lib/sorcery/controller.rb | 20 +- lib/sorcery/controller/config.rb | 38 +-- .../submodules/brute_force_protection.rb | 3 +- lib/sorcery/controller/submodules/external.rb | 29 +- .../controller/submodules/http_basic_auth.rb | 11 +- .../controller/submodules/session_timeout.rb | 11 +- lib/sorcery/crypto_providers/bcrypt.rb | 12 +- lib/sorcery/model.rb | 39 ++- lib/sorcery/model/config.rb | 106 +++---- .../model/submodules/activity_logging.rb | 31 +- .../model/submodules/reset_password.rb | 64 ++-- .../model/submodules/user_activation.rb | 85 +++--- lib/sorcery/model/temporary_token.rb | 2 +- lib/sorcery/providers/facebook.rb | 9 +- lib/sorcery/providers/github.rb | 12 +- lib/sorcery/providers/google.rb | 8 +- lib/sorcery/providers/heroku.rb | 14 +- lib/sorcery/providers/jira.rb | 28 +- lib/sorcery/providers/linkedin.rb | 10 +- lib/sorcery/providers/liveid.rb | 11 +- lib/sorcery/providers/paypal.rb | 8 +- lib/sorcery/providers/salesforce.rb | 8 +- lib/sorcery/providers/slack.rb | 7 +- lib/sorcery/providers/twitter.rb | 10 +- lib/sorcery/providers/vk.rb | 8 +- lib/sorcery/providers/xing.rb | 16 +- lib/sorcery/test_helpers/internal.rb | 20 +- lib/sorcery/test_helpers/internal/rails.rb | 16 +- lib/sorcery/test_helpers/rails/controller.rb | 2 +- lib/sorcery/test_helpers/rails/integration.rb | 11 +- spec/active_record/user_activation_spec.rb | 5 +- .../user_activity_logging_spec.rb | 6 +- .../user_brute_force_protection_spec.rb | 7 +- spec/controllers/controller_oauth2_spec.rb | 278 +++++++++--------- spec/controllers/controller_oauth_spec.rb | 152 +++++----- .../controller_remember_me_spec.rb | 64 ++-- .../controller_session_timeout_spec.rb | 29 +- spec/controllers/controller_spec.rb | 82 +++--- spec/orm/active_record.rb | 2 +- .../app/active_record/authentication.rb | 2 +- spec/rails_app/app/active_record/user.rb | 4 +- spec/rails_app/config.ru | 2 +- spec/rails_app/config/application.rb | 12 +- spec/rails_app/config/boot.rb | 2 +- spec/rails_app/config/environments/test.rb | 2 +- .../config/initializers/session_store.rb | 6 +- spec/rails_app/config/routes.rb | 2 +- .../user_activation_shared_examples.rb | 130 ++++---- .../user_reset_password_shared_examples.rb | 102 +++---- spec/shared_examples/user_shared_examples.rb | 233 +++++++-------- spec/sorcery_crypto_providers_spec.rb | 139 ++++----- spec/spec_helper.rb | 23 +- 52 files changed, 927 insertions(+), 1006 deletions(-) diff --git a/lib/sorcery/controller.rb b/lib/sorcery/controller.rb index 6cfb5600..eb2ca099 100644 --- a/lib/sorcery/controller.rb +++ b/lib/sorcery/controller.rb @@ -20,9 +20,9 @@ module InstanceMethods # Will trigger auto-login attempts via the call to logged_in? # If all attempts to auto-login fail, the failure callback will be called. def require_login - if !logged_in? + unless logged_in? session[:return_to_url] = request.url if Config.save_return_to_url && request.get? && !request.xhr? - self.send(Config.not_authenticated_action) + send(Config.not_authenticated_action) end end @@ -34,7 +34,7 @@ def login(*credentials) if user old_session = session.dup.to_hash reset_sorcery_session - old_session.each_pair do |k,v| + old_session.each_pair do |k, v| session[k.to_sym] = v end form_authenticity_token @@ -87,7 +87,7 @@ def current_user=(user) # used when a user tries to access a page while logged out, is asked to login, # and we want to return him back to the page he originally wanted. def redirect_back_or_to(url, flash_hash = {}) - redirect_to(session[:return_to_url] || url, :flash => flash_hash) + redirect_to(session[:return_to_url] || url, flash: flash_hash) session[:return_to_url] = nil end @@ -102,7 +102,7 @@ def not_authenticated # # @param [] user the user instance. # @return - do not depend on the return value. - def auto_login(user, should_remember = false) + def auto_login(user, _should_remember = false) session[:user_id] = user.id.to_s @current_user = user end @@ -132,26 +132,24 @@ def login_from_session end def after_login!(user, credentials = []) - Config.after_login.each {|c| self.send(c, user, credentials)} + Config.after_login.each { |c| send(c, user, credentials) } end def after_failed_login!(credentials) - Config.after_failed_login.each {|c| self.send(c, credentials)} + Config.after_failed_login.each { |c| send(c, credentials) } end def before_logout! - Config.before_logout.each {|c| self.send(c)} + Config.before_logout.each { |c| send(c) } end def after_logout!(user) - Config.after_logout.each {|c| self.send(c, user)} + Config.after_logout.each { |c| send(c, user) } end def user_class @user_class ||= Config.user_class.to_s.constantize end - end - end end diff --git a/lib/sorcery/controller/config.rb b/lib/sorcery/controller/config.rb index fbfc028e..99e1f3fb 100644 --- a/lib/sorcery/controller/config.rb +++ b/lib/sorcery/controller/config.rb @@ -2,21 +2,22 @@ module Sorcery module Controller module Config class << self - attr_accessor :submodules, - :user_class, # what class to use as the user class. - :not_authenticated_action, # what controller action to call for non-authenticated users. + attr_accessor :submodules + # what class to use as the user class. + attr_accessor :user_class + # what controller action to call for non-authenticated users. + attr_accessor :not_authenticated_action + # when a non logged in user tries to enter a page that requires login, + # save the URL he wanted to reach, and send him there after login. + attr_accessor :save_return_to_url + # set domain option for cookies + attr_accessor :cookie_domain - :save_return_to_url, # when a non logged in user tries to enter a page that requires - # login, save the URL he wanted to reach, - # and send him there after login. - - :cookie_domain, # set domain option for cookies - - :login_sources, - :after_login, - :after_failed_login, - :before_logout, - :after_logout + attr_accessor :login_sources + attr_accessor :after_login + attr_accessor :after_failed_login + attr_accessor :before_logout + attr_accessor :after_logout def init! @defaults = { @@ -35,14 +36,14 @@ def init! # Resets all configuration options to their default values. def reset! - @defaults.each do |k,v| - instance_variable_set(k,v) + @defaults.each do |k, v| + instance_variable_set(k, v) end end def update! - @defaults.each do |k,v| - instance_variable_set(k,v) if !instance_variable_defined?(k) + @defaults.each do |k, v| + instance_variable_set(k, v) unless instance_variable_defined?(k) end end @@ -58,6 +59,7 @@ def configure! @configure_blk.call(self) if @configure_blk end end + init! reset! end diff --git a/lib/sorcery/controller/submodules/brute_force_protection.rb b/lib/sorcery/controller/submodules/brute_force_protection.rb index 7603f48b..e4756b7b 100644 --- a/lib/sorcery/controller/submodules/brute_force_protection.rb +++ b/lib/sorcery/controller/submodules/brute_force_protection.rb @@ -16,7 +16,6 @@ def self.included(base) end module InstanceMethods - protected # Increments the failed logins counter on every failed login. @@ -28,7 +27,7 @@ def update_failed_logins_count!(credentials) # Resets the failed logins counter. # Runs as a hook after a successful login. - def reset_failed_logins_count!(user, credentials) + def reset_failed_logins_count!(user, _credentials) user.sorcery_adapter.update_attribute(user_class.sorcery_config.failed_logins_count_attribute_name, 0) end end diff --git a/lib/sorcery/controller/submodules/external.rb b/lib/sorcery/controller/submodules/external.rb index 946c5128..9907fab5 100644 --- a/lib/sorcery/controller/submodules/external.rb +++ b/lib/sorcery/controller/submodules/external.rb @@ -89,16 +89,15 @@ def sorcery_fetch_user_hash(provider_name) end # for backwards compatibility - def access_token(*args) + def access_token(*_args) @access_token end - # this method should be somewhere else. It only does something once per application per provider. def sorcery_fixup_callback_url(provider) provider.original_callback_url ||= provider.callback_url if provider.original_callback_url.present? && provider.original_callback_url[0] == '/' - uri = URI.parse(request.url.gsub(/\?.*$/,'')) + uri = URI.parse(request.url.gsub(/\?.*$/, '')) uri.path = '' uri.query = nil uri.scheme = 'https' if request.env['HTTP_X_FORWARDED_PROTO'] == 'https' @@ -152,12 +151,14 @@ def create_and_validate_from(provider_name) user, saved = user_class.create_and_validate_from_provider(provider_name, @user_hash[:uid], attrs) - session[:incomplete_user] = { - :provider => {config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name}, - :user_hash => attrs - } unless saved + unless saved + session[:incomplete_user] = { + provider: { config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name }, + user_hash: attrs + } + end - return user + user end # this method automatically creates a new user from the data in the external user hash. @@ -186,15 +187,19 @@ def create_from(provider_name, &block) def user_attrs(user_info_mapping, user_hash) attrs = {} - user_info_mapping.each do |k,v| - if (varr = v.split("/")).size > 1 - attribute_value = varr.inject(user_hash[:user_info]) {|hash, value| hash[value]} rescue nil + user_info_mapping.each do |k, v| + if (varr = v.split('/')).size > 1 + attribute_value = begin + varr.inject(user_hash[:user_info]) { |hash, value| hash[value] } + rescue + nil + end attribute_value.nil? ? attrs : attrs.merge!(k => attribute_value) else attrs.merge!(k => user_hash[:user_info][v]) end end - return attrs + attrs end end end diff --git a/lib/sorcery/controller/submodules/http_basic_auth.rb b/lib/sorcery/controller/submodules/http_basic_auth.rb index a6dd30b4..672615f3 100644 --- a/lib/sorcery/controller/submodules/http_basic_auth.rb +++ b/lib/sorcery/controller/submodules/http_basic_auth.rb @@ -11,10 +11,10 @@ def self.included(base) base.send(:include, InstanceMethods) Config.module_eval do class << self - attr_accessor :controller_to_realm_map # What realm to display for which controller name. + attr_accessor :controller_to_realm_map # What realm to display for which controller name. def merge_http_basic_auth_defaults! - @defaults.merge!(:@controller_to_realm_map => {"application" => "Application"}) + @defaults.merge!(:@controller_to_realm_map => { 'application' => 'Application' }) end end merge_http_basic_auth_defaults! @@ -23,7 +23,6 @@ def merge_http_basic_auth_defaults! end module InstanceMethods - protected # to be used as a before_action. @@ -37,7 +36,7 @@ module InstanceMethods # To overcome this, we set a session when requesting the password, which logout will # reset, and that's how we know if we need to request for HTTP auth again. def require_login_from_http_basic - (request_http_basic_authentication(realm_name_by_controller) && (session[:http_authentication_used] = true) && return) if (request.authorization.nil? || session[:http_authentication_used].nil?) + (request_http_basic_authentication(realm_name_by_controller) && (session[:http_authentication_used] = true) && return) if request.authorization.nil? || session[:http_authentication_used].nil? require_login session[:http_authentication_used] = nil unless logged_in? end @@ -62,12 +61,10 @@ def realm_name_by_controller end nil else - Config.controller_to_realm_map["application"] + Config.controller_to_realm_map['application'] end end - end - end end end diff --git a/lib/sorcery/controller/submodules/session_timeout.rb b/lib/sorcery/controller/submodules/session_timeout.rb index d0507b75..79185c4b 100644 --- a/lib/sorcery/controller/submodules/session_timeout.rb +++ b/lib/sorcery/controller/submodules/session_timeout.rb @@ -8,10 +8,10 @@ def self.included(base) base.send(:include, InstanceMethods) Config.module_eval do class << self - attr_accessor :session_timeout, # how long in seconds to keep the session alive. - - :session_timeout_from_last_action # use the last action as the beginning of session - # timeout. + # how long in seconds to keep the session alive. + attr_accessor :session_timeout + # use the last action as the beginning of session timeout. + attr_accessor :session_timeout_from_last_action def merge_session_timeout_defaults! @defaults.merge!(:@session_timeout => 3600, # 1.hour @@ -29,7 +29,7 @@ module InstanceMethods # Registers last login to be used as the timeout starting point. # Runs as a hook after a successful login. - def register_login_time(user, credentials) + def register_login_time(_user, _credentials) session[:login_time] = session[:last_action_time] = Time.now.in_time_zone end @@ -48,7 +48,6 @@ def validate_session def sorcery_session_expired?(time) Time.now.in_time_zone - time > Config.session_timeout end - end end end diff --git a/lib/sorcery/crypto_providers/bcrypt.rb b/lib/sorcery/crypto_providers/bcrypt.rb index 816f452b..35a4923c 100644 --- a/lib/sorcery/crypto_providers/bcrypt.rb +++ b/lib/sorcery/crypto_providers/bcrypt.rb @@ -53,7 +53,7 @@ def cost # Creates a BCrypt hash for the password passed. def encrypt(*tokens) - ::BCrypt::Password.create(join_tokens(tokens), :cost => cost) + ::BCrypt::Password.create(join_tokens(tokens), cost: cost) end # Does the hash match the tokens? Uses the same tokens that were used to encrypt. @@ -85,13 +85,11 @@ def join_tokens(tokens) end def new_from_hash(hash) - begin - ::BCrypt::Password.new(hash) - rescue ::BCrypt::Errors::InvalidHash - return nil - end + ::BCrypt::Password.new(hash) + rescue ::BCrypt::Errors::InvalidHash + return nil end end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/model.rb b/lib/sorcery/model.rb index 43053e3d..50b670af 100644 --- a/lib/sorcery/model.rb +++ b/lib/sorcery/model.rb @@ -17,7 +17,7 @@ def authenticates_with_sorcery! include_required_submodules! # This runs the options block set in the initializer on the model class. - ::Sorcery::Controller::Config.user_config.tap{|blk| blk.call(@sorcery_config) if blk} + ::Sorcery::Controller::Config.user_config.tap { |blk| blk.call(@sorcery_config) if blk } define_base_fields init_orm_hooks! @@ -29,7 +29,7 @@ def authenticates_with_sorcery! private def define_base_fields - self.class_eval do + class_eval do sorcery_config.username_attribute_names.each do |username| sorcery_adapter.define_field username, String, length: 255 end @@ -39,13 +39,12 @@ def define_base_fields sorcery_adapter.define_field sorcery_config.crypted_password_attribute_name, String, length: 255 sorcery_adapter.define_field sorcery_config.salt_attribute_name, String, length: 255 end - end # includes required submodules into the model class, # which usually is called User. def include_required_submodules! - self.class_eval do + class_eval do @sorcery_config.submodules = ::Sorcery::Controller::Config.submodules @sorcery_config.submodules.each do |mod| begin @@ -60,11 +59,11 @@ def include_required_submodules! # add virtual password accessor and ORM callbacks. def init_orm_hooks! - sorcery_adapter.define_callback :before, :validation, :encrypt_password, if: Proc.new {|record| + sorcery_adapter.define_callback :before, :validation, :encrypt_password, if: proc { |record| record.send(sorcery_config.password_attribute_name).present? } - sorcery_adapter.define_callback :after, :save, :clear_virtual_password, if: Proc.new {|record| + sorcery_adapter.define_callback :after, :save, :clear_virtual_password, if: proc { |record| record.send(sorcery_config.password_attribute_name).present? } @@ -82,7 +81,7 @@ def sorcery_config # Finds the user by the username and compares the user's password to the one supplied to the method. # returns the user if success, nil otherwise. def authenticate(*credentials) - raise ArgumentError, "at least 2 arguments required" if credentials.size < 2 + raise ArgumentError, 'at least 2 arguments required' if credentials.size < 2 return false if credentials[0].blank? @@ -93,19 +92,19 @@ def authenticate(*credentials) user = sorcery_adapter.find_by_credentials(credentials) if user.respond_to?(:active_for_authentication?) - return nil if !user.active_for_authentication? + return nil unless user.active_for_authentication? end set_encryption_attributes - user if user && @sorcery_config.before_authenticate.all? {|c| user.send(c)} && user.valid_password?(credentials[1]) + user if user && @sorcery_config.before_authenticate.all? { |c| user.send(c) } && user.valid_password?(credentials[1]) end # encrypt tokens using current encryption_provider. def encrypt(*tokens) return tokens.first if @sorcery_config.encryption_provider.nil? - set_encryption_attributes() + set_encryption_attributes CryptoProviders::AES256.key = @sorcery_config.encryption_key @sorcery_config.encryption_provider.encrypt(*tokens) @@ -119,7 +118,7 @@ def set_encryption_attributes end def add_config_inheritance - self.class_eval do + class_eval do def self.inherited(subclass) subclass.class_eval do class << self @@ -131,7 +130,6 @@ class << self end end end - end module InstanceMethods @@ -148,10 +146,10 @@ def external? # Calls the configured encryption provider to compare the supplied password with the encrypted one. def valid_password?(pass) - crypted = self.send(sorcery_config.crypted_password_attribute_name) + crypted = send(sorcery_config.crypted_password_attribute_name) return crypted == pass if sorcery_config.encryption_provider.nil? - salt = self.send(sorcery_config.salt_attribute_name) unless sorcery_config.salt_attribute_name.nil? + salt = send(sorcery_config.salt_attribute_name) unless sorcery_config.salt_attribute_name.nil? sorcery_config.encryption_provider.matches?(crypted, pass, salt) end @@ -162,16 +160,16 @@ def valid_password?(pass) # encrypts password with salt and saves it. def encrypt_password config = sorcery_config - self.send(:"#{config.salt_attribute_name}=", new_salt = TemporaryToken.generate_random_token) if !config.salt_attribute_name.nil? - self.send(:"#{config.crypted_password_attribute_name}=", self.class.encrypt(self.send(config.password_attribute_name),new_salt)) + send(:"#{config.salt_attribute_name}=", new_salt = TemporaryToken.generate_random_token) unless config.salt_attribute_name.nil? + send(:"#{config.crypted_password_attribute_name}=", self.class.encrypt(send(config.password_attribute_name), new_salt)) end def clear_virtual_password config = sorcery_config - self.send(:"#{config.password_attribute_name}=", nil) + send(:"#{config.password_attribute_name}=", nil) if respond_to?(:"#{config.password_attribute_name}_confirmation=") - self.send(:"#{config.password_attribute_name}_confirmation=", nil) + send(:"#{config.password_attribute_name}_confirmation=", nil) end end @@ -179,12 +177,11 @@ def clear_virtual_password # supports both the ActionMailer 3 way of calling, and the plain old Ruby object way. def generic_send_email(method, mailer) config = sorcery_config - mail = config.send(mailer).send(config.send(method),self) - if defined?(ActionMailer) && config.send(mailer).kind_of?(Class) && config.send(mailer) < ActionMailer::Base + mail = config.send(mailer).send(config.send(method), self) + if defined?(ActionMailer) && config.send(mailer).is_a?(Class) && config.send(mailer) < ActionMailer::Base mail.send(config.email_delivery_method) end end end - end end diff --git a/lib/sorcery/model/config.rb b/lib/sorcery/model/config.rb index 5774f0d8..9fec869d 100644 --- a/lib/sorcery/model/config.rb +++ b/lib/sorcery/model/config.rb @@ -4,43 +4,45 @@ module Sorcery module Model class Config + # change default username attribute, for example, to use :email as the login. + attr_accessor :username_attribute_names + # change *virtual* password attribute, the one which is used until an encrypted one is generated. + attr_accessor :password_attribute_name + # change default email attribute. + attr_accessor :email_attribute_name + # downcase the username before trying to authenticate, default is false + attr_accessor :downcase_username_before_authenticating + # change default crypted_password attribute. + attr_accessor :crypted_password_attribute_name + # what pattern to use to join the password with the salt + attr_accessor :salt_join_token + # change default salt attribute. + attr_accessor :salt_attribute_name + # how many times to apply encryption to the password. + attr_accessor :stretches + # encryption key used to encrypt reversible encryptions such as AES256. + attr_accessor :encryption_key + # make this configuration inheritable for subclasses. Useful for ActiveRecord's STI. + attr_accessor :subclasses_inherit_config + # configured in config/application.rb + attr_accessor :submodules + # an array of method names to call before authentication completes. used internally. + attr_accessor :before_authenticate + # method to send email related + # options: `:deliver_later`, `:deliver_now`, `:deliver` + # Default: :deliver (Rails version < 4.2) or :deliver_now (Rails version 4.2+) + # method to send email related + attr_accessor :email_delivery_method + # an array of method names to call after configuration by user. used internally. + attr_accessor :after_config + + # change default encryption_provider. + attr_reader :encryption_provider + # use an external encryption class. + attr_reader :custom_encryption_provider + # encryption algorithm name. See 'encryption_algorithm=' below for available options. + attr_reader :encryption_algorithm - attr_accessor :username_attribute_names, # change default username attribute, for example, to use :email - # as the login. - - :password_attribute_name, # change *virtual* password attribute, the one which is used - # until an encrypted one is generated. - - :email_attribute_name, # change default email attribute. - - :downcase_username_before_authenticating, # downcase the username before trying to authenticate, default is false - - :crypted_password_attribute_name, # change default crypted_password attribute. - :salt_join_token, # what pattern to use to join the password with the salt - :salt_attribute_name, # change default salt attribute. - :stretches, # how many times to apply encryption to the password. - :encryption_key, # encryption key used to encrypt reversible encryptions such as - # AES256. - - :subclasses_inherit_config, # make this configuration inheritable for subclasses. Useful for - # ActiveRecord's STI. - - :submodules, # configured in config/application.rb - :before_authenticate, # an array of method names to call before authentication - # completes. used internally. - - :email_delivery_method, # method to send email related - # options: `:deliver_later`, `:deliver_now`, `:deliver` - # Default: :deliver (Rails version < 4.2) or :deliver_now (Rails version 4.2+) - # method to send email related - - :after_config # an array of method names to call after configuration by user. - # used internally. - - attr_reader :encryption_provider, # change default encryption_provider. - :custom_encryption_provider, # use an external encryption class. - :encryption_algorithm # encryption algorithm name. See 'encryption_algorithm=' below - # for available options. def initialize @defaults = { :@submodules => [], @@ -53,7 +55,7 @@ def initialize :@encryption_provider => CryptoProviders::BCrypt, :@custom_encryption_provider => nil, :@encryption_key => nil, - :@salt_join_token => "", + :@salt_join_token => '', :@salt_attribute_name => :salt, :@stretches => nil, :@subclasses_inherit_config => false, @@ -66,13 +68,13 @@ def initialize # Resets all configuration options to their default values. def reset! - @defaults.each do |k,v| - instance_variable_set(k,v) + @defaults.each do |k, v| + instance_variable_set(k, v) end end def username_attribute_names=(fields) - @username_attribute_names = fields.kind_of?(Array) ? fields : [fields] + @username_attribute_names = fields.is_a?(Array) ? fields : [fields] end def custom_encryption_provider=(provider) @@ -82,30 +84,28 @@ def custom_encryption_provider=(provider) def encryption_algorithm=(algo) @encryption_algorithm = algo @encryption_provider = case @encryption_algorithm.to_sym - when :none then nil - when :md5 then CryptoProviders::MD5 - when :sha1 then CryptoProviders::SHA1 - when :sha256 then CryptoProviders::SHA256 - when :sha512 then CryptoProviders::SHA512 - when :aes256 then CryptoProviders::AES256 - when :bcrypt then CryptoProviders::BCrypt - when :custom then @custom_encryption_provider - else raise ArgumentError.new("Encryption algorithm supplied, #{algo}, is invalid") + when :none then nil + when :md5 then CryptoProviders::MD5 + when :sha1 then CryptoProviders::SHA1 + when :sha256 then CryptoProviders::SHA256 + when :sha512 then CryptoProviders::SHA512 + when :aes256 then CryptoProviders::AES256 + when :bcrypt then CryptoProviders::BCrypt + when :custom then @custom_encryption_provider + else raise ArgumentError, "Encryption algorithm supplied, #{algo}, is invalid" end end private + def default_email_delivery_method # Rails 4.2 deprecates #deliver - rails_version_bigger_than_or_equal?('4.2.0') ? :deliver_now : :deliver + rails_version_bigger_than_or_equal?('4.2.0') ? :deliver_now : :deliver end def rails_version_bigger_than_or_equal?(version) Gem::Version.new(version) <= Gem::Version.new(Rails.version) end - end - end end - diff --git a/lib/sorcery/model/submodules/activity_logging.rb b/lib/sorcery/model/submodules/activity_logging.rb index 1548abb6..f27969d2 100644 --- a/lib/sorcery/model/submodules/activity_logging.rb +++ b/lib/sorcery/model/submodules/activity_logging.rb @@ -12,12 +12,16 @@ def self.included(base) base.send(:include, InstanceMethods) base.sorcery_config.class_eval do - attr_accessor :last_login_at_attribute_name, # last login attribute name. - :last_logout_at_attribute_name, # last logout attribute name. - :last_activity_at_attribute_name, # last activity attribute name. - :last_login_from_ip_address_name, # last activity login source - :activity_timeout # how long since last activity is - # the user defined offline + # last login attribute name. + attr_accessor :last_login_at_attribute_name + # last logout attribute name. + attr_accessor :last_logout_at_attribute_name + # last activity attribute name. + attr_accessor :last_activity_at_attribute_name + # last activity login source + attr_accessor :last_login_from_ip_address_name + # how long since last activity is the user defined offline + attr_accessor :activity_timeout end base.sorcery_config.instance_eval do @@ -51,28 +55,27 @@ def set_last_ip_address(ip_address) # online method shows if user is active (logout action makes user inactive too) def online? - return false if self.send(sorcery_config.last_activity_at_attribute_name).nil? + return false if send(sorcery_config.last_activity_at_attribute_name).nil? - logged_in? && self.send(sorcery_config.last_activity_at_attribute_name) > sorcery_config.activity_timeout.seconds.ago + logged_in? && send(sorcery_config.last_activity_at_attribute_name) > sorcery_config.activity_timeout.seconds.ago end # shows if user is logged in, but it not show if user is online - see online? def logged_in? - return false if self.send(sorcery_config.last_login_at_attribute_name).nil? - return true if self.send(sorcery_config.last_login_at_attribute_name).present? && self.send(sorcery_config.last_logout_at_attribute_name).nil? + return false if send(sorcery_config.last_login_at_attribute_name).nil? + return true if send(sorcery_config.last_login_at_attribute_name).present? && send(sorcery_config.last_logout_at_attribute_name).nil? - self.send(sorcery_config.last_login_at_attribute_name) > self.send(sorcery_config.last_logout_at_attribute_name) + send(sorcery_config.last_login_at_attribute_name) > send(sorcery_config.last_logout_at_attribute_name) end def logged_out? - not logged_in? + !logged_in? end - end module ClassMethods - protected + def define_activity_logging_fields sorcery_adapter.define_field sorcery_config.last_login_at_attribute_name, Time sorcery_adapter.define_field sorcery_config.last_logout_at_attribute_name, Time diff --git a/lib/sorcery/model/submodules/reset_password.rb b/lib/sorcery/model/submodules/reset_password.rb index 0acd8b65..45cc04f7 100644 --- a/lib/sorcery/model/submodules/reset_password.rb +++ b/lib/sorcery/model/submodules/reset_password.rb @@ -12,26 +12,23 @@ module Submodules module ResetPassword def self.included(base) base.sorcery_config.class_eval do - attr_accessor :reset_password_token_attribute_name, # reset password code attribute name. - :reset_password_token_expires_at_attribute_name, # expires at attribute name. - :reset_password_email_sent_at_attribute_name, # when was email sent, used for hammering - # protection. - - :reset_password_mailer, # mailer class. Needed. - - :reset_password_mailer_disabled, # when true sorcery will not automatically - # email password reset details and allow you to - # manually handle how and when email is sent - - :reset_password_email_method_name, # reset password email method on your - # mailer class. - - :reset_password_expiration_period, # how many seconds before the reset request - # expires. nil for never expires. - - :reset_password_time_between_emails # hammering protection, how long to wait - # before allowing another email to be sent. - + # Reset password code attribute name. + attr_accessor :reset_password_token_attribute_name + # Expires at attribute name. + attr_accessor :reset_password_token_expires_at_attribute_name + # When was email sent, used for hammering protection. + attr_accessor :reset_password_email_sent_at_attribute_name + # Mailer class (needed) + attr_accessor :reset_password_mailer + # When true sorcery will not automatically email password reset details and allow you to + # manually handle how and when email is sent + attr_accessor :reset_password_mailer_disabled + # Reset password email method on your mailer class. + attr_accessor :reset_password_email_method_name + # How many seconds before the reset request expires. nil for never expires. + attr_accessor :reset_password_expiration_period + # Hammering protection, how long to wait before allowing another email to be sent. + attr_accessor :reset_password_time_between_emails end base.sorcery_config.instance_eval do @@ -42,7 +39,7 @@ def self.included(base) :@reset_password_mailer_disabled => false, :@reset_password_email_method_name => :reset_password_email, :@reset_password_expiration_period => nil, - :@reset_password_time_between_emails => 5 * 60 ) + :@reset_password_time_between_emails => 5 * 60) reset! end @@ -53,7 +50,6 @@ def self.included(base) base.sorcery_config.after_config << :define_reset_password_fields base.send(:include, InstanceMethods) - end module ClassMethods @@ -70,8 +66,8 @@ def load_from_reset_password_token(token) # This submodule requires the developer to define his own mailer class to be used by it # when reset_password_mailer_disabled is false def validate_mailer_defined - msg = "To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass)." - raise ArgumentError, msg if @sorcery_config.reset_password_mailer == nil && @sorcery_config.reset_password_mailer_disabled == false + message = 'To use reset_password submodule, you must define a mailer (config.reset_password_mailer = YourMailerClass).' + raise ArgumentError, message if @sorcery_config.reset_password_mailer.nil? && @sorcery_config.reset_password_mailer_disabled == false end def define_reset_password_fields @@ -79,26 +75,25 @@ def define_reset_password_fields sorcery_adapter.define_field sorcery_config.reset_password_token_expires_at_attribute_name, Time sorcery_adapter.define_field sorcery_config.reset_password_email_sent_at_attribute_name, Time end - end module InstanceMethods - # generates a reset code with expiration + # Generates a reset code with expiration def generate_reset_password_token! config = sorcery_config - attributes = {config.reset_password_token_attribute_name => TemporaryToken.generate_random_token, - config.reset_password_email_sent_at_attribute_name => Time.now.in_time_zone} + attributes = { config.reset_password_token_attribute_name => TemporaryToken.generate_random_token, + config.reset_password_email_sent_at_attribute_name => Time.now.in_time_zone } attributes[config.reset_password_token_expires_at_attribute_name] = Time.now.in_time_zone + config.reset_password_expiration_period if config.reset_password_expiration_period - self.sorcery_adapter.update_attributes(attributes) + sorcery_adapter.update_attributes(attributes) end - # generates a reset code with expiration and sends an email to the user. + # Generates a reset code with expiration and sends an email to the user. def deliver_reset_password_instructions! mail = false config = sorcery_config # hammering protection - return false if config.reset_password_time_between_emails.present? && self.send(config.reset_password_email_sent_at_attribute_name) && self.send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.seconds.ago.utc + return false if config.reset_password_time_between_emails.present? && send(config.reset_password_email_sent_at_attribute_name) && send(config.reset_password_email_sent_at_attribute_name) > config.reset_password_time_between_emails.seconds.ago.utc self.class.sorcery_adapter.transaction do generate_reset_password_token! mail = send_reset_password_email! unless config.reset_password_mailer_disabled @@ -109,7 +104,7 @@ def deliver_reset_password_instructions! # Clears token and tries to update the new password for the user. def change_password!(new_password) clear_reset_password_token - self.send(:"#{sorcery_config.password_attribute_name}=", new_password) + send(:"#{sorcery_config.password_attribute_name}=", new_password) sorcery_adapter.save end @@ -122,11 +117,10 @@ def send_reset_password_email! # Clears the token. def clear_reset_password_token config = sorcery_config - self.send(:"#{config.reset_password_token_attribute_name}=", nil) - self.send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil) if config.reset_password_expiration_period + send(:"#{config.reset_password_token_attribute_name}=", nil) + send(:"#{config.reset_password_token_expires_at_attribute_name}=", nil) if config.reset_password_expiration_period end end - end end end diff --git a/lib/sorcery/model/submodules/user_activation.rb b/lib/sorcery/model/submodules/user_activation.rb index 52e5183c..d8ef4fff 100644 --- a/lib/sorcery/model/submodules/user_activation.rb +++ b/lib/sorcery/model/submodules/user_activation.rb @@ -8,33 +8,24 @@ module Submodules module UserActivation def self.included(base) base.sorcery_config.class_eval do - attr_accessor :activation_state_attribute_name, # the attribute name to hold activation state - # (active/pending). - - :activation_token_attribute_name, # the attribute name to hold activation code - # (sent by email). - - :activation_token_expires_at_attribute_name, # the attribute name to hold activation code - # expiration date. - - :activation_token_expiration_period, # how many seconds before the activation code - # expires. nil for never expires. - - :user_activation_mailer, # your mailer class. Required when - # activation_mailer_disabled == false. - - :activation_mailer_disabled, # when true sorcery will not automatically - # email activation details and allow you to - # manually handle how and when email is sent - - :activation_needed_email_method_name, # activation needed email method on your - # mailer class. - - :activation_success_email_method_name, # activation success email method on your - # mailer class. - - :prevent_non_active_users_to_login # do you want to prevent or allow users that - # did not activate by email to login? + # The attribute name to hold activation state (active/pending). + attr_accessor :activation_state_attribute_name + # The attribute name to hold activation code (sent by email). + attr_accessor :activation_token_attribute_name + # The attribute name to hold activation code expiration date. + attr_accessor :activation_token_expires_at_attribute_name + # How many seconds before the activation code expires. nil for never expires. + attr_accessor :activation_token_expiration_period + # Your mailer class. Required when activation_mailer_disabled == false. + attr_accessor :user_activation_mailer + # When true sorcery will not automatically email activation details and allow you to manually handle how and when email is sent + attr_accessor :activation_mailer_disabled + # Activation needed email method on your mailer class. + attr_accessor :activation_needed_email_method_name + # Activation success email method on your mailer class. + attr_accessor :activation_success_email_method_name + # Do you want to prevent or allow users that did not activate by email to login? + attr_accessor :prevent_non_active_users_to_login end base.sorcery_config.instance_eval do @@ -52,9 +43,9 @@ def self.included(base) base.class_eval do # don't setup activation if no password supplied - this user is created automatically - sorcery_adapter.define_callback :before, :create, :setup_activation, :if => Proc.new { |user| user.send(sorcery_config.password_attribute_name).present? } + sorcery_adapter.define_callback :before, :create, :setup_activation, if: proc { |user| user.send(sorcery_config.password_attribute_name).present? } # don't send activation needed email if no crypted password created - this user is external (OAuth etc.) - sorcery_adapter.define_callback :after, :create, :send_activation_needed_email!, :if => :send_activation_needed_email? + sorcery_adapter.define_callback :after, :create, :send_activation_needed_email!, if: :send_activation_needed_email? end base.sorcery_config.after_config << :validate_mailer_defined @@ -63,7 +54,6 @@ def self.included(base) base.extend(ClassMethods) base.send(:include, InstanceMethods) - end module ClassMethods @@ -80,12 +70,12 @@ def load_from_activation_token(token) # This submodule requires the developer to define his own mailer class to be used by it # when activation_mailer_disabled is false def validate_mailer_defined - msg = "To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass)." - raise ArgumentError, msg if @sorcery_config.user_activation_mailer == nil && @sorcery_config.activation_mailer_disabled == false + message = 'To use user_activation submodule, you must define a mailer (config.user_activation_mailer = YourMailerClass).' + raise ArgumentError, message if @sorcery_config.user_activation_mailer.nil? && @sorcery_config.activation_mailer_disabled == false end def define_user_activation_fields - self.class_eval do + class_eval do sorcery_adapter.define_field sorcery_config.activation_state_attribute_name, String sorcery_adapter.define_field sorcery_config.activation_token_attribute_name, String sorcery_adapter.define_field sorcery_config.activation_token_expires_at_attribute_name, Time @@ -97,18 +87,18 @@ module InstanceMethods def setup_activation config = sorcery_config generated_activation_token = TemporaryToken.generate_random_token - self.send(:"#{config.activation_token_attribute_name}=", generated_activation_token) - self.send(:"#{config.activation_state_attribute_name}=", "pending") - self.send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.activation_token_expiration_period) if config.activation_token_expiration_period + send(:"#{config.activation_token_attribute_name}=", generated_activation_token) + send(:"#{config.activation_state_attribute_name}=", 'pending') + send(:"#{config.activation_token_expires_at_attribute_name}=", Time.now.in_time_zone + config.activation_token_expiration_period) if config.activation_token_expiration_period end # clears activation code, sets the user as 'active' and optionaly sends a success email. def activate! config = sorcery_config - self.send(:"#{config.activation_token_attribute_name}=", nil) - self.send(:"#{config.activation_state_attribute_name}=", "active") + send(:"#{config.activation_token_attribute_name}=", nil) + send(:"#{config.activation_state_attribute_name}=", 'active') send_activation_success_email! if send_activation_success_email? - sorcery_adapter.save(:validate => false, :raise_on_failure => true) + sorcery_adapter.save(validate: false, raise_on_failure: true) end attr_accessor :skip_activation_needed_email, :skip_activation_success_email @@ -125,24 +115,21 @@ def send_activation_success_email! end def send_activation_success_email? - !external? && ( - !(sorcery_config.activation_success_email_method_name.nil? || - sorcery_config.activation_mailer_disabled == true) - ) && !skip_activation_success_email + !external? && + !(sorcery_config.activation_success_email_method_name.nil? || sorcery_config.activation_mailer_disabled == true) && + !skip_activation_success_email end def send_activation_needed_email? - !external? && ( - !(sorcery_config.activation_needed_email_method_name.nil? || - sorcery_config.activation_mailer_disabled == true) - ) && !skip_activation_needed_email + !external? && + !(sorcery_config.activation_needed_email_method_name.nil? || sorcery_config.activation_mailer_disabled == true) && + !skip_activation_needed_email end def prevent_non_active_login config = sorcery_config - config.prevent_non_active_users_to_login ? self.send(config.activation_state_attribute_name) == "active" : true + config.prevent_non_active_users_to_login ? send(config.activation_state_attribute_name) == 'active' : true end - end end end diff --git a/lib/sorcery/model/temporary_token.rb b/lib/sorcery/model/temporary_token.rb index 23c6712b..99b0fdfa 100644 --- a/lib/sorcery/model/temporary_token.rb +++ b/lib/sorcery/model/temporary_token.rb @@ -18,7 +18,7 @@ def self.generate_random_token module ClassMethods def load_from_token(token, token_attr_name, token_expiration_date_attr) return nil if token.blank? - user = sorcery_adapter.find_by_token(token_attr_name,token) + user = sorcery_adapter.find_by_token(token_attr_name, token) if !user.blank? && !user.send(token_expiration_date_attr).nil? return Time.now.in_time_zone < user.send(token_expiration_date_attr) ? user : nil end diff --git a/lib/sorcery/providers/facebook.rb b/lib/sorcery/providers/facebook.rb index 6b5738ec..5dd5e2af 100644 --- a/lib/sorcery/providers/facebook.rb +++ b/lib/sorcery/providers/facebook.rb @@ -7,7 +7,6 @@ module Providers # ... # class Facebook < Base - include Protocols::Oauth2 attr_reader :mode, :param_name, :parse @@ -40,13 +39,12 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) + def login_url(_params, _session) authorize_url end # overrides oauth2#authorize_url to allow customized scope. def authorize_url - # Fix: replace default oauth2 options, specially to prevent the Faraday gem which # concatenates with "/", removing the Facebook api version options = { @@ -60,15 +58,14 @@ def authorize_url end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end get_access_token(args, token_url: token_url, mode: mode, - param_name: param_name, parse: parse) + param_name: param_name, parse: parse) end - end end end diff --git a/lib/sorcery/providers/github.rb b/lib/sorcery/providers/github.rb index d91640d3..359d30a8 100644 --- a/lib/sorcery/providers/github.rb +++ b/lib/sorcery/providers/github.rb @@ -7,7 +7,6 @@ module Providers # ... # class Github < Base - include Protocols::Oauth2 attr_accessor :auth_path, :scope, :token_url, :user_info_path @@ -35,12 +34,12 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - authorize_url({ authorize_url: auth_path }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_path) end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end @@ -49,12 +48,11 @@ def process_callback(params, session) end def primary_email(access_token) - response = access_token.get(user_info_path + "/emails") + response = access_token.get(user_info_path + '/emails') emails = JSON.parse(response.body) - primary = emails.find{|i| i['primary'] } + primary = emails.find { |i| i['primary'] } primary && primary['email'] || emails.first && emails.first['email'] end - end end end diff --git a/lib/sorcery/providers/google.rb b/lib/sorcery/providers/google.rb index 8fb0d67e..d68e2b8e 100644 --- a/lib/sorcery/providers/google.rb +++ b/lib/sorcery/providers/google.rb @@ -7,7 +7,6 @@ module Providers # ... # class Google < Base - include Protocols::Oauth2 attr_accessor :auth_url, :scope, :token_url, :user_info_url @@ -33,19 +32,18 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - authorize_url({ authorize_url: auth_url }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_url) end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end get_access_token(args, token_url: token_url, token_method: :post) end - end end end diff --git a/lib/sorcery/providers/heroku.rb b/lib/sorcery/providers/heroku.rb index b405d49d..cd420d56 100644 --- a/lib/sorcery/providers/heroku.rb +++ b/lib/sorcery/providers/heroku.rb @@ -1,6 +1,5 @@ module Sorcery module Providers - # This class adds support for OAuth with heroku.com. # config.heroku.key = @@ -13,7 +12,6 @@ module Providers # The full path must be set for OAuth Callback URL when configuring the API Client Information on Heroku. class Heroku < Base - include Protocols::Oauth2 attr_accessor :auth_path, :scope, :token_url, :user_info_path @@ -40,18 +38,18 @@ def get_user_hash(access_token) end end - def login_url(params, session) - authorize_url({ authorize_url: auth_path }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_path) end # tries to login the user from access token - def process_callback(params, session) - raise "Invalid state. Potential Cross Site Forgery" if params[:state] != state - args = { }.tap do |a| + def process_callback(params, _session) + raise 'Invalid state. Potential Cross Site Forgery' if params[:state] != state + args = {}.tap do |a| a[:code] = params[:code] if params[:code] end get_access_token(args, token_url: token_url, token_method: :post) end end end -end \ No newline at end of file +end diff --git a/lib/sorcery/providers/jira.rb b/lib/sorcery/providers/jira.rb index f65f2bac..45e87601 100644 --- a/lib/sorcery/providers/jira.rb +++ b/lib/sorcery/providers/jira.rb @@ -7,7 +7,6 @@ module Providers # ... # class Jira < Base - include Protocols::Oauth attr_accessor :access_token_path, :authorize_path, :request_token_path, @@ -15,22 +14,20 @@ class Jira < Base def initialize @configuration = { - authorize_path: '/authorize', - request_token_path: '/request-token', - access_token_path: '/access-token' + authorize_path: '/authorize', + request_token_path: '/request-token', + access_token_path: '/access-token' } @user_info_path = '/users/me' end # Override included get_consumer method to provide authorize_path - #read extra configurations + # read extra configurations def get_consumer - @configuration = @configuration.merge({ - site: site, - signature_method: signature_method, - consumer_key: key, - private_key_file: private_key_file - }) + @configuration = @configuration.merge(site: site, + signature_method: signature_method, + consumer_key: key, + private_key_file: private_key_file) ::OAuth::Consumer.new(@key, @secret, @configuration) end @@ -45,13 +42,13 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) + def login_url(_params, session) req_token = get_request_token session[:request_token] = req_token.token session[:request_token_secret] = req_token.secret - #it was like that -> redirect_to authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret }) - #for some reason Jira does not need these parameters + # it was like that -> redirect_to authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret }) + # for some reason Jira does not need these parameters get_request_token( session[:request_token], @@ -67,10 +64,9 @@ def process_callback(params, session) request_token_secret: session[:request_token_secret] } - args.merge!({ code: params[:code] }) if params[:code] + args[:code] = params[:code] if params[:code] get_access_token(args) end - end end end diff --git a/lib/sorcery/providers/linkedin.rb b/lib/sorcery/providers/linkedin.rb index 1a3dbaa4..ea303e78 100644 --- a/lib/sorcery/providers/linkedin.rb +++ b/lib/sorcery/providers/linkedin.rb @@ -7,7 +7,6 @@ module Providers # ... # class Linkedin < Base - include Protocols::Oauth attr_accessor :authorize_path, :access_permissions, :access_token_path, @@ -31,7 +30,7 @@ def get_consumer end def get_user_hash(access_token) - fields = self.user_info_fields.join(',') + fields = user_info_fields.join(',') response = access_token.get("#{@user_info_path}:(id,#{fields})", 'x-li-format' => 'json') auth_hash(access_token).tap do |h| @@ -42,11 +41,11 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) + def login_url(_params, session) req_token = get_request_token session[:request_token] = req_token.token session[:request_token_secret] = req_token.secret - authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret }) + authorize_url(request_token: req_token.token, request_token_secret: req_token.secret) end # tries to login the user from access token @@ -57,10 +56,9 @@ def process_callback(params, session) request_token_secret: session[:request_token_secret] } - args.merge!({ code: params[:code] }) if params[:code] + args[:code] = params[:code] if params[:code] get_access_token(args) end - end end end diff --git a/lib/sorcery/providers/liveid.rb b/lib/sorcery/providers/liveid.rb index bf8c0cc7..547e9f17 100644 --- a/lib/sorcery/providers/liveid.rb +++ b/lib/sorcery/providers/liveid.rb @@ -7,7 +7,6 @@ module Providers # ... # class Liveid < Base - include Protocols::Oauth2 attr_accessor :auth_url, :token_path, :user_info_url, :scope @@ -34,20 +33,18 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - self.authorize_url({ authorize_url: auth_url }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_url) end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end - get_access_token(args, access_token_path: token_path, - access_token_method: :post) + get_access_token(args, access_token_path: token_path, access_token_method: :post) end - end end end diff --git a/lib/sorcery/providers/paypal.rb b/lib/sorcery/providers/paypal.rb index 28b6c224..ff1de9cd 100644 --- a/lib/sorcery/providers/paypal.rb +++ b/lib/sorcery/providers/paypal.rb @@ -7,7 +7,6 @@ module Providers # ... # class Paypal < Base - include Protocols::Oauth2 attr_accessor :auth_url, :scope, :token_url, :user_info_url @@ -45,18 +44,17 @@ def get_access_token(args, options = {}) ) end - def login_url(params, session) - authorize_url({ authorize_url: auth_url }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_url) end - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end get_access_token(args, token_url: token_url, token_method: :post) end - end end end diff --git a/lib/sorcery/providers/salesforce.rb b/lib/sorcery/providers/salesforce.rb index d14cb475..90e5c3f5 100644 --- a/lib/sorcery/providers/salesforce.rb +++ b/lib/sorcery/providers/salesforce.rb @@ -7,7 +7,6 @@ module Providers # ... # class Salesforce < Base - include Protocols::Oauth2 attr_accessor :auth_url, :token_url, :scope @@ -32,19 +31,18 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - authorize_url({ authorize_url: auth_url }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_url) end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end get_access_token(args, token_url: token_url, token_method: :post) end - end end end diff --git a/lib/sorcery/providers/slack.rb b/lib/sorcery/providers/slack.rb index 129cf5c3..1d38ac5f 100644 --- a/lib/sorcery/providers/slack.rb +++ b/lib/sorcery/providers/slack.rb @@ -3,7 +3,6 @@ module Providers # This class adds support for OAuth with slack.com. class Slack < Base - include Protocols::Oauth2 attr_accessor :auth_path, :scope, :token_url, :user_info_path @@ -29,12 +28,12 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - authorize_url({ authorize_url: auth_path }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_path) end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end diff --git a/lib/sorcery/providers/twitter.rb b/lib/sorcery/providers/twitter.rb index ad39b100..59205995 100644 --- a/lib/sorcery/providers/twitter.rb +++ b/lib/sorcery/providers/twitter.rb @@ -7,7 +7,6 @@ module Providers # ... # class Twitter < Base - include Protocols::Oauth attr_accessor :state, :user_info_path @@ -35,11 +34,11 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - req_token = self.get_request_token + def login_url(_params, session) + req_token = get_request_token session[:request_token] = req_token.token session[:request_token_secret] = req_token.secret - self.authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret }) + authorize_url(request_token: req_token.token, request_token_secret: req_token.secret) end # tries to login the user from access token @@ -50,10 +49,9 @@ def process_callback(params, session) request_token_secret: session[:request_token_secret] } - args.merge!({ code: params[:code] }) if params[:code] + args[:code] = params[:code] if params[:code] get_access_token(args) end - end end end diff --git a/lib/sorcery/providers/vk.rb b/lib/sorcery/providers/vk.rb index 1bab66d4..3e7fbcbc 100644 --- a/lib/sorcery/providers/vk.rb +++ b/lib/sorcery/providers/vk.rb @@ -7,7 +7,6 @@ module Providers # ... # class Vk < Base - include Protocols::Oauth2 attr_accessor :auth_path, :token_path, :user_info_url, :scope @@ -45,19 +44,18 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) - self.authorize_url({ authorize_url: auth_path }) + def login_url(_params, _session) + authorize_url(authorize_url: auth_path) end # tries to login the user from access token - def process_callback(params, session) + def process_callback(params, _session) args = {}.tap do |a| a[:code] = params[:code] if params[:code] end get_access_token(args, token_url: token_path, token_method: :post) end - end end end diff --git a/lib/sorcery/providers/xing.rb b/lib/sorcery/providers/xing.rb index ba487bb3..6994071f 100644 --- a/lib/sorcery/providers/xing.rb +++ b/lib/sorcery/providers/xing.rb @@ -7,7 +7,6 @@ module Providers # ... # class Xing < Base - include Protocols::Oauth attr_accessor :access_token_path, :authorize_path, :request_token_path, @@ -15,10 +14,10 @@ class Xing < Base def initialize @configuration = { - site: 'https://api.xing.com/v1', - authorize_path: '/authorize', - request_token_path: '/request_token', - access_token_path: '/access_token' + site: 'https://api.xing.com/v1', + authorize_path: '/authorize', + request_token_path: '/request_token', + access_token_path: '/access_token' } @user_info_path = '/users/me' end @@ -39,11 +38,11 @@ def get_user_hash(access_token) # calculates and returns the url to which the user should be redirected, # to get authenticated at the external provider's site. - def login_url(params, session) + def login_url(_params, session) req_token = get_request_token session[:request_token] = req_token.token session[:request_token_secret] = req_token.secret - authorize_url({ request_token: req_token.token, request_token_secret: req_token.secret }) + authorize_url(request_token: req_token.token, request_token_secret: req_token.secret) end # tries to login the user from access token @@ -54,10 +53,9 @@ def process_callback(params, session) request_token_secret: session[:request_token_secret] } - args.merge!({ code: params[:code] }) if params[:code] + args[:code] = params[:code] if params[:code] get_access_token(args) end - end end end diff --git a/lib/sorcery/test_helpers/internal.rb b/lib/sorcery/test_helpers/internal.rb index 29b358b6..79c04d08 100644 --- a/lib/sorcery/test_helpers/internal.rb +++ b/lib/sorcery/test_helpers/internal.rb @@ -3,7 +3,7 @@ module TestHelpers # Internal TestHelpers are used to test the gem, internally, and should not be used to test apps *using* sorcery. # This file will be included in the spec_helper file. module Internal - def self.included(base) + def self.included(_base) # reducing default cost for specs speed CryptoProviders::BCrypt.class_eval do class << self @@ -24,31 +24,31 @@ def destroy end def build_new_user(attributes_hash = nil) - user_attributes_hash = attributes_hash || {:username => 'gizmo', :email => "bla@bla.com", :password => 'secret'} + user_attributes_hash = attributes_hash || { username: 'gizmo', email: 'bla@bla.com', password: 'secret' } @user = User.new(user_attributes_hash) end def create_new_user(attributes_hash = nil) @user = build_new_user(attributes_hash) - @user.sorcery_adapter.save(:raise_on_failure => true) + @user.sorcery_adapter.save(raise_on_failure: true) @user end def create_new_external_user(provider, attributes_hash = nil) - user_attributes_hash = attributes_hash || {:username => 'gizmo'} + user_attributes_hash = attributes_hash || { username: 'gizmo' } @user = User.new(user_attributes_hash) - @user.sorcery_adapter.save(:raise_on_failure => true) - @user.authentications.create!({:provider => provider, :uid => 123}) + @user.sorcery_adapter.save(raise_on_failure: true) + @user.authentications.create!(provider: provider, uid: 123) @user end def custom_create_new_external_user(provider, authentication_class, attributes_hash = nil) authentication_association = authentication_class.name.underscore.pluralize - user_attributes_hash = attributes_hash || {:username => 'gizmo'} + user_attributes_hash = attributes_hash || { username: 'gizmo' } @user = User.new(user_attributes_hash) - @user.sorcery_adapter.save(:raise_on_failure => true) - @user.send(authentication_association).create!({:provider => provider, :uid => 123}) + @user.sorcery_adapter.save(raise_on_failure: true) + @user.send(authentication_association).create!(provider: provider, uid: 123) @user end @@ -67,7 +67,7 @@ def update_model(&block) # reload user class between specs # so it will be possible to test the different submodules in isolation def reload_user_class - Object.send(:remove_const, "User") + Object.send(:remove_const, 'User') load 'user.rb' if User.respond_to?(:reset_column_information) User.reset_column_information diff --git a/lib/sorcery/test_helpers/internal/rails.rb b/lib/sorcery/test_helpers/internal/rails.rb index 6dfa4588..28e4a45d 100644 --- a/lib/sorcery/test_helpers/internal/rails.rb +++ b/lib/sorcery/test_helpers/internal/rails.rb @@ -20,22 +20,22 @@ def sorcery_reload!(submodules = [], options = {}) # remove all plugin before_actions so they won't fail other tests. # I don't like this way, but I didn't find another. # hopefully it won't break until Rails 4. - chain = if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new("4.1.0") + chain = if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new('4.1.0') SorceryController._process_action_callbacks.send :chain else SorceryController._process_action_callbacks end - chain.delete_if {|c| SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) } + chain.delete_if { |c| SUBMODULES_AUTO_ADDED_CONTROLLER_FILTERS.include?(c.filter) } # configure ::Sorcery::Controller::Config.submodules = submodules ::Sorcery::Controller::Config.user_class = nil - ActionController::Base.send(:include,::Sorcery::Controller) - ::Sorcery::Controller::Config.user_class = "User" + ActionController::Base.send(:include, ::Sorcery::Controller) + ::Sorcery::Controller::Config.user_class = 'User' ::Sorcery::Controller::Config.user_config do |user| - options.each do |property,value| + options.each do |property, value| user.send(:"#{property}=", value) end end @@ -60,12 +60,12 @@ def sorcery_controller_external_property_set(provider, property, value) # all this without calling the :logout action explicitly. # A dirty dirty hack. def clear_user_without_logout - subject.instance_variable_set(:@current_user,nil) + subject.instance_variable_set(:@current_user, nil) end if ::Rails.version < '5.0.0' - %w( get post put ).each do |method| - define_method(method) do |action, options={}| + %w(get post put).each do |method| + define_method(method) do |action, options = {}| super action, options[:params] || {}, options[:session] end end diff --git a/lib/sorcery/test_helpers/rails/controller.rb b/lib/sorcery/test_helpers/rails/controller.rb index b13345d8..48ffab41 100644 --- a/lib/sorcery/test_helpers/rails/controller.rb +++ b/lib/sorcery/test_helpers/rails/controller.rb @@ -2,7 +2,7 @@ module Sorcery module TestHelpers module Rails module Controller - def login_user(user = nil, test_context = {}) + def login_user(user = nil, _test_context = {}) user ||= @user @controller.send(:auto_login, user) @controller.send(:after_login!, user, [user.send(user.sorcery_config.username_attribute_names.first), 'secret']) diff --git a/lib/sorcery/test_helpers/rails/integration.rb b/lib/sorcery/test_helpers/rails/integration.rb index eb64dfad..1ee3566a 100644 --- a/lib/sorcery/test_helpers/rails/integration.rb +++ b/lib/sorcery/test_helpers/rails/integration.rb @@ -2,20 +2,19 @@ module Sorcery module TestHelpers module Rails module Integration - - #Accepts arguments for user to login, route to use and HTTP method - #Defaults - @user, 'sessions_url' and POST + # Accepts arguments for user to login, route to use and HTTP method + # Defaults - @user, 'sessions_url' and POST def login_user(user = nil, route = nil, http_method = :post) user ||= @user route ||= sessions_url username_attr = user.sorcery_config.username_attribute_names.first username = user.send(username_attr) - page.driver.send(http_method, route, { :"#{username_attr}" => username, :password => 'secret' }) + page.driver.send(http_method, route, :"#{username_attr}" => username, :password => 'secret') end - #Accepts route and HTTP method arguments - #Default - 'logout_url' and GET + # Accepts route and HTTP method arguments + # Default - 'logout_url' and GET def logout_user(route = nil, http_method = :get) route ||= logout_url page.driver.send(http_method, route) diff --git a/spec/active_record/user_activation_spec.rb b/spec/active_record/user_activation_spec.rb index ae67d542..82a7020d 100644 --- a/spec/active_record/user_activation_spec.rb +++ b/spec/active_record/user_activation_spec.rb @@ -3,7 +3,7 @@ require 'rails_app/app/mailers/sorcery_mailer' require 'shared_examples/user_activation_shared_examples' -describe User, "with activation submodule", :active_record => true do +describe User, 'with activation submodule', active_record: true do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation") User.reset_column_information @@ -13,6 +13,5 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activation") end - it_behaves_like "rails_3_activation_model" - + it_behaves_like 'rails_3_activation_model' end diff --git a/spec/active_record/user_activity_logging_spec.rb b/spec/active_record/user_activity_logging_spec.rb index e838bef2..b185b45b 100644 --- a/spec/active_record/user_activity_logging_spec.rb +++ b/spec/active_record/user_activity_logging_spec.rb @@ -1,8 +1,7 @@ require 'spec_helper' require 'shared_examples/user_activity_logging_shared_examples' -describe User, "with activity logging submodule", :active_record => true do - +describe User, 'with activity logging submodule', active_record: true do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activity_logging") User.reset_column_information @@ -12,6 +11,5 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/activity_logging") end - it_behaves_like "rails_3_activity_logging_model" - + it_behaves_like 'rails_3_activity_logging_model' end diff --git a/spec/active_record/user_brute_force_protection_spec.rb b/spec/active_record/user_brute_force_protection_spec.rb index 29ee7deb..544b8ff6 100644 --- a/spec/active_record/user_brute_force_protection_spec.rb +++ b/spec/active_record/user_brute_force_protection_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require 'shared_examples/user_brute_force_protection_shared_examples' -describe User, "with brute_force_protection submodule", :active_record => true do +describe User, 'with brute_force_protection submodule', active_record: true do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/brute_force_protection") User.reset_column_information @@ -11,6 +11,5 @@ ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/brute_force_protection") end - it_behaves_like "rails_3_brute_force_protection_model" - -end \ No newline at end of file + it_behaves_like 'rails_3_brute_force_protection_model' +end diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index 1a9fa3d4..513aaace 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -2,7 +2,7 @@ # require 'shared_examples/controller_oauth2_shared_examples' -describe SorceryController, :active_record => true, :type => :controller do +describe SorceryController, active_record: true, type: :controller do before(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external") @@ -26,45 +26,44 @@ it 'creates a new user' do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name' }) + sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'name') - expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}) - get :test_create_from_provider, :params => { provider: 'facebook' } + expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Noam Ben Ari') + get :test_create_from_provider, params: { provider: 'facebook' } end it 'supports nested attributes' do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'hometown/name' }) - expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Haifa, Israel'}) + sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'hometown/name') + expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Haifa, Israel') - get :test_create_from_provider, :params => { provider: 'facebook' } + get :test_create_from_provider, params: { provider: 'facebook' } end it 'does not crash on missing nested attributes' do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name', created_at: 'does/not/exist' }) + sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'name', created_at: 'does/not/exist') - expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}) + expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Noam Ben Ari') - get :test_create_from_provider, :params => { provider: 'facebook' } + get :test_create_from_provider, params: { provider: 'facebook' } end describe 'with a block' do it 'does not create user' do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name' }) + sorcery_controller_external_property_set(:facebook, :user_info_mapping, username: 'name') u = double('user') - expect(User).to receive(:create_from_provider).with('facebook', '123', {username: 'Noam Ben Ari'}).and_return(u).and_yield(u) + expect(User).to receive(:create_from_provider).with('facebook', '123', username: 'Noam Ben Ari').and_return(u).and_yield(u) # test_create_from_provider_with_block in controller will check for uniqueness of username - get :test_create_from_provider_with_block, :params => { provider: 'facebook' } + get :test_create_from_provider_with_block, params: { provider: 'facebook' } end end end # ----------------- OAuth ----------------------- - context "with OAuth features" do - + context 'with OAuth features' do let(:user) { double('user', id: 42) } before(:each) do @@ -76,30 +75,30 @@ Authentication.sorcery_adapter.delete_all end - context "when callback_url begin with /" do + context 'when callback_url begin with /' do before do - sorcery_controller_external_property_set(:facebook, :callback_url, "/oauth/twitter/callback") + sorcery_controller_external_property_set(:facebook, :callback_url, '/oauth/twitter/callback') end - it "login_at redirects correctly" do + it 'login_at redirects correctly' do get :login_at_test_facebook expect(response).to be_a_redirect expect(response).to redirect_to("https://www.facebook.com/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state") end - it "logins with state" do + it 'logins with state' do get :login_at_test_with_state expect(response).to be_a_redirect expect(response).to redirect_to("https://www.facebook.com/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state=bla") end - it "logins with Graph API version" do - sorcery_controller_external_property_set(:facebook, :api_version, "v2.2") + it 'logins with Graph API version' do + sorcery_controller_external_property_set(:facebook, :api_version, 'v2.2') get :login_at_test_with_state expect(response).to be_a_redirect expect(response).to redirect_to("https://www.facebook.com/v2.2/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state=bla") end - it "logins without state after login with state" do + it 'logins without state after login with state' do get :login_at_test_with_state expect(response).to redirect_to("https://www.facebook.com/v2.2/dialog/oauth?client_id=#{::Sorcery::Controller::Config.facebook.key}&display=page&redirect_uri=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&response_type=code&scope=email&state=bla") @@ -108,12 +107,12 @@ end after do - sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com') end end - context "when callback_url begin with http://" do - it "login_at redirects correctly" do + context 'when callback_url begin with http://' do + it 'login_at redirects correctly' do create_new_user get :login_at_test_facebook expect(response).to be_a_redirect @@ -129,7 +128,7 @@ expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user) get :test_login_from_facebook - expect(flash[:notice]).to eq "Success!" + expect(flash[:notice]).to eq 'Success!' end it "'login_from' fails if user doesn't exist" do @@ -137,30 +136,28 @@ expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(nil) get :test_login_from_facebook - expect(flash[:alert]).to eq "Failed!" + expect(flash[:alert]).to eq 'Failed!' end - it "on successful login_from the user is redirected to the url he originally wanted" do + it 'on successful login_from the user is redirected to the url he originally wanted' do # dirty hack for rails 4 allow(subject).to receive(:register_last_activity_time_to_db) sorcery_model_property_set(:authentications_class, Authentication) expect(User).to receive(:load_from_provider).with(:facebook, '123').and_return(user) - get :test_return_to_with_external_facebook, :params => {}, session: { :return_to_url => "fuu" } + get :test_return_to_with_external_facebook, params: {}, session: { return_to_url: 'fuu' } - expect(response).to redirect_to("fuu") - expect(flash[:notice]).to eq "Success!" + expect(response).to redirect_to('fuu') + expect(flash[:notice]).to eq 'Success!' end [:github, :google, :liveid, :vk, :salesforce, :paypal, :slack].each do |provider| - describe "with #{provider}" do - - it "login_at redirects correctly" do + it 'login_at redirects correctly' do get :"login_at_test_#{provider}" expect(response).to be_a_redirect - expect(response).to redirect_to(provider_url provider) + expect(response).to redirect_to(provider_url(provider)) end it "'login_from' logins if user exists" do @@ -171,7 +168,7 @@ expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user) get :"test_login_from_#{provider}" - expect(flash[:notice]).to eq "Success!" + expect(flash[:notice]).to eq 'Success!' end it "'login_from' fails if user doesn't exist" do @@ -179,7 +176,7 @@ expect(User).to receive(:load_from_provider).with(provider, '123').and_return(nil) get :"test_login_from_#{provider}" - expect(flash[:alert]).to eq "Failed!" + expect(flash[:alert]).to eq 'Failed!' end it "on successful login_from the user is redirected to the url he originally wanted (#{provider})" do @@ -188,53 +185,51 @@ sorcery_model_property_set(:authentications_class, Authentication) expect(User).to receive(:load_from_provider).with(provider, '123').and_return(user) - get :"test_return_to_with_external_#{provider}", :params => {}, session: { :return_to_url => "fuu" } + get :"test_return_to_with_external_#{provider}", params: {}, session: { return_to_url: 'fuu' } - expect(response).to redirect_to "fuu" - expect(flash[:notice]).to eq "Success!" + expect(response).to redirect_to 'fuu' + expect(flash[:notice]).to eq 'Success!' end end end - end - describe "OAuth with User Activation features" do + describe 'OAuth with User Activation features' do before(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation") end - sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation, :external], user_activation_mailer: ::SorceryMailer) sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack]) - sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:github, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:github, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:github, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:google, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:google, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:google, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:liveid, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:liveid, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:liveid, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:vk, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:vk, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:vk, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:salesforce, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com") + # TODO: refactor + sorcery_controller_external_property_set(:facebook, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:facebook, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:github, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:github, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:github, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:google, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:google, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:google, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:liveid, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:liveid, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:liveid, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:vk, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:vk, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:vk, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:salesforce, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:salesforce, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:salesforce, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:paypal, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:paypal, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:paypal, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:slack, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:slack, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:slack, :callback_url, 'http://blabla.com') end - - after(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.rollback("#{Rails.root}/db/migrate/external") @@ -246,14 +241,14 @@ User.sorcery_adapter.delete_all end - it "does not send activation email to external users" do + it 'does not send activation email to external users' do old_size = ActionMailer::Base.deliveries.size create_new_external_user(:facebook) expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "does not send external users an activation success email" do + it 'does not send external users an activation success email' do sorcery_model_property_set(:activation_success_email_method_name, nil) create_new_external_user(:facebook) old_size = ActionMailer::Base.deliveries.size @@ -278,8 +273,7 @@ end end - describe "OAuth with user activation features" do - + describe 'OAuth with user activation features' do let(:user) { double('user', id: 42) } before(:all) do @@ -304,7 +298,7 @@ sorcery_model_property_set(:authentications_class, Authentication) end - it "registers login time" do + it 'registers login time' do now = Time.now.in_time_zone Timecop.freeze(now) expect(User).to receive(:load_from_provider).and_return(user) @@ -313,20 +307,19 @@ Timecop.return end - it "does not register login time if configured so" do + it 'does not register login time if configured so' do sorcery_controller_property_set(:register_login_time, false) now = Time.now.in_time_zone Timecop.freeze(now) expect(User).to receive(:load_from_provider).and_return(user) expect(user).to receive(:set_last_login_at).never get "test_login_from_#{provider}".to_sym - end end end end - describe "OAuth with session timeout features" do + describe 'OAuth with session timeout features' do before(:all) do sorcery_reload!([:session_timeout, :external]) end @@ -337,7 +330,7 @@ context "when #{provider}" do before(:each) do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_property_set(:session_timeout,0.5) + sorcery_controller_property_set(:session_timeout, 0.5) stub_all_oauth2_requests! end @@ -345,19 +338,19 @@ Timecop.return end - it "does not reset session before session timeout" do + it 'does not reset session before session timeout' do expect(User).to receive(:load_from_provider).with(provider.to_sym, '123').and_return(user) get "test_login_from_#{provider}".to_sym expect(session[:user_id]).not_to be_nil - expect(flash[:notice]).to eq "Success!" + expect(flash[:notice]).to eq 'Success!' end - it "resets session after session timeout" do + it 'resets session after session timeout' do expect(User).to receive(:load_from_provider).with(provider.to_sym, '123').and_return(user) get "test_login_from_#{provider}".to_sym - expect(session[:user_id]).to eq "42" - Timecop.travel(Time.now.in_time_zone+0.6) + expect(session[:user_id]).to eq '42' + Timecop.travel(Time.now.in_time_zone + 0.6) get :test_should_be_logged_in expect(session[:user_id]).to be_nil @@ -368,73 +361,74 @@ end def stub_all_oauth2_requests! - access_token = double(OAuth2::AccessToken) + access_token = double(OAuth2::AccessToken) allow(access_token).to receive(:token_param=) - response = double(OAuth2::Response) - allow(response).to receive(:body) { { - "id"=>"123", - "user_id"=>"123", # Needed for Salesforce - "name"=>"Noam Ben Ari", - "first_name"=>"Noam", - "last_name"=>"Ben Ari", - "link"=>"http://www.facebook.com/nbenari1", - "hometown"=>{"id"=>"110619208966868", "name"=>"Haifa, Israel"}, - "location"=>{"id"=>"106906559341067", "name"=>"Pardes Hanah, Hefa, Israel"}, - "bio"=>"I'm a new daddy, and enjoying it!", - "gender"=>"male", - "email"=>"nbenari@gmail.com", - "timezone"=>2, - "locale"=>"en_US", - "languages"=>[{"id"=>"108405449189952", "name"=>"Hebrew"}, {"id"=>"106059522759137", "name"=>"English"}, {"id"=>"112624162082677", "name"=>"Russian"}], - "verified"=>true, - "updated_time"=>"2011-02-16T20:59:38+0000", - # response for VK auth - "response"=>[ - { - "uid"=>"123", - "first_name"=>"Noam", - "last_name"=>"Ben Ari" - } - ], - "user"=> { - "name"=>"Sonny Whether", - "id"=>"123", - "email"=>"bobby@example.com" - } - }.to_json } + response = double(OAuth2::Response) + allow(response).to receive(:body) { + { + 'id' => '123', + 'user_id' => '123', # Needed for Salesforce + 'name' => 'Noam Ben Ari', + 'first_name' => 'Noam', + 'last_name' => 'Ben Ari', + 'link' => 'http://www.facebook.com/nbenari1', + 'hometown' => { 'id' => '110619208966868', 'name' => 'Haifa, Israel' }, + 'location' => { 'id' => '106906559341067', 'name' => 'Pardes Hanah, Hefa, Israel' }, + 'bio' => "I'm a new daddy, and enjoying it!", + 'gender' => 'male', + 'email' => 'nbenari@gmail.com', + 'timezone' => 2, + 'locale' => 'en_US', + 'languages' => [{ 'id' => '108405449189952', 'name' => 'Hebrew' }, { 'id' => '106059522759137', 'name' => 'English' }, { 'id' => '112624162082677', 'name' => 'Russian' }], + 'verified' => true, + 'updated_time' => '2011-02-16T20:59:38+0000', + # response for VK auth + 'response' => [ + { + 'uid' => '123', + 'first_name' => 'Noam', + 'last_name' => 'Ben Ari' + } + ], + 'user' => { + 'name' => 'Sonny Whether', + 'id' => '123', + 'email' => 'bobby@example.com' + } + }.to_json } allow(access_token).to receive(:get) { response } - allow(access_token).to receive(:token) { "187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3" } + allow(access_token).to receive(:token) { '187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3' } # access_token params for VK auth - allow(access_token).to receive(:params) { { "user_id"=>"100500", "email"=>"nbenari@gmail.com" } } + allow(access_token).to receive(:params) { { 'user_id' => '100500', 'email' => 'nbenari@gmail.com' } } allow_any_instance_of(OAuth2::Strategy::AuthCode).to receive(:get_token) { access_token } end def set_external_property sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack]) - sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:github, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:github, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:github, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:google, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:google, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:google, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:liveid, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:liveid, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:liveid, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:vk, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:vk, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:vk, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:salesforce, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com") - sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:facebook, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:facebook, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:github, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:github, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:github, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:google, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:google, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:google, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:liveid, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:liveid, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:liveid, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:vk, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:vk, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:vk, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:salesforce, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:salesforce, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:salesforce, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:paypal, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:paypal, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:paypal, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:slack, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:slack, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:slack, :callback_url, 'http://blabla.com') end def provider_url(provider) diff --git a/spec/controllers/controller_oauth_spec.rb b/spec/controllers/controller_oauth_spec.rb index 8305d98c..c796f084 100644 --- a/spec/controllers/controller_oauth_spec.rb +++ b/spec/controllers/controller_oauth_spec.rb @@ -4,12 +4,36 @@ require 'ostruct' def stub_all_oauth_requests! - consumer = OAuth::Consumer.new("key","secret", :site => "http://myapi.com") + consumer = OAuth::Consumer.new('key', 'secret', site: 'http://myapi.com') req_token = OAuth::RequestToken.new(consumer) acc_token = OAuth::AccessToken.new(consumer) - response = OpenStruct.new() - response.body = {"following"=>false, "listed_count"=>0, "profile_link_color"=>"0084B4", "profile_image_url"=>"http://a1.twimg.com/profile_images/536178575/noamb_normal.jpg", "description"=>"Programmer/Heavy Metal Fan/New Father", "status"=>{"text"=>"coming soon to sorcery gem: twitter and facebook authentication support.", "truncated"=>false, "favorited"=>false, "source"=>"web", "geo"=>nil, "in_reply_to_screen_name"=>nil, "in_reply_to_user_id"=>nil, "in_reply_to_status_id_str"=>nil, "created_at"=>"Sun Mar 06 23:01:12 +0000 2011", "contributors"=>nil, "place"=>nil, "retweeted"=>false, "in_reply_to_status_id"=>nil, "in_reply_to_user_id_str"=>nil, "coordinates"=>nil, "retweet_count"=>0, "id"=>44533012284706816, "id_str"=>"44533012284706816"}, "show_all_inline_media"=>false, "geo_enabled"=>true, "profile_sidebar_border_color"=>"a8c7f7", "url"=>nil, "followers_count"=>10, "screen_name"=>"nbenari", "profile_use_background_image"=>true, "location"=>"Israel", "statuses_count"=>25, "profile_background_color"=>"022330", "lang"=>"en", "verified"=>false, "notifications"=>false, "profile_background_image_url"=>"http://a3.twimg.com/profile_background_images/104087198/04042010339.jpg", "favourites_count"=>5, "created_at"=>"Fri Nov 20 21:58:19 +0000 2009", "is_translator"=>false, "contributors_enabled"=>false, "protected"=>false, "follow_request_sent"=>false, "time_zone"=>"Greenland", "profile_text_color"=>"333333", "name"=>"Noam Ben Ari", "friends_count"=>10, "profile_sidebar_fill_color"=>"C0DFEC", "id"=>123, "id_str"=>"91434812", "profile_background_tile"=>false, "utc_offset"=>-10800}.to_json + response = OpenStruct.new + response.body = { + 'following' => false, 'listed_count' => 0, 'profile_link_color' => '0084B4', + 'profile_image_url' => 'http://a1.twimg.com/profile_images/536178575/noamb_normal.jpg', + 'description' => 'Programmer/Heavy Metal Fan/New Father', + 'status' => { + 'text' => 'coming soon to sorcery gem: twitter and facebook authentication support.', + 'truncated' => false, 'favorited' => false, 'source' => 'web', 'geo' => nil, + 'in_reply_to_screen_name' => nil, 'in_reply_to_user_id' => nil, + 'in_reply_to_status_id_str' => nil, 'created_at' => 'Sun Mar 06 23:01:12 +0000 2011', + 'contributors' => nil, 'place' => nil, 'retweeted' => false, 'in_reply_to_status_id' => nil, + 'in_reply_to_user_id_str' => nil, 'coordinates' => nil, 'retweet_count' => 0, + 'id' => 44533012284706816, 'id_str' => '44533012284706816' + }, + 'show_all_inline_media' => false, 'geo_enabled' => true, + 'profile_sidebar_border_color' => 'a8c7f7', 'url' => nil, 'followers_count' => 10, + 'screen_name' => 'nbenari', 'profile_use_background_image' => true, 'location' => 'Israel', + 'statuses_count' => 25, 'profile_background_color' => '022330', 'lang' => 'en', + 'verified' => false, 'notifications' => false, + 'profile_background_image_url' => 'http://a3.twimg.com/profile_background_images/104087198/04042010339.jpg', + 'favourites_count' => 5, 'created_at' => 'Fri Nov 20 21:58:19 +0000 2009', + 'is_translator' => false, 'contributors_enabled' => false, 'protected' => false, + 'follow_request_sent' => false, 'time_zone' => 'Greenland', 'profile_text_color' => '333333', + 'name' => 'Noam Ben Ari', 'friends_count' => 10, 'profile_sidebar_fill_color' => 'C0DFEC', + 'id' => 123, 'id_str' => '91434812', 'profile_background_tile' => false, 'utc_offset' => -10800 + }.to_json session[:request_token] = req_token.token session[:request_token_secret] = req_token.secret @@ -21,83 +45,80 @@ def stub_all_oauth_requests! allow(acc_token).to receive(:get) { response } end -describe SorceryController, :type => :controller do - +describe SorceryController, type: :controller do let(:user) { double('user', id: 42) } before(:all) do sorcery_reload!([:external]) sorcery_controller_property_set(:external_providers, [:twitter, :jira]) - sorcery_controller_external_property_set(:twitter, :key, "eYVNBjBDi33aa9GkA3w") - sorcery_controller_external_property_set(:twitter, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") - sorcery_controller_external_property_set(:twitter, :callback_url, "http://blabla.com") - - sorcery_controller_external_property_set(:jira, :key, "7810b8e317ebdc81601c72f8daecc0f1") - sorcery_controller_external_property_set(:jira, :secret, "MyAppUsingJira") - sorcery_controller_external_property_set(:jira, :site, "http://jira.mycompany.com/plugins/servlet/oauth") - sorcery_controller_external_property_set(:jira, :signature_method, "RSA-SHA1") - sorcery_controller_external_property_set(:jira, :private_key_file, "myrsakey.pem") - sorcery_controller_external_property_set(:jira, :callback_url, "http://myappusingjira.com/home") + sorcery_controller_external_property_set(:twitter, :key, 'eYVNBjBDi33aa9GkA3w') + sorcery_controller_external_property_set(:twitter, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') + sorcery_controller_external_property_set(:twitter, :callback_url, 'http://blabla.com') + + sorcery_controller_external_property_set(:jira, :key, '7810b8e317ebdc81601c72f8daecc0f1') + sorcery_controller_external_property_set(:jira, :secret, 'MyAppUsingJira') + sorcery_controller_external_property_set(:jira, :site, 'http://jira.mycompany.com/plugins/servlet/oauth') + sorcery_controller_external_property_set(:jira, :signature_method, 'RSA-SHA1') + sorcery_controller_external_property_set(:jira, :private_key_file, 'myrsakey.pem') + sorcery_controller_external_property_set(:jira, :callback_url, 'http://myappusingjira.com/home') end # ----------------- OAuth ----------------------- describe SorceryController, "'using external API to login'" do - before(:each) do stub_all_oauth_requests! end - context "when callback_url begin with /" do + context 'when callback_url begin with /' do before do - sorcery_controller_external_property_set(:twitter, :callback_url, "/oauth/twitter/callback") + sorcery_controller_external_property_set(:twitter, :callback_url, '/oauth/twitter/callback') end - it "login_at redirects correctly" do + it 'login_at redirects correctly' do get :login_at_test expect(response).to be_a_redirect - expect(response).to redirect_to("http://myapi.com/oauth/authorize?oauth_callback=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&oauth_token=") + expect(response).to redirect_to('http://myapi.com/oauth/authorize?oauth_callback=http%3A%2F%2Ftest.host%2Foauth%2Ftwitter%2Fcallback&oauth_token=') end after do - sorcery_controller_external_property_set(:twitter, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:twitter, :callback_url, 'http://blabla.com') end end - context "when callback_url begin with http://" do - it "login_at redirects correctly", pending: true do + context 'when callback_url begin with http://' do + it 'login_at redirects correctly', pending: true do get :login_at_test expect(response).to be_a_redirect - expect(response).to redirect_to("http://myapi.com/oauth/authorize?oauth_callback=http%3A%2F%2Fblabla.com&oauth_token=") + expect(response).to redirect_to('http://myapi.com/oauth/authorize?oauth_callback=http%3A%2F%2Fblabla.com&oauth_token=') end end - it "logins if user exists" do + it 'logins if user exists' do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(user) - get :test_login_from, :params => { :oauth_verifier => "blablaRERASDFcxvSDFA" } - expect(flash[:notice]).to eq "Success!" + get :test_login_from, params: { oauth_verifier: 'blablaRERASDFcxvSDFA' } + expect(flash[:notice]).to eq 'Success!' end it "'login_from' fails if user doesn't exist" do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(nil) - get :test_login_from, :params => { :oauth_verifier => "blablaRERASDFcxvSDFA" } - expect(flash[:alert]).to eq "Failed!" + get :test_login_from, params: { oauth_verifier: 'blablaRERASDFcxvSDFA' } + expect(flash[:alert]).to eq 'Failed!' end it "on successful 'login_from' the user is redirected to the url he originally wanted" do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(user) - get :test_return_to_with_external, params: {}, :session => { :return_to_url => "fuu" } - expect(response).to redirect_to("fuu") - expect(flash[:notice]).to eq "Success!" + get :test_return_to_with_external, params: {}, session: { return_to_url: 'fuu' } + expect(response).to redirect_to('fuu') + expect(flash[:notice]).to eq 'Success!' end - context "when jira" do - it "user logins successfully" do + context 'when jira' do + it 'user logins successfully' do get :login_at_test_jira expect(session[:request_token]).not_to be_nil expect(response).to be_a_redirect end end - end describe SorceryController do @@ -106,31 +127,31 @@ def stub_all_oauth_requests! stub_all_oauth_requests! end - it "creates a new user" do - sorcery_controller_external_property_set(:twitter, :user_info_mapping, {:username => "screen_name"}) + it 'creates a new user' do + sorcery_controller_external_property_set(:twitter, :user_info_mapping, username: 'screen_name') expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) - expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'nbenari'}).and_return(user) + expect(User).to receive(:create_from_provider).with('twitter', '123', username: 'nbenari').and_return(user) - get :test_create_from_provider, :params => { :provider => "twitter" } + get :test_create_from_provider, params: { provider: 'twitter' } end - it "supports nested attributes" do - sorcery_controller_external_property_set(:twitter, :user_info_mapping, {:username => "status/text"}) + it 'supports nested attributes' do + sorcery_controller_external_property_set(:twitter, :user_info_mapping, username: 'status/text') expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) - expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'coming soon to sorcery gem: twitter and facebook authentication support.'}).and_return(user) + expect(User).to receive(:create_from_provider).with('twitter', '123', username: 'coming soon to sorcery gem: twitter and facebook authentication support.').and_return(user) - get :test_create_from_provider, :params => { :provider => "twitter" } + get :test_create_from_provider, params: { provider: 'twitter' } end - it "does not crash on missing nested attributes" do - sorcery_controller_external_property_set(:twitter, :user_info_mapping, {:username => "status/text", :created_at => "does/not/exist"}) + it 'does not crash on missing nested attributes' do + sorcery_controller_external_property_set(:twitter, :user_info_mapping, username: 'status/text', created_at: 'does/not/exist') expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) - expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'coming soon to sorcery gem: twitter and facebook authentication support.'}).and_return(user) + expect(User).to receive(:create_from_provider).with('twitter', '123', username: 'coming soon to sorcery gem: twitter and facebook authentication support.').and_return(user) - get :test_create_from_provider, :params => { :provider => "twitter" } + get :test_create_from_provider, params: { provider: 'twitter' } end - it "binds new provider" do + it 'binds new provider' do sorcery_model_property_set(:authentications_class, UserProvider) allow(user).to receive_message_chain(:sorcery_config, :username_attribute_names, :first) { :username } @@ -138,31 +159,30 @@ def stub_all_oauth_requests! login_user(user) expect(user).to receive(:add_provider_to_user).with('twitter', '123') - get :test_add_second_provider, :params => { :provider => "twitter" } + get :test_add_second_provider, params: { provider: 'twitter' } end - describe "with a block" do - it "does not create user" do + describe 'with a block' do + it 'does not create user' do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_external_property_set(:twitter, :user_info_mapping, {:username => "screen_name"}) + sorcery_controller_external_property_set(:twitter, :user_info_mapping, username: 'screen_name') u = double('user') expect(User).to receive(:load_from_provider).with('twitter', '123').and_return(nil) - expect(User).to receive(:create_from_provider).with('twitter', '123', {username: 'nbenari'}).and_return(u).and_yield(u) + expect(User).to receive(:create_from_provider).with('twitter', '123', username: 'nbenari').and_return(u).and_yield(u) - get :test_create_from_provider_with_block, :params => { :provider => "twitter" } + get :test_create_from_provider_with_block, params: { provider: 'twitter' } end - end end end - describe SorceryController, "OAuth with user activation features" do + describe SorceryController, 'OAuth with user activation features' do before(:all) do sorcery_reload!([:activity_logging, :external]) end - context "when twitter" do + context 'when twitter' do before(:each) do sorcery_controller_property_set(:register_login_time, true) sorcery_controller_property_set(:register_logout_time, false) @@ -171,7 +191,7 @@ def stub_all_oauth_requests! stub_all_oauth_requests! end - it "registers login time" do + it 'registers login time' do now = Time.now.in_time_zone Timecop.freeze(now) expect(User).to receive(:load_from_provider).and_return(user) @@ -180,7 +200,7 @@ def stub_all_oauth_requests! Timecop.return end - it "does not register login time if configured so" do + it 'does not register login time if configured so' do sorcery_controller_property_set(:register_login_time, false) now = Time.now.in_time_zone Timecop.freeze(now) @@ -192,7 +212,7 @@ def stub_all_oauth_requests! end end - describe SorceryController, "OAuth with session timeout features" do + describe SorceryController, 'OAuth with session timeout features' do before(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external") @@ -208,10 +228,10 @@ def stub_all_oauth_requests! end end - context "when twitter" do + context 'when twitter' do before(:each) do sorcery_model_property_set(:authentications_class, Authentication) - sorcery_controller_property_set(:session_timeout,0.5) + sorcery_controller_property_set(:session_timeout, 0.5) stub_all_oauth_requests! end @@ -219,17 +239,17 @@ def stub_all_oauth_requests! Timecop.return end - it "does not reset session before session timeout" do + it 'does not reset session before session timeout' do expect(User).to receive(:load_from_provider).with(:twitter, '123').and_return(user) get :test_login_from expect(session[:user_id]).not_to be_nil - expect(flash[:notice]).to eq "Success!" + expect(flash[:notice]).to eq 'Success!' end - it "resets session after session timeout" do + it 'resets session after session timeout' do get :test_login_from - Timecop.travel(Time.now.in_time_zone+0.6) + Timecop.travel(Time.now.in_time_zone + 0.6) get :test_should_be_logged_in expect(session[:user_id]).to be_nil diff --git a/spec/controllers/controller_remember_me_spec.rb b/spec/controllers/controller_remember_me_spec.rb index 447da320..1a477244 100644 --- a/spec/controllers/controller_remember_me_spec.rb +++ b/spec/controllers/controller_remember_me_spec.rb @@ -1,12 +1,10 @@ require 'spec_helper' -describe SorceryController, :type => :controller do - +describe SorceryController, type: :controller do let!(:user) { double('user', id: 42) } # ----------------- REMEMBER ME ----------------------- - context "with remember me features" do - + context 'with remember me features' do before(:all) do sorcery_reload!([:remember_me]) end @@ -23,53 +21,53 @@ allow(user).to receive_message_chain(:sorcery_config, :remember_me_token_expires_at_attribute_name).and_return(:remember_me_token_expires_at) end - it "sets cookie on remember_me!" do + it 'sets cookie on remember_me!' do expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) expect(user).to receive(:remember_me!) - post :test_login_with_remember, :params => { :email => 'bla@bla.com', :password => 'secret' } + post :test_login_with_remember, params: { email: 'bla@bla.com', password: 'secret' } - expect(cookies.signed["remember_me_token"]).to eq assigns[:current_user].remember_me_token + expect(cookies.signed['remember_me_token']).to eq assigns[:current_user].remember_me_token end - it "clears cookie on forget_me!" do - cookies["remember_me_token"] == {:value => 'asd54234dsfsd43534', :expires => 3600} + it 'clears cookie on forget_me!' do + cookies['remember_me_token'] == { value: 'asd54234dsfsd43534', expires: 3600 } get :test_logout - expect(cookies["remember_me_token"]).to be_nil + expect(cookies['remember_me_token']).to be_nil end - it "clears cookie on force_forget_me!" do - cookies["remember_me_token"] == {:value => 'asd54234dsfsd43534', :expires => 3600} + it 'clears cookie on force_forget_me!' do + cookies['remember_me_token'] == { value: 'asd54234dsfsd43534', expires: 3600 } get :test_logout_with_force_forget_me - expect(cookies["remember_me_token"]).to be_nil + expect(cookies['remember_me_token']).to be_nil end - it "login(email,password,remember_me) logs user in and remembers" do + it 'login(email,password,remember_me) logs user in and remembers' do expect(User).to receive(:authenticate).with('bla@bla.com', 'secret', '1').and_return(user) expect(user).to receive(:remember_me!) expect(user).to receive(:remember_me_token).and_return('abracadabra').twice - post :test_login_with_remember_in_login, :params => { :email => 'bla@bla.com', :password => 'secret', :remember => "1" } + post :test_login_with_remember_in_login, params: { email: 'bla@bla.com', password: 'secret', remember: '1' } - expect(cookies.signed["remember_me_token"]).not_to be_nil - expect(cookies.signed["remember_me_token"]).to eq assigns[:user].remember_me_token + expect(cookies.signed['remember_me_token']).not_to be_nil + expect(cookies.signed['remember_me_token']).to eq assigns[:user].remember_me_token end - it "logout also calls forget_me!" do + it 'logout also calls forget_me!' do session[:user_id] = user.id.to_s - expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user) + expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user) expect(user).to receive(:remember_me!) expect(user).to receive(:forget_me!) get :test_logout_with_remember - expect(cookies["remember_me_token"]).to be_nil + expect(cookies['remember_me_token']).to be_nil end - it "logs user in from cookie" do - session[:user_id] = user.id.to_s - expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user) + it 'logs user in from cookie' do + session[:user_id] = user.id.to_s + expect(User.sorcery_adapter).to receive(:find_by_id).with(user.id.to_s).and_return(user) expect(user).to receive(:remember_me!) expect(user).to receive(:remember_me_token).and_return('token').twice expect(user).to receive(:has_remember_me_token?) { true } @@ -87,30 +85,30 @@ expect(assigns[:current_user]).to eq user end - it "doest not remember_me! when not asked to, even if third parameter is used" do - post :test_login_with_remember_in_login, :params => { :email => 'bla@bla.com', :password => 'secret', :remember => "0" } + it 'doest not remember_me! when not asked to, even if third parameter is used' do + post :test_login_with_remember_in_login, params: { email: 'bla@bla.com', password: 'secret', remember: '0' } - expect(cookies["remember_me_token"]).to be_nil + expect(cookies['remember_me_token']).to be_nil end - it "doest not remember_me! when not asked to" do - post :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } - expect(cookies["remember_me_token"]).to be_nil + it 'doest not remember_me! when not asked to' do + post :test_login, params: { email: 'bla@bla.com', password: 'secret' } + expect(cookies['remember_me_token']).to be_nil end # --- login_user(user) --- specify { expect(@controller).to respond_to :auto_login } - it "auto_login(user) logs in an user instance without remembering" do + it 'auto_login(user) logs in an user instance without remembering' do session[:user_id] = nil subject.auto_login(user) get :test_login_from_cookie expect(assigns[:current_user]).to eq user - expect(cookies["remember_me_token"]).to be_nil + expect(cookies['remember_me_token']).to be_nil end - it "auto_login(user, true) logs in an user instance with remembering" do + it 'auto_login(user, true) logs in an user instance with remembering' do session[:user_id] = nil expect(user).to receive(:remember_me!) subject.auto_login(user, true) @@ -118,7 +116,7 @@ get :test_login_from_cookie expect(assigns[:current_user]).to eq user - expect(cookies["remember_me_token"]).not_to be_nil + expect(cookies['remember_me_token']).not_to be_nil end end end diff --git a/spec/controllers/controller_session_timeout_spec.rb b/spec/controllers/controller_session_timeout_spec.rb index b5a6f374..47a8c6ef 100644 --- a/spec/controllers/controller_session_timeout_spec.rb +++ b/spec/controllers/controller_session_timeout_spec.rb @@ -1,14 +1,13 @@ require 'spec_helper' -describe SorceryController, :type => :controller do - +describe SorceryController, type: :controller do let!(:user) { double('user', id: 42) } # ----------------- SESSION TIMEOUT ----------------------- - context "with session timeout features" do + context 'with session timeout features' do before(:all) do sorcery_reload!([:session_timeout]) - sorcery_controller_property_set(:session_timeout,0.5) + sorcery_controller_property_set(:session_timeout, 0.5) end after(:each) do @@ -20,7 +19,7 @@ allow(user).to receive_message_chain(:sorcery_config, :username_attribute_names, :first) { :username } end - it "does not reset session before session timeout" do + it 'does not reset session before session timeout' do login_user user get :test_should_be_logged_in @@ -28,38 +27,38 @@ expect(response).to be_a_success end - it "resets session after session timeout" do + it 'resets session after session timeout' do login_user user - Timecop.travel(Time.now.in_time_zone+0.6) + Timecop.travel(Time.now.in_time_zone + 0.6) get :test_should_be_logged_in expect(session[:user_id]).to be_nil expect(response).to be_a_redirect end - it "works if the session is stored as a string or a Time" do + it 'works if the session is stored as a string or a Time' do session[:login_time] = Time.now.to_s # TODO: ??? expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) - get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } + get :test_login, params: { email: 'bla@bla.com', password: 'secret' } expect(session[:user_id]).not_to be_nil expect(response).to be_a_success end context "with 'session_timeout_from_last_action'" do - it "does not logout if there was activity" do + it 'does not logout if there was activity' do sorcery_controller_property_set(:session_timeout_from_last_action, true) expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) - get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } - Timecop.travel(Time.now.in_time_zone+0.3) + get :test_login, params: { email: 'bla@bla.com', password: 'secret' } + Timecop.travel(Time.now.in_time_zone + 0.3) get :test_should_be_logged_in expect(session[:user_id]).not_to be_nil - Timecop.travel(Time.now.in_time_zone+0.3) + Timecop.travel(Time.now.in_time_zone + 0.3) get :test_should_be_logged_in expect(session[:user_id]).not_to be_nil @@ -68,8 +67,8 @@ it "with 'session_timeout_from_last_action' logs out if there was no activity" do sorcery_controller_property_set(:session_timeout_from_last_action, true) - get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } - Timecop.travel(Time.now.in_time_zone+0.6) + get :test_login, params: { email: 'bla@bla.com', password: 'secret' } + Timecop.travel(Time.now.in_time_zone + 0.6) get :test_should_be_logged_in expect(session[:user_id]).to be_nil diff --git a/spec/controllers/controller_spec.rb b/spec/controllers/controller_spec.rb index a0e202b8..ea747578 100644 --- a/spec/controllers/controller_spec.rb +++ b/spec/controllers/controller_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' -describe SorceryController, :type => :controller do - describe "plugin configuration" do +describe SorceryController, type: :controller do + describe 'plugin configuration' do before(:all) do sorcery_reload! end @@ -12,9 +12,9 @@ end it "enables configuration option 'user_class'" do - sorcery_controller_property_set(:user_class, "TestUser") + sorcery_controller_property_set(:user_class, 'TestUser') - expect(Sorcery::Controller::Config.user_class).to eq "TestUser" + expect(Sorcery::Controller::Config.user_class).to eq 'TestUser' end it "enables configuration option 'not_authenticated_action'" do @@ -22,11 +22,10 @@ expect(Sorcery::Controller::Config.not_authenticated_action).to eq :my_action end - end # ----------------- PLUGIN ACTIVATED ----------------------- - context "when activated with sorcery" do + context 'when activated with sorcery' do let(:user) { double('user', id: 42) } before(:all) do @@ -50,79 +49,77 @@ specify { should respond_to(:require_login) } - describe "#login" do - - context "when succeeds" do + describe '#login' do + context 'when succeeds' do before do expect(User).to receive(:authenticate).with('bla@bla.com', 'secret').and_return(user) - get :test_login, :params => { :email => 'bla@bla.com', :password => 'secret' } + get :test_login, params: { email: 'bla@bla.com', password: 'secret' } end - it "assigns user to @user variable" do + it 'assigns user to @user variable' do expect(assigns[:user]).to eq user end - it "writes user id in session" do + it 'writes user id in session' do expect(session[:user_id]).to eq user.id.to_s end - it "sets csrf token in session" do + it 'sets csrf token in session' do expect(session[:_csrf_token]).not_to be_nil end - end - context "when fails" do + context 'when fails' do before do expect(User).to receive(:authenticate).with('bla@bla.com', 'opensesame!').and_return(nil) - get :test_login, :params => { :email => 'bla@bla.com', :password => 'opensesame!' } + get :test_login, params: { email: 'bla@bla.com', password: 'opensesame!' } end - it "sets @user variable to nil" do + it 'sets @user variable to nil' do expect(assigns[:user]).to be_nil end - it "sets user_id in session to nil" do + it 'sets user_id in session to nil' do expect(session[:user_id]).to be_nil end end end - describe "#logout" do - it "clears the session" do + describe '#logout' do + it 'clears the session' do cookies[:remember_me_token] = nil session[:user_id] = user.id.to_s - expect(User.sorcery_adapter).to receive(:find_by_id).with("42") { user } + expect(User.sorcery_adapter).to receive(:find_by_id).with('42') { user } get :test_logout expect(session[:user_id]).to be_nil end end - describe "#logged_in?" do - it "returns true when user is logged in" do + describe '#logged_in?' do + it 'returns true when user is logged in' do session[:user_id] = user.id.to_s - expect(User.sorcery_adapter).to receive(:find_by_id).with("42") { user } + expect(User.sorcery_adapter).to receive(:find_by_id).with('42') { user } expect(subject.logged_in?).to be true end - it "returns false when user is not logged in" do + it 'returns false when user is not logged in' do session[:user_id] = nil expect(subject.logged_in?).to be false end end - describe "#current_user" do - it "current_user returns the user instance if logged in" do + describe '#current_user' do + it 'current_user returns the user instance if logged in' do session[:user_id] = user.id.to_s - expect(User.sorcery_adapter).to receive(:find_by_id).once.with("42") { user } + expect(User.sorcery_adapter).to receive(:find_by_id).once.with('42') { user } 2.times { expect(subject.current_user).to eq user } # memoized! end - it "current_user returns false if not logged in" do + it 'current_user returns false if not logged in' do session[:user_id] = nil expect(User.sorcery_adapter).to_not receive(:find_by_id) @@ -130,7 +127,6 @@ end end - it "calls the configured 'not_authenticated_action' when authenticate before_action fails" do session[:user_id] = nil sorcery_controller_property_set(:not_authenticated_action, :test_not_authenticated_action) @@ -139,41 +135,40 @@ expect(response).to be_a_success end - it "require_login before_action saves the url that the user originally wanted" do + it 'require_login before_action saves the url that the user originally wanted' do get :some_action - expect(session[:return_to_url]).to eq "http://test.host/some_action" - expect(response).to redirect_to("http://test.host/") + expect(session[:return_to_url]).to eq 'http://test.host/some_action' + expect(response).to redirect_to('http://test.host/') end - it "require_login before_action does not save the url that the user originally wanted upon all non-get http methods" do + it 'require_login before_action does not save the url that the user originally wanted upon all non-get http methods' do [:post, :put, :delete].each do |m| - self.send(m, :some_action) + send(m, :some_action) expect(session[:return_to_url]).to be_nil end end - it "on successful login the user is redirected to the url he originally wanted" do - session[:return_to_url] = "http://test.host/some_action" - post :test_return_to, :params => { :email => 'bla@bla.com', :password => 'secret' } + it 'on successful login the user is redirected to the url he originally wanted' do + session[:return_to_url] = 'http://test.host/some_action' + post :test_return_to, params: { email: 'bla@bla.com', password: 'secret' } - expect(response).to redirect_to("http://test.host/some_action") - expect(flash[:notice]).to eq "haha!" + expect(response).to redirect_to('http://test.host/some_action') + expect(flash[:notice]).to eq 'haha!' end - # --- auto_login(user) --- specify { should respond_to(:auto_login) } - it "auto_login(user) los in a user instance" do + it 'auto_login(user) los in a user instance' do session[:user_id] = nil subject.auto_login(user) expect(subject.logged_in?).to be true end - it "auto_login(user) works even if current_user was already set to false" do + it 'auto_login(user) works even if current_user was already set to false' do get :test_logout expect(session[:user_id]).to be_nil @@ -186,5 +181,4 @@ expect(assigns[:result]).to eq user end end - end diff --git a/spec/orm/active_record.rb b/spec/orm/active_record.rb index 87f56b04..50a1c874 100644 --- a/spec/orm/active_record.rb +++ b/spec/orm/active_record.rb @@ -17,5 +17,5 @@ def teardown_orm end def migrations_path - Rails.root.join("db", "migrate", "core") + Rails.root.join('db', 'migrate', 'core') end diff --git a/spec/rails_app/app/active_record/authentication.rb b/spec/rails_app/app/active_record/authentication.rb index 33234367..69a2df10 100644 --- a/spec/rails_app/app/active_record/authentication.rb +++ b/spec/rails_app/app/active_record/authentication.rb @@ -1,3 +1,3 @@ class Authentication < ActiveRecord::Base belongs_to :user -end \ No newline at end of file +end diff --git a/spec/rails_app/app/active_record/user.rb b/spec/rails_app/app/active_record/user.rb index 363bb306..2cd1fd3e 100644 --- a/spec/rails_app/app/active_record/user.rb +++ b/spec/rails_app/app/active_record/user.rb @@ -1,5 +1,5 @@ class User < ActiveRecord::Base - has_many :authentications, :dependent => :destroy - has_many :user_providers, :dependent => :destroy + has_many :authentications, dependent: :destroy + has_many :user_providers, dependent: :destroy accepts_nested_attributes_for :authentications end diff --git a/spec/rails_app/config.ru b/spec/rails_app/config.ru index 2c6ec586..7e681f07 100644 --- a/spec/rails_app/config.ru +++ b/spec/rails_app/config.ru @@ -1,4 +1,4 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require ::File.expand_path('../config/environment', __FILE__) run RailsApp::Application diff --git a/spec/rails_app/config/application.rb b/spec/rails_app/config/application.rb index 2066817c..44b2a9ca 100644 --- a/spec/rails_app/config/application.rb +++ b/spec/rails_app/config/application.rb @@ -1,8 +1,8 @@ require File.expand_path('../boot', __FILE__) -require "action_controller/railtie" -require "action_mailer/railtie" -require "rails/test_unit/railtie" +require 'action_controller/railtie' +require 'action_mailer/railtie' +require 'rails/test_unit/railtie' Bundler.require :default, SORCERY_ORM @@ -11,11 +11,11 @@ rescue LoadError end -require "sorcery" +require 'sorcery' module AppRoot class Application < Rails::Application - config.autoload_paths.reject!{ |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers mailers views).include?($1) } + config.autoload_paths.reject! { |p| p =~ /\/app\/(\w+)$/ && !%w(controllers helpers mailers views).include?(Regexp.last_match(1)) } config.autoload_paths += ["#{config.root}/app/#{SORCERY_ORM}"] # Settings in config/environments/* take precedence over those specified here. @@ -44,7 +44,7 @@ class Application < Rails::Application # config.action_view.javascript_expansions[:defaults] = %w(jquery rails) # Configure the default encoding used in templates for Ruby 1.9. - config.encoding = "utf-8" + config.encoding = 'utf-8' # Configure sensitive parameters which will be filtered from the log file. config.filter_parameters += [:password] diff --git a/spec/rails_app/config/boot.rb b/spec/rails_app/config/boot.rb index acb11b98..eaa6ee87 100644 --- a/spec/rails_app/config/boot.rb +++ b/spec/rails_app/config/boot.rb @@ -1,4 +1,4 @@ # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) -require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) +require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) diff --git a/spec/rails_app/config/environments/test.rb b/spec/rails_app/config/environments/test.rb index 56e0a959..501223ed 100644 --- a/spec/rails_app/config/environments/test.rb +++ b/spec/rails_app/config/environments/test.rb @@ -18,7 +18,7 @@ config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment - config.action_controller.allow_forgery_protection = false + config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the diff --git a/spec/rails_app/config/initializers/session_store.rb b/spec/rails_app/config/initializers/session_store.rb index 2674597a..9e03a134 100644 --- a/spec/rails_app/config/initializers/session_store.rb +++ b/spec/rails_app/config/initializers/session_store.rb @@ -1,6 +1,6 @@ # Be sure to restart your server when you modify this file. -AppRoot::Application.config.session_store :cookie_store, :key => '_app_root_session' +AppRoot::Application.config.session_store :cookie_store, key: '_app_root_session' # Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information @@ -8,5 +8,5 @@ # AppRoot::Application.config.session_store :active_record_store if AppRoot::Application.config.respond_to?(:secret_key_base=) - AppRoot::Application.config.secret_key_base = "foobar" -end \ No newline at end of file + AppRoot::Application.config.secret_key_base = 'foobar' +end diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index c75eb535..3ca08ef4 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -1,5 +1,5 @@ AppRoot::Application.routes.draw do - root :to => "application#index" + root to: 'application#index' controller :sorcery do get :test_login diff --git a/spec/shared_examples/user_activation_shared_examples.rb b/spec/shared_examples/user_activation_shared_examples.rb index 6eb82ced..3f446f4f 100644 --- a/spec/shared_examples/user_activation_shared_examples.rb +++ b/spec/shared_examples/user_activation_shared_examples.rb @@ -1,15 +1,15 @@ -shared_examples_for "rails_3_activation_model" do +shared_examples_for 'rails_3_activation_model' do let(:user) { create_new_user } let(:new_user) { build_new_user } - context "loaded plugin configuration" do + context 'loaded plugin configuration' do before(:all) do - sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation], user_activation_mailer: ::SorceryMailer) end after(:each) do User.sorcery_config.reset! - sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation], user_activation_mailer: ::SorceryMailer) end it "enables configuration option 'activation_state_attribute_name'" do @@ -48,23 +48,22 @@ expect(User.sorcery_config.activation_mailer_disabled).to eq :my_activation_mailer_disabled end - it "if mailer is nil and mailer is enabled, throw exception!" do - expect{sorcery_reload!([:user_activation], :activation_mailer_disabled => false)}.to raise_error(ArgumentError) + it 'if mailer is nil and mailer is enabled, throw exception!' do + expect { sorcery_reload!([:user_activation], activation_mailer_disabled: false) }.to raise_error(ArgumentError) end - it "if mailer is disabled and mailer is nil, do NOT throw exception" do - expect{sorcery_reload!([:user_activation], :activation_mailer_disabled => true)}.to_not raise_error + it 'if mailer is disabled and mailer is nil, do NOT throw exception' do + expect { sorcery_reload!([:user_activation], activation_mailer_disabled: true) }.to_not raise_error end end - - context "activation process" do + context 'activation process' do before(:all) do - sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation], user_activation_mailer: ::SorceryMailer) end it "initializes user state to 'pending'" do - expect(user.activation_state).to eq "pending" + expect(user.activation_state).to eq 'pending' end specify { expect(user).to respond_to :activate! } @@ -75,35 +74,34 @@ user2 = User.sorcery_adapter.find(user.id) # go to db to make sure it was saved and not just in memory expect(user2.activation_token).to be_nil - expect(user2.activation_state).to eq "active" - expect(User.sorcery_adapter.find_by_activation_token activation_token).to be_nil + expect(user2.activation_state).to eq 'active' + expect(User.sorcery_adapter.find_by_activation_token(activation_token)).to be_nil end - - context "mailer is enabled" do - it "sends the user an activation email" do + context 'mailer is enabled' do + it 'sends the user an activation email' do old_size = ActionMailer::Base.deliveries.size create_new_user expect(ActionMailer::Base.deliveries.size).to eq old_size + 1 end - it "calls send_activation_needed_email! method of user" do + it 'calls send_activation_needed_email! method of user' do expect(new_user).to receive(:send_activation_needed_email!).once - new_user.sorcery_adapter.save(:raise_on_failure => true) + new_user.sorcery_adapter.save(raise_on_failure: true) end - it "subsequent saves do not send activation email" do + it 'subsequent saves do not send activation email' do user old_size = ActionMailer::Base.deliveries.size - user.email = "Shauli" - user.sorcery_adapter.save(:raise_on_failure => true) + user.email = 'Shauli' + user.sorcery_adapter.save(raise_on_failure: true) expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "sends the user an activation success email on successful activation" do + it 'sends the user an activation success email on successful activation' do user old_size = ActionMailer::Base.deliveries.size user.activate! @@ -111,29 +109,29 @@ expect(ActionMailer::Base.deliveries.size).to eq old_size + 1 end - it "calls send_activation_success_email! method of user on activation" do + it 'calls send_activation_success_email! method of user on activation' do expect(user).to receive(:send_activation_success_email!).once user.activate! end - it "subsequent saves do not send activation success email" do + it 'subsequent saves do not send activation success email' do user.activate! old_size = ActionMailer::Base.deliveries.size - user.email = "Shauli" - user.sorcery_adapter.save(:raise_on_failure => true) + user.email = 'Shauli' + user.sorcery_adapter.save(raise_on_failure: true) expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "activation needed email is optional" do + it 'activation needed email is optional' do sorcery_model_property_set(:activation_needed_email_method_name, nil) old_size = ActionMailer::Base.deliveries.size expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "activation success email is optional" do + it 'activation success email is optional' do sorcery_model_property_set(:activation_success_email_method_name, nil) old_size = ActionMailer::Base.deliveries.size user.activate! @@ -141,40 +139,40 @@ expect(ActionMailer::Base.deliveries.size).to eq old_size end - context "activation_needed_email is skipped" do + context 'activation_needed_email is skipped' do before(:each) do @user = build_new_user @user.skip_activation_needed_email = true end - it "does not send the user an activation email" do + it 'does not send the user an activation email' do old_size = ActionMailer::Base.deliveries.size - @user.sorcery_adapter.save(:raise_on_failure => true) + @user.sorcery_adapter.save(raise_on_failure: true) expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "does not call send_activation_needed_email! method of user" do + it 'does not call send_activation_needed_email! method of user' do expect(@user).to receive(:send_activation_needed_email!).never - @user.sorcery_adapter.save(:raise_on_failure => true) + @user.sorcery_adapter.save(raise_on_failure: true) end - it "calls send_activation_success_email! method of user on activation" do + it 'calls send_activation_success_email! method of user on activation' do expect(@user).to receive(:send_activation_success_email!).never @user.activate! end end - context "activation_success_email is skipped" do + context 'activation_success_email is skipped' do before(:each) do @user = build_new_user @user.skip_activation_success_email = true end - it "does not send the user an activation success email on successful activation" do + it 'does not send the user an activation success email on successful activation' do old_size = ActionMailer::Base.deliveries.size @user.activate! @@ -184,34 +182,34 @@ end end - context "mailer has been disabled" do + context 'mailer has been disabled' do before(:each) do - sorcery_reload!([:user_activation], :activation_mailer_disabled => true, :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation], activation_mailer_disabled: true, user_activation_mailer: ::SorceryMailer) end - it "does not send the user an activation email" do + it 'does not send the user an activation email' do old_size = ActionMailer::Base.deliveries.size create_new_user expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "does not call send_activation_needed_email! method of user" do + it 'does not call send_activation_needed_email! method of user' do user = build_new_user expect(user).to receive(:send_activation_needed_email!).never - user.sorcery_adapter.save(:raise_on_failure => true) + user.sorcery_adapter.save(raise_on_failure: true) end - it "does not send the user an activation success email on successful activation" do + it 'does not send the user an activation success email on successful activation' do old_size = ActionMailer::Base.deliveries.size user.activate! expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "calls send_activation_success_email! method of user on activation" do + it 'calls send_activation_success_email! method of user on activation' do expect(user).to receive(:send_activation_success_email!).never user.activate! @@ -219,67 +217,67 @@ end end - describe "prevent non-active login feature" do + describe 'prevent non-active login feature' do before(:all) do - sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation], user_activation_mailer: ::SorceryMailer) end before(:each) do User.sorcery_adapter.delete_all end - it "does not allow a non-active user to authenticate" do - expect(User.authenticate user.email, 'secret').to be_falsy + it 'does not allow a non-active user to authenticate' do + expect(User.authenticate(user.email, 'secret')).to be_falsy end - it "allows a non-active user to authenticate if configured so" do + it 'allows a non-active user to authenticate if configured so' do sorcery_model_property_set(:prevent_non_active_users_to_login, false) - expect(User.authenticate user.email, 'secret').to be_truthy + expect(User.authenticate(user.email, 'secret')).to be_truthy end end - describe "load_from_activation_token" do + describe 'load_from_activation_token' do before(:all) do - sorcery_reload!([:user_activation], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation], user_activation_mailer: ::SorceryMailer) end after(:each) do Timecop.return end - it "load_from_activation_token returns user when token is found" do - expect(User.load_from_activation_token user.activation_token).to eq user + it 'load_from_activation_token returns user when token is found' do + expect(User.load_from_activation_token(user.activation_token)).to eq user end - it "load_from_activation_token does NOT return user when token is NOT found" do - expect(User.load_from_activation_token "a").to be_nil + it 'load_from_activation_token does NOT return user when token is NOT found' do + expect(User.load_from_activation_token('a')).to be_nil end - it "load_from_activation_token returas user when token is found and not expired" do + it 'load_from_activation_token returas user when token is found and not expired' do sorcery_model_property_set(:activation_token_expiration_period, 500) - expect(User.load_from_activation_token user.activation_token).to eq user + expect(User.load_from_activation_token(user.activation_token)).to eq user end - it "load_from_activation_token does NOT return user when token is found and expired" do + it 'load_from_activation_token does NOT return user when token is found and expired' do sorcery_model_property_set(:activation_token_expiration_period, 0.1) user - Timecop.travel(Time.now.in_time_zone+0.5) + Timecop.travel(Time.now.in_time_zone + 0.5) - expect(User.load_from_activation_token user.activation_token).to be_nil + expect(User.load_from_activation_token(user.activation_token)).to be_nil end - it "load_from_activation_token returns nil if token is blank" do - expect(User.load_from_activation_token nil).to be_nil - expect(User.load_from_activation_token "").to be_nil + it 'load_from_activation_token returns nil if token is blank' do + expect(User.load_from_activation_token(nil)).to be_nil + expect(User.load_from_activation_token('')).to be_nil end - it "load_from_activation_token is always valid if expiration period is nil" do + it 'load_from_activation_token is always valid if expiration period is nil' do sorcery_model_property_set(:activation_token_expiration_period, nil) - expect(User.load_from_activation_token user.activation_token).to eq user + expect(User.load_from_activation_token(user.activation_token)).to eq user end end end diff --git a/spec/shared_examples/user_reset_password_shared_examples.rb b/spec/shared_examples/user_reset_password_shared_examples.rb index c0e96bda..801b92f2 100644 --- a/spec/shared_examples/user_reset_password_shared_examples.rb +++ b/spec/shared_examples/user_reset_password_shared_examples.rb @@ -1,24 +1,22 @@ -shared_examples_for "rails_3_reset_password_model" do +shared_examples_for 'rails_3_reset_password_model' do # ----------------- PLUGIN CONFIGURATION ----------------------- let(:user) { create_new_user } - describe "loaded plugin configuration" do - + describe 'loaded plugin configuration' do before(:all) do - sorcery_reload!([:reset_password], :reset_password_mailer => ::SorceryMailer) + sorcery_reload!([:reset_password], reset_password_mailer: ::SorceryMailer) end after(:each) do User.sorcery_config.reset! end - context "API" do - + context 'API' do specify { expect(user).to respond_to :deliver_reset_password_instructions! } specify { expect(user).to respond_to :change_password! } - it "responds to .load_from_reset_password_token" do + it 'responds to .load_from_reset_password_token' do expect(User).to respond_to :load_from_reset_password_token end end @@ -41,12 +39,12 @@ expect(User.sorcery_config.reset_password_mailer_disabled).to eq :my_reset_password_mailer_disabled end - it "if mailer is nil and mailer is enabled, throw exception!" do - expect{sorcery_reload!([:reset_password], :reset_password_mailer_disabled => false)}.to raise_error(ArgumentError) + it 'if mailer is nil and mailer is enabled, throw exception!' do + expect { sorcery_reload!([:reset_password], reset_password_mailer_disabled: false) }.to raise_error(ArgumentError) end - it "if mailer is disabled and mailer is nil, do NOT throw exception" do - expect{sorcery_reload!([:reset_password], :reset_password_mailer_disabled => true)}.to_not raise_error + it 'if mailer is disabled and mailer is nil, do NOT throw exception' do + expect { sorcery_reload!([:reset_password], reset_password_mailer_disabled: true) }.to_not raise_error end it "allows configuration option 'reset_password_email_method_name'" do @@ -74,11 +72,9 @@ end end - - describe "when activated with sorcery" do - + describe 'when activated with sorcery' do before(:all) do - sorcery_reload!([:reset_password], :reset_password_mailer => ::SorceryMailer) + sorcery_reload!([:reset_password], reset_password_mailer: ::SorceryMailer) end before(:each) do @@ -90,46 +86,46 @@ Timecop.return end - it "load_from_reset_password_token returns user when token is found" do + it 'load_from_reset_password_token returns user when token is found' do user.generate_reset_password_token! - updated_user = User.sorcery_adapter.find(user.id) + updated_user = User.sorcery_adapter.find(user.id) - expect(User.load_from_reset_password_token user.reset_password_token).to eq updated_user + expect(User.load_from_reset_password_token(user.reset_password_token)).to eq updated_user end - it "load_from_reset_password_token does NOT return user when token is NOT found" do + it 'load_from_reset_password_token does NOT return user when token is NOT found' do user.generate_reset_password_token! - expect(User.load_from_reset_password_token "a").to be_nil + expect(User.load_from_reset_password_token('a')).to be_nil end - it "load_from_reset_password_token returns user when token is found and not expired" do + it 'load_from_reset_password_token returns user when token is found and not expired' do sorcery_model_property_set(:reset_password_expiration_period, 500) user.generate_reset_password_token! - updated_user = User.sorcery_adapter.find(user.id) + updated_user = User.sorcery_adapter.find(user.id) - expect(User.load_from_reset_password_token user.reset_password_token).to eq updated_user + expect(User.load_from_reset_password_token(user.reset_password_token)).to eq updated_user end - it "load_from_reset_password_token does NOT return user when token is found and expired" do + it 'load_from_reset_password_token does NOT return user when token is found and expired' do sorcery_model_property_set(:reset_password_expiration_period, 0.1) user.generate_reset_password_token! - Timecop.travel(Time.now.in_time_zone+0.5) + Timecop.travel(Time.now.in_time_zone + 0.5) - expect(User.load_from_reset_password_token user.reset_password_token).to be_nil + expect(User.load_from_reset_password_token(user.reset_password_token)).to be_nil end - it "load_from_reset_password_token is always valid if expiration period is nil" do + it 'load_from_reset_password_token is always valid if expiration period is nil' do sorcery_model_property_set(:reset_password_expiration_period, nil) user.generate_reset_password_token! - updated_user = User.sorcery_adapter.find(user.id) + updated_user = User.sorcery_adapter.find(user.id) - expect(User.load_from_reset_password_token user.reset_password_token).to eq updated_user + expect(User.load_from_reset_password_token(user.reset_password_token)).to eq updated_user end - it "load_from_reset_password_token returns nil if token is blank" do - expect(User.load_from_reset_password_token nil).to be_nil - expect(User.load_from_reset_password_token "").to be_nil + it 'load_from_reset_password_token returns nil if token is blank' do + expect(User.load_from_reset_password_token(nil)).to be_nil + expect(User.load_from_reset_password_token('')).to be_nil end it "'deliver_reset_password_instructions!' generates a reset_password_token" do @@ -144,7 +140,7 @@ expect(user.deliver_reset_password_instructions!).to be_an_instance_of Mail::Message end - it "the reset_password_token is random" do + it 'the reset_password_token is random' do sorcery_model_property_set(:reset_password_time_between_emails, 0) user.deliver_reset_password_instructions! old_password_code = user.reset_password_token @@ -153,21 +149,21 @@ expect(user.reset_password_token).not_to eq old_password_code end - context "mailer is enabled" do - it "sends an email on reset" do + context 'mailer is enabled' do + it 'sends an email on reset' do old_size = ActionMailer::Base.deliveries.size user.deliver_reset_password_instructions! expect(ActionMailer::Base.deliveries.size).to eq old_size + 1 end - it "calls send_reset_password_email! on reset" do + it 'calls send_reset_password_email! on reset' do expect(user).to receive(:send_reset_password_email!).once user.deliver_reset_password_instructions! end - it "does not send an email if time between emails has not passed since last email" do + it 'does not send an email if time between emails has not passed since last email' do sorcery_model_property_set(:reset_password_time_between_emails, 10000) old_size = ActionMailer::Base.deliveries.size user.deliver_reset_password_instructions! @@ -179,40 +175,39 @@ expect(ActionMailer::Base.deliveries.size).to eq old_size + 1 end - it "sends an email if time between emails has passed since last email" do + it 'sends an email if time between emails has passed since last email' do sorcery_model_property_set(:reset_password_time_between_emails, 0.5) old_size = ActionMailer::Base.deliveries.size user.deliver_reset_password_instructions! expect(ActionMailer::Base.deliveries.size).to eq old_size + 1 - Timecop.travel(Time.now.in_time_zone+0.5) + Timecop.travel(Time.now.in_time_zone + 0.5) user.deliver_reset_password_instructions! expect(ActionMailer::Base.deliveries.size).to eq old_size + 2 end end - context "mailer is disabled" do - + context 'mailer is disabled' do before(:all) do - sorcery_reload!([:reset_password], :reset_password_mailer_disabled => true, :reset_password_mailer => ::SorceryMailer) + sorcery_reload!([:reset_password], reset_password_mailer_disabled: true, reset_password_mailer: ::SorceryMailer) end - it "sends an email on reset" do + it 'sends an email on reset' do old_size = ActionMailer::Base.deliveries.size user.deliver_reset_password_instructions! expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "does not call send_reset_password_email! on reset" do + it 'does not call send_reset_password_email! on reset' do expect(user).to receive(:send_reset_password_email!).never user.deliver_reset_password_instructions! end - it "does not send an email if time between emails has not passed since last email" do + it 'does not send an email if time between emails has not passed since last email' do sorcery_model_property_set(:reset_password_time_between_emails, 10000) old_size = ActionMailer::Base.deliveries.size user.deliver_reset_password_instructions! @@ -224,44 +219,43 @@ expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "sends an email if time between emails has passed since last email" do + it 'sends an email if time between emails has passed since last email' do sorcery_model_property_set(:reset_password_time_between_emails, 0.5) old_size = ActionMailer::Base.deliveries.size user.deliver_reset_password_instructions! expect(ActionMailer::Base.deliveries.size).to eq old_size - Timecop.travel(Time.now.in_time_zone+0.5) + Timecop.travel(Time.now.in_time_zone + 0.5) user.deliver_reset_password_instructions! expect(ActionMailer::Base.deliveries.size).to eq old_size end end - it "when change_password! is called, deletes reset_password_token" do + it 'when change_password! is called, deletes reset_password_token' do user.deliver_reset_password_instructions! expect(user.reset_password_token).not_to be_nil - user.change_password!("blabulsdf") + user.change_password!('blabulsdf') user.save! expect(user.reset_password_token).to be_nil end - it "returns false if time between emails has not passed since last email" do + it 'returns false if time between emails has not passed since last email' do sorcery_model_property_set(:reset_password_time_between_emails, 10000) user.deliver_reset_password_instructions! expect(user.deliver_reset_password_instructions!).to be false end - it "encrypts properly on reset" do + it 'encrypts properly on reset' do user.deliver_reset_password_instructions! - user.change_password!("blagu") + user.change_password!('blagu') - expect(Sorcery::CryptoProviders::BCrypt.matches? user.crypted_password, "blagu", user.salt).to be true + expect(Sorcery::CryptoProviders::BCrypt.matches?(user.crypted_password, 'blagu', user.salt)).to be true end - end end diff --git a/spec/shared_examples/user_shared_examples.rb b/spec/shared_examples/user_shared_examples.rb index b242c168..2f93887b 100644 --- a/spec/shared_examples/user_shared_examples.rb +++ b/spec/shared_examples/user_shared_examples.rb @@ -1,10 +1,8 @@ -shared_examples_for "rails_3_core_model" do - +shared_examples_for 'rails_3_core_model' do let(:user) { create_new_user } let(:crypted_password) { user.send User.sorcery_config.crypted_password_attribute_name } - describe "loaded plugin configuration" do - + describe 'loaded plugin configuration' do after(:each) { User.sorcery_config.reset! } it "enables configuration option 'username_attribute_names'" do @@ -57,7 +55,7 @@ end it "enables configuration option 'salt_join_token'" do - salt_join_token = "--%%*&-" + salt_join_token = '--%%*&-' sorcery_model_property_set(:salt_join_token, salt_join_token) expect(User.sorcery_config.salt_join_token).to eq salt_join_token @@ -80,118 +78,113 @@ end end - describe "when activated with sorcery" do + describe 'when activated with sorcery' do before(:all) { sorcery_reload! } before(:each) { User.sorcery_adapter.delete_all } - it "does not add authenticate method to base class", active_record: true do + it 'does not add authenticate method to base class', active_record: true do expect(ActiveRecord::Base).not_to respond_to(:authenticate) if defined?(ActiveRecord) end - it "responds to class method authenticate" do + it 'responds to class method authenticate' do expect(User).to respond_to :authenticate end - describe "#authenticate" do - it "returns user if credentials are good" do - expect(User.authenticate user.email, 'secret').to eq user + describe '#authenticate' do + it 'returns user if credentials are good' do + expect(User.authenticate(user.email, 'secret')).to eq user end - it "returns nil if credentials are bad" do - expect(User.authenticate user.email, 'wrong!').to be nil + it 'returns nil if credentials are bad' do + expect(User.authenticate(user.email, 'wrong!')).to be nil end - context "downcasing username" do + context 'downcasing username' do after do sorcery_reload! end - context "when downcasing set to false" do + context 'when downcasing set to false' do before do sorcery_model_property_set(:downcase_username_before_authenticating, false) end - it "does not find user with wrongly capitalized username" do + it 'does not find user with wrongly capitalized username' do expect(User.authenticate(user.email.capitalize, 'secret')).to be_nil end - it "finds user with correctly capitalized username" do + it 'finds user with correctly capitalized username' do expect(User.authenticate(user.email, 'secret')).to eq user end - end - context "when downcasing set to true" do + context 'when downcasing set to true' do before do sorcery_model_property_set(:downcase_username_before_authenticating, true) end - it "does not find user with wrongly capitalized username" do + it 'does not find user with wrongly capitalized username' do expect(User.authenticate(user.email.capitalize, 'secret')).to eq user end - it "finds user with correctly capitalized username" do + it 'finds user with correctly capitalized username' do expect(User.authenticate(user.email, 'secret')).to eq user end - end end - context "and model implements active_for_authentication?" do - - it "authenticates returns user if active_for_authentication? returns true" do + context 'and model implements active_for_authentication?' do + it 'authenticates returns user if active_for_authentication? returns true' do allow_any_instance_of(User).to receive(:active_for_authentication?) { true } - expect(User.authenticate user.email, 'secret').to eq user + expect(User.authenticate(user.email, 'secret')).to eq user end - it "authenticate returns nil if active_for_authentication? returns false" do + it 'authenticate returns nil if active_for_authentication? returns false' do allow_any_instance_of(User).to receive(:active_for_authentication?) { false } - expect(User.authenticate user.email, 'secret').to be_nil + expect(User.authenticate(user.email, 'secret')).to be_nil end end end specify { expect(User).to respond_to(:encrypt) } - it "subclass inherits config if defined so" do - sorcery_reload!([],{:subclasses_inherit_config => true}) + it 'subclass inherits config if defined so' do + sorcery_reload!([], subclasses_inherit_config: true) class Admin < User; end expect(Admin.sorcery_config).not_to be_nil expect(Admin.sorcery_config).to eq User.sorcery_config end - it "subclass does not inherit config if not defined so" do - sorcery_reload!([],{:subclasses_inherit_config => false}) + it 'subclass does not inherit config if not defined so' do + sorcery_reload!([], subclasses_inherit_config: false) class Admin2 < User; end expect(Admin2.sorcery_config).to be_nil end end - - describe "registration" do - + describe 'registration' do before(:all) { sorcery_reload! } before(:each) { User.sorcery_adapter.delete_all } - it "by default, encryption_provider is not nil" do + it 'by default, encryption_provider is not nil' do expect(User.sorcery_config.encryption_provider).not_to be_nil end - it "encrypts password when a new user is saved" do - expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be true + it 'encrypts password when a new user is saved' do + expect(User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)).to be true end - it "clears the virtual password field if the encryption process worked" do + it 'clears the virtual password field if the encryption process worked' do expect(user.password).to be_nil end - it "does not clear the virtual password field if save failed due to validity" do + it 'does not clear the virtual password field if save failed due to validity' do User.class_eval do - validates_format_of :email, :with => /\A(.)+@(.)+\Z/, :if => Proc.new {|r| r.email}, :message => "is invalid" + validates_format_of :email, with: /\A(.)+@(.)+\Z/, if: proc { |r| r.email }, message: 'is invalid' end user.password = 'blupush' @@ -201,7 +194,7 @@ class Admin2 < User; end expect(user.password).not_to be_nil end - it "does not clear the virtual password field if save failed due to exception" do + it 'does not clear the virtual password field if save failed due to exception' do user.password = '4blupush' user.username = nil @@ -215,21 +208,21 @@ class Admin2 < User; end expect(user.password).not_to be_nil end - it "does not encrypt the password twice when a user is updated" do - user.email = "blup@bla.com" + it 'does not encrypt the password twice when a user is updated' do + user.email = 'blup@bla.com' user.save - expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be true + expect(User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)).to be true end - it "replaces the crypted_password in case a new password is set" do + it 'replaces the crypted_password in case a new password is set' do user.password = 'new_secret' user.save - expect(User.sorcery_config.encryption_provider.matches? crypted_password, 'secret', user.salt).to be false + expect(User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)).to be false end - describe "when user has password_confirmation_defined" do + describe 'when user has password_confirmation_defined' do before(:all) do update_model { attr_accessor :password_confirmation } end @@ -239,17 +232,17 @@ class Admin2 < User; end User.send(:remove_method, :password_confirmation=) end - it "clears the virtual password field if the encryption process worked" do - user = create_new_user(username: "u", password: "secret", password_confirmation: "secret", email: "email@example.com") + it 'clears the virtual password field if the encryption process worked' do + user = create_new_user(username: 'u', password: 'secret', password_confirmation: 'secret', email: 'email@example.com') expect(user.password_confirmation).to be_nil end - it "does not clear the virtual password field if save failed due to validity" do + it 'does not clear the virtual password field if save failed due to validity' do User.class_eval do - validates_format_of :email, :with => /\A(.)+@(.)+\Z/ + validates_format_of :email, with: /\A(.)+@(.)+\Z/ end - user = build_new_user(username: "u", password: "secret", password_confirmation: "secret", email: "asd") + user = build_new_user(username: 'u', password: 'secret', password_confirmation: 'secret', email: 'asd') user.save expect(user.password_confirmation).not_to be_nil @@ -257,22 +250,21 @@ class Admin2 < User; end end end - describe "password validation" do - - let(:user_with_pass) { create_new_user({:username => 'foo_bar', :email => "foo@bar.com", :password => 'foobar'})} + describe 'password validation' do + let(:user_with_pass) { create_new_user(username: 'foo_bar', email: 'foo@bar.com', password: 'foobar') } specify { expect(user_with_pass).to respond_to :valid_password? } - it "returns true if password is correct" do - expect(user_with_pass.valid_password?("foobar")).to be true + it 'returns true if password is correct' do + expect(user_with_pass.valid_password?('foobar')).to be true end - it "returns false if password is incorrect" do - expect(user_with_pass.valid_password?("foobug")).to be false + it 'returns false if password is incorrect' do + expect(user_with_pass.valid_password?('foobug')).to be false end end - describe "generic send email" do + describe 'generic send email' do before(:all) do ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation") User.reset_column_information @@ -287,37 +279,37 @@ class Admin2 < User; end allow(::SorceryMailer).to receive(:activation_success_email).and_return(@mail) end - it "use deliver_later" do + it 'use deliver_later' do sorcery_reload!([:user_activation, :user_activation_mailer, :activation_needed_email_method_name, :email_delivery_method], - user_activation_mailer: SorceryMailer ,activation_needed_email_method_name: nil, email_delivery_method: :deliver_later) + user_activation_mailer: SorceryMailer, activation_needed_email_method_name: nil, email_delivery_method: :deliver_later) expect(@mail).to receive(:deliver_later).once user.activate! end describe 'email_delivery_method is default' do - it "use deliver_now if rails version 4.2+" do + it 'use deliver_now if rails version 4.2+' do allow(Rails).to receive(:version).and_return('4.2.0') sorcery_reload!([:user_activation, :user_activation_mailer, :activation_needed_email_method_name], - user_activation_mailer: SorceryMailer ,activation_needed_email_method_name: nil) + user_activation_mailer: SorceryMailer, activation_needed_email_method_name: nil) expect(@mail).to receive(:deliver_now).once user.activate! end - it "use deliver if rails version < 4.2" do + it 'use deliver if rails version < 4.2' do allow(Rails).to receive(:version).and_return('4.1.0') sorcery_reload!([:user_activation, :user_activation_mailer, :activation_needed_email_method_name], - user_activation_mailer: SorceryMailer ,activation_needed_email_method_name: nil) + user_activation_mailer: SorceryMailer, activation_needed_email_method_name: nil) expect(@mail).to receive(:deliver).once user.activate! end end end - describe "special encryption cases" do + describe 'special encryption cases' do before(:all) do - sorcery_reload!() - @text = "Some Text!" + sorcery_reload! + @text = 'Some Text!' end before(:each) do @@ -328,20 +320,20 @@ class Admin2 < User; end User.sorcery_config.reset! end - it "works with no password encryption" do + it 'works with no password encryption' do sorcery_model_property_set(:encryption_algorithm, :none) username = user.send(User.sorcery_config.username_attribute_names.first) - expect(User.authenticate username, 'secret').to be_truthy + expect(User.authenticate(username, 'secret')).to be_truthy end - it "works with custom password encryption" do + it 'works with custom password encryption' do class MyCrypto def self.encrypt(*tokens) - tokens.flatten.join('').gsub(/e/,'A') + tokens.flatten.join('').tr('e', 'A') end - def self.matches?(crypted,*tokens) + def self.matches?(crypted, *tokens) crypted == encrypt(*tokens) end end @@ -350,87 +342,87 @@ def self.matches?(crypted,*tokens) username = user.send(User.sorcery_config.username_attribute_names.first) - expect(User.authenticate username, 'secret').to be_truthy + expect(User.authenticate(username, 'secret')).to be_truthy end - it "if encryption algo is aes256, it sets key to crypto provider" do + it 'if encryption algo is aes256, it sets key to crypto provider' do sorcery_model_property_set(:encryption_algorithm, :aes256) sorcery_model_property_set(:encryption_key, nil) expect { User.encrypt @text }.to raise_error(ArgumentError) - sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343") + sorcery_model_property_set(:encryption_key, 'asd234dfs423fddsmndsflktsdf32343') expect { User.encrypt @text }.not_to raise_error end - it "if encryption algo is aes256, it sets key to crypto provider, even if attributes are set in reverse" do + it 'if encryption algo is aes256, it sets key to crypto provider, even if attributes are set in reverse' do sorcery_model_property_set(:encryption_key, nil) sorcery_model_property_set(:encryption_algorithm, :none) - sorcery_model_property_set(:encryption_key, "asd234dfs423fddsmndsflktsdf32343") + sorcery_model_property_set(:encryption_key, 'asd234dfs423fddsmndsflktsdf32343') sorcery_model_property_set(:encryption_algorithm, :aes256) expect { User.encrypt @text }.not_to raise_error end - it "if encryption algo is md5 it works" do + it 'if encryption algo is md5 it works' do sorcery_model_property_set(:encryption_algorithm, :md5) - expect(User.encrypt @text).to eq Sorcery::CryptoProviders::MD5.encrypt(@text) + expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::MD5.encrypt(@text) end - it "if encryption algo is sha1 it works" do + it 'if encryption algo is sha1 it works' do sorcery_model_property_set(:encryption_algorithm, :sha1) - expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA1.encrypt(@text) + expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::SHA1.encrypt(@text) end - it "if encryption algo is sha256 it works" do + it 'if encryption algo is sha256 it works' do sorcery_model_property_set(:encryption_algorithm, :sha256) - expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA256.encrypt(@text) + expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::SHA256.encrypt(@text) end - it "if encryption algo is sha512 it works" do + it 'if encryption algo is sha512 it works' do sorcery_model_property_set(:encryption_algorithm, :sha512) - expect(User.encrypt @text).to eq Sorcery::CryptoProviders::SHA512.encrypt(@text) + expect(User.encrypt(@text)).to eq Sorcery::CryptoProviders::SHA512.encrypt(@text) end - it "salt is random for each user and saved in db" do + it 'salt is random for each user and saved in db' do sorcery_model_property_set(:salt_attribute_name, :salt) expect(user.salt).not_to be_nil end - it "if salt is set uses it to encrypt" do + it 'if salt is set uses it to encrypt' do sorcery_model_property_set(:salt_attribute_name, :salt) sorcery_model_property_set(:encryption_algorithm, :sha512) expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret') - expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt) + expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret', user.salt) end - it "if salt_join_token is set uses it to encrypt" do + it 'if salt_join_token is set uses it to encrypt' do sorcery_model_property_set(:salt_attribute_name, :salt) - sorcery_model_property_set(:salt_join_token, "-@=>") + sorcery_model_property_set(:salt_join_token, '-@=>') sorcery_model_property_set(:encryption_algorithm, :sha512) expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret') - Sorcery::CryptoProviders::SHA512.join_token = "" + Sorcery::CryptoProviders::SHA512.join_token = '' - expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt) + expect(user.crypted_password).not_to eq Sorcery::CryptoProviders::SHA512.encrypt('secret', user.salt) Sorcery::CryptoProviders::SHA512.join_token = User.sorcery_config.salt_join_token - expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret',user.salt) + expect(user.crypted_password).to eq Sorcery::CryptoProviders::SHA512.encrypt('secret', user.salt) end end - describe "ORM adapter" do + describe 'ORM adapter' do before(:all) do - sorcery_reload!() + sorcery_reload! User.sorcery_adapter.delete_all end @@ -441,26 +433,25 @@ def self.matches?(crypted,*tokens) User.sorcery_config.reset! end - - it "find_by_username works as expected" do + it 'find_by_username works as expected' do sorcery_model_property_set(:username_attribute_names, [:username]) - expect(User.sorcery_adapter.find_by_username "gizmo").to eq user + expect(User.sorcery_adapter.find_by_username('gizmo')).to eq user end - it "find_by_username works as expected with multiple username attributes" do + it 'find_by_username works as expected with multiple username attributes' do sorcery_model_property_set(:username_attribute_names, [:username, :email]) - expect(User.sorcery_adapter.find_by_username "gizmo").to eq user + expect(User.sorcery_adapter.find_by_username('gizmo')).to eq user end - it "find_by_email works as expected" do - expect(User.sorcery_adapter.find_by_email "bla@bla.com").to eq user + it 'find_by_email works as expected' do + expect(User.sorcery_adapter.find_by_email('bla@bla.com')).to eq user end end end -shared_examples_for "external_user" do +shared_examples_for 'external_user' do let(:user) { create_new_user } let(:external_user) { create_new_external_user :twitter } @@ -472,16 +463,15 @@ def self.matches?(crypted,*tokens) expect(user).to respond_to(:external?) end - it "external? is false for regular users" do + it 'external? is false for regular users' do expect(user.external?).to be false end - it "external? is true for external users" do + it 'external? is true for external users' do expect(external_user.external?).to be true end - describe ".create_from_provider" do - + describe '.create_from_provider' do before(:all) do if SORCERY_ORM == :active_record ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/external") @@ -500,24 +490,23 @@ def self.matches?(crypted,*tokens) it 'supports nested attributes' do sorcery_model_property_set(:authentications_class, Authentication) - expect { User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) }.to change { User.count }.by(1) + expect { User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') }.to change { User.count }.by(1) expect(User.first.username).to eq 'Noam Ben Ari' end context 'with block' do it 'create user when block return true' do - expect { - User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) { true } - }.to change { User.count }.by(1) + expect do + User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') { true } + end.to change { User.count }.by(1) end it 'does not create user when block return false' do - expect { - User.create_from_provider('facebook', '123', {username: 'Noam Ben Ari'}) { false } - }.not_to change { User.count } + expect do + User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') { false } + end.not_to change { User.count } end end - end describe 'activation' do @@ -527,7 +516,7 @@ def self.matches?(crypted,*tokens) ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation") end - sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer) + sorcery_reload!([:user_activation, :external], user_activation_mailer: ::SorceryMailer) end after(:all) do @@ -542,15 +531,14 @@ def self.matches?(crypted,*tokens) end [:facebook, :github, :google, :liveid, :slack].each do |provider| - - it "does not send activation email to external users" do + it 'does not send activation email to external users' do old_size = ActionMailer::Base.deliveries.size create_new_external_user(provider) expect(ActionMailer::Base.deliveries.size).to eq old_size end - it "does not send external users an activation success email" do + it 'does not send external users an activation success email' do sorcery_model_property_set(:activation_success_email_method_name, nil) create_new_external_user(provider) old_size = ActionMailer::Base.deliveries.size @@ -559,6 +547,5 @@ def self.matches?(crypted,*tokens) expect(ActionMailer::Base.deliveries.size).to eq old_size end end - end end diff --git a/spec/sorcery_crypto_providers_spec.rb b/spec/sorcery_crypto_providers_spec.rb index 0bac380e..7194dea9 100644 --- a/spec/sorcery_crypto_providers_spec.rb +++ b/spec/sorcery_crypto_providers_spec.rb @@ -1,198 +1,185 @@ require 'spec_helper' -describe "Crypto Providers wrappers" do - +describe 'Crypto Providers wrappers' do describe Sorcery::CryptoProviders::MD5 do - after(:each) do Sorcery::CryptoProviders::MD5.reset! end - it "encrypt works via wrapper like normal lib" do - expect(Sorcery::CryptoProviders::MD5.encrypt 'Noam Ben-Ari').to eq Digest::MD5.hexdigest('Noam Ben-Ari') + it 'encrypt works via wrapper like normal lib' do + expect(Sorcery::CryptoProviders::MD5.encrypt('Noam Ben-Ari')).to eq Digest::MD5.hexdigest('Noam Ben-Ari') end - it "works with multiple stretches" do + it 'works with multiple stretches' do Sorcery::CryptoProviders::MD5.stretches = 3 - expect(Sorcery::CryptoProviders::MD5.encrypt 'Noam Ben-Ari').to eq Digest::MD5.hexdigest(Digest::MD5.hexdigest(Digest::MD5.hexdigest('Noam Ben-Ari'))) + expect(Sorcery::CryptoProviders::MD5.encrypt('Noam Ben-Ari')).to eq Digest::MD5.hexdigest(Digest::MD5.hexdigest(Digest::MD5.hexdigest('Noam Ben-Ari'))) end - it "matches? returns true when matches" do - expect(Sorcery::CryptoProviders::MD5.matches? Digest::MD5.hexdigest('Noam Ben-Ari'), 'Noam Ben-Ari').to be true + it 'matches? returns true when matches' do + expect(Sorcery::CryptoProviders::MD5.matches?(Digest::MD5.hexdigest('Noam Ben-Ari'), 'Noam Ben-Ari')).to be true end - it "matches? returns false when no match" do - expect(Sorcery::CryptoProviders::MD5.matches? Digest::MD5.hexdigest('Noam Ben-Ari'), 'Some Dude').to be false + it 'matches? returns false when no match' do + expect(Sorcery::CryptoProviders::MD5.matches?(Digest::MD5.hexdigest('Noam Ben-Ari'), 'Some Dude')).to be false end - end describe Sorcery::CryptoProviders::SHA1 do - before(:all) do @digest = 'Noam Ben-Ari' - Sorcery::CryptoProviders::SHA1.stretches.times {@digest = Digest::SHA1.hexdigest(@digest)} + Sorcery::CryptoProviders::SHA1.stretches.times { @digest = Digest::SHA1.hexdigest(@digest) } end after(:each) do Sorcery::CryptoProviders::SHA1.reset! end - it "encrypt works via wrapper like normal lib" do - expect(Sorcery::CryptoProviders::SHA1.encrypt 'Noam Ben-Ari').to eq @digest + it 'encrypt works via wrapper like normal lib' do + expect(Sorcery::CryptoProviders::SHA1.encrypt('Noam Ben-Ari')).to eq @digest end - it "works with multiple stretches" do + it 'works with multiple stretches' do Sorcery::CryptoProviders::SHA1.stretches = 3 - expect(Sorcery::CryptoProviders::SHA1.encrypt 'Noam Ben-Ari').to eq Digest::SHA1.hexdigest(Digest::SHA1.hexdigest(Digest::SHA1.hexdigest('Noam Ben-Ari'))) + expect(Sorcery::CryptoProviders::SHA1.encrypt('Noam Ben-Ari')).to eq Digest::SHA1.hexdigest(Digest::SHA1.hexdigest(Digest::SHA1.hexdigest('Noam Ben-Ari'))) end - it "matches? returns true when matches" do - expect(Sorcery::CryptoProviders::SHA1.matches? @digest, 'Noam Ben-Ari').to be true + it 'matches? returns true when matches' do + expect(Sorcery::CryptoProviders::SHA1.matches?(@digest, 'Noam Ben-Ari')).to be true end - it "matches? returns false when no match" do - expect(Sorcery::CryptoProviders::SHA1.matches? @digest, 'Some Dude').to be false + it 'matches? returns false when no match' do + expect(Sorcery::CryptoProviders::SHA1.matches?(@digest, 'Some Dude')).to be false end - it "matches password encrypted using salt and join token from upstream" do - Sorcery::CryptoProviders::SHA1.join_token = "test" - expect(Sorcery::CryptoProviders::SHA1.encrypt ['password', 'gq18WBnJYNh2arkC1kgH']).to eq '894b5bf1643b8d0e1b2eaddb22426be7036dab70' + it 'matches password encrypted using salt and join token from upstream' do + Sorcery::CryptoProviders::SHA1.join_token = 'test' + expect(Sorcery::CryptoProviders::SHA1.encrypt(%w(password gq18WBnJYNh2arkC1kgH))).to eq '894b5bf1643b8d0e1b2eaddb22426be7036dab70' end end describe Sorcery::CryptoProviders::SHA256 do - before(:all) do @digest = 'Noam Ben-Ari' - Sorcery::CryptoProviders::SHA256.stretches.times {@digest = Digest::SHA256.hexdigest(@digest)} + Sorcery::CryptoProviders::SHA256.stretches.times { @digest = Digest::SHA256.hexdigest(@digest) } end after(:each) do Sorcery::CryptoProviders::SHA256.reset! end - it "encrypt works via wrapper like normal lib" do - expect(Sorcery::CryptoProviders::SHA256.encrypt 'Noam Ben-Ari').to eq @digest + it 'encrypt works via wrapper like normal lib' do + expect(Sorcery::CryptoProviders::SHA256.encrypt('Noam Ben-Ari')).to eq @digest end - it "works with multiple stretches" do + it 'works with multiple stretches' do Sorcery::CryptoProviders::SHA256.stretches = 3 - expect(Sorcery::CryptoProviders::SHA256.encrypt 'Noam Ben-Ari').to eq Digest::SHA256.hexdigest(Digest::SHA256.hexdigest(Digest::SHA256.hexdigest('Noam Ben-Ari'))) + expect(Sorcery::CryptoProviders::SHA256.encrypt('Noam Ben-Ari')).to eq Digest::SHA256.hexdigest(Digest::SHA256.hexdigest(Digest::SHA256.hexdigest('Noam Ben-Ari'))) end - it "matches? returns true when matches" do - expect(Sorcery::CryptoProviders::SHA256.matches? @digest, 'Noam Ben-Ari').to be true + it 'matches? returns true when matches' do + expect(Sorcery::CryptoProviders::SHA256.matches?(@digest, 'Noam Ben-Ari')).to be true end - it "matches? returns false when no match" do - expect(Sorcery::CryptoProviders::SHA256.matches? @digest, 'Some Dude').to be false + it 'matches? returns false when no match' do + expect(Sorcery::CryptoProviders::SHA256.matches?(@digest, 'Some Dude')).to be false end - end describe Sorcery::CryptoProviders::SHA512 do - before(:all) do @digest = 'Noam Ben-Ari' - Sorcery::CryptoProviders::SHA512.stretches.times {@digest = Digest::SHA512.hexdigest(@digest)} + Sorcery::CryptoProviders::SHA512.stretches.times { @digest = Digest::SHA512.hexdigest(@digest) } end after(:each) do Sorcery::CryptoProviders::SHA512.reset! end - it "encrypt works via wrapper like normal lib" do - expect(Sorcery::CryptoProviders::SHA512.encrypt 'Noam Ben-Ari').to eq @digest + it 'encrypt works via wrapper like normal lib' do + expect(Sorcery::CryptoProviders::SHA512.encrypt('Noam Ben-Ari')).to eq @digest end - it "works with multiple stretches" do + it 'works with multiple stretches' do Sorcery::CryptoProviders::SHA512.stretches = 3 - expect(Sorcery::CryptoProviders::SHA512.encrypt 'Noam Ben-Ari').to eq Digest::SHA512.hexdigest(Digest::SHA512.hexdigest(Digest::SHA512.hexdigest('Noam Ben-Ari'))) + expect(Sorcery::CryptoProviders::SHA512.encrypt('Noam Ben-Ari')).to eq Digest::SHA512.hexdigest(Digest::SHA512.hexdigest(Digest::SHA512.hexdigest('Noam Ben-Ari'))) end - it "matches? returns true when matches" do - expect(Sorcery::CryptoProviders::SHA512.matches? @digest, 'Noam Ben-Ari').to be true + it 'matches? returns true when matches' do + expect(Sorcery::CryptoProviders::SHA512.matches?(@digest, 'Noam Ben-Ari')).to be true end - it "matches? returns false when no match" do - expect(Sorcery::CryptoProviders::SHA512.matches? @digest, 'Some Dude').to be false + it 'matches? returns false when no match' do + expect(Sorcery::CryptoProviders::SHA512.matches?(@digest, 'Some Dude')).to be false end - end describe Sorcery::CryptoProviders::AES256 do - before(:all) do - aes = OpenSSL::Cipher::Cipher.new("AES-256-ECB") + aes = OpenSSL::Cipher::Cipher.new('AES-256-ECB') aes.encrypt - @key = "asd234dfs423fddsmndsflktsdf32343" + @key = 'asd234dfs423fddsmndsflktsdf32343' aes.key = @key @digest = 'Noam Ben-Ari' - @digest = [aes.update(@digest) + aes.final].pack("m").chomp + @digest = [aes.update(@digest) + aes.final].pack('m').chomp Sorcery::CryptoProviders::AES256.key = @key end - it "encrypt works via wrapper like normal lib" do - expect(Sorcery::CryptoProviders::AES256.encrypt 'Noam Ben-Ari').to eq @digest + it 'encrypt works via wrapper like normal lib' do + expect(Sorcery::CryptoProviders::AES256.encrypt('Noam Ben-Ari')).to eq @digest end - it "matches? returns true when matches" do - expect(Sorcery::CryptoProviders::AES256.matches? @digest, 'Noam Ben-Ari').to be true + it 'matches? returns true when matches' do + expect(Sorcery::CryptoProviders::AES256.matches?(@digest, 'Noam Ben-Ari')).to be true end - it "matches? returns false when no match" do - expect(Sorcery::CryptoProviders::AES256.matches? @digest, 'Some Dude').to be false + it 'matches? returns false when no match' do + expect(Sorcery::CryptoProviders::AES256.matches?(@digest, 'Some Dude')).to be false end - it "can be decrypted" do - aes = OpenSSL::Cipher::Cipher.new("AES-256-ECB") + it 'can be decrypted' do + aes = OpenSSL::Cipher::Cipher.new('AES-256-ECB') aes.decrypt aes.key = @key - expect(aes.update(@digest.unpack("m").first) + aes.final).to eq "Noam Ben-Ari" + expect(aes.update(@digest.unpack('m').first) + aes.final).to eq 'Noam Ben-Ari' end - end describe Sorcery::CryptoProviders::BCrypt do - before(:all) do Sorcery::CryptoProviders::BCrypt.cost = 1 - @digest = BCrypt::Password.create('Noam Ben-Ari', :cost => Sorcery::CryptoProviders::BCrypt.cost) + @digest = BCrypt::Password.create('Noam Ben-Ari', cost: Sorcery::CryptoProviders::BCrypt.cost) end after(:each) do Sorcery::CryptoProviders::BCrypt.reset! end - it "is comparable with original secret" do - expect(BCrypt::Password.new Sorcery::CryptoProviders::BCrypt.encrypt('Noam Ben-Ari')).to eq 'Noam Ben-Ari' + it 'is comparable with original secret' do + expect(BCrypt::Password.new(Sorcery::CryptoProviders::BCrypt.encrypt('Noam Ben-Ari'))).to eq 'Noam Ben-Ari' end - it "works with multiple costs" do + it 'works with multiple costs' do Sorcery::CryptoProviders::BCrypt.cost = 3 - expect(BCrypt::Password.new(Sorcery::CryptoProviders::BCrypt.encrypt 'Noam Ben-Ari')).to eq 'Noam Ben-Ari' + expect(BCrypt::Password.new(Sorcery::CryptoProviders::BCrypt.encrypt('Noam Ben-Ari'))).to eq 'Noam Ben-Ari' end - it "matches? returns true when matches" do - expect(Sorcery::CryptoProviders::BCrypt.matches? @digest, 'Noam Ben-Ari').to be true + it 'matches? returns true when matches' do + expect(Sorcery::CryptoProviders::BCrypt.matches?(@digest, 'Noam Ben-Ari')).to be true end - it "matches? returns false when no match" do - expect(Sorcery::CryptoProviders::BCrypt.matches? @digest, 'Some Dude').to be false + it 'matches? returns false when no match' do + expect(Sorcery::CryptoProviders::BCrypt.matches?(@digest, 'Some Dude')).to be false end - it "respond_to?(:stretches) returns true" do - expect(Sorcery::CryptoProviders::BCrypt.respond_to? :stretches).to be true + it 'respond_to?(:stretches) returns true' do + expect(Sorcery::CryptoProviders::BCrypt.respond_to?(:stretches)).to be true end - it "sets cost when stretches is set" do + it 'sets cost when stretches is set' do Sorcery::CryptoProviders::BCrypt.stretches = 4 # stubbed in Sorcery::TestHelpers::Internal expect(Sorcery::CryptoProviders::BCrypt.cost).to eq 1 end - end - end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 2c9a488c..770d7c9c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,7 +1,7 @@ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) -ENV["RAILS_ENV"] ||= 'test' +ENV['RAILS_ENV'] ||= 'test' SORCERY_ORM = :active_record @@ -13,18 +13,19 @@ require 'timecop' def setup_orm; end + def teardown_orm; end require "orm/#{SORCERY_ORM}" -require "rails_app/config/environment" +require 'rails_app/config/environment' -class TestMailer < ActionMailer::Base;end +class TestMailer < ActionMailer::Base; end -Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f } RSpec.configure do |config| - config.include RSpec::Rails::ControllerExampleGroup, :file_path => /controller(.)*_spec.rb$/ + config.include RSpec::Rails::ControllerExampleGroup, file_path: /controller(.)*_spec.rb$/ config.mock_with :rspec config.use_transactional_fixtures = true @@ -36,9 +37,13 @@ class TestMailer < ActionMailer::Base;end config.include ::Sorcery::TestHelpers::Internal config.include ::Sorcery::TestHelpers::Internal::Rails - if ((Module.const_defined?('::Rails::Controller::Testing') rescue false)) - config.include ::Rails::Controller::Testing::TestProcess, :type => :controller - config.include ::Rails::Controller::Testing::TemplateAssertions, :type => :controller - config.include ::Rails::Controller::Testing::Integration, :type => :controller + if begin + Module.const_defined?('::Rails::Controller::Testing') + rescue + false + end + config.include ::Rails::Controller::Testing::TestProcess, type: :controller + config.include ::Rails::Controller::Testing::TemplateAssertions, type: :controller + config.include ::Rails::Controller::Testing::Integration, type: :controller end end From 5d20b9a0327ac8095adb11950d4fa6325464c832 Mon Sep 17 00:00:00 2001 From: Dan Kim Date: Tue, 13 Dec 2016 00:25:33 +0300 Subject: [PATCH 37/46] Fix code style --- lib/generators/sorcery/install_generator.rb | 38 +++++++++--------- .../submodules/brute_force_protection.rb | 28 ++++++------- lib/sorcery/model/submodules/remember_me.rb | 12 +++--- sorcery.gemspec | 40 +++++++++---------- .../app/controllers/sorcery_controller.rb | 18 ++++----- spec/rails_app/app/mailers/sorcery_mailer.rb | 27 ++++++------- 6 files changed, 78 insertions(+), 85 deletions(-) diff --git a/lib/generators/sorcery/install_generator.rb b/lib/generators/sorcery/install_generator.rb index fed87d83..8c9db77b 100644 --- a/lib/generators/sorcery/install_generator.rb +++ b/lib/generators/sorcery/install_generator.rb @@ -9,36 +9,35 @@ class InstallGenerator < Rails::Generators::Base source_root File.expand_path('../templates', __FILE__) - argument :submodules, :optional => true, :type => :array, :banner => "submodules" + argument :submodules, optional: true, type: :array, banner: 'submodules' - class_option :model, :optional => true, :type => :string, :banner => "model", - :desc => "Specify the model class name if you will use anything other than 'User'" + class_option :model, optional: true, type: :string, banner: 'model', + desc: "Specify the model class name if you will use anything other than 'User'" - class_option :migrations, :optional => true, :type => :boolean, :banner => "migrations", - :desc => "[DEPRECATED] Please use --only-submodules option instead" - - class_option :only_submodules, :optional => true, :type => :boolean, :banner => "only-submodules", - :desc => "Specify if you want to add submodules to an existing model\n\t\t\t # (will generate migrations files, and add submodules to config file)" + class_option :migrations, optional: true, type: :boolean, banner: 'migrations', + desc: '[DEPRECATED] Please use --only-submodules option instead' + class_option :only_submodules, optional: true, type: :boolean, banner: 'only-submodules', + desc: "Specify if you want to add submodules to an existing model\n\t\t\t # (will generate migrations files, and add submodules to config file)" def check_deprecated_options if options[:migrations] - warn("[DEPRECATED] `--migrations` option is deprecated, please use `--only-submodules` instead") + warn('[DEPRECATED] `--migrations` option is deprecated, please use `--only-submodules` instead') end end # Copy the initializer file to config/initializers folder. def copy_initializer_file - template "initializer.rb", sorcery_config_path unless only_submodules? + template 'initializer.rb', sorcery_config_path unless only_submodules? end def configure_initializer_file # Add submodules to the initializer file. if submodules - submodule_names = submodules.collect{ |submodule| ':' + submodule } + submodule_names = submodules.collect { |submodule| ':' + submodule } gsub_file sorcery_config_path, /submodules = \[.*\]/ do |str| - current_submodule_names = (str =~ /\[(.*)\]/ ? $1 : '').delete(' ').split(',') + current_submodule_names = (str =~ /\[(.*)\]/ ? Regexp.last_match(1) : '').delete(' ').split(',') "submodules = [#{(current_submodule_names | submodule_names).join(', ')}]" end end @@ -54,7 +53,7 @@ def configure_model end def inject_sorcery_to_model - indents = " " * (namespaced? ? 2 : 1) + indents = ' ' * (namespaced? ? 2 : 1) inject_into_class(model_path, model_class_name, "#{indents}authenticates_with_sorcery!\n") end @@ -63,29 +62,29 @@ def inject_sorcery_to_model def copy_migration_files # Copy core migration file in all cases except when you pass --only-submodules. return unless defined?(Sorcery::Generators::InstallGenerator::ActiveRecord) - migration_template "migration/core.rb", "db/migrate/sorcery_core.rb", migration_class_name: migration_class_name unless only_submodules? + migration_template 'migration/core.rb', 'db/migrate/sorcery_core.rb', migration_class_name: migration_class_name unless only_submodules? if submodules submodules.each do |submodule| - unless submodule == "http_basic_auth" || submodule == "session_timeout" || submodule == "core" + unless submodule == 'http_basic_auth' || submodule == 'session_timeout' || submodule == 'core' migration_template "migration/#{submodule}.rb", "db/migrate/sorcery_#{submodule}.rb", migration_class_name: migration_class_name end end end - end # Define the next_migration_number method (necessary for the migration_template method to work) def self.next_migration_number(dirname) if ActiveRecord::Base.timestamped_migrations sleep 1 # make sure each time we get a different timestamp - Time.new.utc.strftime("%Y%m%d%H%M%S") + Time.new.utc.strftime('%Y%m%d%H%M%S') else - "%.3d" % (current_migration_number(dirname) + 1) + '%.3d' % (current_migration_number(dirname) + 1) end end private + def only_submodules? options[:migrations] || options[:only_submodules] end @@ -94,10 +93,9 @@ def migration_class_name if Rails::VERSION::MAJOR >= 5 "ActiveRecord::Migration[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]" else - "ActiveRecord::Migration" + 'ActiveRecord::Migration' end end - end end end diff --git a/lib/sorcery/model/submodules/brute_force_protection.rb b/lib/sorcery/model/submodules/brute_force_protection.rb index eb2cebef..50925066 100644 --- a/lib/sorcery/model/submodules/brute_force_protection.rb +++ b/lib/sorcery/model/submodules/brute_force_protection.rb @@ -10,10 +10,10 @@ def self.included(base) base.sorcery_config.class_eval do attr_accessor :failed_logins_count_attribute_name, # failed logins attribute name. :lock_expires_at_attribute_name, # this field indicates whether user - # is banned and when it will be active again. + # is banned and when it will be active again. :consecutive_login_retries_amount_limit, # how many failed logins allowed. :login_lock_time_period, # how long the user should be banned. - # in seconds. 0 for permanent. + # in seconds. 0 for permanent. :unlock_token_attribute_name, # Unlock token attribute name :unlock_token_email_method_name, # Mailer method name @@ -43,14 +43,14 @@ def self.included(base) module ClassMethods def load_from_unlock_token(token) return nil if token.blank? - user = sorcery_adapter.find_by_token(sorcery_config.unlock_token_attribute_name,token) + user = sorcery_adapter.find_by_token(sorcery_config.unlock_token_attribute_name, token) user end protected def define_brute_force_protection_fields - sorcery_adapter.define_field sorcery_config.failed_logins_count_attribute_name, Integer, :default => 0 + sorcery_adapter.define_field sorcery_config.failed_logins_count_attribute_name, Integer, default: 0 sorcery_adapter.define_field sorcery_config.lock_expires_at_attribute_name, Time sorcery_adapter.define_field sorcery_config.unlock_token_attribute_name, String end @@ -61,11 +61,11 @@ module InstanceMethods # Calls 'lock!' if login retries limit was reached. def register_failed_login! config = sorcery_config - return if !unlocked? + return unless unlocked? sorcery_adapter.increment(config.failed_logins_count_attribute_name) - if self.send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit + if send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit lock! end end @@ -75,9 +75,9 @@ def register_failed_login! # /!\ def unlock! config = sorcery_config - attributes = {config.lock_expires_at_attribute_name => nil, - config.failed_logins_count_attribute_name => 0, - config.unlock_token_attribute_name => nil} + attributes = { config.lock_expires_at_attribute_name => nil, + config.failed_logins_count_attribute_name => 0, + config.unlock_token_attribute_name => nil } sorcery_adapter.update_attributes(attributes) end @@ -89,8 +89,8 @@ def locked? def lock! config = sorcery_config - attributes = {config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period, - config.unlock_token_attribute_name => TemporaryToken.generate_random_token} + attributes = { config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period, + config.unlock_token_attribute_name => TemporaryToken.generate_random_token } sorcery_adapter.update_attributes(attributes) unless config.unlock_token_mailer_disabled || config.unlock_token_mailer.nil? @@ -100,7 +100,7 @@ def lock! def unlocked? config = sorcery_config - self.send(config.lock_expires_at_attribute_name).nil? + send(config.lock_expires_at_attribute_name).nil? end def send_unlock_token_email! @@ -113,8 +113,8 @@ def send_unlock_token_email! # Runs as a hook before authenticate. def prevent_locked_user_login config = sorcery_config - if !self.unlocked? && config.login_lock_time_period != 0 - self.unlock! if self.send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone + if !unlocked? && config.login_lock_time_period != 0 + unlock! if send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone end unlocked? end diff --git a/lib/sorcery/model/submodules/remember_me.rb b/lib/sorcery/model/submodules/remember_me.rb index b0bb766b..f4e55235 100644 --- a/lib/sorcery/model/submodules/remember_me.rb +++ b/lib/sorcery/model/submodules/remember_me.rb @@ -11,7 +11,6 @@ def self.included(base) :remember_me_token_expires_at_attribute_name, # the expires attribute in the model class. :remember_me_token_persist_globally, # persist a single token globally for all logins/logouts (supporting multiple simultaneous browsers) :remember_me_for # how long in seconds to remember. - end base.sorcery_config.instance_eval do @@ -36,7 +35,6 @@ def define_remember_me_fields sorcery_adapter.define_field sorcery_config.remember_me_token_attribute_name, String sorcery_adapter.define_field sorcery_config.remember_me_token_expires_at_attribute_name, Time end - end module InstanceMethods @@ -47,14 +45,14 @@ def remember_me! update_options = { config.remember_me_token_expires_at_attribute_name => Time.now.in_time_zone + config.remember_me_for } unless config.remember_me_token_persist_globally && has_remember_me_token? - update_options.merge!(config.remember_me_token_attribute_name => TemporaryToken.generate_random_token) + update_options[config.remember_me_token_attribute_name] = TemporaryToken.generate_random_token end - self.sorcery_adapter.update_attributes(update_options) + sorcery_adapter.update_attributes(update_options) end def has_remember_me_token? - self.send(sorcery_config.remember_me_token_attribute_name).present? + send(sorcery_config.remember_me_token_attribute_name).present? end # You shouldn't really use this one yourself - it's called by the controller's 'forget_me!' method. @@ -66,8 +64,8 @@ def forget_me! # You shouldn't really use this one yourself - it's called by the controller's 'force_forget_me!' method. def force_forget_me! config = sorcery_config - self.sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => nil, - config.remember_me_token_expires_at_attribute_name => nil) + sorcery_adapter.update_attributes(config.remember_me_token_attribute_name => nil, + config.remember_me_token_expires_at_attribute_name => nil) end end end diff --git a/sorcery.gemspec b/sorcery.gemspec index f6d5959f..6687ca8f 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -3,33 +3,33 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'sorcery/version' Gem::Specification.new do |s| - s.name = "sorcery" + s.name = 'sorcery' s.version = Sorcery::VERSION - s.authors = ["Noam Ben Ari", "Kir Shatrov", "Grzegorz Witek"] - s.email = "nbenari@gmail.com" - s.description = "Provides common authentication needs such as signing in/out, activating by email and resetting password." - s.summary = "Magical authentication for Rails 3 & 4 applications" - s.homepage = "https://github.com/Sorcery/sorcery" + s.authors = ['Noam Ben Ari', 'Kir Shatrov', 'Grzegorz Witek'] + s.email = 'nbenari@gmail.com' + s.description = 'Provides common authentication needs such as signing in/out, activating by email and resetting password.' + s.summary = 'Magical authentication for Rails 3 & 4 applications' + s.homepage = 'https://github.com/Sorcery/sorcery' s.post_install_message = "As of version 1.0 oauth/oauth2 won't be automatically bundled\n" - s.post_install_message += "you need to add those dependencies to your Gemfile" + s.post_install_message += 'you need to add those dependencies to your Gemfile' - s.files = `git ls-files`.split($/) - s.require_paths = ["lib"] + s.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR) + s.require_paths = ['lib'] - s.licenses = ["MIT"] + s.licenses = ['MIT'] s.required_ruby_version = '>= 2.0.0' - s.add_dependency "oauth", "~> 0.4", ">= 0.4.4" - s.add_dependency "oauth2", ">= 0.8.0" - s.add_dependency "bcrypt", "~> 3.1" + s.add_dependency 'oauth', '~> 0.4', '>= 0.4.4' + s.add_dependency 'oauth2', '>= 0.8.0' + s.add_dependency 'bcrypt', '~> 3.1' - s.add_development_dependency "abstract", ">= 1.0.0" - s.add_development_dependency "json", ">= 1.7.7" - s.add_development_dependency "yard", "~> 0.6.0" + s.add_development_dependency 'abstract', '>= 1.0.0' + s.add_development_dependency 'json', '>= 1.7.7' + s.add_development_dependency 'yard', '~> 0.6.0' - s.add_development_dependency "timecop" - s.add_development_dependency "simplecov", ">= 0.3.8" - s.add_development_dependency "rspec-rails", "~> 3.5.0" - s.add_development_dependency "test-unit", "~> 3.1.0" + s.add_development_dependency 'timecop' + s.add_development_dependency 'simplecov', '>= 0.3.8' + s.add_development_dependency 'rspec-rails', '~> 3.5.0' + s.add_development_dependency 'test-unit', '~> 3.1.0' end diff --git a/spec/rails_app/app/controllers/sorcery_controller.rb b/spec/rails_app/app/controllers/sorcery_controller.rb index bc0d9f8c..37e5c88a 100644 --- a/spec/rails_app/app/controllers/sorcery_controller.rb +++ b/spec/rails_app/app/controllers/sorcery_controller.rb @@ -6,8 +6,7 @@ class SorceryController < ActionController::Base before_action :require_login_from_http_basic, only: [:test_http_basic_auth] before_action :require_login, only: [:test_logout, :test_logout_with_force_forget_me, :test_should_be_logged_in, :some_action] - def index - end + def index; end def some_action head :ok @@ -87,7 +86,7 @@ def login_at_test_twitter login_at(:twitter) end - alias :login_at_test :login_at_test_twitter + alias login_at_test login_at_test_twitter def login_at_test_facebook login_at(:facebook) @@ -126,7 +125,7 @@ def login_at_test_slack end def login_at_test_with_state - login_at(:facebook, {state: 'bla'}) + login_at(:facebook, state: 'bla') end def test_login_from_twitter @@ -137,7 +136,7 @@ def test_login_from_twitter end end - alias :test_login_from :test_login_from_twitter + alias test_login_from test_login_from_twitter def test_login_from_facebook if @user = login_from(:facebook) @@ -227,7 +226,7 @@ def test_return_to_with_external_jira end end - alias :test_return_to_with_external :test_return_to_with_external_twitter + alias test_return_to_with_external test_return_to_with_external_twitter def test_return_to_with_external_facebook if @user = login_from(:facebook) @@ -307,9 +306,9 @@ def test_add_second_provider provider = params[:provider] if logged_in? if @user = add_provider_to_user(provider) - redirect_to "bla", :notice => "Success!" + redirect_to 'bla', notice: 'Success!' else - redirect_to "blu", :alert => "Failed!" + redirect_to 'blu', alert: 'Failed!' end end end @@ -317,7 +316,7 @@ def test_add_second_provider def test_create_from_provider_with_block provider = params[:provider] login_from(provider) - @user = create_from(provider) do |user| + @user = create_from(provider) do |_user| # check uniqueness of email # User.where(email: user.email).empty? false @@ -328,5 +327,4 @@ def test_create_from_provider_with_block redirect_to 'blu', alert: 'Failed!' end end - end diff --git a/spec/rails_app/app/mailers/sorcery_mailer.rb b/spec/rails_app/app/mailers/sorcery_mailer.rb index 2692755a..4a415d43 100644 --- a/spec/rails_app/app/mailers/sorcery_mailer.rb +++ b/spec/rails_app/app/mailers/sorcery_mailer.rb @@ -1,32 +1,31 @@ class SorceryMailer < ActionMailer::Base - - default :from => "notifications@example.com" + default from: 'notifications@example.com' def activation_needed_email(user) @user = user - @url = "http://example.com/login" - mail(:to => user.email, - :subject => "Welcome to My Awesome Site") + @url = 'http://example.com/login' + mail(to: user.email, + subject: 'Welcome to My Awesome Site') end def activation_success_email(user) @user = user - @url = "http://example.com/login" - mail(:to => user.email, - :subject => "Your account is now activated") + @url = 'http://example.com/login' + mail(to: user.email, + subject: 'Your account is now activated') end def reset_password_email(user) @user = user - @url = "http://example.com/login" - mail(:to => user.email, - :subject => "Your password has been reset") + @url = 'http://example.com/login' + mail(to: user.email, + subject: 'Your password has been reset') end def send_unlock_token_email(user) @user = user @url = "http://example.com/unlock/#{user.unlock_token}" - mail(:to => user.email, - :subject => "Your account has been locked due to many wrong logins") + mail(to: user.email, + subject: 'Your account has been locked due to many wrong logins') end -end \ No newline at end of file +end From c4157f89acf0d02eed12dbd5e3b3bd7b542bed90 Mon Sep 17 00:00:00 2001 From: Dan Kim Date: Tue, 13 Dec 2016 00:31:48 +0300 Subject: [PATCH 38/46] Fix code style --- lib/sorcery/crypto_providers/bcrypt.rb | 4 +- .../20101224223622_add_activation_to_users.rb | 6 +- ...224223624_add_activity_logging_to_users.rb | 10 +-- ...626_add_brute_force_protection_to_users.rb | 8 +-- .../core/20101224223620_create_users.rb | 8 +-- ...24223623_add_remember_me_token_to_users.rb | 6 +- ...01224223622_add_reset_password_to_users.rb | 8 +-- spec/shared_examples/user_shared_examples.rb | 69 +++++++++++++++---- 8 files changed, 80 insertions(+), 39 deletions(-) diff --git a/lib/sorcery/crypto_providers/bcrypt.rb b/lib/sorcery/crypto_providers/bcrypt.rb index 35a4923c..4c1a5655 100644 --- a/lib/sorcery/crypto_providers/bcrypt.rb +++ b/lib/sorcery/crypto_providers/bcrypt.rb @@ -48,8 +48,8 @@ def cost @cost ||= 10 end attr_writer :cost - alias :stretches :cost - alias :stretches= :cost= + alias stretches cost + alias stretches= cost= # Creates a BCrypt hash for the password passed. def encrypt(*tokens) diff --git a/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb b/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb index a6592696..cf0f8cac 100644 --- a/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb +++ b/spec/rails_app/db/migrate/activation/20101224223622_add_activation_to_users.rb @@ -1,8 +1,8 @@ class AddActivationToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up - add_column :users, :activation_state, :string, :default => nil - add_column :users, :activation_token, :string, :default => nil - add_column :users, :activation_token_expires_at, :datetime, :default => nil + add_column :users, :activation_state, :string, default: nil + add_column :users, :activation_token, :string, default: nil + add_column :users, :activation_token_expires_at, :datetime, default: nil add_index :users, :activation_token end diff --git a/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb b/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb index f949efdf..52c0d9e9 100644 --- a/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb +++ b/spec/rails_app/db/migrate/activity_logging/20101224223624_add_activity_logging_to_users.rb @@ -1,9 +1,9 @@ class AddActivityLoggingToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up - add_column :users, :last_login_at, :datetime, :default => nil - add_column :users, :last_logout_at, :datetime, :default => nil - add_column :users, :last_activity_at, :datetime, :default => nil - add_column :users, :last_login_from_ip_address, :string, :default => nil + add_column :users, :last_login_at, :datetime, default: nil + add_column :users, :last_logout_at, :datetime, default: nil + add_column :users, :last_activity_at, :datetime, default: nil + add_column :users, :last_login_from_ip_address, :string, default: nil add_index :users, [:last_logout_at, :last_activity_at] end @@ -16,4 +16,4 @@ def self.down remove_column :users, :last_login_at remove_column :users, :last_login_from_ip_address end -end \ No newline at end of file +end diff --git a/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb b/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb index be210206..42a53520 100644 --- a/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb +++ b/spec/rails_app/db/migrate/brute_force_protection/20101224223626_add_brute_force_protection_to_users.rb @@ -1,8 +1,8 @@ class AddBruteForceProtectionToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up - add_column :users, :failed_logins_count, :integer, :default => 0 - add_column :users, :lock_expires_at, :datetime, :default => nil - add_column :users, :unlock_token, :string, :default => nil + add_column :users, :failed_logins_count, :integer, default: 0 + add_column :users, :lock_expires_at, :datetime, default: nil + add_column :users, :unlock_token, :string, default: nil end def self.down @@ -10,4 +10,4 @@ def self.down remove_column :users, :lock_expires_at remove_column :users, :failed_logins_count end -end \ No newline at end of file +end diff --git a/spec/rails_app/db/migrate/core/20101224223620_create_users.rb b/spec/rails_app/db/migrate/core/20101224223620_create_users.rb index 20b00e1d..a542db86 100644 --- a/spec/rails_app/db/migrate/core/20101224223620_create_users.rb +++ b/spec/rails_app/db/migrate/core/20101224223620_create_users.rb @@ -1,16 +1,16 @@ class CreateUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up create_table :users do |t| - t.string :username, :null => false - t.string :email, :default => nil + t.string :username, null: false + t.string :email, default: nil t.string :crypted_password t.string :salt - t.timestamps :null => false + t.timestamps null: false end end def self.down drop_table :users end -end \ No newline at end of file +end diff --git a/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb b/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb index 5ee1bea6..66c8cd94 100644 --- a/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb +++ b/spec/rails_app/db/migrate/remember_me/20101224223623_add_remember_me_token_to_users.rb @@ -1,7 +1,7 @@ class AddRememberMeTokenToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up - add_column :users, :remember_me_token, :string, :default => nil - add_column :users, :remember_me_token_expires_at, :datetime, :default => nil + add_column :users, :remember_me_token, :string, default: nil + add_column :users, :remember_me_token_expires_at, :datetime, default: nil add_index :users, :remember_me_token end @@ -12,4 +12,4 @@ def self.down remove_column :users, :remember_me_token_expires_at remove_column :users, :remember_me_token end -end \ No newline at end of file +end diff --git a/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb b/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb index 14a45cfb..e80e61f8 100644 --- a/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb +++ b/spec/rails_app/db/migrate/reset_password/20101224223622_add_reset_password_to_users.rb @@ -1,8 +1,8 @@ class AddResetPasswordToUsers < ActiveRecord::CompatibleLegacyMigration.migration_class def self.up - add_column :users, :reset_password_token, :string, :default => nil - add_column :users, :reset_password_token_expires_at, :datetime, :default => nil - add_column :users, :reset_password_email_sent_at, :datetime, :default => nil + add_column :users, :reset_password_token, :string, default: nil + add_column :users, :reset_password_token_expires_at, :datetime, default: nil + add_column :users, :reset_password_email_sent_at, :datetime, default: nil end def self.down @@ -10,4 +10,4 @@ def self.down remove_column :users, :reset_password_token_expires_at remove_column :users, :reset_password_token end -end \ No newline at end of file +end diff --git a/spec/shared_examples/user_shared_examples.rb b/spec/shared_examples/user_shared_examples.rb index 2f93887b..7ba81611 100644 --- a/spec/shared_examples/user_shared_examples.rb +++ b/spec/shared_examples/user_shared_examples.rb @@ -175,7 +175,9 @@ class Admin2 < User; end end it 'encrypts password when a new user is saved' do - expect(User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)).to be true + expect( + User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt) + ).to be true end it 'clears the virtual password field if the encryption process worked' do @@ -184,7 +186,8 @@ class Admin2 < User; end it 'does not clear the virtual password field if save failed due to validity' do User.class_eval do - validates_format_of :email, with: /\A(.)+@(.)+\Z/, if: proc { |r| r.email }, message: 'is invalid' + validates_format_of :email, with: /\A(.)+@(.)+\Z/, + if: proc { |r| r.email }, message: 'is invalid' end user.password = 'blupush' @@ -212,14 +215,18 @@ class Admin2 < User; end user.email = 'blup@bla.com' user.save - expect(User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)).to be true + expect( + User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt) + ).to be true end it 'replaces the crypted_password in case a new password is set' do user.password = 'new_secret' user.save - expect(User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt)).to be false + expect( + User.sorcery_config.encryption_provider.matches?(crypted_password, 'secret', user.salt) + ).to be false end describe 'when user has password_confirmation_defined' do @@ -233,7 +240,11 @@ class Admin2 < User; end end it 'clears the virtual password field if the encryption process worked' do - user = create_new_user(username: 'u', password: 'secret', password_confirmation: 'secret', email: 'email@example.com') + user = create_new_user( + username: 'u', + password: 'secret', password_confirmation: 'secret', + email: 'email@example.com' + ) expect(user.password_confirmation).to be_nil end @@ -242,7 +253,11 @@ class Admin2 < User; end User.class_eval do validates_format_of :email, with: /\A(.)+@(.)+\Z/ end - user = build_new_user(username: 'u', password: 'secret', password_confirmation: 'secret', email: 'asd') + user = build_new_user( + username: 'u', + password: 'secret', password_confirmation: 'secret', + email: 'asd' + ) user.save expect(user.password_confirmation).not_to be_nil @@ -251,7 +266,9 @@ class Admin2 < User; end end describe 'password validation' do - let(:user_with_pass) { create_new_user(username: 'foo_bar', email: 'foo@bar.com', password: 'foobar') } + let(:user_with_pass) do + create_new_user(username: 'foo_bar', email: 'foo@bar.com', password: 'foobar') + end specify { expect(user_with_pass).to respond_to :valid_password? } @@ -280,8 +297,15 @@ class Admin2 < User; end end it 'use deliver_later' do - sorcery_reload!([:user_activation, :user_activation_mailer, :activation_needed_email_method_name, :email_delivery_method], - user_activation_mailer: SorceryMailer, activation_needed_email_method_name: nil, email_delivery_method: :deliver_later) + sorcery_reload!( + [ + :user_activation, :user_activation_mailer, + :activation_needed_email_method_name, :email_delivery_method + ], + user_activation_mailer: SorceryMailer, + activation_needed_email_method_name: nil, + email_delivery_method: :deliver_later + ) expect(@mail).to receive(:deliver_later).once user.activate! @@ -290,16 +314,30 @@ class Admin2 < User; end describe 'email_delivery_method is default' do it 'use deliver_now if rails version 4.2+' do allow(Rails).to receive(:version).and_return('4.2.0') - sorcery_reload!([:user_activation, :user_activation_mailer, :activation_needed_email_method_name], - user_activation_mailer: SorceryMailer, activation_needed_email_method_name: nil) + sorcery_reload!( + [ + :user_activation, :user_activation_mailer, + :activation_needed_email_method_name + ], + user_activation_mailer: SorceryMailer, + activation_needed_email_method_name: nil + ) + expect(@mail).to receive(:deliver_now).once user.activate! end it 'use deliver if rails version < 4.2' do allow(Rails).to receive(:version).and_return('4.1.0') - sorcery_reload!([:user_activation, :user_activation_mailer, :activation_needed_email_method_name], - user_activation_mailer: SorceryMailer, activation_needed_email_method_name: nil) + sorcery_reload!( + [ + :user_activation, :user_activation_mailer, + :activation_needed_email_method_name + ], + user_activation_mailer: SorceryMailer, + activation_needed_email_method_name: nil + ) + expect(@mail).to receive(:deliver).once user.activate! end @@ -490,7 +528,10 @@ def self.matches?(crypted, *tokens) it 'supports nested attributes' do sorcery_model_property_set(:authentications_class, Authentication) - expect { User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') }.to change { User.count }.by(1) + expect do + User.create_from_provider('facebook', '123', username: 'Noam Ben Ari') + end.to change { User.count }.by(1) + expect(User.first.username).to eq 'Noam Ben Ari' end From 51e4912eaf797684830063a3cbcc22f926efc287 Mon Sep 17 00:00:00 2001 From: Dan Kim Date: Sun, 18 Dec 2016 23:20:17 +0300 Subject: [PATCH 39/46] Update README (#26) * Update README.md * Fix email links * Update code style in README.md --- README.md | 376 +++++++++++++++--------------------------------------- 1 file changed, 104 insertions(+), 272 deletions(-) diff --git a/README.md b/README.md index d350a37d..6058e070 100644 --- a/README.md +++ b/README.md @@ -7,103 +7,89 @@ [![Inline docs](http://inch-ci.org/github/Sorcery/sorcery.svg?branch=master)](http://inch-ci.org/github/Sorcery/sorcery) [![Join the chat at https://gitter.im/Sorcery/sorcery](https://badges.gitter.im/join_chat.svg)](https://gitter.im/Sorcery/sorcery?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -## Project +Magical Authentication for Rails. Supports ActiveRecord, DataMapper, Mongoid and MongoMapper. -Magical Authentication for Rails. Supports ActiveRecord, -DataMapper, Mongoid and MongoMapper. +Inspired by Restful Authentication, Authlogic and Devise. Crypto code taken almost unchanged from Authlogic. OAuth code inspired by OmniAuth and Ryan Bates's Railscast about it. -Inspired by restful_authentication, Authlogic and Devise. Crypto code taken -almost unchanged from Authlogic. OAuth code inspired by OmniAuth and Ryan -Bates's railscasts about it. +### Philosophy -**Rails 5 status:** [Sorcery 0.9.1](http://rubygems.org/gems/sorcery/versions/0.9.1) should work fine with Rails 5. We can't guarantee it at this point, though, so please open an issue for any problem with Rails 5. +Sorcery is a stripped-down, bare-bones authentication library, with which you can write your own authentication flow. It was built with a few goals in mind: -**Rails 4 status:** [Sorcery 0.9.0](http://rubygems.org/gems/sorcery/versions/0.9.0) is fully tested and ready for Rails 4.0, 4.1 and 4.2. - -**Mongoid status:** Version 0.9.0 works with Mongoid 4. - -https://github.com/Sorcery/sorcery/wiki/Simple-Password-Authentication - -## Philosophy - -Sorcery is a stripped-down, bare-bones authentication library, with which you -can write your own authentication flow. It was built with a few goals in mind: - -* Less is more - less than 20 public methods to remember for the entire - feature-set make the lib easy to 'get'. -* No built-in or generated code - use the library's methods inside *your - own* MVC structures, and don't fight to fix someone else's. -* Magic yes, Voodoo no - the lib should be easy to hack for most developers. -* Configuration over Confusion - Centralized (1 file), Simple & short - configuration as possible, not drowning in syntactic sugar. -* Keep MVC cleanly separated - DB is for models, sessions are for - controllers. Models stay unaware of sessions. - - -Hopefully, I've achieved this. If not, let me know. +- Less is more - less than 20 public methods to remember for the entire feature-set make the lib easy to 'get'. +- No built-in or generated code - use the library's methods inside *your own* MVC structures, and don't fight to fix someone else's. +- Magic yes, Voodoo no - the lib should be easy to hack for most developers. +- Configuration over Confusion - Centralized (1 file), Simple & short configuration as possible, not drowning in syntactic sugar. +- Keep MVC cleanly separated - DB is for models, sessions are for controllers. Models stay unaware of sessions. ## Useful Links -[Documentation](http://rubydoc.info/gems/sorcery) | -[Railscast](http://railscasts.com/episodes/283-authentication-with-sorcery) | [Simple tutorial](https://github.com/Sorcery/sorcery/wiki/Simple-Password-Authentication) | [Example Rails 4 app](https://github.com/Sorcery/sorcery-example-app) +- [Documentation](http://rubydoc.info/gems/sorcery) +- [Railscast](http://railscasts.com/episodes/283-authentication-with-sorcery) +- [Simple tutorial](https://github.com/Sorcery/sorcery/wiki/Simple-Password-Authentication) +- [Example Rails app](https://github.com/Sorcery/sorcery-example-app) + +Check out the tutorials in the [wiki](https://github.com/Sorcery/sorcery/wiki) for more: -Check out the tutorials in the [Wiki](https://github.com/Sorcery/sorcery/wiki) for more! +- [DataMapper Support](https://github.com/Sorcery/sorcery/wiki/DataMapper-Support) +- [DelayedJob Integration](https://github.com/Sorcery/sorcery/wiki/DelayedJob-Integration) +- [Simple Password Authentication](https://github.com/Sorcery/sorcery/wiki/Simple-Password-Authentication) +- [Single Table Inheritance Support](https://github.com/Sorcery/sorcery/wiki/Single-Table-Inheritance-Support) +- [Upgrading](https://github.com/Sorcery/sorcery/wiki/Upgrading) ## API Summary Below is a summary of the library methods. Most method names are self explaining and the rest are commented: - -### core +### Core ```ruby -require_login # this is a before action +require_login # This is a before action login(email, password, remember_me = false) -auto_login(user)# login without credentials +auto_login(user) # Login without credentials logout -logged_in? # available to view -current_user # available to view -redirect_back_or_to # used when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted. -@user.external? # external users, such as facebook/twitter etc. -@user.active_for_authentication? # add this method to define behaviour that will prevent selected users from signing in -@user.valid_password?('secret') # compares 'secret' with the actual @user's password, returns true if they match +logged_in? # Available in views +current_user # Available in views +redirect_back_or_to # Use when a user tries to access a page while logged out, is asked to login, and we want to return him back to the page he originally wanted +@user.external? # Users who signed up using Facebook, Twitter, etc. +@user.active_for_authentication? # Add this method to define behaviour that will prevent selected users from signing in +@user.valid_password?('secret') # Compares 'secret' with the actual user's password, returns true if they match User.authenticates_with_sorcery! ``` -### http basic auth +### HTTP Basic Auth ```ruby -require_login_from_http_basic # this is a before action +require_login_from_http_basic # This is a before action ``` -### external +### External ```ruby -login_at(provider) # sends the user to an external service (twitter etc.) to authenticate. -login_from(provider) # tries to login from the external provider's callback. -create_from(provider) # create the user in the local app db. +login_at(provider) # Sends the user to an external service (Facebook, Twitter, etc.) to authenticate +login_from(provider) # Tries to login from the external provider's callback +create_from(provider) # Create the user in the local app database ``` -### remember me +### Remember Me ```ruby -auto_login(user, should_remember=false) # login without credentials, optional remember_me +auto_login(user, should_remember = false) # Login without credentials, optional remember_me remember_me! forget_me! -force_forget_me! # completely forgets all sessions by clearing the token, even if remember_me_token_persist_globally is true +force_forget_me! # Forgets all sessions by clearing the token, even if remember_me_token_persist_globally is set to true ``` -### reset password +### Reset Password ```ruby User.load_from_reset_password_token(token) -@user.generate_reset_password_token! # if you want to send the email by youself -@user.deliver_reset_password_instructions! # generates the token and sends the email +@user.generate_reset_password_token! # Use if you want to send the email by yourself +@user.deliver_reset_password_instructions! # Generates the token and sends the email @user.change_password!(new_password) ``` -### user activation +### User Activation ```ruby User.load_from_activation_token(token) @@ -115,278 +101,124 @@ Please see the tutorials in the github wiki for detailed usage information. ## Installation -If using bundler, first add 'sorcery' to your Gemfile: +Add this line to your application's Gemfile: ```ruby -gem "sorcery" +gem 'sorcery' ``` -And run +And then execute: -```ruby -bundle install -``` + $ bundle -Otherwise simply +Or install it yourself as: -```ruby -gem install sorcery -``` + $ gem install sorcery -## Rails configuration +## Configuration -```bash -rails generate sorcery:install -``` +Run the following command to generate the core migration file, the initializer file and the +`User` model class. -This will generate the core migration file, the initializer file and the -'User' model class. + $ rails generate sorcery:install -```bash -rails generate sorcery:install remember_me reset_password -``` +Run the following command generate the migrations files for remember_me and reset_password submodules and will create the initializer file (and add submodules to it), and create the `User` model class. -This will generate the migrations files for remember_me and reset_password -submodules and will create the initializer file (and add submodules to it), -and create the 'User' model class. + $ rails generate sorcery:install remember_me reset_password -```bash -rails generate sorcery:install --model Person -``` +Run the following command to generate the core migration file, the initializer and change the model class (in the initializer and migration files) to the class `Person` (and its pluralized version, 'people') -This will generate the core migration file, the initializer and change the -model class (in the initializer and migration files) to the class 'Person' -(and its pluralized version, 'people') + $ rails generate sorcery:install --model Person -```bash -rails generate sorcery:install http_basic_auth external remember_me --only-submodules -``` +Run the following command to generate only the migration files for the specified submodules and will add them to the initializer file. -This will generate only the migration files for the specified submodules and -will add them to the initializer file. + $ rails generate sorcery:install http_basic_auth external remember_me --only-submodules Inside the initializer, the comments will tell you what each setting does. -## DelayedJob Integration - -By default emails are sent synchronously. You can send them asynchronously by -using the [delayed_job gem](https://github.com/collectiveidea/delayed_job). - -After implementing the `delayed_job` into your project add the code below at -the end of the `config/initializers/sorcery.rb` file. After that all emails -will be sent asynchronously. - -```ruby -module Sorcery - module Model - module InstanceMethods - def generic_send_email(method, mailer) - config = sorcery_config - mail = config.send(mailer).delay.send(config.send(method), self) - end - end - end -end -``` - -Sidekiq and Resque integrations are coming soon. - -## Single Table Inheritance (STI) Support +## Full Features List by Module -STI is supported via the `user.subclasses_inherit_config` setting in config/initializers/sorcery.rb. - -## Full Features List by module - -**Core** (see [lib/sorcery/model.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model.rb) and -[lib/sorcery/controller.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/controller.rb)): - -* login/logout, optional return user to requested url on login, configurable - redirect for non-logged-in users. -* password encryption, algorithms: bcrypt(default), md5, sha1, sha256, - sha512, aes256, custom(yours!), none. Configurable stretches and salt. -* configurable attribute names for username, password and email. -* allow multiple fields to serve as username. +**Core** (see [lib/sorcery/model.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model.rb) and [lib/sorcery/controller.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/controller.rb)): +- Login / logout, optional return user to requested url on login, configurable redirect for non-logged-in users. +- Password encryption, algorithms: bcrypt (default), MD5, SHA-1, SHA-256, SHA-512, AES or custom. Configurable stretches and salt. +- Configurable attribute names for username, password and email. +- Allow multiple fields to serve as username. **User Activation** (see [lib/sorcery/model/submodules/user_activation.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model/submodules/user_activation.rb)): -* User activation by email with optional success email. -* configurable attribute names. -* configurable mailer, method name, and attribute name. -* configurable temporary token expiration. -* Optionally prevent non-active users to login. - +- User activation by email with optional success email +- Configurable attribute names +- Configurable mailer, method name, and attribute name +- Configurable temporary token expiration +- Optionally prevent non-active users to login **Reset Password** (see [lib/sorcery/model/submodules/reset_password.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model/submodules/reset_password.rb)): -* Reset password with email verification. -* configurable mailer, method name, and attribute name. -* configurable temporary token expiration. -* configurable time between emails (hammering protection). - +- Reset password with email verification +- Configurable mailer, method name, and attribute name +- Configurable temporary token expiration +- Configurable time between emails (hammering protection) **Remember Me** (see [lib/sorcery/model/submodules/remember_me.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model/submodules/remember_me.rb)): -* Remember me with configurable expiration. -* configurable attribute names. -* configurable to persist globally (supporting multiple browsers at the same time), or starting anew after each login - +- Remember me with configurable expiration +- Configurable attribute names +- Configurable to persist globally (supporting multiple browsers at the same time), or starting anew after each login **Session Timeout** (see [lib/sorcery/controller/submodules/session_timeout.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/controller/submodules/session_timeout.rb)): -* Configurable session timeout. -* Optionally session timeout will be calculated from last user action. - +- Configurable session timeout +- Optionally session timeout will be calculated from last user action **Brute Force Protection** (see [lib/sorcery/model/submodules/brute_force_protection.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model/submodules/brute_force_protection.rb)): -* Brute force login hammering protection. -* configurable logins before lock and lock duration. - +- Brute force login hammering protection +- configurable logins before lock and lock duration **Basic HTTP Authentication** (see [lib/sorcery/controller/submodules/http_basic_auth.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/controller/submodules/http_basic_auth.rb)): -* A before action for requesting authentication with HTTP Basic. -* automatic login from HTTP Basic. -* automatic login is disabled if session key changed. - +- A before action for requesting authentication with HTTP Basic +- Automatic login from HTTP Basic +- Automatic login is disabled if session key changed **Activity Logging** (see [lib/sorcery/model/submodules/activity_logging.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/model/submodules/activity_logging.rb)): -* automatic logging of last login, last logout, last activity time and IP - address for last login. -* configurable timeout by which to decide whether to include a user in the - list of logged in users. - +- Automatic logging of last login, last logout, last activity time and IP address for last login +- Configurable timeout by which to decide whether to include a user in the list of logged in users **External** (see [lib/sorcery/controller/submodules/external.rb](https://github.com/Sorcery/sorcery/blob/master/lib/sorcery/controller/submodules/external.rb)): -* OAuth1 and OAuth2 support (currently: Twitter, Facebook, Github, Google, Heroku, - LinkedIn, VK, LiveID, Xing, and Salesforce) -* configurable db field names and authentications table. - - -## Next Planned Features - -I've got some thoughts which include (unordered): - -* Passing a block to encrypt, allowing the developer to define his own mix - of salting and encrypting -* Forgot username, maybe as part of the reset_password module -* Scoping logins (to a subdomain or another arbitrary field) -* Allowing storing the salt and crypted password in the same DB field for - extra security -* Other reset password strategies (security questions?) -* Other brute force protection strategies (captcha) - - -Have an idea? Let me know, and it might get into the gem! - -## Backward compatibility - -While the lib is young and evolving fast I'm breaking backward compatibility -quite often. I'm constantly finding better ways to do things and throwing away -old ways. To let you know when things are changing in a non-compatible way, -I'm bumping the minor version of the gem. The patch version changes are -backward compatible. - -In short, an app that works with x.3.1 should be able to upgrade to x.3.2 with -no code changes. The same cannot be said about upgrading to x.4.0 and above, -however. - -## DataMapper Support - -Important notes: - -* Expected to work with DM adapters: dm-mysql-adapter, - dm-redis-adapter. -* Submodules DM adapter dependent: activity_logging (dm-mysql-adapter) -* Usage: include DataMapper::Resource in user model, follow sorcery - instructions (remember to add property id, validators and accessor -attributes such as password and password_confirmation) -* Option downcase__username_before_authenticating and dm-mysql, - http://datamapper.lighthouseapp.com/projects/20609/tickets/1105-add-support-for-definingchanging-default-collation - -## Upgrading - -Important notes while upgrading: +- OAuth1 and OAuth2 support (currently: Twitter, Facebook, Github, Google, Heroku, LinkedIn, VK, LiveID, Xing, Salesforce) +- Configurable database column names +- Authentications table -* If you are upgrading from <= **1.0.0** +## Planned Features - * `before_logout` does not take arguments anymore (`current_user` still returns user at this point) - * `after_logout` takes one argument (`user`) as `current_user` returns `nil` then +- Passing a block to encrypt, allowing the developer to define his own mix of salting and encrypting +- Forgot username, maybe as part of the reset_password module +- Scoping logins (to a subdomain or another arbitrary field) +- Allowing storing the salt and encrypted password in the same DB field for extra security +- Other reset password strategies (security questions?) +- Other brute force protection strategies (captcha) -* If you are upgrading from <= **0.8.6** and you use Sorcery model methods in your app, - you might need to change them from `user.method` to `user.sorcery_adapter.method` and from - `User.method` to `User.sorcery_adapter_method` +Have an idea? Let us know, and it might get into the gem! -* If you are upgrading from <= **0.8.5** and you're using Sorcery test helpers, - you need to change the way you include them to following code: - - ```ruby - RSpec.configure do |config| - config.include Sorcery::TestHelpers::Rails::Controller, type: :controller - config.include Sorcery::TestHelpers::Rails::Integration, type: :feature - end - ``` - -* If are upgrading to **0.8.2** and use activity_logging feature with - ActiveRecord, you will have to add a new column - `last_login_from_ip_address` - [#465](https://github.com/NoamB/sorcery/issues/465) -* Sinatra support existed until **v0.7.0** (including), but was dropped - later due to being a maintenance nightmare. -* If upgrading from <= **0.6.1 to >= **0.7.0** you need to change - 'username - _attribute_name' to 'username_attribute_names' in initializer. -* If upgrading from <= **v0.5.1** to >= **v0.5.2** you need to explicitly - set your user_class model in the initializer file. - - ```ruby - # This line must come after the 'user config' block. - config.user_class = User - ``` - - -## Contributing to sorcery - -Your feedback is very welcome and will make this gem much much better for you, -me and everyone else. Besides feedback on code, features, suggestions and bug -reports, you may want to actually make an impact on the code. For this: - -* Fork it. -* Fix it. -* Test it. -* Commit it. -* Send me a pull request so I'll... Pull it. +## Contributing +Bug reports and pull requests are welcome on GitHub at https://github.com/Sorcery/sorcery. If you feel sorcery has made your life easier, and you would like to express -your thanks via a donation, my paypal email is in the contact details. +your thanks via a donation, my PayPal email is in the contact details. ## Contact Feel free to ask questions using these contact details: -#### Noam Ben-Ari - -email: nbenari@gmail.com ( also for paypal ) - -twitter: @nbenari - -#### Kir Shatrov - -email: shatrov@me.com - -twitter: @Kiiiir - -#### Grzegorz Witek - -email: arnvald.to@gmail.com - -twitter: @arnvald +- Noam Ben-Ari: [nbenari@gmail.com](mailto:nbenari@gmail.com) (also PayPal), [Twitter](https://twitter.com/nbenari) +- Kir Shatrov: [shatrov@me.com](mailto:shatrov@me.com), [Twitter](https://twitter.com/Kiiiir) +- Grzegorz Witek: [arnvald.to@gmail.com](mailto:arnvald.to@gmail.com), [Twitter](https://twitter.com/arnvald) -## Copyright +## License -Copyright (c) 2010-2014 Noam Ben Ari (nbenari@gmail.com). See LICENSE.txt for -further details. +The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). From d6e7c2f711c14946ecd379a5fc9a2c232ac61dc4 Mon Sep 17 00:00:00 2001 From: Cai Huanyu Date: Sun, 25 Dec 2016 22:19:41 +0800 Subject: [PATCH 40/46] Add Wechat provider (#27) --- CHANGELOG.md | 1 + .../sorcery/templates/initializer.rb | 4 + lib/sorcery/controller/submodules/external.rb | 1 + lib/sorcery/providers/wechat.rb | 79 ++++++++++++ spec/controllers/controller_oauth2_spec.rb | 119 ++++++++++-------- .../app/controllers/sorcery_controller.rb | 20 +++ spec/rails_app/config/routes.rb | 3 + 7 files changed, 172 insertions(+), 55 deletions(-) create mode 100644 lib/sorcery/providers/wechat.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 256eb954..f6f735ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ * Deprecated using `callback_filter` in favor of `callback_action` * Added null: false to migrations * Added support for Rails 5 by @kyuden +* Added WeChat provider to external submodule. ## 0.9.1 diff --git a/lib/generators/sorcery/templates/initializer.rb b/lib/generators/sorcery/templates/initializer.rb index cd7074f8..ab3ddf5e 100644 --- a/lib/generators/sorcery/templates/initializer.rb +++ b/lib/generators/sorcery/templates/initializer.rb @@ -121,6 +121,10 @@ # config.paypal.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=paypal" # config.paypal.user_info_mapping = {:email => "email"} # + # config.wechat.key = "" + # config.wechat.secret = "" + # config.wechat.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=wechat" + # # config.google.key = "" # config.google.secret = "" # config.google.callback_url = "http://0.0.0.0:3000/oauth/callback?provider=google" diff --git a/lib/sorcery/controller/submodules/external.rb b/lib/sorcery/controller/submodules/external.rb index 9907fab5..67ef1a27 100644 --- a/lib/sorcery/controller/submodules/external.rb +++ b/lib/sorcery/controller/submodules/external.rb @@ -21,6 +21,7 @@ def self.included(base) require 'sorcery/providers/salesforce' require 'sorcery/providers/paypal' require 'sorcery/providers/slack' + require 'sorcery/providers/wechat' Config.module_eval do class << self diff --git a/lib/sorcery/providers/wechat.rb b/lib/sorcery/providers/wechat.rb new file mode 100644 index 00000000..329246d0 --- /dev/null +++ b/lib/sorcery/providers/wechat.rb @@ -0,0 +1,79 @@ +module Sorcery + module Providers + # This class adds support for OAuth with open.wx.qq.com. + # + # config.wechat.key = + # config.wechat.secret = + # ... + # + class Wechat < Base + include Protocols::Oauth2 + + attr_reader :mode, :param_name, :parse + attr_accessor :auth_url, :scope, :token_url, :user_info_path + + def initialize + super + + @scope = 'snsapi_login' + @auth_url = 'https://open.weixin.qq.com/connect/qrconnect' + @user_info_path = 'https://api.weixin.qq.com/sns/userinfo' + @token_url = 'https://api.weixin.qq.com/sns/oauth2/access_token' + @state = SecureRandom.hex(16) + @mode = :body + @parse = :json + @param_name = 'access_token' + end + + def authorize_url(options = {}) + oauth_params = { + appid: @key, + redirect_uri: @callback_url, + response_type: 'code', + scope: scope, + state: @state + } + "#{options[:authorize_url]}?#{oauth_params.to_query}#wechat_redirect" + end + + def get_user_hash(access_token) + response = access_token.get(user_info_path, params: { + access_token: access_token.token, + openid: access_token.params['openid'], + }) + + {}.tap do |h| + h[:user_info] = JSON.parse(response.body) + h[:uid] = h[:user_info]['unionid'] + end + end + + def get_access_token(args, options = {}) + client = build_client(options) + client.auth_code.get_token( + args[:code], + { appid: @key, secret: @secret, parse: parse }, + options + ) + end + + def login_url(_params, _session) + authorize_url authorize_url: auth_url + end + + def process_callback(params, _session) + args = {}.tap do |a| + a[:code] = params[:code] if params[:code] + end + + get_access_token( + args, + token_url: token_url, + mode: mode, + param_name: param_name, + ) + end + end + end +end + diff --git a/spec/controllers/controller_oauth2_spec.rb b/spec/controllers/controller_oauth2_spec.rb index 513aaace..34f9044a 100644 --- a/spec/controllers/controller_oauth2_spec.rb +++ b/spec/controllers/controller_oauth2_spec.rb @@ -151,7 +151,7 @@ expect(flash[:notice]).to eq 'Success!' end - [:github, :google, :liveid, :vk, :salesforce, :paypal, :slack].each do |provider| + [:github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat].each do |provider| describe "with #{provider}" do it 'login_at redirects correctly' do get :"login_at_test_#{provider}" @@ -200,34 +200,37 @@ ActiveRecord::Migrator.migrate("#{Rails.root}/db/migrate/activation") end - sorcery_reload!([:user_activation, :external], user_activation_mailer: ::SorceryMailer) - sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack]) + sorcery_reload!([:user_activation,:external], :user_activation_mailer => ::SorceryMailer) + sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat]) # TODO: refactor - sorcery_controller_external_property_set(:facebook, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:facebook, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:github, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:github, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:github, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:google, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:google, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:google, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:liveid, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:liveid, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:liveid, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:vk, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:vk, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:vk, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:salesforce, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:salesforce, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:salesforce, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:paypal, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:paypal, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:paypal, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:slack, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:slack, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:slack, :callback_url, 'http://blabla.com') + sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:github, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:github, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:github, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:google, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:google, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:google, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:liveid, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:liveid, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:liveid, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:vk, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:vk, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:vk, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:salesforce, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:wechat, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:wechat, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:wechat, :callback_url, "http://blabla.com") end after(:all) do @@ -257,7 +260,7 @@ expect(ActionMailer::Base.deliveries.size).to eq old_size end - [:github, :google, :liveid, :vk, :salesforce, :paypal].each do |provider| + [:github, :google, :liveid, :vk, :salesforce, :paypal, :wechat].each do |provider| it "does not send activation email to external users (#{provider})" do old_size = ActionMailer::Base.deliveries.size create_new_external_user provider @@ -394,7 +397,9 @@ def stub_all_oauth2_requests! 'name' => 'Sonny Whether', 'id' => '123', 'email' => 'bobby@example.com' - } + }, + # response for wechat auth + 'unionid' => '123', }.to_json } allow(access_token).to receive(:get) { response } allow(access_token).to receive(:token) { '187041a618229fdaf16613e96e1caabc1e86e46bbfad228de41520e63fe45873684c365a14417289599f3' } @@ -404,31 +409,34 @@ def stub_all_oauth2_requests! end def set_external_property - sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack]) - sorcery_controller_external_property_set(:facebook, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:facebook, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:facebook, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:github, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:github, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:github, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:google, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:google, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:google, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:liveid, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:liveid, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:liveid, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:vk, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:vk, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:vk, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:salesforce, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:salesforce, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:salesforce, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:paypal, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:paypal, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:paypal, :callback_url, 'http://blabla.com') - sorcery_controller_external_property_set(:slack, :key, 'eYVNBjBDi33aa9GkA3w') - sorcery_controller_external_property_set(:slack, :secret, 'XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8') - sorcery_controller_external_property_set(:slack, :callback_url, 'http://blabla.com') + sorcery_controller_property_set(:external_providers, [:facebook, :github, :google, :liveid, :vk, :salesforce, :paypal, :slack, :wechat]) + sorcery_controller_external_property_set(:facebook, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:facebook, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:facebook, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:github, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:github, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:github, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:google, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:google, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:google, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:liveid, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:liveid, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:liveid, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:vk, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:vk, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:vk, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:salesforce, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:salesforce, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:salesforce, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:paypal, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:paypal, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:paypal, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:slack, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:slack, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:slack, :callback_url, "http://blabla.com") + sorcery_controller_external_property_set(:wechat, :key, "eYVNBjBDi33aa9GkA3w") + sorcery_controller_external_property_set(:wechat, :secret, "XpbeSdCoaKSmQGSeokz5qcUATClRW5u08QWNfv71N8") + sorcery_controller_external_property_set(:wechat, :callback_url, "http://blabla.com") end def provider_url(provider) @@ -439,7 +447,8 @@ def provider_url(provider) liveid: "https://oauth.live.com/authorize?client_id=#{::Sorcery::Controller::Config.liveid.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=wl.basic+wl.emails+wl.offline_access&state", vk: "https://oauth.vk.com/authorize?client_id=#{::Sorcery::Controller::Config.vk.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=#{::Sorcery::Controller::Config.vk.scope}&state", salesforce: "https://login.salesforce.com/services/oauth2/authorize?client_id=#{::Sorcery::Controller::Config.salesforce.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope#{'=' + ::Sorcery::Controller::Config.salesforce.scope unless ::Sorcery::Controller::Config.salesforce.scope.nil?}&state", - slack: "https://slack.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.slack.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=identity.basic%2C+identity.email&state" + slack: "https://slack.com/oauth/authorize?client_id=#{::Sorcery::Controller::Config.slack.key}&display&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=identity.basic%2C+identity.email&state", + wechat: "https://open.weixin.qq.com/connect/qrconnect?appid=#{::Sorcery::Controller::Config.wechat.key}&redirect_uri=http%3A%2F%2Fblabla.com&response_type=code&scope=snsapi_login&state=#wechat_redirect" }[provider] end end diff --git a/spec/rails_app/app/controllers/sorcery_controller.rb b/spec/rails_app/app/controllers/sorcery_controller.rb index 37e5c88a..6416cb0d 100644 --- a/spec/rails_app/app/controllers/sorcery_controller.rb +++ b/spec/rails_app/app/controllers/sorcery_controller.rb @@ -100,6 +100,10 @@ def login_at_test_paypal login_at(:paypal) end + def login_at_test_wechat + login_at(:wechat) + end + def login_at_test_google login_at(:google) end @@ -162,6 +166,14 @@ def test_login_from_paypal end end + def test_login_from_wechat + if @user = login_from(:wechat) + redirect_to 'bla', notice: 'Success!' + else + redirect_to 'blu', alert: 'Failed!' + end + end + def test_login_from_google if @user = login_from(:google) redirect_to 'bla', notice: 'Success!' @@ -252,6 +264,14 @@ def test_return_to_with_external_paypal end end + def test_return_to_with_external_wechat + if @user = login_from(:wechat) + redirect_back_or_to 'bla', notice: 'Success!' + else + redirect_to 'blu', alert: 'Failed!' + end + end + def test_return_to_with_external_google if @user = login_from(:google) redirect_back_or_to 'bla', notice: 'Success!' diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index 3ca08ef4..e66ef752 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -21,6 +21,7 @@ get :test_login_from_facebook get :test_login_from_github get :test_login_from_paypal + get :test_login_from_wechat get :test_login_from_google get :test_login_from_liveid get :test_login_from_vk @@ -32,6 +33,7 @@ get :login_at_test_facebook get :login_at_test_github get :login_at_test_paypal + get :login_at_test_wechat get :login_at_test_google get :login_at_test_liveid get :login_at_test_vk @@ -43,6 +45,7 @@ get :test_return_to_with_external_facebook get :test_return_to_with_external_github get :test_return_to_with_external_paypal + get :test_return_to_with_external_wechat get :test_return_to_with_external_google get :test_return_to_with_external_liveid get :test_return_to_with_external_vk From 87364c44b344b62f752637ee8b3ec9ab5327feb3 Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 25 Dec 2016 14:50:37 +0900 Subject: [PATCH 41/46] Remove unnecessary dependency for development --- sorcery.gemspec | 1 - 1 file changed, 1 deletion(-) diff --git a/sorcery.gemspec b/sorcery.gemspec index 6687ca8f..cdc2f73f 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -24,7 +24,6 @@ Gem::Specification.new do |s| s.add_dependency 'oauth2', '>= 0.8.0' s.add_dependency 'bcrypt', '~> 3.1' - s.add_development_dependency 'abstract', '>= 1.0.0' s.add_development_dependency 'json', '>= 1.7.7' s.add_development_dependency 'yard', '~> 0.6.0' From 1e336488b002bec9934b26fbd32589e74df1cbbb Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 25 Dec 2016 20:42:16 +0900 Subject: [PATCH 42/46] Drop json dependency for development needed on ruby 1.8 --- sorcery.gemspec | 2 -- 1 file changed, 2 deletions(-) diff --git a/sorcery.gemspec b/sorcery.gemspec index cdc2f73f..3a68452e 100644 --- a/sorcery.gemspec +++ b/sorcery.gemspec @@ -24,9 +24,7 @@ Gem::Specification.new do |s| s.add_dependency 'oauth2', '>= 0.8.0' s.add_dependency 'bcrypt', '~> 3.1' - s.add_development_dependency 'json', '>= 1.7.7' s.add_development_dependency 'yard', '~> 0.6.0' - s.add_development_dependency 'timecop' s.add_development_dependency 'simplecov', '>= 0.3.8' s.add_development_dependency 'rspec-rails', '~> 3.5.0' From 7e16f978fb1a76243766af2bc2861b322a3eac2d Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 25 Dec 2016 20:48:09 +0900 Subject: [PATCH 43/46] Fix warning of deprecated constant. sorcery/lib/sorcery/crypto_providers/aes256.rb:46: warning: constant OpenSSL::Cipher::Cipher is deprecated --- lib/sorcery/crypto_providers/aes256.rb | 2 +- spec/sorcery_crypto_providers_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/sorcery/crypto_providers/aes256.rb b/lib/sorcery/crypto_providers/aes256.rb index c11c8d04..616f0f92 100644 --- a/lib/sorcery/crypto_providers/aes256.rb +++ b/lib/sorcery/crypto_providers/aes256.rb @@ -43,7 +43,7 @@ def decrypt(crypted) def aes raise ArgumentError, "#{name} expects a 32 bytes long key. Please use Sorcery::Model::Config.encryption_key to set it." if @key.nil? || @key == '' - @aes ||= OpenSSL::Cipher::Cipher.new('AES-256-ECB') + @aes ||= OpenSSL::Cipher.new('AES-256-ECB') end end end diff --git a/spec/sorcery_crypto_providers_spec.rb b/spec/sorcery_crypto_providers_spec.rb index 7194dea9..604018fb 100644 --- a/spec/sorcery_crypto_providers_spec.rb +++ b/spec/sorcery_crypto_providers_spec.rb @@ -115,7 +115,7 @@ describe Sorcery::CryptoProviders::AES256 do before(:all) do - aes = OpenSSL::Cipher::Cipher.new('AES-256-ECB') + aes = OpenSSL::Cipher.new('AES-256-ECB') aes.encrypt @key = 'asd234dfs423fddsmndsflktsdf32343' aes.key = @key @@ -137,7 +137,7 @@ end it 'can be decrypted' do - aes = OpenSSL::Cipher::Cipher.new('AES-256-ECB') + aes = OpenSSL::Cipher.new('AES-256-ECB') aes.decrypt aes.key = @key expect(aes.update(@digest.unpack('m').first) + aes.final).to eq 'Noam Ben-Ari' From 8a9a50c458967548ee419f050d346426b1d17631 Mon Sep 17 00:00:00 2001 From: kyuden Date: Sun, 25 Dec 2016 20:52:33 +0900 Subject: [PATCH 44/46] Test against ruby 2.4.0 --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index ca6f782d..0d3b9b83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ rvm: - 2.1.10 - 2.2.6 - 2.3.3 + - 2.4.0 env: global: @@ -43,5 +44,14 @@ matrix: - rvm: 2.3.3 gemfile: gemfiles/active_record-rails40.gemfile + - rvm: 2.4.0 + gemfile: gemfiles/active_record-rails40.gemfile + + - rvm: 2.4.0 + gemfile: gemfiles/active_record-rails41.gemfile + + - rvm: 2.4.0 + gemfile: gemfiles/active_record-rails42.gemfile + - rvm: jruby gemfile: Gemfile From 4e4c1ca1c7ec7222f37233eeb7d5b5ff13a61939 Mon Sep 17 00:00:00 2001 From: kyuden Date: Wed, 28 Dec 2016 14:29:24 +0900 Subject: [PATCH 45/46] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6f735ae..357ec47a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Added null: false to migrations * Added support for Rails 5 by @kyuden * Added WeChat provider to external submodule. +* Added support for Ruby 2.4 by @kyuden ## 0.9.1 From 6ccbec9d649a063562577080fc0aab404c89d93d Mon Sep 17 00:00:00 2001 From: Masahiro Kyuden Date: Fri, 30 Dec 2016 02:35:58 +0900 Subject: [PATCH 46/46] Namespace login locking methods (#31) * Rename #lock! to #login_lock! * Rename #unlock! to #login_unlock! * Rename #locked? to #login_locked? * Rename #unlocked? to #login_unlocked? * Fix spec * Update CHANGELOG.md * Change CHANGELOG.md wording --- CHANGELOG.md | 1 + .../submodules/brute_force_protection.rb | 22 +++++++++---------- ..._brute_force_protection_shared_examples.rb | 10 ++++----- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 357ec47a..0a44a0ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Added support for Rails 5 by @kyuden * Added WeChat provider to external submodule. * Added support for Ruby 2.4 by @kyuden +* Namespace login lock/unlock methods to fix conflicts with Rails lock/unlock (thanks to @kyuden) ## 0.9.1 diff --git a/lib/sorcery/model/submodules/brute_force_protection.rb b/lib/sorcery/model/submodules/brute_force_protection.rb index 50925066..3830d0eb 100644 --- a/lib/sorcery/model/submodules/brute_force_protection.rb +++ b/lib/sorcery/model/submodules/brute_force_protection.rb @@ -58,22 +58,22 @@ def define_brute_force_protection_fields module InstanceMethods # Called by the controller to increment the failed logins counter. - # Calls 'lock!' if login retries limit was reached. + # Calls 'login_lock!' if login retries limit was reached. def register_failed_login! config = sorcery_config - return unless unlocked? + return unless login_unlocked? sorcery_adapter.increment(config.failed_logins_count_attribute_name) if send(config.failed_logins_count_attribute_name) >= config.consecutive_login_retries_amount_limit - lock! + login_lock! end end # /!\ # Moved out of protected for use like activate! in controller # /!\ - def unlock! + def login_unlock! config = sorcery_config attributes = { config.lock_expires_at_attribute_name => nil, config.failed_logins_count_attribute_name => 0, @@ -81,13 +81,13 @@ def unlock! sorcery_adapter.update_attributes(attributes) end - def locked? - !unlocked? + def login_locked? + !login_unlocked? end protected - def lock! + def login_lock! config = sorcery_config attributes = { config.lock_expires_at_attribute_name => Time.now.in_time_zone + config.login_lock_time_period, config.unlock_token_attribute_name => TemporaryToken.generate_random_token } @@ -98,7 +98,7 @@ def lock! end end - def unlocked? + def login_unlocked? config = sorcery_config send(config.lock_expires_at_attribute_name).nil? end @@ -113,10 +113,10 @@ def send_unlock_token_email! # Runs as a hook before authenticate. def prevent_locked_user_login config = sorcery_config - if !unlocked? && config.login_lock_time_period != 0 - unlock! if send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone + if !login_unlocked? && config.login_lock_time_period != 0 + login_unlock! if send(config.lock_expires_at_attribute_name) <= Time.now.in_time_zone end - unlocked? + login_unlocked? end end end diff --git a/spec/shared_examples/user_brute_force_protection_shared_examples.rb b/spec/shared_examples/user_brute_force_protection_shared_examples.rb index b267dcc2..2cf15a6e 100644 --- a/spec/shared_examples/user_brute_force_protection_shared_examples.rb +++ b/spec/shared_examples/user_brute_force_protection_shared_examples.rb @@ -38,15 +38,15 @@ expect(config.login_lock_time_period).to eq 2.hours end - describe '#locked?' do + describe '#login_locked?' do it 'is locked' do user.send("#{config.lock_expires_at_attribute_name}=", Time.now + 5.days) - expect(user).to be_locked + expect(user).to be_login_locked end it "isn't locked" do user.send("#{config.lock_expires_at_attribute_name}=", nil) - expect(user).not_to be_locked + expect(user).not_to be_login_locked end end end @@ -130,7 +130,7 @@ end end - describe '#unlock!' do + describe '#login_unlock!' do it 'unlocks after entering unlock token' do sorcery_model_property_set(:consecutive_login_retries_amount_limit, 2) sorcery_model_property_set(:login_lock_time_period, 0) @@ -144,7 +144,7 @@ expect(user).not_to be_nil - user.unlock! + user.login_unlock! expect(User.load_from_unlock_token(user.unlock_token)).to be_nil end end