Skip to content

Commit

Permalink
WIP: validate key name
Browse files Browse the repository at this point in the history
  • Loading branch information
fcd1 committed Mar 7, 2024
1 parent 778fa01 commit 2ab72de
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
47 changes: 47 additions & 0 deletions lib/atc/utils/object_key_name_utils.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'pathname'
module Atc::Utils::ObjectKeyNameUtils
# About Cloud Storage objects: https://cloud.google.com/storage/docs/objects
# According to the above (and quite probably most Google Cloud Storage documentation),
# objects have names
# AWS - Creating object key names:
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-keys.html
# As seen in the title for the above page, an object in AWS S3 has a key name (or key)
# So fcd1 decided to call this module ObjectKeyNameUtils to try and cover both naming
# conventions. However, it's just a name and fcd1 is cool if module is renamed

# Following method verifies that the given path to file
# meets both the requirements for a valid AWS S3 object key name, and the requirements
# for a valid Google Cloud Storage object name. So it must meet the more restrictive of the
# two requirements, which are the AWS S3 object key name requirements. See above links
# QUESTION: Are relative paths valid, as opposed to just absolute paths? Current implementation
# allows both for now, but this can be changed.
# The path to the filename can only contain, in addition to the '/' delimiter,
# the following characters: a-zA-Z0-9_
# In addition to the above characters, the filename (without the path) can also contain
# one period, '.', used to delimit the file extension
# Method expects an absolute path as its only argument
def self.valid_key_name?(path_filename)
# Uncomment the following if only absolute paths are valid and relative paths are invalid
# return false unless Pathname.new(path_filename).absolute?

path_to_file, filename = Pathname.new(path_filename).split

# for filename, get extension (if there is one) and base filename
filename_extension = filename.extname
base_filename = filename.to_s.delete_suffix(filename_extension)

# check filename extension
if filename_extension
return false if (/[^a-zA-Z0-9_]/ =~ filename_extension.delete_prefix('.'))
end

# check base filename
return false if (/[^a-zA-Z0-9_]/ =~ base_filename)

# check each component in the path to the file
path_to_file.each_filename do |path_segment|
return false if (/[^a-zA-Z0-9_]/ =~ path_segment)
end
true
end
end
39 changes: 39 additions & 0 deletions spec/atc/utils/object_key_name_utils_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# coding: utf-8
# frozen_string_literal: true

require 'rails_helper'

describe Atc::Utils::ObjectKeyNameUtils do
context '.valid_key_name?' do
let(:sample_invalid_paths) do
[
'/top_dîr/sub_dir/file',
'/top_dir/sub_dîr/file',
'/top_dir/sub_dir/fîle',
'/top_dir/sub_dir/fîle.txt',
'/top_dir/sub_dir/file.îxt',
'/top_dir/sub.dir/file.txt',
'/top_dir/sub_dir/file.txt.txt'
]
end
let(:sample_valid_paths) do
[
'/top_dir/sub_dir/file',
'relative_path/sub_dir/file',
'/top_dir/sub_dir/file.txt'
]
end

it 'returns false for all sample invalid paths' do
sample_invalid_paths.each do |path|
expect(described_class.valid_key_name?(path)).to (be false), lambda { "Test failed on path #{path}." }
end
end

it 'returns true for all sample valid paths' do
sample_valid_paths.each do |path|
expect(described_class.valid_key_name?(path)).to (be true), lambda { "Test failed on path #{path}." }
end
end
end
end

0 comments on commit 2ab72de

Please sign in to comment.