Module: Omen::Attributes

Defined in:
lib/omen/attributes.rb

Overview

What a Postgres role may and may not be. A role is created with every dangerous attribute already off, so this gem sets only what whoever created it may set, and reads the rest back rather than asserting them: saying NOSUPERUSER needs the SUPERUSER attribute, so a managed database refuses the very statement that would have made the role safe.

Constant Summary collapse

SETTABLE =

Set on the role, because whoever may create a role may set these.

'NOCREATEDB NOCREATEROLE'
DANGEROUS =

Read back instead, since saying no to one of these needs the attribute itself.

{ rolsuper: 'SUPERUSER', rolbypassrls: 'BYPASSRLS',
rolreplication: 'REPLICATION', }

Class Method Summary collapse

Class Method Details

.dangerous(connection, name) ⇒ Array<String>

Returns what the role holds that no read-only request should reach.

Parameters:

  • connection (ActiveRecord::ConnectionAdapters::AbstractAdapter) —

    a writing one.

  • name (String) —

    the role to ask about.

Returns:

  • (Array<String>) —

    what the role holds that no read-only request should reach.



37
38
39
40
# File 'lib/omen/attributes.rb', line 37

def self.dangerous(connection, name)
  row = held(connection, name) || {}
  DANGEROUS.filter_map { |column, attribute| attribute if row[column.to_s] }
end

.exists?(connection, name) ⇒ Boolean

Returns whether the role is there at all to be granted anything.

Parameters:

  • connection (ActiveRecord::ConnectionAdapters::AbstractAdapter) —

    a writing one.

  • name (String) —

    the role to ask about.

Returns:

  • (Boolean) —

    whether the role is there at all to be granted anything.



21
# File 'lib/omen/attributes.rb', line 21

def self.exists?(connection, name) = held(connection, name).present?

.held(connection, name) ⇒ Hash?

Nil where there is no such role, so that an empty list and a missing role read apart.

Parameters:

  • connection (ActiveRecord::ConnectionAdapters::AbstractAdapter) —

    a writing one.

  • name (String) —

    the role to ask about.

Returns:

  • (Hash, nil) —

    the row of what the role is, or nothing where the role is not.



27
28
29
30
31
32
# File 'lib/omen/attributes.rb', line 27

def self.held(connection, name)
  connection.select_one <<~SQL.squish
    SELECT #{DANGEROUS.keys.join ', '} FROM pg_roles
    WHERE rolname = #{connection.quote name}
  SQL
end

.settable(login: false) ⇒ String

Returns what an ALTER ROLE may assert against any database, managed or not.

Parameters:

  • login (Boolean) (defaults to: false) —

    whether anything connects as the role.

Returns:

  • (String) —

    what an ALTER ROLE may assert against any database, managed or not.



16
# File 'lib/omen/attributes.rb', line 16

def self.settable(login: false) = "#{ ? 'LOGIN' : 'NOLOGIN'} #{SETTABLE}"