Manage certificates created by applications

Added watch on certificate path to watch on certificates
created/updated by apps.

As part of watch notification, create new D-Bus new certificate
and for existing D-Bus object update the properties.

Tested:
Test case 1
1) Ensure no certificate is present
2) Restart certificate service
3) Restart bmcweb service
4) Verified that certificate object is created for the
   self-signed certificate created by bmcweb.

Test case 2
1) After a certificate is present
2) Modify the bmcweb certificate by replacing it
   with a valid certificate manually.
3) Verified that certificate manager is notified
and certificate objects properties are updated.

Test case 3
1) Upload CSR based certificate file
2) Verified that private key is appended to the file

Test case 4
1) Create a dummy file in certificate folder
2) Verified that notification is received and file is ignored

Test case 5
1) Verified install, replace, generate csr.

Change-Id: I7d1e3624958e4b68e5ba7bc6150c19b11fca501a
Signed-off-by: Marri Devender Rao <devenrao@in.ibm.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index e498a16..ff20da0 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -32,3 +32,4 @@
 certs_manager_test_LDADD = $(top_builddir)/certs_manager.o
 certs_manager_test_LDADD += $(top_builddir)/certificate.o
 certs_manager_test_LDADD += $(top_builddir)/csr.o
+certs_manager_test_LDADD += $(top_builddir)/watch.o
diff --git a/test/certs_manager_test.cpp b/test/certs_manager_test.cpp
index a783ba3..d596234 100644
--- a/test/certs_manager_test.cpp
+++ b/test/certs_manager_test.cpp
@@ -145,8 +145,13 @@
     std::string verifyPath(installPath);
     UnitsToRestart verifyUnit(unit);
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    Certificate certificate(bus, objPath, type, unit, installPath,
-                            certificateFile, false);
+    auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
+                    std::move(installPath));
+    MainApp mainApp(&manager);
+    mainApp.install(certificateFile);
     EXPECT_TRUE(fs::exists(verifyPath));
 }
 
@@ -161,8 +166,13 @@
     std::string verifyPath(installPath);
     UnitsToRestart verifyUnit(unit);
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    Certificate certificate(bus, objPath, type, unit, installPath,
-                            certificateFile, false);
+    auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
+                    std::move(installPath));
+    MainApp mainApp(&manager);
+    mainApp.install(certificateFile);
     EXPECT_TRUE(fs::exists(verifyPath));
 }
 
@@ -177,8 +187,13 @@
     std::string verifyPath(installPath);
     UnitsToRestart verifyUnit(unit);
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    Certificate certificate(bus, objPath, type, unit, installPath,
-                            certificateFile, false);
+    auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
+                    std::move(installPath));
+    MainApp mainApp(&manager);
+    mainApp.install(certificateFile);
     EXPECT_TRUE(fs::exists(verifyPath));
 }
 
@@ -193,8 +208,13 @@
     std::string verifyPath(installPath);
     UnitsToRestart verifyUnit(unit);
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    Certificate certificate(bus, objPath, type, unit, installPath,
-                            certificateFile, false);
+    auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
+                    std::move(installPath));
+    MainApp mainApp(&manager);
+    mainApp.install(certificateFile);
     EXPECT_TRUE(fs::exists(verifyPath));
     EXPECT_TRUE(compareFiles(verifyPath, certificateFile));
 }
@@ -215,8 +235,13 @@
         {
             try
             {
-                Certificate certificate(bus, objPath, type, unit, installPath,
-                                        uploadFile, false);
+                auto event = sdeventplus::Event::get_default();
+                // Attach the bus to sd_event to service user requests
+                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+                Manager manager(bus, event, objPath.c_str(), type,
+                                std::move(unit), std::move(installPath));
+                MainApp mainApp(&manager);
+                mainApp.install(uploadFile);
             }
             catch (const InternalFailure& e)
             {
@@ -227,6 +252,31 @@
     EXPECT_FALSE(fs::exists(verifyPath));
 }
 
+/** @brief Test replacing existing certificate
+ */
+TEST_F(TestCertificates, TestReplaceCertificate)
+{
+    std::string endpoint("ldap");
+    std::string unit("");
+    std::string type("server");
+    std::string installPath(certDir + "/" + certificateFile);
+    std::string verifyPath(installPath);
+    auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
+    auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
+                    std::move(installPath));
+    MainApp mainApp(&manager);
+    mainApp.install(certificateFile);
+    EXPECT_TRUE(fs::exists(verifyPath));
+    EXPECT_TRUE(fs::exists(verifyPath));
+    CertificatePtr& ptr = manager.getCertificate();
+    EXPECT_NE(ptr, nullptr);
+    ptr->replace(certificateFile);
+    EXPECT_TRUE(fs::exists(verifyPath));
+}
+
 /** @brief Check if install fails if certificate file is empty
  */
 TEST_F(TestCertificates, TestEmptyCertificateFile)
@@ -246,8 +296,13 @@
         {
             try
             {
-                Certificate certificate(bus, objPath, type, unit, installPath,
-                                        emptyFile, false);
+                auto event = sdeventplus::Event::get_default();
+                // Attach the bus to sd_event to service user requests
+                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+                Manager manager(bus, event, objPath.c_str(), type,
+                                std::move(unit), std::move(installPath));
+                MainApp mainApp(&manager);
+                mainApp.install(emptyFile);
             }
             catch (const InvalidCertificate& e)
             {
@@ -282,8 +337,13 @@
         {
             try
             {
-                Certificate certificate(bus, objPath, type, unit, installPath,
-                                        certificateFile, false);
+                auto event = sdeventplus::Event::get_default();
+                // Attach the bus to sd_event to service user requests
+                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+                Manager manager(bus, event, objPath.c_str(), type,
+                                std::move(unit), std::move(installPath));
+                MainApp mainApp(&manager);
+                mainApp.install(certificateFile);
             }
             catch (const InvalidCertificate& e)
             {
@@ -294,46 +354,6 @@
     EXPECT_FALSE(fs::exists(verifyPath));
 }
 
-/** @brief check certificate delete at manager level
- */
-TEST_F(TestCertificates, TestCertManagerDelete)
-{
-    std::string endpoint("ldap");
-    std::string unit("");
-    std::string type("client");
-    std::string installPath(certDir + "/" + certificateFile);
-    std::string verifyPath(installPath);
-    std::string verifyUnit(unit);
-    // Get default event loop
-    auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    auto event = sdeventplus::Event::get_default();
-    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
-                    std::move(installPath));
-    MainApp mainApp(&manager);
-    // delete certificate file and verify file is deleted
-    mainApp.delete_();
-    EXPECT_FALSE(fs::exists(verifyPath));
-}
-
-/** @brief check certificate install at manager level
- */
-TEST_F(TestCertificates, TestCertManagerInstall)
-{
-    std::string endpoint("ldap");
-    std::string unit("");
-    std::string type("client");
-    std::string installPath(certDir + "/" + certificateFile);
-    std::string verifyPath(installPath);
-    std::string verifyUnit(unit);
-    auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    auto event = sdeventplus::Event::get_default();
-    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
-                    std::move(installPath));
-    MainApp mainApp(&manager);
-    mainApp.install(certificateFile);
-    EXPECT_TRUE(fs::exists(verifyPath));
-}
-
 /**
  * Class to generate private and certificate only file and test verification
  */
@@ -395,8 +415,13 @@
         {
             try
             {
-                Certificate certificate(bus, objPath, type, unit, installPath,
-                                        certificateFile, false);
+                auto event = sdeventplus::Event::get_default();
+                // Attach the bus to sd_event to service user requests
+                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+                Manager manager(bus, event, objPath.c_str(), type,
+                                std::move(unit), std::move(installPath));
+                MainApp mainApp(&manager);
+                mainApp.install(certificateFile);
             }
             catch (const InvalidCertificate& e)
             {
@@ -417,44 +442,18 @@
     std::string installPath(certDir + "/" + keyFile);
     std::string verifyPath(installPath);
     std::string verifyUnit(unit);
-
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
     EXPECT_THROW(
         {
             try
             {
-                Certificate certificate(bus, objPath, type, unit, installPath,
-                                        keyFile, false);
-            }
-            catch (const InvalidCertificate& e)
-            {
-                throw;
-            }
-        },
-        InvalidCertificate);
-    EXPECT_FALSE(fs::exists(verifyPath));
-}
-
-/** @brief Check if Manager install method fails for invalid certificate file
- */
-TEST_F(TestInvalidCertificate, TestCertManagerInstall)
-{
-    std::string endpoint("ldap");
-    std::string unit("");
-    std::string type("client");
-    std::string installPath(certDir + "/" + certificateFile);
-    std::string verifyPath(installPath);
-    std::string verifyUnit(unit);
-    auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
-    auto event = sdeventplus::Event::get_default();
-    Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
-                    std::move(installPath));
-    MainApp mainApp(&manager);
-    EXPECT_THROW(
-        {
-            try
-            {
-                mainApp.install(certificateFile);
+                auto event = sdeventplus::Event::get_default();
+                // Attach the bus to sd_event to service user requests
+                bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+                Manager manager(bus, event, objPath.c_str(), type,
+                                std::move(unit), std::move(installPath));
+                MainApp mainApp(&manager);
+                mainApp.install(keyFile);
             }
             catch (const InvalidCertificate& e)
             {
@@ -479,6 +478,8 @@
     std::string verifyPath(installPath);
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
     auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                     std::move(installPath));
     MainApp mainApp(&manager);
@@ -528,6 +529,8 @@
     std::string unstructuredName("unstructuredName");
     auto objPath = std::string(OBJPATH) + '/' + type + '/' + endpoint;
     auto event = sdeventplus::Event::get_default();
+    // Attach the bus to sd_event to service user requests
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
     Manager manager(bus, event, objPath.c_str(), type, std::move(unit),
                     std::move(installPath));
     Status status;