blob: 38885caa664d1f495a8dbf369d6e2bf9e8fdb0e1 [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.
#include <string>
#include <gtest/gtest.h>
#include <mesos/mesos.hpp>
#include <mesos/authorizer/authorizer.hpp>
#include <mesos/module/authorizer.hpp>
#include <stout/try.hpp>
#include "authorizer/local/authorizer.hpp"
#include "tests/mesos.hpp"
#include "tests/module.hpp"
using namespace process;
namespace mesos {
namespace internal {
namespace tests {
using std::string;
template <typename T>
class AuthorizationTest : public MesosTest {};
typedef ::testing::Types<LocalAuthorizer,
tests::Module<Authorizer, TestLocalAuthorizer>>
AuthorizerTypes;
TYPED_TEST_CASE(AuthorizationTest, AuthorizerTypes);
TYPED_TEST(AuthorizationTest, AnyPrincipalRunAsUser)
{
ACLs acls;
{
// Any principal can run as "guest" user.
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_users()->add_values("guest");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can run as "guest", using TaskInfo.command.user,
// TaskInfo.ExecutorInfo.command.user, or FrameworkInfo.user.
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
CommandInfo* commandInfo = taskInfo.mutable_command();
commandInfo->set_user("guest");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("guest");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
taskInfo.mutable_executor()->mutable_command()->set_user("guest");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "foo" can run as "root" since the ACLs are permissive.
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
CommandInfo* commandInfo = taskInfo.mutable_command();
commandInfo->set_user("root");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "foo" can run as "root" since the ACLs are permissive.
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("root");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
taskInfo.mutable_executor()->mutable_command()->set_user("root");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, NoPrincipalRunAsUser)
{
// No principal can run as "root" user.
ACLs acls;
{
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE);
acl->mutable_users()->add_values("root");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" cannot run as "root".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
CommandInfo* commandInfo = taskInfo.mutable_command();
commandInfo->set_user("root");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("root");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
taskInfo.mutable_executor()->mutable_command()->set_user("root");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, PrincipalRunAsAnyUser)
{
// A principal "foo" can run as any user.
ACLs acls;
acls.set_permissive(false); // Restrictive.
{
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->set_type(mesos::ACL::Entity::ANY);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can run as "user1" and "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");;
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, AnyPrincipalRunAsAnyUser)
{
// Any principal can run as any user.
ACLs acls;
acls.set_permissive(false); // Restrictive.
{
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_users()->set_type(mesos::ACL::Entity::ANY);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principals "foo" and "bar" can run as "user1" and "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, OnlySomePrincipalsRunAsSomeUsers)
{
// Only some principals can run as some users.
ACLs acls;
{
// ACL for some principals to run as some users.
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->add_values("foo");
acl->mutable_principals()->add_values("bar");
acl->mutable_users()->add_values("user1");
acl->mutable_users()->add_values("user2");
}
{
// ACL for no one else to run as some users.
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE);
acl->mutable_users()->add_values("user1");
acl->mutable_users()->add_values("user2");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principals "foo" and "bar" can run as "user1" and "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "baz" cannot run as "user1".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("baz");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "baz" cannot run as "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("baz");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, SomePrincipalOnlySomeUser)
{
// Some principal can run as only some user.
ACLs acls;
// ACL for some principal to run as some user.
{
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->add_values("user1");
}
{
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can run as "user1".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "foo" cannot run as "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" can run as "user1" and "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, PrincipalRunAsSomeUserRestrictive)
{
ACLs acls;
acls.set_permissive(false); // Restrictive.
{
// A principal can run as "user1";
mesos::ACL::RunTask* acl = acls.add_run_tasks();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->add_values("user1");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can run as "user1".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user1");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "foo" cannot run as "user2".
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
taskInfo.mutable_command()->set_user("user2");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("foo");
TaskInfo taskInfo;
taskInfo.mutable_executor()->mutable_command()->set_user("user2");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot run as "user2" since no ACL is set.
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
TaskInfo taskInfo;
CommandInfo* commandInfo = taskInfo.mutable_command();
commandInfo->set_user("user2");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
FrameworkInfo frameworkInfo;
frameworkInfo.set_user("user2");
request.mutable_object()->mutable_framework_info()->CopyFrom(frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RUN_TASK);
request.mutable_subject()->set_value("bar");
TaskInfo taskInfo;
taskInfo.mutable_executor()->mutable_command()->set_user("user2");
request.mutable_object()->mutable_task_info()->CopyFrom(taskInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, AnyPrincipalOfferedRole)
{
ACLs acls;
{
// Any principal can be offered "*" role's resources.
mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->add_values("*");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principals "foo" and "bar" can be offered "*" role's resources.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("*");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("*");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, SomePrincipalsOfferedRole)
{
ACLs acls;
{
// Some principals can be offered "ads" role's resources.
mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks();
acl->mutable_principals()->add_values("foo");
acl->mutable_principals()->add_values("bar");
acl->mutable_roles()->add_values("ads");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principals "foo", "bar" and "baz" (no ACL) can be offered "ads"
// role's resources.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("ads");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("ads");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("baz");
request.mutable_object()->set_value("ads");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, PrincipalOfferedRole)
{
// Only a principal can be offered "analytics" role's resources.
ACLs acls;
{
// ACL for a principal to be offered "analytics" role's resources.
mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->add_values("analytics");
}
{
// ACL for no one else to be offered "analytics" role's resources.
mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::NONE);
acl->mutable_roles()->add_values("analytics");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can be offered "analytics" role's resources.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("analytics");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot be offered "analytics" role's resources.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("analytics");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, PrincipalNotOfferedAnyRoleRestrictive)
{
ACLs acls;
acls.set_permissive(false);
{
// A principal "foo" can be offered "analytics" role's resources.
mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->add_values("analytics");
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can be offered "analytics" role's resources.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("analytics");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot be offered "analytics" role's resources.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("analytics");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot be offered "ads" role's resources because no ACL.
{
authorization::Request request;
request.set_action(authorization::REGISTER_FRAMEWORK_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("ads");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// Tests the authorization of ACLs used for dynamic reservation of resources.
TYPED_TEST(AuthorizationTest, Reserve)
{
ACLs acls;
{
// Principals "foo" and "bar" can reserve resources for any role.
mesos::ACL::ReserveResources* acl = acls.add_reserve_resources();
acl->mutable_principals()->add_values("foo");
acl->mutable_principals()->add_values("bar");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// Principal "baz" can only reserve resources for the "ads" role.
mesos::ACL::ReserveResources* acl = acls.add_reserve_resources();
acl->mutable_principals()->add_values("baz");
acl->mutable_roles()->add_values("ads");
}
{
// No other principals can reserve resources.
mesos::ACL::ReserveResources* acl = acls.add_reserve_resources();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principals "foo" and "bar" can reserve resources for any role,
// so requests 1 and 2 will pass.
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("bar");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("awesome_role");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("awesome_role");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "baz" can only reserve resources for the "ads" role, so request 3
// will pass, but requests 4 and 5 will fail.
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("baz");
request.mutable_object()->set_value("ads");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("baz");
request.mutable_object()->set_value("awesome_role");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("baz");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "zelda" is not mentioned in the ACLs of the Authorizer, so it
// will be caught by the final ACL, which provides a default case that denies
// access for all other principals. This request will fail.
{
authorization::Request request;
request.set_action(authorization::RESERVE_RESOURCES_WITH_ROLE);
request.mutable_subject()->set_value("zelda");
request.mutable_object()->set_value("ads");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of ACLs used for unreserve
// operations on dynamically reserved resources.
TYPED_TEST(AuthorizationTest, Unreserve)
{
ACLs acls;
{
// "foo" principal can unreserve its own resources.
mesos::ACL::UnreserveResources* acl = acls.add_unreserve_resources();
acl->mutable_principals()->add_values("foo");
acl->mutable_reserver_principals()->add_values("foo");
}
{
// "bar" principal cannot unreserve anyone's resources.
mesos::ACL::UnreserveResources* acl = acls.add_unreserve_resources();
acl->mutable_principals()->add_values("bar");
acl->mutable_reserver_principals()->set_type(mesos::ACL::Entity::NONE);
}
{
// "ops" principal can unreserve anyone's resources.
mesos::ACL::UnreserveResources* acl = acls.add_unreserve_resources();
acl->mutable_principals()->add_values("ops");
acl->mutable_reserver_principals()->set_type(mesos::ACL::Entity::ANY);
}
{
// No other principals can unreserve resources.
mesos::ACL::UnreserveResources* acl = acls.add_unreserve_resources();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_reserver_principals()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can unreserve its own resources.
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot unreserve anyone's
// resources, so requests 2 and 3 will fail.
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("bar");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can unreserve anyone's resources,
// so requests 4 and 5 will succeed.
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("bar");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("ops");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "zelda" is not mentioned in the ACLs of the Authorizer, so it
// will be caught by the final ACL, which provides a default case that denies
// access for all other principals. This case will fail.
{
authorization::Request request;
request.set_action(authorization::UNRESERVE_RESOURCES_WITH_PRINCIPAL);
request.mutable_subject()->set_value("zelda");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// Tests the authorization of ACLs used for the creation of persistent volumes.
TYPED_TEST(AuthorizationTest, CreateVolume)
{
ACLs acls;
{
// Principal "foo" can create volumes for any role.
mesos::ACL::CreateVolume* acl = acls.add_create_volumes();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// Principal "bar" can only create volumes for the "panda" role.
mesos::ACL::CreateVolume* acl = acls.add_create_volumes();
acl->mutable_principals()->add_values("bar");
acl->mutable_roles()->add_values("panda");
}
{
// Principal "baz" cannot create volumes.
mesos::ACL::CreateVolume* acl = acls.add_create_volumes();
acl->mutable_principals()->add_values("baz");
acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
}
{
// No other principals can create volumes.
mesos::ACL::CreateVolume* acl = acls.add_create_volumes();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can create volumes for any role, so this request will pass.
{
authorization::Request request;
request.set_action(authorization::CREATE_VOLUME_WITH_ROLE);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("awesome_role");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can create volumes for the "panda" role,
// so this request will pass.
{
authorization::Request request;
request.set_action(authorization::CREATE_VOLUME_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("panda");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot create volumes for the "giraffe" role,
// so this request will fail.
{
authorization::Request request;
request.set_action(authorization::CREATE_VOLUME_WITH_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("giraffe");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "baz" cannot create volumes for any role,
// so this request will fail.
{
authorization::Request request;
request.set_action(authorization::CREATE_VOLUME_WITH_ROLE);
request.mutable_subject()->set_value("baz");
request.mutable_object()->set_value("panda");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "zelda" is not mentioned in the ACLs of the Authorizer, so it
// will be caught by the final ACL, which provides a default case that denies
// access for all other principals. This request will fail.
{
authorization::Request request;
request.set_action(authorization::CREATE_VOLUME_WITH_ROLE);
request.mutable_subject()->set_value("zelda");
request.mutable_object()->set_value("panda");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of ACLs used for destruction
// operations on persistent volumes.
TYPED_TEST(AuthorizationTest, DestroyVolume)
{
ACLs acls;
{
// "foo" principal can destroy its own volumes.
mesos::ACL::DestroyVolume* acl = acls.add_destroy_volumes();
acl->mutable_principals()->add_values("foo");
acl->mutable_creator_principals()->add_values("foo");
}
{
// "bar" principal cannot destroy anyone's volumes.
mesos::ACL::DestroyVolume* acl = acls.add_destroy_volumes();
acl->mutable_principals()->add_values("bar");
acl->mutable_creator_principals()->set_type(mesos::ACL::Entity::NONE);
}
{
// "ops" principal can destroy anyone's volumes.
mesos::ACL::DestroyVolume* acl = acls.add_destroy_volumes();
acl->mutable_principals()->add_values("ops");
acl->mutable_creator_principals()->set_type(mesos::ACL::Entity::ANY);
}
{
// No other principals can destroy volumes.
mesos::ACL::DestroyVolume* acl = acls.add_destroy_volumes();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_creator_principals()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can destroy its own volumes, so this will pass.
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot destroy anyone's
// volumes, so requests 2 and 3 will fail.
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("bar");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can destroy anyone's volumes,
// so requests 4 and 5 will succeed.
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("ops");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("bar");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "zelda" is not mentioned in the ACLs of the Authorizer, so it
// will be caught by the final ACL, which provides a default case that denies
// access for all other principals. This case will fail.
{
authorization::Request request;
request.set_action(authorization::DESTROY_VOLUME_WITH_PRINCIPAL);
request.mutable_subject()->set_value("zelda");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of requests to update quotas.
TYPED_TEST(AuthorizationTest, UpdateQuota)
{
ACLs acls;
{
// "foo" principal can update quotas for all roles.
mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// "bar" principal can update quotas for "dev" role.
mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
acl->mutable_principals()->add_values("bar");
acl->mutable_roles()->add_values("dev");
}
{
// Anyone can update quotas for "test" role.
mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->add_values("test");
}
{
// No other principal can update quotas.
mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can update quota for all roles, so this will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("foo");
request.mutable_object()->mutable_quota_info()->set_role("prod");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can update quotas for role "dev", so this will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_quota_info()->set_role("dev");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can only update quotas for role "dev", so this will fail.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_quota_info()->set_role("prod");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Anyone can update quotas for role "test", so this will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_object()->mutable_quota_info()->set_role("test");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "jeff" is not mentioned in the ACLs of the `Authorizer`, so it
// will be caught by the final ACL, which provides a default case that denies
// access for all other principals. This case will fail.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("jeff");
request.mutable_object()->mutable_quota_info()->set_role("prod");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// This tests that update_quotas and set_quotas/remove_quotas
// cannot be used together.
// TODO(zhitao): Remove this test case at the end of the deprecation
// cycle started with 1.0.
TYPED_TEST(AuthorizationTest, ConflictQuotaACLs) {
{
ACLs acls;
{
// Add an UpdateQuota ACL.
mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// Add a SetQuota ACL.
mesos::ACL::SetQuota* acl = acls.add_set_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
// Create an `Authorizer` with the ACLs should error out.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_ERROR(create);
}
{
ACLs acls;
{
// Add an UpdateQuota ACL.
mesos::ACL::UpdateQuota* acl = acls.add_update_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// Add a RemoveQuota ACL.
mesos::ACL::RemoveQuota* acl = acls.add_remove_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_quota_principals()->set_type(mesos::ACL::Entity::ANY);
}
// Create an `Authorizer` with the ACLs should error out.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_ERROR(create);
}
}
// This tests the authorization of requests to set quotas.
// TODO(zhitao): Remove this test case at the end of the deprecation
// cycle started with 1.0.
TYPED_TEST(AuthorizationTest, SetQuota)
{
ACLs acls;
{
// "foo" principal can set quotas for all roles.
mesos::ACL::SetQuota* acl = acls.add_set_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// "bar" principal can set quotas for "dev" role.
mesos::ACL::SetQuota* acl = acls.add_set_quotas();
acl->mutable_principals()->add_values("bar");
acl->mutable_roles()->add_values("dev");
}
{
// Anyone can set quotas for "test" role.
mesos::ACL::SetQuota* acl = acls.add_set_quotas();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->add_values("test");
}
{
// No other principal can set quotas.
mesos::ACL::SetQuota* acl = acls.add_set_quotas();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can set quota for all roles, so this will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("SetQuota");
request.mutable_object()->mutable_quota_info()->set_role("prod");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can set quotas for role "dev", so this will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("SetQuota");
request.mutable_object()->mutable_quota_info()->set_role("dev");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can only set quotas for role "dev", so this will fail.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("SetQuota");
request.mutable_object()->mutable_quota_info()->set_role("prod");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Anyone can set quotas for role "test", so request 6 will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_object()->set_value("SetQuota");
request.mutable_object()->mutable_quota_info()->set_role("test");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "jeff" is not mentioned in the ACLs of the `Authorizer`, so it
// will be caught by the final ACL, which provides a default case that denies
// access for all other principals. This case will fail.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("jeff");
request.mutable_object()->set_value("SetQuota");
request.mutable_object()->mutable_quota_info()->set_role("prod");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of requests to remove quotas.
// TODO(zhitao): Remove this test case at the end of the deprecation
// cycle started with 1.0.
TYPED_TEST(AuthorizationTest, RemoveQuota)
{
ACLs acls;
{
// "foo" principal can remove its own quotas.
mesos::ACL::RemoveQuota* acl = acls.add_remove_quotas();
acl->mutable_principals()->add_values("foo");
acl->mutable_quota_principals()->add_values("foo");
}
{
// "bar" principal cannot remove anyone's quotas.
mesos::ACL::RemoveQuota* acl = acls.add_remove_quotas();
acl->mutable_principals()->add_values("bar");
acl->mutable_quota_principals()->set_type(mesos::ACL::Entity::NONE);
}
{
// "ops" principal can remove anyone's quotas.
mesos::ACL::RemoveQuota* acl = acls.add_remove_quotas();
acl->mutable_principals()->add_values("ops");
acl->mutable_quota_principals()->set_type(mesos::ACL::Entity::ANY);
}
{
// No other principals can remove quotas.
mesos::ACL::RemoveQuota* acl = acls.add_remove_quotas();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_quota_principals()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Principal "foo" can remove its own quotas, so request 1 will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("foo");
request.mutable_object()->set_value("RemoveQuota");
request.mutable_object()->mutable_quota_info()->set_principal("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot remove anyone's quotas, so requests 2 and 3 will
// fail.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("RemoveQuota");
request.mutable_object()->mutable_quota_info()->set_principal("bar");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("RemoveQuota");
request.mutable_object()->mutable_quota_info()->set_principal("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can remove anyone's quotas, so requests 4 and 5 will pass.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("RemoveQuota");
request.mutable_object()->mutable_quota_info()->set_principal("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("ops");
request.mutable_object()->set_value("RemoveQuota");
request.mutable_object()->mutable_quota_info();
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "jeff" is not mentioned in the ACLs of the `Authorizer`, so it
// will be caught by the final rule, which provides a default case that denies
// access for all other principals. This case will fail.
{
authorization::Request request;
request.set_action(authorization::UPDATE_QUOTA);
request.mutable_subject()->set_value("jeff");
request.mutable_object()->set_value("RemoveQuota");
request.mutable_object()->mutable_quota_info()->set_principal("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of requests to ViewFramework.
TYPED_TEST(AuthorizationTest, ViewFramework)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal can view no frameworks.
mesos::ACL::ViewFramework* acl = acls.add_view_frameworks();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
{
// "bar" principal can see frameworks running under user "bar".
mesos::ACL::ViewFramework* acl = acls.add_view_frameworks();
acl->mutable_principals()->add_values("bar");
acl->mutable_users()->add_values("bar");
}
{
// "ops" principal can see all frameworks.
mesos::ACL::ViewFramework* acl = acls.add_view_frameworks();
acl->mutable_principals()->add_values("ops");
acl->mutable_users()->set_type(mesos::ACL::Entity::ANY);
}
{
// No one else can view any frameworks.
mesos::ACL::ViewFramework* acl = acls.add_view_frameworks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Create FrameworkInfo with a generic user as object to authorized.
FrameworkInfo frameworkInfo;
{
frameworkInfo.set_user("user");
frameworkInfo.set_name("f");
}
// Create FrameworkInfo with user "bar" as object to authorized.
FrameworkInfo frameworkInfoBar;
{
frameworkInfoBar.set_user("bar");
frameworkInfoBar.set_name("f");
}
// Principal "foo" cannot view frameworkInfo running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_FRAMEWORK);
request.mutable_subject()->set_value("foo");
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot view a framework Info running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_FRAMEWORK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can view a frameworkInfo running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_FRAMEWORK);
request.mutable_subject()->set_value("ops");
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a frameworkInfo running with user "bar".
{
authorization::Request request;
request.set_action(authorization::VIEW_FRAMEWORK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of requests to ViewTasks.
TYPED_TEST(AuthorizationTest, ViewTask)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal can view no Task.
mesos::ACL::ViewTask* acl = acls.add_view_tasks();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
{
// "bar" principal can see tasks running under user "bar".
mesos::ACL::ViewTask* acl = acls.add_view_tasks();
acl->mutable_principals()->add_values("bar");
acl->mutable_users()->add_values("bar");
}
{
// "ops" principal can see all tasks.
mesos::ACL::ViewTask* acl = acls.add_view_tasks();
acl->mutable_principals()->add_values("ops");
acl->mutable_users()->set_type(mesos::ACL::Entity::ANY);
}
{
// No one else can view any tasks.
mesos::ACL::ViewTask* acl = acls.add_view_tasks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Create TaskInfo with a generic user as object to be authorized.
TaskInfo taskInfo;
{
taskInfo.set_name("Task");
taskInfo.mutable_task_id()->set_value("t");
taskInfo.mutable_slave_id()->set_value("s");
taskInfo.mutable_command()->set_value("echo hello");
taskInfo.mutable_command()->set_user("user");
}
// Create TaskInfo with user "bar" as object to be authorized.
TaskInfo taskInfoBar;
{
taskInfoBar.set_name("Task");
taskInfoBar.mutable_task_id()->set_value("t");
taskInfoBar.mutable_slave_id()->set_value("s");
taskInfoBar.mutable_command()->set_value("echo hello");
taskInfoBar.mutable_command()->set_user("bar");
}
// Create TaskInfo with user "bar" as object to be authorized.
TaskInfo taskInfoNoUser;
{
taskInfoNoUser.set_name("Task");
taskInfoNoUser.mutable_task_id()->set_value("t");
taskInfoNoUser.mutable_slave_id()->set_value("s");
taskInfoNoUser.mutable_command()->set_value("echo hello");
}
// Create ExecutorInfo with a generic user in command.
ExecutorInfo executorInfo;
{
executorInfo.set_name("Task");
executorInfo.mutable_executor_id()->set_value("t");
executorInfo.mutable_command()->set_value("echo hello");
executorInfo.mutable_command()->set_user("user");
}
// Create ExecutorInfo with user "bar" in command.
ExecutorInfo executorInfoBar;
{
executorInfoBar.set_name("Task");
executorInfoBar.mutable_executor_id()->set_value("t");
executorInfoBar.mutable_command()->set_value("echo hello");
executorInfoBar.mutable_command()->set_user("bar");
}
// Create TaskInfo with ExecutorInfo containing generic user.
TaskInfo taskInfoExecutor;
{
taskInfoExecutor.set_name("Task");
taskInfoExecutor.mutable_task_id()->set_value("t");
taskInfoExecutor.mutable_slave_id()->set_value("s");
taskInfoExecutor.mutable_command()->set_value("echo hello");
taskInfoExecutor.mutable_executor()->MergeFrom(executorInfo);
}
// Create TaskInfo with ExecutorInfo containing user "bar".
TaskInfo taskInfoExecutorBar;
{
taskInfoExecutorBar.set_name("Task");
taskInfoExecutorBar.mutable_task_id()->set_value("t");
taskInfoExecutorBar.mutable_slave_id()->set_value("s");
taskInfoExecutorBar.mutable_executor()->MergeFrom(executorInfoBar);
}
// Create Task with a generic user as object to be authorized.
Task task;
{
task.set_name("Task");
task.mutable_task_id()->set_value("t");
task.mutable_slave_id()->set_value("s");
task.set_state(TaskState::TASK_STARTING);
task.set_user("user");
}
// Create Task with user "bar" as object to be authorized.
Task taskBar;
{
taskBar.set_name("Task");
taskBar.mutable_task_id()->set_value("t");
taskBar.mutable_slave_id()->set_value("s");
taskBar.set_state(TaskState::TASK_STARTING);
taskBar.set_user("bar");
}
// Create FrameworkInfo with a generic user as object to authorized.
FrameworkInfo frameworkInfo;
{
frameworkInfo.set_user("user");
frameworkInfo.set_name("f");
}
// Create FrameworkInfo with user "bar" as object to authorized.
FrameworkInfo frameworkInfoBar;
{
frameworkInfoBar.set_user("bar");
frameworkInfoBar.set_name("f");
}
// Checks for the combination TaskInfo and FrameworkInfo.
// Principal "foo" cannot view a request with taskInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("foo");
request.mutable_object()->mutable_task_info()->MergeFrom(taskInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot view a request with taskInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task_info()->MergeFrom(taskInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can view a request with taskInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("ops");
request.mutable_object()->mutable_task_info()->MergeFrom(taskInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a request with taskInfo and frameworkInfo
// running with user "bar".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task_info()->MergeFrom(taskInfoBar);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a request with a taskInfo without user
// and frameworkInfo running with user "bar".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task_info()->MergeFrom(taskInfoNoUser);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot view a request with a taskInfo containing an
// executorInfo with generic user.
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task_info()->MergeFrom(taskInfoExecutor);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a request with a taskInfo containing an
// executorInfo with user bar.
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task_info()->MergeFrom(
taskInfoExecutorBar);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Checks for the combination Task and FrameworkInfo.
// Principal "foo" cannot view a request with task and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("foo");
request.mutable_object()->mutable_task()->MergeFrom(task);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot view a request with task and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task()->MergeFrom(task);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can view a request with taskInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("ops");
request.mutable_object()->mutable_task()->MergeFrom(task);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a request with task and frameworkInfo
// running with user "bar".
{
authorization::Request request;
request.set_action(authorization::VIEW_TASK);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_task()->MergeFrom(taskBar);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of requests to ViewExecutor.
TYPED_TEST(AuthorizationTest, ViewExecutor)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal can view no executor.
mesos::ACL::ViewExecutor* acl = acls.add_view_executors();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
{
// "bar" principal can see executors running under user "bar".
mesos::ACL::ViewExecutor* acl = acls.add_view_executors();
acl->mutable_principals()->add_values("bar");
acl->mutable_users()->add_values("bar");
}
{
// "ops" principal can see all executors.
mesos::ACL::ViewExecutor* acl = acls.add_view_executors();
acl->mutable_principals()->add_values("ops");
acl->mutable_users()->set_type(mesos::ACL::Entity::ANY);
}
{
// No one else can view any executors.
mesos::ACL::ViewExecutor* acl = acls.add_view_executors();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Create ExecutorInfo with a generic user in command as object to
// be authorized.
ExecutorInfo executorInfo;
{
executorInfo.set_name("Task");
executorInfo.mutable_executor_id()->set_value("t");
executorInfo.mutable_command()->set_value("echo hello");
executorInfo.mutable_command()->set_user("user");
}
// Create ExecutorInfo with user "bar" in command as object to
// be authorized.
ExecutorInfo executorInfoBar;
{
executorInfoBar.set_name("Executor");
executorInfoBar.mutable_executor_id()->set_value("e");
executorInfoBar.mutable_command()->set_value("echo hello");
executorInfoBar.mutable_command()->set_user("bar");
}
// Create ExecutorInfo with no user in command as object to
// be authorized.
ExecutorInfo executorInfoNoUser;
{
executorInfoNoUser.set_name("Executor");
executorInfoNoUser.mutable_executor_id()->set_value("e");
executorInfoNoUser.mutable_command()->set_value("echo hello");
}
// Create FrameworkInfo with a generic user as object to authorized.
FrameworkInfo frameworkInfo;
{
frameworkInfo.set_user("user");
frameworkInfo.set_name("f");
}
// Create FrameworkInfo with user "bar" as object to authorized.
FrameworkInfo frameworkInfoBar;
{
frameworkInfoBar.set_user("bar");
frameworkInfoBar.set_name("f");
}
// Principal "foo" cannot view a request with executorInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_EXECUTOR);
request.mutable_subject()->set_value("foo");
request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot view a request with executorInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_EXECUTOR);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can view a request with executorInfo and frameworkInfo
// running with user "user".
{
authorization::Request request;
request.set_action(authorization::VIEW_EXECUTOR);
request.mutable_subject()->set_value("ops");
request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a request with executorInfo and frameworkInfo
// running with user "bar".
{
authorization::Request request;
request.set_action(authorization::VIEW_EXECUTOR);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_executor_info()->MergeFrom(
executorInfoBar);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can view a request with a executorInfo without user
// and frameworkInfo running with user "bar".
{
authorization::Request request;
request.set_action(authorization::VIEW_EXECUTOR);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_executor_info()->MergeFrom(
executorInfoNoUser);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
// This tests the authorization of sandboxe access.
TYPED_TEST(AuthorizationTest, SandBoxAccess)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal cannot view any sandboxes.
mesos::ACL::AccessSandbox* acl = acls.add_access_sandboxes();
acl->mutable_principals()->add_values("foo");
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
{
// "bar" principal can see sandboxes running under user "bar".
mesos::ACL::AccessSandbox* acl = acls.add_access_sandboxes();
acl->mutable_principals()->add_values("bar");
acl->mutable_users()->add_values("bar");
}
{
// "ops" principal can see all sandboxes.
mesos::ACL::AccessSandbox* acl = acls.add_access_sandboxes();
acl->mutable_principals()->add_values("ops");
acl->mutable_users()->set_type(mesos::ACL::Entity::ANY);
}
{
// No one else can view any sandboxes.
mesos::ACL::AccessSandbox* acl = acls.add_access_sandboxes();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_users()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Create ExecutorInfo with a user not mentioned in the ACLs in
// command as object to be authorized.
ExecutorInfo executorInfo;
{
executorInfo.set_name("Task");
executorInfo.mutable_executor_id()->set_value("t");
executorInfo.mutable_command()->set_value("echo hello");
executorInfo.mutable_command()->set_user("user");
}
// Create ExecutorInfo with user "bar" in command as object to
// be authorized.
ExecutorInfo executorInfoBar;
{
executorInfoBar.set_name("Executor");
executorInfoBar.mutable_executor_id()->set_value("e");
executorInfoBar.mutable_command()->set_value("echo hello");
executorInfoBar.mutable_command()->set_user("bar");
}
// Create ExecutorInfo with no user in command as object to
// be authorized.
ExecutorInfo executorInfoNoUser;
{
executorInfoNoUser.set_name("Executor");
executorInfoNoUser.mutable_executor_id()->set_value("e");
executorInfoNoUser.mutable_command()->set_value("echo hello");
}
// Create FrameworkInfo with a generic user as object to authorized.
FrameworkInfo frameworkInfo;
{
frameworkInfo.set_user("user");
frameworkInfo.set_name("f");
}
// Create FrameworkInfo with user "bar" as object to authorized.
FrameworkInfo frameworkInfoBar;
{
frameworkInfoBar.set_user("bar");
frameworkInfoBar.set_name("f");
}
// Principal "foo" cannot access a sandbox with a request with
// ExecutorInfo and FrameworkInfo running with user "user".
{
authorization::Request request;
request.set_action(authorization::ACCESS_SANDBOX);
request.mutable_subject()->set_value("foo");
request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "bar" cannot access a sandbox with a request with
// ExecutorInfo and FrameworkInfo running with user "user".
{
authorization::Request request;
request.set_action(authorization::ACCESS_SANDBOX);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Principal "ops" can access a sandbox with a request with
// ExecutorInfo and FrameworkInfo running with user "user".
{
authorization::Request request;
request.set_action(authorization::ACCESS_SANDBOX);
request.mutable_subject()->set_value("ops");
request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfo);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can access a sandbox with a request with
// ExecutorInfo and FrameworkInfo running with user "bar".
{
authorization::Request request;
request.set_action(authorization::ACCESS_SANDBOX);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_executor_info()->MergeFrom(
executorInfoBar);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Principal "bar" can access a sandbox with a request with a
// ExecutorInfo without user and FrameworkInfo running with user
// "bar".
{
authorization::Request request;
request.set_action(authorization::ACCESS_SANDBOX);
request.mutable_subject()->set_value("bar");
request.mutable_object()->mutable_executor_info()->MergeFrom(
executorInfoNoUser);
request.mutable_object()->mutable_framework_info()->MergeFrom(
frameworkInfoBar);
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
// This tests that a missing request.object is allowed for an ACL whose
// Object is ANY.
// NOTE: The only usecase for this behavior is currently teardownFramework.
TYPED_TEST(AuthorizationTest, OptionalObject)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal can teardown `ANY` framework
mesos::ACL::TeardownFramework* acl = acls.add_teardown_frameworks();
acl->mutable_principals()->add_values("foo");
acl->mutable_framework_principals()->set_type(mesos::ACL::Entity::ANY);
}
{
// No other principal can teardown any framework.
mesos::ACL::TeardownFramework* acl = acls.add_teardown_frameworks();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_framework_principals()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Check that principal "foo" can teardown any framework (i.e., a request with
// missing object).
{
authorization::Request request;
request.set_action(authorization::TEARDOWN_FRAMEWORK_WITH_PRINCIPAL);
request.mutable_subject()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Check that principal "bar" cannot teardown any framework (i.e., a request
// with missing object).
{
authorization::Request request;
request.set_action(authorization::TEARDOWN_FRAMEWORK_WITH_PRINCIPAL);
request.mutable_subject()->set_value("bar");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
}
TYPED_TEST(AuthorizationTest, ViewFlags)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal can see the flags.
mesos::ACL::ViewFlags* acl = acls.add_view_flags();
acl->mutable_principals()->add_values("foo");
acl->mutable_flags()->set_type(mesos::ACL::Entity::ANY);
}
{
// Nobody else can see the flags.
mesos::ACL::ViewFlags* acl = acls.add_view_flags();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_flags()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
{
authorization::Request request;
request.set_action(authorization::VIEW_FLAGS);
request.mutable_subject()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
{
authorization::Request request;
request.set_action(authorization::VIEW_FLAGS);
request.mutable_subject()->set_value("bar");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Test that no authorizer is created with invalid flags.
{
ACLs invalid;
mesos::ACL::ViewFlags* acl = invalid.add_view_flags();
acl->mutable_principals()->add_values("foo");
acl->mutable_flags()->add_values("yoda");
Try<Authorizer*> create = TypeParam::create(parameterize(invalid));
EXPECT_ERROR(create);
}
}
// This tests the authorization of ACLs used for unreserve
// operations on dynamically reserved resources.
TYPED_TEST(AuthorizationTest, ValidateEndpoints)
{
{
ACLs acls;
mesos::ACL::GetEndpoint* acl = acls.add_get_endpoints();
acl->mutable_principals()->add_values("foo");
acl->mutable_paths()->add_values("/frameworks");
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
EXPECT_ERROR(create);
}
{
ACLs acls;
mesos::ACL::GetEndpoint* acl = acls.add_get_endpoints();
acl->mutable_principals()->add_values("foo");
acl->mutable_paths()->add_values("/frameworks");
acl->mutable_paths()->add_values("/monitor/statistics");
acl->mutable_paths()->add_values("/containers");
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
EXPECT_ERROR(create);
}
{
ACLs acls;
mesos::ACL::GetEndpoint* acl = acls.add_get_endpoints();
acl->mutable_principals()->add_values("foo");
acl->mutable_paths()->add_values("/monitor/statistics");
acl->mutable_paths()->add_values("/monitor/statistics.json");
acl->mutable_paths()->add_values("/containers");
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
delete create.get();
}
}
// This tests the authorization of requests to ViewRole.
TYPED_TEST(AuthorizationTest, ViewRole)
{
// Setup ACLs.
ACLs acls;
{
// "foo" principal can view `ANY` role.
mesos::ACL::ViewRole* acl = acls.add_view_roles();
acl->mutable_principals()->add_values("foo");
acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY);
}
{
// "bar" principal can view role `bar`.
mesos::ACL::ViewRole* acl = acls.add_view_roles();
acl->mutable_principals()->add_values("bar");
acl->mutable_roles()->add_values("bar");
}
{
// No other principal can view any role.
mesos::ACL::ViewRole* acl = acls.add_view_roles();
acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY);
acl->mutable_roles()->set_type(mesos::ACL::Entity::NONE);
}
// Create an `Authorizer` with the ACLs.
Try<Authorizer*> create = TypeParam::create(parameterize(acls));
ASSERT_SOME(create);
Owned<Authorizer> authorizer(create.get());
// Check that principal "foo" can view any role.
{
authorization::Request request;
request.set_action(authorization::VIEW_ROLE);
request.mutable_subject()->set_value("foo");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
// Check that principal "bar" cannot see role `foo`.
{
authorization::Request request;
request.set_action(authorization::VIEW_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("foo");
AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request));
}
// Check that principal "bar" can see role `bar`.
{
authorization::Request request;
request.set_action(authorization::VIEW_ROLE);
request.mutable_subject()->set_value("bar");
request.mutable_object()->set_value("bar");
AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request));
}
}
} // namespace tests {
} // namespace internal {
} // namespace mesos {