зеркало из https://github.com/github/ruby.git
[rubygems/rubygems] Introduce `Gem::PrintableUri` that would redact URIs to be used on outputs
We need to redact URI credential in several places and copy pasting the code into each part of it is not ideal. This class is responsible for parsing URI strings and redacting credential from it. Also, it will handle URI object in the same manner. We will be reusing this class whenever we need to print/display a URI to users. URI with the following format will be redacted: - Token: `http://my-secure-token@example.com` => `http://REDACTED@example.com` - Username & Password: `http://my-username:my-secure-password@example.com` => `http://my-username:REDACTED@example.com` - x-oauth-basic: `http://my-secure-token:x-oauth-basic@example.com` => `http://REDACTED:x-oauth-basic@example.com` https://github.com/rubygems/rubygems/commit/f1e45d3a89
This commit is contained in:
Родитель
14a9e24f7e
Коммит
b41802421a
|
@ -0,0 +1,81 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'uri'
|
||||
require_relative 'uri_parser'
|
||||
|
||||
class Gem::PrintableUri
|
||||
def self.parse_uri(uri)
|
||||
new(uri).parse_uri
|
||||
end
|
||||
|
||||
def initialize(original_uri)
|
||||
@credential_redacted = false
|
||||
@original_uri = original_uri
|
||||
end
|
||||
|
||||
def parse_uri
|
||||
@original_uri = Gem::UriParser.parse_uri(@original_uri)
|
||||
@uri = @original_uri.clone
|
||||
redact_credential
|
||||
|
||||
self
|
||||
end
|
||||
|
||||
def parsed_uri?
|
||||
@uri.is_a? URI::Generic
|
||||
end
|
||||
|
||||
def credential_redacted?
|
||||
@credential_redacted
|
||||
end
|
||||
|
||||
def original_password
|
||||
return unless parsed_uri?
|
||||
|
||||
@original_uri.password
|
||||
end
|
||||
|
||||
def to_s
|
||||
@uri.to_s
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redact_credential
|
||||
return unless redactable_credential?
|
||||
|
||||
if token?
|
||||
@uri.user = 'REDACTED'
|
||||
elsif oauth_basic?
|
||||
@uri.user = 'REDACTED'
|
||||
elsif password?
|
||||
@uri.password = 'REDACTED' if password?
|
||||
end
|
||||
|
||||
@credential_redacted = true
|
||||
end
|
||||
|
||||
def redactable_credential?
|
||||
return false unless parsed_uri?
|
||||
|
||||
password? || oauth_basic? || token?
|
||||
end
|
||||
|
||||
def password?
|
||||
return false unless parsed_uri?
|
||||
|
||||
!!@uri.password
|
||||
end
|
||||
|
||||
def oauth_basic?
|
||||
return false unless parsed_uri?
|
||||
|
||||
@uri.password == 'x-oauth-basic'
|
||||
end
|
||||
|
||||
def token?
|
||||
return false unless parsed_uri?
|
||||
|
||||
!@uri.user.nil? && @uri.password.nil?
|
||||
end
|
||||
end
|
|
@ -0,0 +1,116 @@
|
|||
require_relative 'helper'
|
||||
require 'uri'
|
||||
require 'rubygems/printable_uri'
|
||||
|
||||
class TestPrintableUri < Gem::TestCase
|
||||
def test_parsed_uri
|
||||
assert_equal true, Gem::PrintableUri.parse_uri("https://www.example.com").parsed_uri?
|
||||
end
|
||||
|
||||
def test_parsed_uri_with_empty_uri_object
|
||||
assert_equal true, Gem::PrintableUri.parse_uri(URI("")).parsed_uri?
|
||||
end
|
||||
|
||||
def test_parsed_uri_with_valid_uri_object
|
||||
assert_equal true, Gem::PrintableUri.parse_uri(URI("https://www.example.com")).parsed_uri?
|
||||
end
|
||||
|
||||
def test_parsed_uri_with_other_objects
|
||||
assert_equal false, Gem::PrintableUri.parse_uri(Object.new).parsed_uri?
|
||||
end
|
||||
|
||||
def test_parsed_uri_with_invalid_uri
|
||||
assert_equal false, Gem::PrintableUri.parse_uri("https://www.example.com:80index").parsed_uri?
|
||||
end
|
||||
|
||||
def test_credential_redacted_with_user_pass
|
||||
assert_equal true, Gem::PrintableUri.parse_uri("https://user:pass@example.com").credential_redacted?
|
||||
end
|
||||
|
||||
def test_credential_redacted_with_token
|
||||
assert_equal true, Gem::PrintableUri.parse_uri("https://token@example.com").credential_redacted?
|
||||
end
|
||||
|
||||
def test_credential_redacted_with_user_x_oauth_basic
|
||||
assert_equal true, Gem::PrintableUri.parse_uri("https://token:x-oauth-basic@example.com").credential_redacted?
|
||||
end
|
||||
|
||||
def test_credential_redacted_without_credential
|
||||
assert_equal false, Gem::PrintableUri.parse_uri("https://www.example.com").credential_redacted?
|
||||
end
|
||||
|
||||
def test_credential_redacted_with_empty_uri_object
|
||||
assert_equal false, Gem::PrintableUri.parse_uri(URI("")).credential_redacted?
|
||||
end
|
||||
|
||||
def test_credential_redacted_with_valid_uri_object
|
||||
assert_equal true, Gem::PrintableUri.parse_uri(URI("https://user:pass@example.com")).credential_redacted?
|
||||
end
|
||||
|
||||
def test_credential_redacted_with_other_objects
|
||||
assert_equal false, Gem::PrintableUri.parse_uri(Object.new).credential_redacted?
|
||||
end
|
||||
|
||||
def test_original_password_user_pass
|
||||
assert_equal "pass", Gem::PrintableUri.parse_uri("https://user:pass@example.com").original_password
|
||||
end
|
||||
|
||||
def test_original_password_with_token
|
||||
assert_equal nil, Gem::PrintableUri.parse_uri("https://token@example.com").original_password
|
||||
end
|
||||
|
||||
def test_original_password_without_credential
|
||||
assert_equal nil, Gem::PrintableUri.parse_uri("https://www.example.com").original_password
|
||||
end
|
||||
|
||||
def test_original_password_with_invalid_uri
|
||||
assert_equal nil, Gem::PrintableUri.parse_uri("https://www.example.com:80index").original_password
|
||||
end
|
||||
|
||||
def test_original_password_with_empty_uri_object
|
||||
assert_equal nil, Gem::PrintableUri.parse_uri(URI("")).original_password
|
||||
end
|
||||
|
||||
def test_original_password_with_valid_uri_object
|
||||
assert_equal "pass", Gem::PrintableUri.parse_uri(URI("https://user:pass@example.com")).original_password
|
||||
end
|
||||
|
||||
def test_original_password_with_other_objects
|
||||
assert_equal nil, Gem::PrintableUri.parse_uri(Object.new).original_password
|
||||
end
|
||||
|
||||
def test_to_s_with_user_pass
|
||||
assert_equal "https://user:REDACTED@example.com", Gem::PrintableUri.parse_uri("https://user:pass@example.com").to_s
|
||||
end
|
||||
|
||||
def test_to_s_with_token
|
||||
assert_equal "https://REDACTED@example.com", Gem::PrintableUri.parse_uri("https://token@example.com").to_s
|
||||
end
|
||||
|
||||
def test_to_s_with_user_x_oauth_basic
|
||||
assert_equal "https://REDACTED:x-oauth-basic@example.com", Gem::PrintableUri.parse_uri("https://token:x-oauth-basic@example.com").to_s
|
||||
end
|
||||
|
||||
def test_to_s_without_credential
|
||||
assert_equal "https://www.example.com", Gem::PrintableUri.parse_uri("https://www.example.com").to_s
|
||||
end
|
||||
|
||||
def test_to_s_with_invalid_uri
|
||||
assert_equal "https://www.example.com:80index", Gem::PrintableUri.parse_uri("https://www.example.com:80index").to_s
|
||||
end
|
||||
|
||||
def test_to_s_with_empty_uri_object
|
||||
assert_equal "", Gem::PrintableUri.parse_uri(URI("")).to_s
|
||||
end
|
||||
|
||||
def test_to_s_with_valid_uri_object
|
||||
assert_equal "https://user:REDACTED@example.com", Gem::PrintableUri.parse_uri(URI("https://user:pass@example.com")).to_s
|
||||
end
|
||||
|
||||
def test_to_s_with_other_objects
|
||||
obj = Object.new
|
||||
obj.stub(:to_s, "my-to-s") do
|
||||
assert_equal "my-to-s", Gem::PrintableUri.parse_uri(obj).to_s
|
||||
end
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче