Import workspace IP validation from Mdm

This allows us to actually test the validations, since the code calls
out to Rex::Socket::RangeWalker.

MS-902
This commit is contained in:
Adam Cammack 2016-03-29 17:56:22 -05:00
parent 7bd6d0c696
commit 3b0170e87d
No known key found for this signature in database
GPG Key ID: C9378BA088092D66
2 changed files with 133 additions and 0 deletions

View File

@ -0,0 +1,60 @@
module Mdm::Workspace::BoundaryRange
extend ActiveSupport::Concern
included do
#
# Validations
#
validate :boundary_must_be_ip_range
#
# Instance Methods
#
# If {#limit_to_network} is disabled, this will always return `true`.
# Otherwise, return `true` only if all of the given IPs are within the
# project {#boundary boundaries}.
#
# @param ips [String] IP range(s)
# @return [true] if actions on ips are allowed.
# @return [false] if actions are not allowed on ips.
def allow_actions_on?(ips)
return true unless limit_to_network
return true unless boundary
return true if boundary.empty?
boundaries = Shellwords.split(boundary)
return true if boundaries.empty? # It's okay if there is no boundary range after all
given_range = Rex::Socket::RangeWalker.new(ips)
return false unless given_range # Can't do things to nonexistant IPs
allowed = false
boundaries.each do |boundary_range|
ok_range = Rex::Socket::RangeWalker.new(boundary)
allowed = true if ok_range.include_range? given_range
end
return allowed
end
# Validates that {#boundary} is {#valid_ip_or_range? a valid IP address or
# IP address range}. Due to this not being tested before it was moved here
# from Mdm, the default workspace does not validate. We therefore don't
# validate boundaries of workspaces that don't use them.
#
# @return [void]
def boundary_must_be_ip_range
errors.add(:boundary, "must be a valid IP range") unless !limit_to_network || valid_ip_or_range?(boundary)
end
private
# Returns whether `string` is a valid IP address or IP address range.
#
# @return [true] if valid IP address or IP address range.
# @return [false] otherwise.
def valid_ip_or_range?(string)
range = Rex::Socket::RangeWalker.new(string)
range && range.ranges && range.ranges.any?
end
end
end

View File

@ -0,0 +1,73 @@
RSpec.describe Mdm::Workspace, type: :model do
subject(:workspace) do
Mdm::Workspace.new
end
context 'validations' do
context 'boundary' do
let(:boundary) do
nil
end
let(:error) do
'must be a valid IP range'
end
context 'when the workspace is limited to a network' do
before(:example) do
workspace.boundary = boundary
workspace.limit_to_network = true
workspace.valid?
end
it 'should validate using #valid_ip_or_range?' do
expect(workspace).to receive(:valid_ip_or_range?).with(boundary).and_return(false)
workspace.valid?
end
context 'with valid IP' do
let(:boundary) do
'192.168.0.1'
end
it 'should not record an error' do
expect(workspace.errors[:boundary]).not_to include(error)
end
end
context 'with valid range' do
let(:boundary) do
'192.168.0.1/24'
end
it 'should not record an error' do
expect(workspace.errors[:boundary]).not_to include(error)
end
end
context 'with invalid IP or range' do
let(:boundary) do
'192.168'
end
it 'should record error that boundary must be a valid IP range' do
expect(workspace).not_to be_valid
expect(workspace.errors[:boundary]).to include(error)
end
end
end
context 'when the workspace is not network limited' do
before(:example) do
workspace.boundary = boundary
workspace.valid?
end
it 'should not care about the value of the boundary' do
expect(workspace.errors[:boundary]).not_to include(error)
end
end
end
end
end