class Terminalwire::Client::Entitlement::Paths::Permit
def convert(value)
def convert(value) mode = Integer(value) raise ArgumentError, "The mode #{format_octet value} must be an octet value between #{format_octet MODE_RANGE.first} and #{format_octet MODE_RANGE.last}" unless MODE_RANGE.cover?(mode) mode end
def format_octet(value)
def format_octet(value) format("0o%03o", value) end
def initialize(path:, mode: MODE)
def initialize(path:, mode: MODE) @path = Pathname.new(path).expand_path @mode = convert(mode) end
def permitted?(path:, mode: @mode)
def permitted?(path:, mode: @mode) permitted_path?(path) && permitted_mode?(mode) end
def permitted_mode?(value)
def permitted_mode?(value) # Ensure the mode is at least as permissive as the permitted mode. mode = convert(value) # Extract permission bits for owner, group, and others owner_bits = mode & OWNER_PERMISSIONS group_bits = mode & GROUP_PERMISSIONS others_bits = mode & OTHERS_PERMISSIONS # Ensure that the mode doesn't grant more permissions than @mode in any class (owner, group, others) (owner_bits <= @mode & OWNER_PERMISSIONS) && (group_bits <= @mode & GROUP_PERMISSIONS) && (others_bits <= @mode & OTHERS_PERMISSIONS) end
def permitted_path?(path)
def permitted_path?(path) # This MUST be done via File.fnmatch because Pathname#fnmatch does not work. If you # try changing this 🚨 YOU MAY CIRCUMVENT THE SECURITY MEASURES IN PLACE. 🚨 File.fnmatch @path.to_s, File.expand_path(path), File::FNM_PATHNAME end
def serialize
def serialize { location: @path.to_s, mode: @mode } end