| // 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< |
| // TODO(josephw): Modules are not supported on Windows (MESOS-5994). |
| #ifndef __WINDOWS__ |
| tests::Module<Authorizer, TestLocalAuthorizer>, |
| #endif // __WINDOWS__ |
| LocalAuthorizer> 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); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_framework_info()->set_role("*"); |
| 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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_framework_info()->set_role("*"); |
| 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); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_framework_info()->set_role("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); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_framework_info()->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("baz"); |
| request.mutable_object()->mutable_framework_info()->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_framework_info()->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_framework_info()->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_framework_info()->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_framework_info()->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_framework_info()->set_role("ads"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // Checks that the behavior of the authorizer is correct when using |
| // hierarchical roles while registering frameworks. |
| TYPED_TEST(AuthorizationTest, RegisterFrameworkHierarchical) |
| { |
| ACLs acls; |
| |
| { |
| // "elizabeth-ii" principal can register frameworks with role |
| // `king` and its nested ones. |
| mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // "charles" principal can register frameworks with just roles |
| // nested under `king`. |
| mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // "j-welby" principal register frameworks with just role 'king'. |
| mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // No other principal can register frameworks in any role. |
| mesos::ACL::RegisterFramework* acl = acls.add_register_frameworks(); |
| 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()); |
| |
| // `elizabeth-ii` has full permissions for the `king` role as well as all |
| // its nested roles. She should be able to register frameworks in the next |
| // three blocks. |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->mutable_framework_info()->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_framework_info()->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_framework_info()->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `charles` doesn't have permissions for the `king` role, so the first |
| // test should fail. However he has permissions for `king`'s nested roles |
| // so the next two tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->mutable_framework_info()->set_role("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->mutable_framework_info()->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_framework_info()->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `j-welby` only has permissions for the role `king` itself, but not |
| // for its nested roles, therefore only the first of the following three |
| // tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->mutable_framework_info()->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_framework_info()->set_role("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_FRAMEWORK); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_framework_info()->set_role("king/prince/duke"); |
| 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"); |
| } |
| |
| { |
| // Principal "elizabeth-ii" can reserve for the "king" role and its |
| // nested ones. |
| mesos::ACL::ReserveResources* acl = acls.add_reserve_resources(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // Principal "charles" can reserve for any role below the "king/" role. |
| // Not in "king" itself. |
| mesos::ACL::ReserveResources* acl = acls.add_reserve_resources(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // Principal "j-welby" can reserve only for the "king" role but not |
| // in any nested one. |
| mesos::ACL::ReserveResources* acl = acls.add_reserve_resources(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // 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); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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); |
| request.mutable_subject()->set_value("baz"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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); |
| request.mutable_subject()->set_value("baz"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| 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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("zelda"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("ads"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // `elizabeth-ii` has full permissions for the `king` role as well as all |
| // its nested roles. She should be able to reserve resources in the next |
| // three blocks. |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `charles` doesn't have permissions for the `king` role, so the first |
| // test should fail. However he has permissions for `king`'s nested roles |
| // so the next two tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `j-welby` only has permissions for the role `king` itself, but not |
| // for its nested roles, therefore only the first of the following three |
| // tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::RESERVE_RESOURCES); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince/duke"); |
| 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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::UNRESERVE_RESOURCES); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::UNRESERVE_RESOURCES); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::UNRESERVE_RESOURCES); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::UNRESERVE_RESOURCES); |
| request.mutable_subject()->set_value("zelda"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_principal("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); |
| } |
| |
| { |
| // Principal "elizabeth-ii" can create volumes for the "king" role and its |
| // nested ones. |
| mesos::ACL::CreateVolume* acl = acls.add_create_volumes(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // Principal "charles" can create volumes for any role below the "king/" |
| // role. Not in "king" itself. |
| mesos::ACL::CreateVolume* acl = acls.add_create_volumes(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // Principal "j-welby" can create volumes only for the "king" role but |
| // not in any nested one. |
| mesos::ACL::CreateVolume* acl = acls.add_create_volumes(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // 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); |
| } |
| |
| { |
| // 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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("baz"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("zelda"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("panda"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // `elizabeth-ii` has full permissions for the `king` role as well as all |
| // its nested roles. She should be able to create volumes in the next |
| // three blocks. |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `charles` doesn't have permissions for the `king` role, so the first |
| // test should fail. However he has permissions for `king`'s nested roles |
| // so the next two tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `j-welby` only has permissions for the role `king` itself, but not |
| // for its nested roles, therefore only the first of the following three |
| // tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::CREATE_VOLUME); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_resource() |
| ->mutable_reservations() |
| ->Add() |
| ->set_role("king/prince/duke"); |
| 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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::DESTROY_VOLUME); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::DESTROY_VOLUME); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::DESTROY_VOLUME); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::DESTROY_VOLUME); |
| request.mutable_subject()->set_value("zelda"); |
| request.mutable_object()->mutable_resource()->mutable_disk() |
| ->mutable_persistence()->set_principal("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"); |
| } |
| |
| { |
| // Principal "elizabeth-ii" can update quotas for the "king" role and its |
| // nested ones. |
| mesos::ACL::UpdateQuota* acl = acls.add_update_quotas(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // Principal "charles" can update quotas for any role below the "king/" |
| // role. Not in "king" itself. |
| mesos::ACL::UpdateQuota* acl = acls.add_update_quotas(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // Principal "j-welby" can update quotas only for the "king" role but |
| // not in any nested one. |
| mesos::ACL::UpdateQuota* acl = acls.add_update_quotas(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // 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)); |
| } |
| |
| // `elizabeth-ii` has full permissions for the `king` role as well as all |
| // its nested roles. She should be able to update quotas in the next |
| // three blocks. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->mutable_quota_info()->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->mutable_quota_info()->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object() |
| ->mutable_quota_info()->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `charles` doesn't have permissions for the `king` role, so the first |
| // test should fail. However he has permissions for `king`'s nested roles |
| // so the next two tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->mutable_quota_info()->set_role("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->mutable_quota_info()->set_role("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object() |
| ->mutable_quota_info()->set_role("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `j-welby` only has permissions for the role `king` itself, but not |
| // for its nested roles, therefore only the first of the following three |
| // tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->mutable_quota_info()->set_role("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->mutable_quota_info()->set_role("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_QUOTA); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object() |
| ->mutable_quota_info()->set_role("king/prince/duke"); |
| 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 be authorized. |
| FrameworkInfo frameworkInfo; |
| { |
| frameworkInfo.set_user("user"); |
| frameworkInfo.set_name("f"); |
| } |
| |
| // Create FrameworkInfo with user "bar" as object to be 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 ViewContainer. |
| TYPED_TEST(AuthorizationTest, ViewContainer) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal can view no containers. |
| mesos::ACL::ViewContainer* acl = acls.add_view_containers(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can see containers running under user "bar". |
| mesos::ACL::ViewContainer* acl = acls.add_view_containers(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can see all containers. |
| mesos::ACL::ViewContainer* acl = acls.add_view_containers(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can view any containers. |
| mesos::ACL::ViewContainer* acl = acls.add_view_containers(); |
| 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 be authorized. |
| FrameworkInfo frameworkInfo; |
| { |
| frameworkInfo.set_user("user"); |
| frameworkInfo.set_name("f"); |
| } |
| |
| // Create FrameworkInfo with user "bar" as object to be authorized. |
| FrameworkInfo frameworkInfoBar; |
| { |
| frameworkInfoBar.set_user("bar"); |
| frameworkInfoBar.set_name("f"); |
| } |
| |
| // Principal "foo" cannot view containers running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_CONTAINER); |
| 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 containers running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_CONTAINER); |
| 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 containers running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_CONTAINER); |
| 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 containers running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_CONTAINER); |
| 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 be authorized. |
| FrameworkInfo frameworkInfo; |
| { |
| frameworkInfo.set_user("user"); |
| frameworkInfo.set_name("f"); |
| } |
| |
| // Create FrameworkInfo with user "bar" as object to be 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 be authorized. |
| FrameworkInfo frameworkInfo; |
| { |
| frameworkInfo.set_user("user"); |
| frameworkInfo.set_name("f"); |
| } |
| |
| // Create FrameworkInfo with user "bar" as object to be 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 sandbox 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 be authorized. |
| FrameworkInfo frameworkInfo; |
| { |
| frameworkInfo.set_user("user"); |
| frameworkInfo.set_name("f"); |
| } |
| |
| // Create FrameworkInfo with user "bar" as object to be 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 the authorization of launching sessions in nested containers. |
| TYPED_TEST(AuthorizationTest, LaunchNestedContainerSessions) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "ops" can launch sessions in any parent container. |
| mesos::ACL::LaunchNestedContainerSessionUnderParentWithUser* acl = |
| acls.add_launch_nested_container_sessions_under_parent_with_user(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // "foo" cannot launch sessions in any container running as any user. |
| mesos::ACL::LaunchNestedContainerSessionUnderParentWithUser* acl = |
| acls.add_launch_nested_container_sessions_under_parent_with_user(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" can launch sessions nested under a container running as |
| // linux user "bar". |
| mesos::ACL::LaunchNestedContainerSessionUnderParentWithUser* acl = |
| acls.add_launch_nested_container_sessions_under_parent_with_user(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // No one else can launch sessions in nested containers. |
| mesos::ACL::LaunchNestedContainerSessionUnderParentWithUser* acl = |
| acls.add_launch_nested_container_sessions_under_parent_with_user(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "foo" principal cannot launch sessions as commands in any parent |
| // container. They may still get to launch container sessions if they |
| // are allowed to launch nested container sessions whose executors are |
| // running as a given user for which "foo" has permissions and the |
| // session uses a `container_info` instead of a `command_info`. |
| mesos::ACL::LaunchNestedContainerSessionAsUser* acl = |
| acls.add_launch_nested_container_sessions_as_user(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can launch sessions running as user "bar". |
| mesos::ACL::LaunchNestedContainerSessionAsUser* acl = |
| acls.add_launch_nested_container_sessions_as_user(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can launch sessions as any linux user. |
| mesos::ACL::LaunchNestedContainerSessionAsUser* acl = |
| acls.add_launch_nested_container_sessions_as_user(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can launch sessions as any user. |
| mesos::ACL::LaunchNestedContainerSessionAsUser* acl = |
| acls.add_launch_nested_container_sessions_as_user(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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("s"); |
| executorInfoNoUser.mutable_command()->set_value("echo hello"); |
| } |
| |
| // Create ExecutorInfo with no user in command as object to |
| // be authorized. |
| ExecutorInfo executorInfoNoCommand; |
| { |
| executorInfoNoCommand.set_name("Executor"); |
| executorInfoNoCommand.mutable_executor_id()->set_value("t"); |
| } |
| |
| // Principal "foo" cannot launch a session with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| 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 launch a session with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| 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 launch a session with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| 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 "ops" can launch a session with a request with the |
| // default `FrameworkInfo.user`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can launch a session with a request where the |
| // executor is running as a container, it falls back to the |
| // `FrameworkInfo.user`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoCommand); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" can launch a session as user "bar" under parent containers |
| // running as user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Create CommandInfo with a user not mentioned in the ACLs in |
| // command as object to be authorized. |
| CommandInfo commandInfo; |
| { |
| commandInfo.set_value("echo hello"); |
| commandInfo.set_user("user"); |
| } |
| |
| // Create CommandInfo with user "bar" in command as object to |
| // be authorized. |
| CommandInfo commandInfoBar; |
| { |
| commandInfoBar.set_value("echo hello"); |
| commandInfoBar.set_user("bar"); |
| } |
| |
| // Create CommandInfo with no user in command as object to |
| // be authorized. |
| CommandInfo commandInfoNoUser; |
| { |
| commandInfoNoUser.set_value("echo hello"); |
| } |
| |
| // Principal "foo" cannot launch a session with a request with |
| // ExecutorInfo and CommandInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfo); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" cannot launch a session with a request with |
| // CommandInfo running with user "user", even if the ExecutorInfo |
| // is running as "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfo); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" cannot launch a session with a request with |
| // CommandInfo and ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can launch a sessions with any combination of requests. |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER_SESSION); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoNoUser); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoNoUser); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of attaching to the input stream of a container. |
| TYPED_TEST(AuthorizationTest, AttachContainerInput) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal cannot attach to the input of any container. |
| mesos::ACL::AttachContainerInput* acl = |
| acls.add_attach_containers_input(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can attach to the input of containers running under |
| // user "bar". |
| mesos::ACL::AttachContainerInput* acl = |
| acls.add_attach_containers_input(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can attach to the input of all containers. |
| mesos::ACL::AttachContainerInput* acl = |
| acls.add_attach_containers_input(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can attach to the input of any container. |
| mesos::ACL::AttachContainerInput* acl = |
| acls.add_attach_containers_input(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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"); |
| } |
| |
| // Principal "foo" cannot attach to the input of a container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_INPUT); |
| 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 attach to the input of a container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_INPUT); |
| 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 attach to the input of a container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_INPUT); |
| 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 attach to the input of a container with a request with |
| // ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_INPUT); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can attach to the input of a container with a request with |
| // an ExecutorInfo without user. |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_INPUT); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of attaching to the output stream of a |
| // container. |
| TYPED_TEST(AuthorizationTest, AttachContainerOutput) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal cannot attach to the output of any container. |
| mesos::ACL::AttachContainerOutput* acl = |
| acls.add_attach_containers_output(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can attach to the output of containers running under |
| // user "bar". |
| mesos::ACL::AttachContainerOutput* acl = |
| acls.add_attach_containers_output(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can attach to the output of all containers. |
| mesos::ACL::AttachContainerOutput* acl = |
| acls.add_attach_containers_output(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can attach to the output of any container. |
| mesos::ACL::AttachContainerOutput* acl = |
| acls.add_attach_containers_output(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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"); |
| } |
| |
| // Principal "foo" cannot attach to the output of a container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_OUTPUT); |
| 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 attach to the output of a container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_OUTPUT); |
| 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 attach to the output of a container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_OUTPUT); |
| 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 attach to the output of a container with a request with |
| // ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_OUTPUT); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can attach to the output of a container with a request with |
| // an ExecutorInfo without user. |
| { |
| authorization::Request request; |
| request.set_action(authorization::ATTACH_CONTAINER_OUTPUT); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of launching nested containers. |
| TYPED_TEST(AuthorizationTest, LaunchNestedContainers) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "ops" can launch nested containers whose executor runs as any user. |
| mesos::ACL::LaunchNestedContainerUnderParentWithUser* acl = |
| acls.add_launch_nested_containers_under_parent_with_user(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // "foo" cannot launch nested containers. |
| mesos::ACL::LaunchNestedContainerUnderParentWithUser* acl = |
| acls.add_launch_nested_containers_under_parent_with_user(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" can launch nested containers under executors running as |
| // linux user "bar". |
| mesos::ACL::LaunchNestedContainerUnderParentWithUser* acl = |
| acls.add_launch_nested_containers_under_parent_with_user(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // No one else can launch nested containers. |
| mesos::ACL::LaunchNestedContainerUnderParentWithUser* acl = |
| acls.add_launch_nested_containers_under_parent_with_user(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "foo" principal cannot launch nested containers as commands |
| // under any parent container. They may still get to launch nested |
| // container if they are allowed to do so for executors which run as |
| // a given user for which "foo" has permissions and the session |
| // uses a `container_info` instead of a `command_info`. |
| mesos::ACL::LaunchNestedContainerAsUser* acl = |
| acls.add_launch_nested_containers_as_user(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can launch nested containers as user "bar". |
| mesos::ACL::LaunchNestedContainerAsUser* acl = |
| acls.add_launch_nested_containers_as_user(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can launch nested containers any linux user. |
| mesos::ACL::LaunchNestedContainerAsUser* acl = |
| acls.add_launch_nested_containers_as_user(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can launch nested containers as any user. |
| mesos::ACL::LaunchNestedContainerAsUser* acl = |
| acls.add_launch_nested_containers_as_user(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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("s"); |
| executorInfoNoUser.mutable_command()->set_value("echo hello"); |
| } |
| |
| // Create ExecutorInfo with no command as object to be authorized. |
| ExecutorInfo executorInfoNoCommand; |
| { |
| executorInfoNoCommand.set_name("Executor"); |
| executorInfoNoCommand.mutable_executor_id()->set_value("t"); |
| } |
| |
| // Principal "foo" cannot launch a nested container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| 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 launch a nested container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| 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 launch a nested container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| 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 "ops" can launch a nested container with a request with the |
| // default `FrameworkInfo.user`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can launch a nested container with a request |
| // where the executor is running as a container, it falls back |
| // to the `FrameworkInfo.user`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoCommand); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" can launch a nested container as user "bar" under parent |
| // containers running as user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Create CommandInfo with a user not mentioned in the ACLs in |
| // command as object to be authorized. |
| CommandInfo commandInfo; |
| { |
| commandInfo.set_value("echo hello"); |
| commandInfo.set_user("user"); |
| } |
| |
| // Create CommandInfo with user "bar" in command as object to |
| // be authorized. |
| CommandInfo commandInfoBar; |
| { |
| commandInfoBar.set_value("echo hello"); |
| commandInfoBar.set_user("bar"); |
| } |
| |
| // Create CommandInfo with no user in command as object to |
| // be authorized. |
| CommandInfo commandInfoNoUser; |
| { |
| commandInfoNoUser.set_value("echo hello"); |
| } |
| |
| // Principal "foo" cannot launch a session with a request with |
| // ExecutorInfo and CommandInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfo); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" cannot launch a nested container with a request with |
| // CommandInfo running with user "user", even if the ExecutorInfo |
| // is running as "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfo); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" can launch a nested container with a request with |
| // CommandInfo and ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can launch nested containers with any combination of |
| // requests. |
| { |
| authorization::Request request; |
| request.set_action(authorization::LAUNCH_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_command_info()->MergeFrom(commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoNoUser); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfo); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoBar); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_command_info()->MergeFrom( |
| commandInfoNoUser); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of waiting for a nested container. |
| TYPED_TEST(AuthorizationTest, WaitNestedContainer) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal cannot wait of any nested container. |
| mesos::ACL::WaitNestedContainer* acl = |
| acls.add_wait_nested_containers(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can wait for nested containers running under |
| // user "bar". |
| mesos::ACL::WaitNestedContainer* acl = |
| acls.add_wait_nested_containers(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can wait for all nested containers. |
| mesos::ACL::WaitNestedContainer* acl = |
| acls.add_wait_nested_containers(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can wait for any nested container. |
| mesos::ACL::WaitNestedContainer* acl = |
| acls.add_wait_nested_containers(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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"); |
| } |
| |
| // Principal "foo" cannot wait for a nested container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::WAIT_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" cannot wait for a nested container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::WAIT_NESTED_CONTAINER); |
| 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 wait for a nested container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::WAIT_NESTED_CONTAINER); |
| 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 wait for a nested container with a request with |
| // ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::WAIT_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can wait for a nested container with a request with |
| // an ExecutorInfo without user. |
| { |
| authorization::Request request; |
| request.set_action(authorization::WAIT_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of killing a nested container. |
| TYPED_TEST(AuthorizationTest, KillNestedContainer) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal cannot kill any nested container. |
| mesos::ACL::KillNestedContainer* acl = |
| acls.add_kill_nested_containers(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can kill nested containers running under |
| // user "bar". |
| mesos::ACL::KillNestedContainer* acl = |
| acls.add_kill_nested_containers(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can kill all nested containers. |
| mesos::ACL::KillNestedContainer* acl = |
| acls.add_kill_nested_containers(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can kill any nested container. |
| mesos::ACL::KillNestedContainer* acl = |
| acls.add_kill_nested_containers(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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"); |
| } |
| |
| // Principal "foo" cannot kill a nested container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::KILL_NESTED_CONTAINER); |
| 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 kill a nested container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::KILL_NESTED_CONTAINER); |
| 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 kill a nested container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::KILL_NESTED_CONTAINER); |
| 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 kill a nested container with a request with |
| // ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::KILL_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can kill a nested container with a request with |
| // an ExecutorInfo without user. |
| { |
| authorization::Request request; |
| request.set_action(authorization::KILL_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of removing a nested container. |
| TYPED_TEST(AuthorizationTest, RemoveNestedContainer) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal cannot remove any nested container. |
| mesos::ACL::RemoveNestedContainer* acl = |
| acls.add_remove_nested_containers(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| { |
| // "bar" principal can remove nested containers running under user "bar". |
| mesos::ACL::RemoveNestedContainer* acl = |
| acls.add_remove_nested_containers(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_users()->add_values("bar"); |
| } |
| |
| { |
| // "ops" principal can remove all nested containers. |
| mesos::ACL::RemoveNestedContainer* acl = |
| acls.add_remove_nested_containers(); |
| acl->mutable_principals()->add_values("ops"); |
| acl->mutable_users()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // No one else can remove any nested container. |
| mesos::ACL::RemoveNestedContainer* acl = |
| acls.add_remove_nested_containers(); |
| 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()); |
| |
| FrameworkInfo frameworkInfo; |
| frameworkInfo.set_user("user"); |
| |
| // 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"); |
| } |
| |
| // Principal "foo" cannot remove a nested container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::REMOVE_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("foo"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom(executorInfo); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "bar" cannot remove a nested container with a request |
| // with ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::REMOVE_NESTED_CONTAINER); |
| 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 remove a nested container with a request with |
| // ExecutorInfo running with user "user". |
| { |
| authorization::Request request; |
| request.set_action(authorization::REMOVE_NESTED_CONTAINER); |
| 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 remove a nested container with a request with |
| // ExecutorInfo running with user "bar". |
| { |
| authorization::Request request; |
| request.set_action(authorization::REMOVE_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoBar); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Principal "ops" can remove nested container with a request with |
| // an ExecutorInfo without user. |
| { |
| authorization::Request request; |
| request.set_action(authorization::REMOVE_NESTED_CONTAINER); |
| request.mutable_subject()->set_value("ops"); |
| request.mutable_object()->mutable_executor_info()->MergeFrom( |
| executorInfoNoUser); |
| request.mutable_object()->mutable_framework_info()->MergeFrom( |
| frameworkInfo); |
| |
| 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); |
| } |
| } |
| |
| |
| TYPED_TEST(AuthorizationTest, SetLogLevel) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal can set log level. |
| mesos::ACL::SetLogLevel* acl = acls.add_set_log_level(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_level()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can set log level. |
| mesos::ACL::SetLogLevel* acl = acls.add_set_log_level(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_level()->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::SET_LOG_LEVEL); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::SET_LOG_LEVEL); |
| request.mutable_subject()->set_value("bar"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Test that no authorizer is created with invalid ACLs. |
| { |
| ACLs invalid; |
| |
| mesos::ACL::SetLogLevel* acl = invalid.add_set_log_level(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_level()->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"); |
| } |
| |
| { |
| // "elizabeth-ii" principal can view info about the `king` role and |
| // all its nested ones. |
| mesos::ACL::ViewRole* acl = acls.add_view_roles(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // "charles" can only view info about `king`'s nested roles, but not |
| // the role `king` itself. |
| mesos::ACL::ViewRole* acl = acls.add_view_roles(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // "j-welby" can only view info about the `king` role itself |
| // but not its nested roles. |
| mesos::ACL::ViewRole* acl = acls.add_view_roles(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // 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)); |
| } |
| |
| // `elizabeth-ii` has full permissions for the `king` role as well as all |
| // its nested roles. She should be able to view roles in the next |
| // three blocks. |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `charles` doesn't have permissions for the `king` role, so the first |
| // test should fail. However he has permissions for `king`'s nested roles |
| // so the next two tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // `j-welby` only has permissions for the role `king` itself, but not |
| // for its nested roles, therefore only the first of the following three |
| // tests should succeed. |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| authorization::Request request; |
| request.set_action(authorization::VIEW_ROLE); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to UpdateWeight. |
| TYPED_TEST(AuthorizationTest, UpdateWeight) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal can update weights of `ANY` role. |
| mesos::ACL::UpdateWeight* acl = acls.add_update_weights(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // "bar" principal can update the weight of role `bar`. |
| mesos::ACL::UpdateWeight* acl = acls.add_update_weights(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_roles()->add_values("bar"); |
| } |
| |
| { |
| // "elizabeth-ii" principal can update weights of role `king` and |
| // its nested ones. |
| mesos::ACL::UpdateWeight* acl = acls.add_update_weights(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // "charles" principal can update weights of just roles nested |
| // under `king`. |
| mesos::ACL::UpdateWeight* acl = acls.add_update_weights(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // "j-welby" principal can update the weight of just role 'king'. |
| mesos::ACL::UpdateWeight* acl = acls.add_update_weights(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // No other principal can update any weights. |
| mesos::ACL::UpdateWeight* acl = acls.add_update_weights(); |
| 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 update weights of any role. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "bar" cannot update the weight of role `foo`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->set_value("foo"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "bar" can update the weight of role `bar`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->set_value("bar"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "elizabeth-ii" can update the weight of role `king`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "elizabeth-ii" can update the weight of role |
| // `king/prince`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "elizabeth-ii" can update the weight of role |
| // `king/prince/duke`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "charles" cannot update the weight of role `king`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "charles" can update the weight of role `king/prince`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "charles" can update the weight of role |
| // `king/prince/duke`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "j-welby" can update the weight of role `king`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "j-welby" cannot update the weight of role |
| // `king/prince`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "j-welby" cannot update the weight of role |
| // `king/prince/duke`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_WEIGHT); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to GetQuota. |
| TYPED_TEST(AuthorizationTest, GetQuota) |
| { |
| // Setup ACLs. |
| ACLs acls; |
| |
| { |
| // "foo" principal can get quotas of `ANY` role. |
| mesos::ACL::GetQuota* acl = acls.add_get_quotas(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_roles()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // "bar" principal can get the quota of role `bar`. |
| mesos::ACL::GetQuota* acl = acls.add_get_quotas(); |
| acl->mutable_principals()->add_values("bar"); |
| acl->mutable_roles()->add_values("bar"); |
| } |
| |
| { |
| // "elizabeth-ii" principal can view quotas of role `king` and its |
| // nested ones. |
| mesos::ACL::GetQuota* acl = acls.add_get_quotas(); |
| acl->mutable_principals()->add_values("elizabeth-ii"); |
| acl->mutable_roles()->add_values("king/%"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // "charles" principal can view quotas of just roles nested under `king`. |
| mesos::ACL::GetQuota* acl = acls.add_get_quotas(); |
| acl->mutable_principals()->add_values("charles"); |
| acl->mutable_roles()->add_values("king/%"); |
| } |
| |
| { |
| // "j-welby" principal can view the quotas of just role 'king'. |
| mesos::ACL::GetQuota* acl = acls.add_get_quotas(); |
| acl->mutable_principals()->add_values("j-welby"); |
| acl->mutable_roles()->add_values("king"); |
| } |
| |
| { |
| // No other principal can view any quota. |
| mesos::ACL::GetQuota* acl = acls.add_get_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()); |
| |
| // Check that principal "foo" can view quotas of any role. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "bar" cannot view quotas of role `foo`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->set_value("foo"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "bar" can view the quotas of role `bar`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("bar"); |
| request.mutable_object()->set_value("bar"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "elizabeth-ii" can view the quotas of role `king`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "elizabeth-ii" can view the quotas of role |
| // `king/prince`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "elizabeth-ii" can view the quota of role |
| // `king/prince/duke`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("elizabeth-ii"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "charles" cannot view the quota of role `king`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "charles" can view the quota of role `king/prince`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "charles" can view the quota of role |
| // `king/prince/duke`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("charles"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "j-welby" can view the quota of role `king`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king"); |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "j-welby" cannot view the quota of role |
| // `king/prince`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king/prince"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| // Check that principal "j-welby" cannot view the quota of role |
| // `king/prince/duke`. |
| { |
| authorization::Request request; |
| request.set_action(authorization::GET_QUOTA); |
| request.mutable_subject()->set_value("j-welby"); |
| request.mutable_object()->set_value("king/prince/duke"); |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| } |
| |
| |
| TYPED_TEST(AuthorizationTest, RegisterAgent) |
| { |
| ACLs acls; |
| |
| { |
| // "foo" principal can register as an agent. |
| mesos::ACL::RegisterAgent* acl = acls.add_register_agents(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_agents()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can register as an agent. |
| mesos::ACL::RegisterAgent* acl = acls.add_register_agents(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_agents()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(acls)); |
| ASSERT_SOME(create); |
| Owned<Authorizer> authorizer(create.get()); |
| |
| { |
| // "foo" is in the "whitelist". |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_AGENT); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // "bar" is not in the "whitelist". |
| authorization::Request request; |
| request.set_action(authorization::REGISTER_AGENT); |
| request.mutable_subject()->set_value("bar"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // Test that no authorizer is created with invalid ACLs. |
| ACLs invalid; |
| |
| mesos::ACL::RegisterAgent* acl = invalid.add_register_agents(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_agents()->add_values("yoda"); |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(invalid)); |
| EXPECT_ERROR(create); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to UpdateMaintenanceSchedule. |
| TYPED_TEST(AuthorizationTest, UpdateMaintenanceSchedule) |
| { |
| ACLs acls; |
| |
| { |
| // "foo" principal can update maintenance schedule. |
| mesos::ACL::UpdateMaintenanceSchedule* acl = |
| acls.add_update_maintenance_schedules(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can update maintenance schedule. |
| mesos::ACL::UpdateMaintenanceSchedule* acl = |
| acls.add_update_maintenance_schedules(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(acls)); |
| ASSERT_SOME(create); |
| Owned<Authorizer> authorizer(create.get()); |
| |
| { |
| // "foo" is allowed to update maintenance schedules. |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_MAINTENANCE_SCHEDULE); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // "bar" is not allowed to update maintenance schedules. |
| authorization::Request request; |
| request.set_action(authorization::UPDATE_MAINTENANCE_SCHEDULE); |
| request.mutable_subject()->set_value("bar"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // Test that no authorizer is created with invalid ACLs. |
| ACLs invalid; |
| |
| mesos::ACL::UpdateMaintenanceSchedule* acl = |
| invalid.add_update_maintenance_schedules(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->add_values("yoda"); |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(invalid)); |
| EXPECT_ERROR(create); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to GetMaintenanceSchedule. |
| TYPED_TEST(AuthorizationTest, GetMaintenanceSchedule) |
| { |
| ACLs acls; |
| |
| { |
| // "foo" principal can view the maintenance schedule of the whole cluster. |
| mesos::ACL::GetMaintenanceSchedule* acl = |
| acls.add_get_maintenance_schedules(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can view the maintenance schedule. |
| mesos::ACL::GetMaintenanceSchedule* acl = |
| acls.add_get_maintenance_schedules(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(acls)); |
| ASSERT_SOME(create); |
| Owned<Authorizer> authorizer(create.get()); |
| |
| { |
| // "foo" is allowed to view maintenance schedules. The request should |
| // succeed. |
| authorization::Request request; |
| request.set_action(authorization::GET_MAINTENANCE_SCHEDULE); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // "bar" is not allowed to view maintenance schedules. The request |
| // should fail. |
| authorization::Request request; |
| request.set_action(authorization::GET_MAINTENANCE_SCHEDULE); |
| request.mutable_subject()->set_value("bar"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // Test that no authorizer is created with invalid ACLs. |
| ACLs invalid; |
| |
| mesos::ACL::GetMaintenanceSchedule* acl = |
| invalid.add_get_maintenance_schedules(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->add_values("yoda"); |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(invalid)); |
| EXPECT_ERROR(create); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to StartMaintenance. |
| TYPED_TEST(AuthorizationTest, StartMaintenance) |
| { |
| ACLs acls; |
| |
| { |
| // "foo" principal can start maintenance. |
| mesos::ACL::StartMaintenance* acl = acls.add_start_maintenances(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can start maintenance. |
| mesos::ACL::StartMaintenance* acl = acls.add_start_maintenances(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(acls)); |
| ASSERT_SOME(create); |
| Owned<Authorizer> authorizer(create.get()); |
| |
| { |
| // "foo" is allowed to start maintenance mode in nodes. The |
| // request should succeed. |
| authorization::Request request; |
| request.set_action(authorization::START_MAINTENANCE); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // "bar" is not allowed to start maintenance mode in nodes. The |
| // request should fail. |
| authorization::Request request; |
| request.set_action(authorization::START_MAINTENANCE); |
| request.mutable_subject()->set_value("bar"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // Test that no authorizer is created with invalid ACLs. |
| ACLs invalid; |
| |
| mesos::ACL::StartMaintenance* acl = invalid.add_start_maintenances(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->add_values("yoda"); |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(invalid)); |
| EXPECT_ERROR(create); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to StopMaintenance. |
| TYPED_TEST(AuthorizationTest, StopMaintenance) |
| { |
| ACLs acls; |
| |
| { |
| // "foo" principal can stop maintenance. |
| mesos::ACL::StopMaintenance* acl = acls.add_stop_maintenances(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can stop maintenance. |
| mesos::ACL::StopMaintenance* acl = acls.add_stop_maintenances(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(acls)); |
| ASSERT_SOME(create); |
| Owned<Authorizer> authorizer(create.get()); |
| |
| { |
| // "foo" is allowed to stop maintenance on nodes. The request |
| // should succeed. |
| authorization::Request request; |
| request.set_action(authorization::STOP_MAINTENANCE); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // "bar" is not allowed to stop maintenance on nodes. The request |
| // should fail. |
| authorization::Request request; |
| request.set_action(authorization::STOP_MAINTENANCE); |
| request.mutable_subject()->set_value("bar"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // Test that no authorizer is created with invalid ACLs. |
| ACLs invalid; |
| |
| mesos::ACL::StopMaintenance* acl = invalid.add_stop_maintenances(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->add_values("yoda"); |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(invalid)); |
| EXPECT_ERROR(create); |
| } |
| } |
| |
| |
| // This tests the authorization of requests to GetMaintenanceStatus. |
| TYPED_TEST(AuthorizationTest, GetMaintenanceStatus) |
| { |
| ACLs acls; |
| |
| { |
| // "foo" principal view the maintenance status of the whole cluster. |
| mesos::ACL::GetMaintenanceStatus* acl = |
| acls.add_get_maintenance_statuses(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::ANY); |
| } |
| |
| { |
| // Nobody else can view the maintenance status. |
| mesos::ACL::GetMaintenanceStatus* acl = |
| acls.add_get_maintenance_statuses(); |
| acl->mutable_principals()->set_type(mesos::ACL::Entity::ANY); |
| acl->mutable_machines()->set_type(mesos::ACL::Entity::NONE); |
| } |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(acls)); |
| ASSERT_SOME(create); |
| Owned<Authorizer> authorizer(create.get()); |
| |
| { |
| // "foo" is allowed to view maintenance status. The request should |
| // succeed. |
| authorization::Request request; |
| request.set_action(authorization::GET_MAINTENANCE_STATUS); |
| request.mutable_subject()->set_value("foo"); |
| |
| AWAIT_EXPECT_TRUE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // "bar" is not allowed to view maintenance status. The request should fail. |
| authorization::Request request; |
| request.set_action(authorization::GET_MAINTENANCE_STATUS); |
| request.mutable_subject()->set_value("bar"); |
| |
| AWAIT_EXPECT_FALSE(authorizer.get()->authorized(request)); |
| } |
| |
| { |
| // Test that no authorizer is created with invalid ACLs. |
| ACLs invalid; |
| |
| mesos::ACL::GetMaintenanceStatus* acl = |
| invalid.add_get_maintenance_statuses(); |
| acl->mutable_principals()->add_values("foo"); |
| acl->mutable_machines()->add_values("yoda"); |
| |
| Try<Authorizer*> create = TypeParam::create(parameterize(invalid)); |
| EXPECT_ERROR(create); |
| } |
| } |
| |
| } // namespace tests { |
| } // namespace internal { |
| } // namespace mesos { |