Sha256: 5f975011e834b5302751cb8faad1d8a9a7824a6c0385106a1a2efa7ea245acad
Contents?: true
Size: 1.85 KB
Versions: 2
Compression:
Stored size: 1.85 KB
Contents
# frozen_string_literal: true require 'invar/version' require 'invar/scope' require 'delegate' module Invar # Verifies a file is secure class PrivateFile extend Forwardable def_delegators :@delegate_sd_obj, :stat, :to_s, :basename, :dirname, :extname, :==, :chmod, :rename, :write # Mask for limiting to the lowest three octal digits (which store permissions) PERMISSIONS_MASK = 0o777 ALLOWED_USER_MODES = [0o600, 0o400].freeze ALLOWED_GROUP_MODES = [0o060, 0o040, 0o000].freeze DEFAULT_PERMISSIONS = 0o600 # Allowed permissions modes for lockfile. Readable or read-writable by the user or group only ALLOWED_MODES = ALLOWED_USER_MODES.product(ALLOWED_GROUP_MODES).collect do |u, g| u | g # bitwise OR end.freeze def initialize(file_path) @delegate_sd_obj = file_path end def read(**args) verify_permissions! @delegate_sd_obj.read(**args) end def binread(**args) verify_permissions! @delegate_sd_obj.binread(**args) end # Raised when the file has improper permissions class FilePermissionsError < RuntimeError end private # Verifies the file has proper permissions # # @raise [FilePermissionsError] if the file has insecure permissions def verify_permissions! # stat = @delegate_sd_obj.stat file_mode = stat.mode & PERMISSIONS_MASK # TODO: use stat.world_readable? etc instead return if ALLOWED_MODES.include? file_mode msg = format("File '%<path>s' has improper permissions (%<mode>04o). %<hint>s", path: @delegate_sd_obj, mode: file_mode, hint: "Try: chmod 600 #{ @delegate_sd_obj }") raise FilePermissionsError, msg end end end
Version data entries
2 entries across 2 versions & 1 rubygems
Version | Path |
---|---|
invar-0.9.1 | lib/invar/private_file.rb |
invar-0.9.0 | lib/invar/private_file.rb |