Skip to content

Commit

Permalink
WIP on additional tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mjacobus committed Apr 3, 2020
1 parent 0dcf549 commit 2d866c3
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 5 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@
# rspec failure tracking
.rspec_status
/Gemfile.lock
/spec/fixtures/sandbox
1 change: 1 addition & 0 deletions lib/koine/file_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require 'koine/file_system/version'
require 'koine/file_system/file_system'
require 'koine/file_system/path_sanitizer'
require 'koine/file_system/adapters/base'
require 'koine/file_system/adapters/local'

Expand Down
34 changes: 29 additions & 5 deletions lib/koine/file_system/adapters/local.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,56 @@
# frozen_string_literal: true

require 'fileutils'

module Koine
module FileSystem
module Adapters
class Local < Base
def initialize(root:)
def initialize(root:, path_sanitizer: PathSanitizer.new)
@root = root
@path_sanitizer = path_sanitizer
end

def read(path)
if has?(path)
return File.read(full_path(path))
file = File.open(full_path(path), 'rb')
content = file.read
file.close
return content
# return File.read(full_path(path))
end

raise_not_found(path)
end

def has?(path)
File.exist?(full_path(path))
end

def write(path, content, options: {})
path = full_path(path)
ensure_target_dir(path)
File.open(path, 'w') do |f|
f.puts(content)
end
end

private

def full_path(path)
File.expand_path(path, @root)
File.expand_path(sanitize_path(path), @root)
end

def ensure_target_dir(path)
dir = File.dirname(path)
unless Dir.exist?(dir)
FileUtils.mkdir_p(dir)
end
end

def sanitize_path(path)
@path_sanitizer.sanitize(path)
end

# def read(_path)
# def read_stream(_path)
# def write(_path, _contents, options: {})
# def write_stream(_path, _contents, options: {})
Expand Down
13 changes: 13 additions & 0 deletions lib/koine/file_system/path_sanitizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# frozen_string_literal: true

require 'fileutils'

module Koine
module FileSystem
class PathSanitizer
def sanitize(path)
path.to_s.gsub('/../', '/').gsub(%r{\.?\./}, '')
end
end
end
end
Empty file added spec/fixtures/sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions spec/koine/file_system/adapters/local_spec.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
# frozen_string_literal: true

require 'spec_helper'
require 'digest'

RSpec.describe Koine::FileSystem::Adapters::Local do
let(:adapter) { described_class.new(root: FIXTURES_PATH) }

before do
system("rm -rf #{FIXTURES_PATH}/sandbox")
end

describe '#read' do
it 'raises when file does not exist' do
expect do
Expand All @@ -26,4 +31,53 @@
expect(contents).to eq(expected)
end
end

describe '#write' do
let(:content) do
<<~STR
This is a sample file
For local adapter
STR
end

it 'creates a file' do
adapter.write('sandbox/foo/bar.txt', content)

expect(File.read(FIXTURES_PATH + '/sandbox/foo/bar.txt')).to eq(content)
end

it 'creates filters malicious files' do
adapter.write('../../sandbox/../.././../../foo/bar.txt', content)

expect(File.read(FIXTURES_PATH + '/sandbox/foo/bar.txt')).to eq(content)
end

it 'keeps the original file digest' do
content = adapter.read('sample.txt')
adapter.write('sandbox/text/sample.txt', content)

original_content_digest = Digest::SHA1.hexdigest(adapter.read('sample.txt'))
copy_content_digest = Digest::SHA1.hexdigest(adapter.read('sandbox/text/sample.txt'))

expect(copy_content_digest).to eq(original_content_digest)
end

it 'writes binary file' do
content = adapter.read('sample.png')
adapter.write('sandbox/binary/sample.png', content)

# da39a3ee5e6b4b0d3255bfef95601890afd80709 spec/fixtures/sample.png
# adc83b19e793491b1c6ea0fd8b46cd9f32e592fc spec/fixtures/sandbox/binary/sample.png

original_content_digest = Digest::SHA1.hexdigest(adapter.read('sample.png'))
copy_content_digest = Digest::SHA1.hexdigest(adapter.read('sandbox/binary/sample.png'))

expect(copy_content_digest).to eq(original_content_digest)

original = Digest::SHA1.file("#{FIXTURES_PATH}/sample.png")
copy = Digest::SHA1.file("#{FIXTURES_PATH}/sandbox/binary/sample.png")

expect(copy).to eq(original)
end
end
end
19 changes: 19 additions & 0 deletions spec/koine/file_system/path_sanitizer_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Koine::FileSystem::PathSanitizer do
subject(:sanitizer) { described_class.new }

describe '#sanitize' do
SAMPLES = {
'.././foo/bar/.././../../file.txt' => 'foo/bar/file.txt'
}

SAMPLES.each do |key, value|
it "transforms #{key} in #{value}"do
expect(sanitizer.sanitize(key)).to eq(value)
end
end
end
end

0 comments on commit 2d866c3

Please sign in to comment.