diff --git a/Gemfile b/Gemfile index 5e99577d4d9bec774bf74cd5cbfe0fabe8f0f78c..e4614cfd7db769d707666cf9129b0f8ead261ebf 100644 --- a/Gemfile +++ b/Gemfile @@ -25,7 +25,6 @@ gem "json-schema", "2.7.0" gem "devise", "4.2.0" gem "devise_lastseenable", "0.0.6" -gem "devise-token_authenticatable", "0.5.2" # Captcha diff --git a/Gemfile.lock b/Gemfile.lock index 0196e5d41e26fb499198924a2c4c42334950967b..73f20f63eeb5df72a748a9091659e09dd872591f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -171,8 +171,6 @@ GEM railties (>= 4.1.0, < 5.1) responders warden (~> 1.2.3) - devise-token_authenticatable (0.5.2) - devise (>= 4.0.0, < 4.3.0) devise_lastseenable (0.0.6) devise rails (>= 3.0.4) @@ -931,7 +929,6 @@ DEPENDENCIES cucumber-rails (= 1.4.5) database_cleaner (= 1.5.3) devise (= 4.2.0) - devise-token_authenticatable (= 0.5.2) devise_lastseenable (= 0.0.6) diaspora-prosody-config (= 0.0.7) diaspora_federation-rails (= 0.1.5) diff --git a/app/models/user.rb b/app/models/user.rb index 77cdd8d21e9cad4943424a38c549932a8a4e3e1d..e8a09a322db9049c22cf689182f1314de689e94f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,6 +3,7 @@ # the COPYRIGHT file. class User < ActiveRecord::Base + include AuthenticationToken include Connecting include Querying include SocialActions @@ -16,7 +17,7 @@ class User < ActiveRecord::Base scope :halfyear_actives, ->(time = Time.now) { logged_in_since(time - 6.month) } scope :active, -> { joins(:person).where(people: {closed_account: false}) } - devise :token_authenticatable, :database_authenticatable, :registerable, + devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :lockable, :lastseenable, :lock_strategy => :none, :unlock_strategy => :none diff --git a/app/models/user/authentication_token.rb b/app/models/user/authentication_token.rb new file mode 100644 index 0000000000000000000000000000000000000000..ca72950b44f4ac999268010564dfb698ee4cbccf --- /dev/null +++ b/app/models/user/authentication_token.rb @@ -0,0 +1,26 @@ +class User + module AuthenticationToken + extend ActiveSupport::Concern + + # Generate new authentication token and save the record. + def reset_authentication_token! + self.authentication_token = self.class.authentication_token + save(validate: false) + end + + # Generate authentication token unless already exists and save the record. + def ensure_authentication_token! + reset_authentication_token! if authentication_token.blank? + end + + module ClassMethods + # Generate a token checking if one does not already exist in the database. + def authentication_token + loop do + token = Devise.friendly_token(30) + break token unless User.exists?(authentication_token: token) + end + end + end + end +end diff --git a/spec/models/user/authentication_token_spec.rb b/spec/models/user/authentication_token_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..b4b4c2304028324898c90b598c736c7330cfffb0 --- /dev/null +++ b/spec/models/user/authentication_token_spec.rb @@ -0,0 +1,42 @@ +require "spec_helper" + +describe User::AuthenticationToken, type: :model do + describe "#reset_authentication_token!" do + it "sets the authentication token" do + expect(alice.authentication_token).to be_nil + alice.reset_authentication_token! + expect(alice.authentication_token).not_to be_nil + end + + it "resets the authentication token" do + alice.reset_authentication_token! + expect { alice.reset_authentication_token! }.to change { alice.authentication_token } + end + end + + describe "#ensure_authentication_token!" do + it "doesn't change the authentication token" do + alice.reset_authentication_token! + expect { alice.ensure_authentication_token! }.to_not change { alice.authentication_token } + end + + it "sets the authentication token if not yet set" do + expect(alice.authentication_token).to be_nil + alice.ensure_authentication_token! + expect(alice.authentication_token).not_to be_nil + end + end + + describe ".authentication_token" do + it "generates an authentication token" do + expect(User.authentication_token.length).to eq(30) + end + + it "checks that the authentication token is not yet in use by another user" do + alice.reset_authentication_token! + expect(Devise).to receive(:friendly_token).with(30).and_return(alice.authentication_token, "some_unused_token") + + expect(User.authentication_token).to eq("some_unused_token") + end + end +end