]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw/iam: add NotEquals UT 65606/head
authorliubingrun <liubr1@chinatelecom.cn>
Fri, 19 Sep 2025 19:17:07 +0000 (03:17 +0800)
committerliubingrun <liubr1@chinatelecom.cn>
Fri, 19 Sep 2025 19:17:07 +0000 (03:17 +0800)
Signed-off-by: liubingrun <liubr1@chinatelecom.cn>
src/test/rgw/test_rgw_iam_policy.cc

index f90d70c8cc18931d0804b32967478f2a0dc43999..5e8c9d54586de75bb8e2ca52c7e35f1a81264a8f 100644 (file)
@@ -1566,3 +1566,199 @@ TEST(Condition, ArnLike)
     EXPECT_FALSE(ArnLike.eval({{key, "arn:aws:s3:::user"}}));
   }
 }
+
+
+class ConditionTest : public ::testing::Test {
+protected:
+  intrusive_ptr<CephContext> cct;
+  
+  ConditionTest() {
+    cct.reset(new CephContext(CEPH_ENTITY_TYPE_CLIENT), false);
+  }
+};
+
+// Test cases for NotEquals condition logic fix
+// These tests verify that NotEquals conditions use correct AND logic
+// instead of incorrect OR logic (requiring mismatch with ALL values, not ANY)
+
+TEST_F(ConditionTest, StringNotEqualsLogic)
+{
+  std::string key = "aws:UserName";
+  
+  // Test case: value matches one of multiple condition values
+  // Should return false because value equals at least one condition value
+  {
+    Condition stringNotEquals{TokenID::StringNotEquals, key.data(), key.size(), false};
+    stringNotEquals.vals.push_back("alice");
+    stringNotEquals.vals.push_back("bob");
+    stringNotEquals.vals.push_back("charlie");
+
+    // Input "bob" matches second condition value, should return false
+    EXPECT_FALSE(stringNotEquals.eval({{key, "bob"}}));
+    // Input "alice" matches first condition value, should return false  
+    EXPECT_FALSE(stringNotEquals.eval({{key, "alice"}}));
+  }
+  
+  // Test case: value doesn't match any condition values
+  // Should return true because value differs from all condition values
+  {
+    Condition stringNotEquals{TokenID::StringNotEquals, key.data(), key.size(), false};
+    stringNotEquals.vals.push_back("alice");
+    stringNotEquals.vals.push_back("bob");
+    stringNotEquals.vals.push_back("charlie");
+
+    // Input "david" doesn't match any condition value, should return true
+    EXPECT_TRUE(stringNotEquals.eval({{key, "david"}}));
+  }
+}
+
+TEST_F(ConditionTest, NumericNotEqualsLogic)
+{
+  std::string key = "aws:RequestedRegion";
+  
+  // Test case: value matches one of multiple condition values
+  // Should return false because value equals at least one condition value
+  {
+    Condition numericNotEquals{TokenID::NumericNotEquals, key.data(), key.size(), false};
+    numericNotEquals.vals.push_back("10");
+    numericNotEquals.vals.push_back("20");
+    numericNotEquals.vals.push_back("30");
+
+    // Input "20" matches second condition value, should return false
+    EXPECT_FALSE(numericNotEquals.eval({{key, "20"}}));
+    // Input "10" matches first condition value, should return false
+    EXPECT_FALSE(numericNotEquals.eval({{key, "10"}}));
+  }
+  
+  // Test case: value doesn't match any condition values
+  // Should return true because value differs from all condition values
+  {
+    Condition numericNotEquals{TokenID::NumericNotEquals, key.data(), key.size(), false};
+    numericNotEquals.vals.push_back("10");
+    numericNotEquals.vals.push_back("20");
+    numericNotEquals.vals.push_back("30");
+
+    // Input "40" doesn't match any condition value, should return true
+    EXPECT_TRUE(numericNotEquals.eval({{key, "40"}}));
+  }
+}
+
+TEST_F(ConditionTest, DateNotEqualsLogic)
+{
+  std::string key = "aws:CurrentTime";
+  
+  // Test case: value matches one of multiple condition values
+  // Should return false because value equals at least one condition value
+  {
+    Condition dateNotEquals{TokenID::DateNotEquals, key.data(), key.size(), false};
+    dateNotEquals.vals.push_back("2023-01-01T00:00:00Z");
+    dateNotEquals.vals.push_back("2023-06-01T00:00:00Z");
+    dateNotEquals.vals.push_back("2023-12-01T00:00:00Z");
+
+    // Input matches second condition value, should return false
+    EXPECT_FALSE(dateNotEquals.eval({{key, "2023-06-01T00:00:00Z"}}));
+  }
+  
+  // Test case: value doesn't match any condition values
+  // Should return true because value differs from all condition values
+  {
+    Condition dateNotEquals{TokenID::DateNotEquals, key.data(), key.size(), false};
+    dateNotEquals.vals.push_back("2023-01-01T00:00:00Z");
+    dateNotEquals.vals.push_back("2023-06-01T00:00:00Z");
+    dateNotEquals.vals.push_back("2023-12-01T00:00:00Z");
+
+    // Input doesn't match any condition value, should return true
+    EXPECT_TRUE(dateNotEquals.eval({{key, "2024-01-01T00:00:00Z"}}));
+  }
+}
+
+TEST_F(ConditionTest, NotIpAddressLogic)
+{
+  std::string key = "aws:SourceIp";
+  
+  // Test case: value matches one of multiple condition values
+  // Should return false because value equals at least one condition value
+  {
+    Condition notIpAddress{TokenID::NotIpAddress, key.data(), key.size(), false};
+    notIpAddress.vals.push_back("192.168.1.1");
+    notIpAddress.vals.push_back("10.0.0.1");
+    notIpAddress.vals.push_back("172.16.0.1");
+
+    // Input matches second condition value, should return false
+    EXPECT_FALSE(notIpAddress.eval({{key, "10.0.0.1"}}));
+    // Input matches first condition value, should return false
+    EXPECT_FALSE(notIpAddress.eval({{key, "192.168.1.1"}}));
+  }
+  
+  // Test case: value doesn't match any condition values
+  // Should return true because value differs from all condition values
+  {
+    Condition notIpAddress{TokenID::NotIpAddress, key.data(), key.size(), false};
+    notIpAddress.vals.push_back("192.168.1.1");
+    notIpAddress.vals.push_back("10.0.0.1");
+    notIpAddress.vals.push_back("172.16.0.1");
+
+    // Input doesn't match any condition value, should return true
+    EXPECT_TRUE(notIpAddress.eval({{key, "8.8.8.8"}}));
+  }
+}
+
+TEST_F(ConditionTest, ArnNotEqualsLogic)
+{
+  std::string key = "aws:SourceArn";
+  
+  // Test case: value matches one of multiple condition values
+  // Should return false because value equals at least one condition value
+  {
+    Condition arnNotEquals{TokenID::ArnNotEquals, key.data(), key.size(), false};
+    arnNotEquals.vals.push_back("arn:aws:s3:::bucket1");
+    arnNotEquals.vals.push_back("arn:aws:s3:::bucket2");
+    arnNotEquals.vals.push_back("arn:aws:s3:::bucket3");
+
+    // Input matches second condition value, should return false
+    EXPECT_FALSE(arnNotEquals.eval({{key, "arn:aws:s3:::bucket2"}}));
+  }
+  
+  // Test case: value doesn't match any condition values
+  // Should return true because value differs from all condition values
+  {
+    Condition arnNotEquals{TokenID::ArnNotEquals, key.data(), key.size(), false};
+    arnNotEquals.vals.push_back("arn:aws:s3:::bucket1");
+    arnNotEquals.vals.push_back("arn:aws:s3:::bucket2");
+    arnNotEquals.vals.push_back("arn:aws:s3:::bucket3");
+
+    // Input doesn't match any condition value, should return true
+    EXPECT_TRUE(arnNotEquals.eval({{key, "arn:aws:s3:::other-bucket"}}));
+  }
+}
+
+TEST_F(ConditionTest, StringNotLikeLogic)
+{
+  std::string key = "s3:prefix";
+  
+  // Test case: value matches one of multiple condition patterns
+  // Should return false because value matches at least one condition pattern
+  {
+    Condition stringNotLike{TokenID::StringNotLike, key.data(), key.size(), false};
+    stringNotLike.vals.push_back("user/*");
+    stringNotLike.vals.push_back("admin/*");
+    stringNotLike.vals.push_back("temp/*");
+
+    // Input matches second condition pattern, should return false
+    EXPECT_FALSE(stringNotLike.eval({{key, "admin/config.txt"}}));
+    // Input matches first condition pattern, should return false
+    EXPECT_FALSE(stringNotLike.eval({{key, "user/profile.jpg"}}));
+  }
+  
+  // Test case: value doesn't match any condition patterns
+  // Should return true because value differs from all condition patterns
+  {
+    Condition stringNotLike{TokenID::StringNotLike, key.data(), key.size(), false};
+    stringNotLike.vals.push_back("user/*");
+    stringNotLike.vals.push_back("admin/*");
+    stringNotLike.vals.push_back("temp/*");
+
+    // Input doesn't match any condition pattern, should return true
+    EXPECT_TRUE(stringNotLike.eval({{key, "public/document.pdf"}}));
+  }
+}