blob: 6e9f4aabfa810a4569acdcbeb9491f928e29bb9d [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef __CREDENTIALS_HPP__
#define __CREDENTIALS_HPP__
#include <string>
#include <vector>
#include <stout/option.hpp>
#include <stout/path.hpp>
#include <stout/protobuf.hpp>
#include <stout/try.hpp>
#include <stout/os/permissions.hpp>
#include <stout/os/read.hpp>
namespace mesos {
namespace internal {
namespace credentials {
inline Result<Credentials> read(const Path& path)
{
LOG(INFO) << "Loading credentials for authentication from '" << path << "'";
Try<std::string> read = os::read(path.string());
if (read.isError()) {
return Error("Failed to read credentials file '" + path.string() +
"': " + read.error());
} else if (read->empty()) {
return None();
}
Try<os::Permissions> permissions = os::permissions(path.string());
if (permissions.isError()) {
LOG(WARNING) << "Failed to stat credentials file '" << path
<< "': " << permissions.error();
} else if (permissions->others.rwx) {
LOG(WARNING) << "Permissions on credentials file '" << path
<< "' are too open; it is recommended that your"
<< " credentials file is NOT accessible by others";
}
// TODO(nfnt): Remove text format support at the end of the deprecation cycle
// which started with version 1.0.
Try<JSON::Object> json = JSON::parse<JSON::Object>(read.get());
if (!json.isError()) {
Try<Credentials> credentials = ::protobuf::parse<Credentials>(json.get());
if (!credentials.isError()) {
return credentials.get();
}
}
Credentials credentials;
foreach (const std::string& line, strings::tokenize(read.get(), "\n")) {
const std::vector<std::string>& pairs = strings::tokenize(line, " ");
if (pairs.size() != 2) {
return Error("Invalid credential format at line " +
stringify(credentials.credentials().size() + 1));
}
// Add the credential.
Credential* credential = credentials.add_credentials();
credential->set_principal(pairs[0]);
credential->set_secret(pairs[1]);
}
return credentials;
}
inline Result<Credential> readCredential(const Path& path)
{
LOG(INFO) << "Loading credential for authentication from '" << path << "'";
Try<std::string> read = os::read(path.string());
if (read.isError()) {
return Error("Failed to read credential file '" + path.string() +
"': " + read.error());
} else if (read->empty()) {
return None();
}
Try<os::Permissions> permissions = os::permissions(path.string());
if (permissions.isError()) {
LOG(WARNING) << "Failed to stat credential file '" << path
<< "': " << permissions.error();
} else if (permissions->others.rwx) {
LOG(WARNING) << "Permissions on credential file '" << path
<< "' are too open; it is recommended that your"
<< " credential file is NOT accessible by others";
}
Try<JSON::Object> json = JSON::parse<JSON::Object>(read.get());
if (!json.isError()) {
Try<Credential> credential = ::protobuf::parse<Credential>(json.get());
if (!credential.isError()) {
return credential.get();
}
}
// TODO(nfnt): Remove text format support at the end of the deprecation cycle
// which started with version 1.0.
Credential credential;
const std::vector<std::string>& line = strings::tokenize(read.get(), "\n");
if (line.size() != 1) {
return Error("Expecting only one credential");
}
const std::vector<std::string>& pairs = strings::tokenize(line[0], " ");
if (pairs.size() != 2) {
return Error("Invalid credential format");
}
// Add the credential.
credential.set_principal(pairs[0]);
credential.set_secret(pairs[1]);
return credential;
}
} // namespace credentials {
} // namespace internal {
} // namespace mesos {
#endif // __CREDENTIALS_HPP__