mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
fa180ad585
Summary: This stack updates eden to be able to check all of the locations that able users certificate may reside. There can be multiple places where a cert may reside (we cant always definitively choose one place to look based on the platform). Thus we need to be able to configure multiple locations for certs in our eden config. This makes the switch over in eden from using one place for the client cert to use and using the first available client cert from a list. NOTE: most of this diff is fixing unit tests take a look at `EdenConfig.h` and `EdenConfig.cpp` first Reviewed By: wez Differential Revision: D23359939 fbshipit-source-id: 44beecce3ef098a734dbd7c5eb3fa5f0aad6b50b
122 lines
3.5 KiB
C++
122 lines
3.5 KiB
C++
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
#include "eden/fs/config/FieldConverter.h"
|
|
|
|
#include <folly/Conv.h>
|
|
|
|
#include "eden/fs/utils/ChronoParse.h"
|
|
|
|
using folly::Expected;
|
|
using std::string;
|
|
|
|
namespace {
|
|
constexpr std::array<folly::StringPiece, 4> kEnvVars = {
|
|
folly::StringPiece{"HOME"},
|
|
folly::StringPiece{"USER"},
|
|
folly::StringPiece{"USER_ID"},
|
|
folly::StringPiece{"THRIFT_TLS_CL_CERT_PATH"},
|
|
};
|
|
|
|
/**
|
|
* Check if string represents a well-formed file path.
|
|
*/
|
|
bool isValidAbsolutePath(folly::StringPiece path) {
|
|
// All we really care about here is making sure that
|
|
// normalizeBestEffort() isn't going to treat the path as relatively. We
|
|
// probably should just add an option to normalizeBestEffort() to make it
|
|
// reject relative paths.
|
|
try {
|
|
facebook::eden::detail::AbsolutePathSanityCheck()(path);
|
|
return true;
|
|
} catch (std::domain_error&) {
|
|
return false;
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
namespace facebook {
|
|
namespace eden {
|
|
|
|
Expected<AbsolutePath, string> FieldConverter<AbsolutePath>::fromString(
|
|
folly::StringPiece value,
|
|
const std::map<string, string>& convData) const {
|
|
auto sString = value.str();
|
|
for (auto varName : kEnvVars) {
|
|
auto it = convData.find(varName.str());
|
|
if (it != convData.end()) {
|
|
auto envVar = folly::to<string>("${", varName, "}");
|
|
// There may be multiple ${USER} tokens to replace, so loop
|
|
// until we've processed all of them
|
|
while (true) {
|
|
auto idx = sString.find(envVar);
|
|
if (idx == string::npos) {
|
|
break;
|
|
}
|
|
sString.replace(idx, envVar.size(), it->second);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!::isValidAbsolutePath(sString)) {
|
|
return folly::makeUnexpected<string>(folly::to<string>(
|
|
"Cannot convert value '", value, "' to an absolute path"));
|
|
}
|
|
// normalizeBestEffort typically will not throw, but, we want to handle
|
|
// cases where it does, eg. getcwd fails.
|
|
try {
|
|
return facebook::eden::normalizeBestEffort(sString);
|
|
} catch (const std::exception& ex) {
|
|
return folly::makeUnexpected<string>(folly::to<string>(
|
|
"Failed to convert value '",
|
|
value,
|
|
"' to an absolute path, error : ",
|
|
ex.what()));
|
|
}
|
|
}
|
|
|
|
Expected<string, string> FieldConverter<string>::fromString(
|
|
folly::StringPiece value,
|
|
const std::map<string, string>& /* unused */) const {
|
|
return folly::makeExpected<string, string>(value.toString());
|
|
}
|
|
|
|
Expected<std::chrono::nanoseconds, string>
|
|
FieldConverter<std::chrono::nanoseconds>::fromString(
|
|
folly::StringPiece value,
|
|
const std::map<string, string>& /* unused */) const {
|
|
auto result = stringToDuration(value);
|
|
if (result.hasValue()) {
|
|
return result.value();
|
|
}
|
|
return folly::makeUnexpected(chronoParseErrorToString(result.error()).str());
|
|
}
|
|
|
|
std::string FieldConverter<std::chrono::nanoseconds>::toDebugString(
|
|
std::chrono::nanoseconds value) const {
|
|
return durationToString(value);
|
|
}
|
|
|
|
Expected<std::shared_ptr<re2::RE2>, string>
|
|
FieldConverter<std::shared_ptr<re2::RE2>>::fromString(
|
|
folly::StringPiece value,
|
|
const std::map<string, string>& /* unused */) const {
|
|
// value is a regex
|
|
return std::make_shared<re2::RE2>(value.str());
|
|
}
|
|
|
|
std::string FieldConverter<std::shared_ptr<re2::RE2>>::toDebugString(
|
|
std::shared_ptr<re2::RE2> value) const {
|
|
if (value) {
|
|
return value->pattern();
|
|
}
|
|
return "";
|
|
}
|
|
|
|
} // namespace eden
|
|
} // namespace facebook
|