add challenges_for

master
Kanezoh 2022-01-02 22:14:58 +09:00
parent e514ea66df
commit f4f38a41a5
4 changed files with 117 additions and 34 deletions

View File

@ -9,16 +9,80 @@ describe "Mechanize AuthStore test" do
realm = "" realm = ""
auth_store.add_auth(url, user, password) auth_store.add_auth(url, user, password)
auth_store.auth_accounts[url].size.should eq 1 auth_store.auth_accounts[url].size.should eq 1
auth_store.auth_accounts[url][realm].should eq(["kanezoh", "password", nil]) auth_store.auth_accounts[url][realm].should eq(["kanezoh", "password", ""])
end end
it "credentials_for" do it "test_add_auth_domain" do
auth_store = Mechanize::HTTP::AuthStore.new auth_store = Mechanize::HTTP::AuthStore.new
url = URI.parse("http://example.com/") url = URI.parse("http://example.com/")
user = "kanezoh" user = "kanezoh"
password = "password" password = "password"
domain = "domain"
realm = "" realm = ""
auth_store.add_auth(url, user, password) auth_store.add_auth(url, user, password, nil, domain)
auth_store.credentials_for(url, realm).should eq ["kanezoh", "password", nil] auth_store.auth_accounts[url][realm].should eq(["kanezoh", "password", "domain"])
end
it "test_add_auth_realm" do
auth_store = Mechanize::HTTP::AuthStore.new
url = URI.parse("http://example.com/")
auth_store.add_auth url, "user1", "pass"
auth_store.add_auth url, "user2", "pass", "realm"
expected = {
url => {
"" => ["user1", "pass", ""],
"realm" => ["user2", "pass", ""],
},
}
auth_store.auth_accounts.should eq expected
end
it "test_add_auth_realm_case" do
auth_store = Mechanize::HTTP::AuthStore.new
url = URI.parse("http://example.com/")
auth_store.add_auth url, "user1", "pass", "realm"
auth_store.add_auth url, "user2", "pass", "Realm"
expected = {
url => {
"realm" => ["user1", "pass", ""],
"Realm" => ["user2", "pass", ""],
},
}
auth_store.auth_accounts.should eq expected
end
it "test_add_auth_string" do
auth_store = Mechanize::HTTP::AuthStore.new
url = URI.parse("http://example.com/")
auth_store.add_auth "#{url}/path", "user", "pass"
expected = {
url => {
"" => ["user", "pass", ""],
},
}
auth_store.auth_accounts.should eq expected
end
it "test_credentials_eh" do
auth_store = Mechanize::HTTP::AuthStore.new
url = URI.parse("http://example.com/")
challenges = [
Mechanize::HTTP::AuthChallenge.new("Basic", {"realm" => "r"}),
Mechanize::HTTP::AuthChallenge.new("Digest", {"realm" => "r"}),
]
auth_store.credentials?(url, challenges).should_not eq true
auth_store.add_auth url, "user", "pass"
auth_store.credentials?(url, challenges).should eq true
auth_store.credentials?("#{url}/path", challenges).should eq true
end end
end end

View File

@ -65,12 +65,10 @@ describe "Mechanize HTTP Authentication test" do
result[1].raw.should eq expect[1].raw result[1].raw.should eq expect[1].raw
end end
it "test_parse_multiple_without_comma_delimiter" do it "test_parse_multiple_without_comma_delimiter" do
expect = [ expect = [
challenge("Basic", { "realm" => "foo" }, "Basic realm=foo"), challenge("Basic", {"realm" => "foo"}, "Basic realm=foo"),
challenge("Digest", { "realm" => "bar" }, "Digest realm=bar"), challenge("Digest", {"realm" => "bar"}, "Digest realm=bar"),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -85,8 +83,8 @@ describe "Mechanize HTTP Authentication test" do
it "test_parse_multiple_blank" do it "test_parse_multiple_blank" do
expect = [ expect = [
challenge("Basic", { "realm" => "foo" }, "Basic realm=foo"), challenge("Basic", {"realm" => "foo"}, "Basic realm=foo"),
challenge("Digest", { "realm" => "bar" }, "Digest realm=bar"), challenge("Digest", {"realm" => "bar"}, "Digest realm=bar"),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -111,7 +109,7 @@ describe "Mechanize HTTP Authentication test" do
result[0].raw.should eq expect[0].raw result[0].raw.should eq expect[0].raw
end end
it "test_parse_ntlm_type_2_3" do it "test_parse_ntlm_type_2_3" do
expect = [ expect = [
challenge("NTLM", "foo=", "NTLM foo="), challenge("NTLM", "foo=", "NTLM foo="),
] ]
@ -125,7 +123,7 @@ describe "Mechanize HTTP Authentication test" do
it "test_parse_realm_uppercase" do it "test_parse_realm_uppercase" do
expect = [ expect = [
challenge("Basic", { "realm" => "foo" }, "Basic ReAlM=foo"), challenge("Basic", {"realm" => "foo"}, "Basic ReAlM=foo"),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -137,7 +135,7 @@ describe "Mechanize HTTP Authentication test" do
it "test_parse_realm_value_case" do it "test_parse_realm_value_case" do
expect = [ expect = [
challenge("Basic", { "realm" => "Foo" }, "Basic realm=Foo"), challenge("Basic", {"realm" => "Foo"}, "Basic realm=Foo"),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -149,7 +147,7 @@ describe "Mechanize HTTP Authentication test" do
it "test_parse_scheme_uppercase" do it "test_parse_scheme_uppercase" do
expect = [ expect = [
challenge("Basic", { "realm" => "foo" }, "BaSiC realm=foo"), challenge("Basic", {"realm" => "foo"}, "BaSiC realm=foo"),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -159,9 +157,9 @@ describe "Mechanize HTTP Authentication test" do
result[0].raw.should eq expect[0].raw result[0].raw.should eq expect[0].raw
end end
it "test_parse_bad_whitespace_around_auth_param" do it "test_parse_bad_whitespace_around_auth_param" do
expect = [ expect = [
challenge("Basic", { "realm" => "foo" }, "Basic realm = \"foo\""), challenge("Basic", {"realm" => "foo"}, "Basic realm = \"foo\""),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -173,7 +171,7 @@ describe "Mechanize HTTP Authentication test" do
it "test_parse_bad_single_quote" do it "test_parse_bad_single_quote" do
expect = [ expect = [
challenge("Basic", { "realm" => "'foo" }, "Basic realm='foo"), challenge("Basic", {"realm" => "'foo"}, "Basic realm='foo"),
] ]
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
@ -205,7 +203,7 @@ describe "Mechanize HTTP Authentication test" do
parser = Mechanize::HTTP::WWWAuthenticateParser.new parser = Mechanize::HTTP::WWWAuthenticateParser.new
parser.scanner = StringScanner.new "\"escaped \\\" here\"" parser.scanner = StringScanner.new "\"escaped \\\" here\""
string = parser.quoted_string string = parser.quoted_string
string.should eq "escaped \\\" here" string.should eq "escaped \\\" here"
end end

View File

@ -6,12 +6,12 @@ class Mechanize
class AuthChallenge class AuthChallenge
property scheme : String? property scheme : String?
property params : String? | Hash(String, String)? property params : String? | Hash(String, String)?
property raw : String property raw : String
def initialize(scheme = nil, params = nil, raw = "") def initialize(scheme = nil, params = nil, raw = "")
@scheme = scheme @scheme = scheme
@params = params @params = params
@raw = raw @raw = raw
end end
def [](param) def [](param)
@ -37,7 +37,12 @@ class Mechanize
# The name of the realm for this challenge # The name of the realm for this challenge
def realm_name def realm_name
params["realm"] if Hash === params # NTLM has a string for params params_value = params
if params_value.is_a?(Hash)
params_value["realm"] # NTLM has a string for params
else
nil
end
end end
## ##

View File

@ -2,38 +2,54 @@ class Mechanize
module HTTP module HTTP
# This class store info for HTTP Authentication. # This class store info for HTTP Authentication.
class AuthStore class AuthStore
getter auth_accounts : Hash(URI, Hash(String, Array(String?))) getter auth_accounts : Hash(URI, Hash(String, Array(String)))
def initialize def initialize
@auth_accounts = Hash(URI, Hash(String, Array(String?))).new @auth_accounts = Hash(URI, Hash(String, Array(String))).new
end end
def add_auth(uri : String | URI, user : String, pass : String, realm : String? = nil, domain : String? = nil) def add_auth(uri : String | URI, user : String, pass : String, realm : String? = nil, domain : String? = nil)
unless uri.is_a?(URI) unless uri.is_a?(URI)
uri = URI.new(uri) uri = URI.parse(uri)
end end
# uri += '/' uri.path = "/"
uri.user = nil uri.user = nil
uri.password = nil uri.password = nil
if realm.nil? realm = "" if realm.nil?
realm = "" domain = "" if domain.nil?
end
realm_hash = {realm => [user, pass, domain]} realm_hash = {realm => [user, pass, domain]}
auth_accounts[uri] = realm_hash if auth_accounts.has_key?(uri)
auth_accounts[uri].merge!(realm_hash)
else
auth_accounts[uri] = realm_hash
end
end
##
# Returns true if credentials exist for the +challenges+ from the server at
# +uri+.
def credentials?(uri, challenges)
challenges.any? do |challenge|
credentials_for uri, challenge.realm_name
end
end end
# Retrieves credentials for +realm+ on the server at +uri+. # Retrieves credentials for +realm+ on the server at +uri+.
def credentials_for(uri : String | URI, realm : String) : Array(String?) def credentials_for(uri : String | URI, realm : String?) : Array(String)?
unless uri.is_a?(URI) unless uri.is_a?(URI)
uri = URI.new(uri) uri = URI.parse(uri)
end end
# uri += '/' uri.path = "/"
uri.user = nil uri.user = nil
uri.password = nil uri.password = nil
realm = "" if realm.nil?
realms = auth_accounts[uri] realms = auth_accounts.fetch(uri, nil)
return nil if realms.nil?
realms[realm] realms.fetch(realm, nil) || realms.fetch("", nil)
end end
end end
end end