-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |