diff --git a/lib/milia.rb b/lib/milia.rb index 59239ee..25dd091 100644 --- a/lib/milia.rb +++ b/lib/milia.rb @@ -3,6 +3,7 @@ require File.dirname(__FILE__) + '/milia/control' require File.dirname(__FILE__) + '/milia/password_generator' require File.dirname(__FILE__) + '/milia/invite_member' +require File.dirname(__FILE__) + '/milia/support' require File.dirname(__FILE__) + '/milia/railtie' if defined?(Rails::Railtie) diff --git a/lib/milia/base.rb b/lib/milia/base.rb index 5755013..7b7a75d 100644 --- a/lib/milia/base.rb +++ b/lib/milia/base.rb @@ -77,9 +77,7 @@ def acts_as_universal_and_determines_account() # validate that a tenant exists prior to a user creation before_create do |new_user| - if Thread.current[:tenant_id].blank? || - !Thread.current[:tenant_id].kind_of?(Integer) || - Thread.current[:tenant_id].zero? + unless Milia::Support::valid_tenant_id?(Thread.current[:tenant_id]) raise ::Milia::Control::InvalidTenantAccess, "no existing valid current tenant" @@ -90,7 +88,7 @@ def acts_as_universal_and_determines_account() after_create do |new_user| tenant = Tenant.find(Thread.current[:tenant_id]) unless tenant.users.include?(new_user) - new_user.skip_reconfirmation! # For details why this is needed see milia issue #68 + new_user.skip_reconfirmation! # For details why this is needed see milia issue #68 tenant.users << new_user # add user to this tenant if not already there end end # before_create do @@ -153,6 +151,8 @@ def set_current_tenant(tenant) tenant_id = tenant.id when Integer then tenant_id = tenant + when String then + tenant_id = tenant else raise ArgumentError, "invalid tenant object or id" end # case @@ -175,7 +175,9 @@ def set_current_tenant(tenant) # for each of the subordinate models in the join seems like a nice safety issue. # ------------------------------------------------------------------------ def where_restrict_tenant(*args) - args.map { |klass| "#{klass.table_name}.tenant_id = #{Thread.current[:tenant_id]}" }.join(" AND ") + tenant_id = Thread.current[:tenant_id] + clause = args.map { |klass| "#{klass.table_name}.tenant_id = ?" }.join(" AND ") + clause.gsub('?', (tenant_id.kind_of?(String) ? "'#{tenant_id}'" : tenant_id.to_s)) end # ------------------------------------------------------------------------ diff --git a/lib/milia/support.rb b/lib/milia/support.rb new file mode 100644 index 0000000..9cfef28 --- /dev/null +++ b/lib/milia/support.rb @@ -0,0 +1,14 @@ +module Milia + module Support + + # Validate the content and type of the given tenant_id. Currently + # Integers and Strings (UUID) are supported. + def self.valid_tenant_id?(tenant_id) + return false if tenant_id.blank? + return false if tenant_id.kind_of?(Integer) && tenant_id.zero? + return false if !(tenant_id.kind_of?(Integer) || tenant_id.kind_of?(String)) + true + end + + end +end diff --git a/test/Gemfile.lock b/test/Gemfile.lock index a492ba0..fac55f6 100644 --- a/test/Gemfile.lock +++ b/test/Gemfile.lock @@ -71,7 +71,7 @@ GIT thor (>= 0.18.1, < 2.0) PATH - remote: ../../milia + remote: .. specs: milia (1.3.1) devise (~> 4.2) @@ -240,4 +240,4 @@ RUBY VERSION ruby 2.3.1p112 BUNDLED WITH - 1.13.7 + 1.15.1 diff --git a/test/test/fixtures/tenants.yml b/test/test/fixtures/tenants.yml index 7a0c5a5..9dd0eeb 100644 --- a/test/test/fixtures/tenants.yml +++ b/test/test/fixtures/tenants.yml @@ -10,3 +10,7 @@ tenant_3: id: 3 name: tenant_3 +tenant_4: + id: 'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA' + name: tenant_4 + diff --git a/test/test/models/tenant_test.rb b/test/test/models/tenant_test.rb index 39f1756..bd5872e 100644 --- a/test/test/models/tenant_test.rb +++ b/test/test/models/tenant_test.rb @@ -134,19 +134,32 @@ class TenantTest < ActiveSupport::TestCase assert_equal tenants( :tenant_3 ).id, Tenant.current_tenant_id end # should do + should 'set current tenant - tenant id as string' do + assert_equal tenants( :tenant_1 ).id, Tenant.current_tenant_id + Tenant.set_current_tenant( 'AA-AA-AA-AA' ) + assert_equal 'AA-AA-AA-AA', Tenant.current_tenant_id + end # should do + should 'NOT set current tenant - invalid arg' do assert_equal tenants( :tenant_1 ).id, Tenant.current_tenant_id assert_raise(ArgumentError) { - Tenant.set_current_tenant( '2' ) + Tenant.set_current_tenant( 2.2 ) } assert_equal tenants( :tenant_1 ).id, Tenant.current_tenant_id end # should do RESTRICT_SNIPPET = 'posts.tenant_id = 1 AND zines.tenant_id = 1' should 'prepare a restrict tenant snippet' do + Tenant.set_current_tenant( tenants( :tenant_1 ).id ) assert_equal RESTRICT_SNIPPET, Tenant.where_restrict_tenant( Post, Zine ) end # should do +RESTRICT_STRING_SNIPPET = "posts.tenant_id = 'AA-AA-AA-AA' AND zines.tenant_id = 'AA-AA-AA-AA'" + should 'prepare a restrict tenant snippet with strings' do + Tenant.set_current_tenant( 'AA-AA-AA-AA' ) + assert_equal RESTRICT_STRING_SNIPPET, Tenant.where_restrict_tenant( Post, Zine ) + end # should do + should 'clear tenant.users when tenant destroyed' do target = tenants(:tenant_2) Tenant.set_current_tenant( target ) diff --git a/test/test/models/user_test.rb b/test/test/models/user_test.rb index effcdd9..8e47516 100644 --- a/test/test/models/user_test.rb +++ b/test/test/models/user_test.rb @@ -102,7 +102,7 @@ class UserTest < ActiveSupport::TestCase should 'NOT create new user when invalid current tenant - string' do # force the current_tenant to be unexpected object - Thread.current[:tenant_id] = 'peanut clusters' + Thread.current[:tenant_id] = 2.2 assert_no_difference("User.count") do assert_raise(::Milia::Control::InvalidTenantAccess,