From d01c0ff2770e66960b806c3498a13f5ee6a6f580 Mon Sep 17 00:00:00 2001 From: Justin Hiemstra Date: Mon, 9 Oct 2023 19:15:34 +0000 Subject: [PATCH] Port OSDF-Client PR #87 to Pelican This PR brings a PR from OSDF-Client to Pelican that handles parsing token names with `.`s in their name. For more information, see: https://github.com/htcondor/osdf-client/pull/87 --- client/main.go | 50 +++++++++++++++++++++++++++++------------- client/main_test.go | 53 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 15 deletions(-) diff --git a/client/main.go b/client/main.go index 808ce7e55..952eea244 100644 --- a/client/main.go +++ b/client/main.go @@ -176,22 +176,10 @@ func getToken(destination *url.URL, namespace namespaces.Namespace, isWrite bool } // Finally, look in the HTCondor runtime - token_filename := "scitokens.use" - if len(token_name) > 0 { - token_filename = token_name + ".use" - } - log.Debugln("Looking for token file:", token_filename) - if credsDir, isCondorCredsSet := os.LookupEnv("_CONDOR_CREDS"); token_location == "" && isCondorCredsSet { - // Token wasn't specified on the command line or environment, try the default scitoken - if _, err := os.Stat(filepath.Join(credsDir, token_filename)); err != nil { - log.Warningln("Environment variable _CONDOR_CREDS is set, but file being point to does not exist:", err) - } else { - token_location = filepath.Join(credsDir, token_filename) - } - } - if _, err := os.Stat(".condor_creds/" + token_filename); err == nil && token_location == "" { - token_location, _ = filepath.Abs(".condor_creds/" + token_filename) + if token_location == "" { + token_location = discoverHTCondorToken(token_name) } + if token_location == "" { if !ObjectClientOptions.Plugin { value, err := AcquireToken(destination, namespace, isWrite) @@ -363,6 +351,38 @@ func correctURLWithUnderscore(sourceFile string) (string, string) { return sourceFile, originalScheme } +func discoverHTCondorToken(tokenName string) string { + tokenLocation := "" + + // Tokens with dots in their name may need to have dots converted to underscores. + if strings.Contains(tokenName, ".") { + underscoreTokenName := strings.ReplaceAll(tokenName, ".", "_") + // If we find a token after replacing dots, then we're already done. + tokenLocation = discoverHTCondorToken(underscoreTokenName) + if tokenLocation != "" { + return tokenLocation + } + } + + tokenFilename := "scitokens.use" + if len(tokenName) > 0 { + tokenFilename = tokenName + ".use" + } + log.Debugln("Looking for token file:", tokenFilename) + if credsDir, isCondorCredsSet := os.LookupEnv("_CONDOR_CREDS"); tokenLocation == "" && isCondorCredsSet { + // Token wasn't specified on the command line or environment, try the default scitoken + if _, err := os.Stat(filepath.Join(credsDir, tokenFilename)); err != nil { + log.Warningln("Environment variable _CONDOR_CREDS is set, but file being point to does not exist:", err) + } else { + tokenLocation = filepath.Join(credsDir, tokenFilename) + } + } + if _, err := os.Stat(".condor_creds/" + tokenFilename); err == nil && tokenLocation == "" { + tokenLocation, _ = filepath.Abs(".condor_creds/" + tokenFilename) + } + return tokenLocation +} + // Start the transfer, whether read or write back func DoStashCPSingle(sourceFile string, destination string, methods []string, recursive bool) (bytesTransferred int64, err error) { diff --git a/client/main_test.go b/client/main_test.go index d7091285a..8c24ae689 100644 --- a/client/main_test.go +++ b/client/main_test.go @@ -145,6 +145,59 @@ func TestGetToken(t *testing.T) { assert.Equal(t, token_contents, token) os.Unsetenv("_CONDOR_CREDS") + // _CONDOR_CREDS/renamed_handle1.use via renamed_handle1+osdf:///user/ligo/frames + token_contents = "bearer_token_file_contents renamed_handle1.use" + tmpFile = []byte(token_contents) + tmpDir = t.TempDir() + bearer_token_file = filepath.Join(tmpDir, "renamed_handle1.use") + err = os.WriteFile(bearer_token_file, tmpFile, 0644) + assert.NoError(t, err) + os.Setenv("_CONDOR_CREDS", tmpDir) + // Use a valid URL, then replace the scheme + renamedUrl, err = url.Parse("renamed.handle1+osdf:///user/ligo/frames") + renamedUrl.Scheme = "renamed_handle1+osdf" + assert.NoError(t, err) + renamedNamespace, err = namespaces.MatchNamespace("/user/ligo/frames") + assert.NoError(t, err) + token, err = getToken(renamedUrl, renamedNamespace, false, "") + assert.NoError(t, err) + assert.Equal(t, token_contents, token) + os.Unsetenv("_CONDOR_CREDS") + + // _CONDOR_CREDS/renamed_handle2.use via renamed.handle2+osdf:///user/ligo/frames + token_contents = "bearer_token_file_contents renamed.handle2.use" + tmpFile = []byte(token_contents) + tmpDir = t.TempDir() + bearer_token_file = filepath.Join(tmpDir, "renamed_handle2.use") + err = os.WriteFile(bearer_token_file, tmpFile, 0644) + assert.NoError(t, err) + os.Setenv("_CONDOR_CREDS", tmpDir) + renamedUrl, err = url.Parse("renamed.handle2+osdf:///user/ligo/frames") + assert.NoError(t, err) + renamedNamespace, err = namespaces.MatchNamespace("/user/ligo/frames") + assert.NoError(t, err) + token, err = getToken(renamedUrl, renamedNamespace, false, "") + assert.NoError(t, err) + assert.Equal(t, token_contents, token) + os.Unsetenv("_CONDOR_CREDS") + + // _CONDOR_CREDS/renamed.handle3.use via renamed.handle3+osdf:///user/ligo/frames + token_contents = "bearer_token_file_contents renamed.handle3.use" + tmpFile = []byte(token_contents) + tmpDir = t.TempDir() + bearer_token_file = filepath.Join(tmpDir, "renamed.handle3.use") + err = os.WriteFile(bearer_token_file, tmpFile, 0644) + assert.NoError(t, err) + os.Setenv("_CONDOR_CREDS", tmpDir) + renamedUrl, err = url.Parse("renamed.handle3+osdf:///user/ligo/frames") + assert.NoError(t, err) + renamedNamespace, err = namespaces.MatchNamespace("/user/ligo/frames") + assert.NoError(t, err) + token, err = getToken(renamedUrl, renamedNamespace, false, "") + assert.NoError(t, err) + assert.Equal(t, token_contents, token) + os.Unsetenv("_CONDOR_CREDS") + // _CONDOR_CREDS/renamed.use token_contents = "bearer_token_file_contents renamed.use" tmpFile = []byte(token_contents)