Class: Vert::Rls::ConnectionHandler

Inherits:
Object
  • Object
show all
Defined in:
lib/vert/rls/connection_handler.rb

Class Method Summary collapse

Class Method Details

.create_functions_sqlObject



40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/vert/rls/connection_handler.rb', line 40

def create_functions_sql
  <<~SQL
    CREATE OR REPLACE FUNCTION current_tenant_id() RETURNS uuid AS $$
      SELECT NULLIF(current_setting('app.current_tenant_id', true), '')::uuid;
    $$ LANGUAGE SQL STABLE;
    CREATE OR REPLACE FUNCTION current_company_id() RETURNS uuid AS $$
      SELECT NULLIF(current_setting('app.current_company_id', true), '')::uuid;
    $$ LANGUAGE SQL STABLE;
    CREATE OR REPLACE FUNCTION current_user_id() RETURNS uuid AS $$
      SELECT NULLIF(current_setting('app.current_user_id', true), '')::uuid;
    $$ LANGUAGE SQL STABLE;
  SQL
end

.reset_contextObject



19
20
21
22
23
24
25
26
27
28
# File 'lib/vert/rls/connection_handler.rb', line 19

def reset_context
  return unless Vert::Current.rls_configured
  connection = ActiveRecord::Base.connection
  connection.execute("RESET app.current_tenant_id")
  connection.execute("RESET app.current_company_id")
  connection.execute("RESET app.current_user_id")
  Vert::Current.rls_configured = false
rescue StandardError => e
  Rails.logger.error("[Vert::RLS] #{e.message}") if defined?(Rails)
end

.set_context(tenant_id:, company_id: nil, user_id: nil) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
# File 'lib/vert/rls/connection_handler.rb', line 7

def set_context(tenant_id:, company_id: nil, user_id: nil)
  return unless tenant_id.present?
  connection = ActiveRecord::Base.connection
  connection.execute("SET app.current_tenant_id = #{connection.quote(tenant_id.to_s)}")
  connection.execute("SET app.current_company_id = #{connection.quote(company_id.to_s)}") if company_id.present?
  connection.execute("SET app.current_user_id = #{connection.quote(user_id.to_s)}") if user_id.present?
  Vert::Current.rls_configured = true
rescue StandardError => e
  Rails.logger.error("[Vert::RLS] #{e.message}") if defined?(Rails)
  raise
end

.with_context(tenant_id:, company_id: nil, user_id: nil) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/vert/rls/connection_handler.rb', line 30

def with_context(tenant_id:, company_id: nil, user_id: nil)
  previous = Vert::Current.serialize
  set_context(tenant_id: tenant_id, company_id: company_id, user_id: user_id)
  Vert::Current.set_context(tenant_id: tenant_id, company_id: company_id, user_id: user_id)
  yield
ensure
  reset_context
  Vert::Current.deserialize(previous)
end