Merge pull request #1009 from Freika/feature/active_until

Feature/active until
This commit is contained in:
Evgenii Burmakin 2025-04-04 21:21:03 +02:00 committed by GitHub
commit a678c3ba79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 56 additions and 21 deletions

View file

@ -13,7 +13,7 @@ class ApiController < ApplicationController
end
def authenticate_active_api_user!
render json: { error: 'User is not active' }, status: :unauthorized unless current_api_user&.active?
render json: { error: 'User is not active' }, status: :unauthorized unless current_api_user&.active_until&.future?
true
end

View file

@ -26,7 +26,7 @@ class ApplicationController < ActionController::Base
end
def authenticate_active_user!
return if current_user&.active?
return if current_user&.active_until&.future?
redirect_to root_path, notice: 'Your account is not active.', status: :see_other
end

View file

@ -109,7 +109,8 @@ class User < ApplicationRecord
end
def activate
update(status: :active)
# TODO: Remove the `status` column in the future.
update(status: :active, active_until: 1000.years.from_now)
end
def sanitize_input

View file

@ -0,0 +1,19 @@
# frozen_string_literal: true
class SetActiveUntilForSelfhostedUsers < ActiveRecord::Migration[8.0]
def up
return unless DawarichSettings.self_hosted?
# rubocop:disable Rails/SkipsModelValidations
User.where(active_until: nil).update_all(active_until: 1000.years.from_now)
# rubocop:enable Rails/SkipsModelValidations
end
def down
return unless DawarichSettings.self_hosted?
# rubocop:disable Rails/SkipsModelValidations
User.where.not(active_until: nil).update_all(active_until: nil)
# rubocop:enable Rails/SkipsModelValidations
end
end

View file

@ -1 +1 @@
DataMigrate::Data.define(version: 20250403204658)
DataMigrate::Data.define(version: 20250404182629)

View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
class AddActiveUntilToUsers < ActiveRecord::Migration[8.0]
def change
add_column :users, :active_until, :datetime
end
end

3
db/schema.rb generated
View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_03_24_180755) do
ActiveRecord::Schema[8.0].define(version: 2025_04_04_182437) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"
enable_extension "postgis"
@ -230,6 +230,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_03_24_180755) do
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.integer "status", default: 0
t.datetime "active_until"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

View file

@ -7,6 +7,7 @@ FactoryBot.define do
end
status { :active }
active_until { 1000.years.from_now }
password { SecureRandom.hex(8) }
@ -25,6 +26,11 @@ FactoryBot.define do
admin { true }
end
trait :inactive do
status { :inactive }
active_until { 1.day.ago }
end
trait :with_immich_integration do
settings do
{

View file

@ -31,7 +31,7 @@ RSpec.describe User, type: :model do
describe '#activate' do
context 'when self-hosted' do
let!(:user) { create(:user, status: :inactive) }
let!(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
before do
allow(DawarichSettings).to receive(:self_hosted?).and_return(true)
@ -39,19 +39,20 @@ RSpec.describe User, type: :model do
it 'activates user after creation' do
expect(user.active?).to be_truthy
expect(user.active_until).to be_within(1.minute).of(1000.years.from_now)
end
end
context 'when not self-hosted' do
let!(:user) { create(:user, status: :inactive) }
before do
stub_const('SELF_HOSTED', false)
allow(DawarichSettings).to receive(:self_hosted?).and_return(false)
end
xit 'does not activate user' do
it 'does not activate user' do
user = create(:user, status: :inactive, active_until: 1.day.ago)
expect(user.active?).to be_falsey
expect(user.active_until).to be_within(1.minute).of(1.day.ago)
end
end
end

View file

@ -34,7 +34,7 @@ RSpec.describe 'Api::V1::Overland::Batches', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns http unauthorized' do

View file

@ -34,7 +34,7 @@ RSpec.describe 'Api::V1::Owntracks::Points', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns http unauthorized' do

View file

@ -129,7 +129,7 @@ RSpec.describe 'Api::V1::Points', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns an unauthorized response' do
@ -150,7 +150,7 @@ RSpec.describe 'Api::V1::Points', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns an unauthorized response' do
@ -171,7 +171,7 @@ RSpec.describe 'Api::V1::Points', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns an unauthorized response' do

View file

@ -28,7 +28,7 @@ RSpec.describe 'Api::V1::Settings', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns http unauthorized' do

View file

@ -85,7 +85,7 @@ RSpec.describe 'Settings', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'redirects to the root path' do

View file

@ -72,7 +72,7 @@ RSpec.describe '/stats', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns an unauthorized response' do
@ -99,7 +99,7 @@ RSpec.describe '/stats', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'returns an unauthorized response' do

View file

@ -56,7 +56,7 @@ RSpec.describe '/trips', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'redirects to the root path' do
@ -93,7 +93,7 @@ RSpec.describe '/trips', type: :request do
context 'when user is inactive' do
before do
user.update(status: :inactive)
user.update(status: :inactive, active_until: 1.day.ago)
end
it 'redirects to the root path' do