Module: RaiseIfRoot

Defined in:
lib/raise-if-root/library.rb,
lib/raise-if-root/version.rb

Defined Under Namespace

Classes: AssertionFailed

Constant Summary collapse

VERSION =

version string

'0.0.1'.freeze

Class Method Summary collapse

Class Method Details

.add_assertion_callback(&block) ⇒ Object

Add a callback to the list of assertion callbacks that are executed when an assertion fails. The callback will be passed one argument: the AssertionFailed exception object just before it is raised.

Raises:

  • (ArgumentError)

145
146
147
148
149
# File 'lib/raise-if-root/library.rb', line 145

def self.add_assertion_callback(&block)
  raise ArgumentError.new("Must pass block") unless block

  assertion_callbacks << block
end

.assert_equal(label, actual, expected) ⇒ Object

Assert that two values are equal. If they are not, run assertion callbacks and raise AssertionFailed.

Parameters:

  • label (String)

    The label for the comparison we're making

  • actual

    The actual value

  • expected

    The expected value

Raises:


96
97
98
99
100
101
102
103
104
105
# File 'lib/raise-if-root/library.rb', line 96

def self.assert_equal(label, actual, expected)
  if expected.nil?
    warn('warning: RaiseIfRoot.assert_equal called with expected=nil')
  end
  if actual != expected
    err = new_assertion_failed(label, actual, expected)
    run_assertion_callbacks(err)
    raise err
  end
end

.assert_not_equal(label, actual, expected) ⇒ Object

Assert that two values are not equal. But if they are equal, run assertion callbacks and raise AssertionFailed.

Parameters:

  • label (String)

    The label for the comparison we're making

  • actual

    The actual value

  • expected

    The expected value

Raises:


116
117
118
119
120
121
122
# File 'lib/raise-if-root/library.rb', line 116

def self.assert_not_equal(label, actual, expected)
  if actual == expected
    err = new_assertion_failed(label, actual)
    run_assertion_callbacks(err)
    raise err
  end
end

.assertion_callbacksArray<Proc>

The list of stored assertion callbacks. These are executed when an assertion fails just before the assertion is raised.

Returns:

  • (Array<Proc>)

156
157
158
# File 'lib/raise-if-root/library.rb', line 156

def self.assertion_callbacks
  @assertion_callbacks ||= []
end

.new_assertion_failed(label, actual, expected = nil) ⇒ AssertionFailed

Create a new AssertionFailed object.

Parameters:

  • label (String)

    The label for the comparison we're making

  • actual

    The actual value

  • expected (defaults to: nil)

    The expected value, if any

Returns:


132
133
134
135
136
137
138
139
140
# File 'lib/raise-if-root/library.rb', line 132

def self.new_assertion_failed(label, actual, expected=nil)
  # rubocop:disable Style/SpecialGlobalVars
  message = "Process[#{$$}] #{label} is #{actual.inspect}"
  if expected
    message << ", expected #{expected.inspect}"
  end

  AssertionFailed.new(message)
end

.raise_if(uid: nil, gid: nil, uid_not: nil, gid_not: nil, username: nil, username_not: nil) ⇒ Object

Raise AssertionFailed if any of the specified conditions are met. This is the primary method powering RaiseIfRoot.

rubocop:disable Metrics/ParameterLists

Parameters:

  • uid (Integer) (defaults to: nil)

    Raise if the process UID or EUID matches

  • gid (Integer) (defaults to: nil)

    Raise if the process GID or EGID matches

  • uid_not (Integer) (defaults to: nil)

    Raise if the process UID or EUID does not match the provided value

  • gid_not (Integer) (defaults to: nil)

    Raise if the process GID or EGID does not match the provided value

  • username (String) (defaults to: nil)

    Raise if the username of the process UID or EUID matches the provided value

  • username_not (String) (defaults to: nil)

    Raise if the username of the process UID or EUID does not match the provided value

Raises:


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/raise-if-root/library.rb', line 50

def self.raise_if(uid: nil, gid: nil, uid_not: nil, gid_not: nil,
                  username: nil, username_not: nil)
  if uid
    assert_not_equal('UID', Process.uid, uid)
    assert_not_equal('EUID', Process.euid, uid)
  end

  if gid
    assert_not_equal('GID', Process.gid, gid)
    assert_not_equal('EGID', Process.egid, gid)
  end

  if uid_not
    assert_equal('UID', Process.uid, uid_not)
    assert_equal('EUID', Process.euid, uid_not)
  end

  if gid_not
    assert_equal('GID', Process.gid, gid_not)
    assert_equal('EGID', Process.egid, gid_not)
  end

  # raise if username
  if username
    assert_not_equal('username', Etc.getpwuid(Process.uid).name, username)
    assert_not_equal('effective username', Etc.getpwuid(Process.euid).name,
                     username)
  end

  # raise unless username is username_not
  if username_not
    assert_equal('username', Etc.getpwuid(Process.uid).name, username_not)
    assert_equal('effective username', Etc.getpwuid(Process.euid).name,
                 username_not)
  end
end

.raise_if_rootObject

Raise if the process UID/EUID is 0 or if the process GID/EGID is 0.

Raises:


15
16
17
# File 'lib/raise-if-root/library.rb', line 15

def self.raise_if_root
  raise_if(uid: 0, gid: 0)
end

.raise_if_uid(uid) ⇒ Object

Raise if the process UID or EUID equals uid.

Parameters:

  • uid (Integer)

Raises:

See Also:


27
28
29
# File 'lib/raise-if-root/library.rb', line 27

def self.raise_if_uid(uid)
  raise_if(uid: uid)
end

.run_assertion_callbacks(err) ⇒ Array

Execute all of the stored assertion callbacks.

Parameters:

Returns:

  • (Array)

    The collected return values of the callbacks.


166
167
168
# File 'lib/raise-if-root/library.rb', line 166

def self.run_assertion_callbacks(err)
  assertion_callbacks.map { |block| block.call(err) }
end