diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt index 5a2f65f..1a4193b 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/extensions/server_software/nexus/ProvisionNexus.kt @@ -67,7 +67,7 @@ private fun Prov.getDefaultNetworkingInterface(): String? { fun provisionNexusServer(serverName: String, certbotEmail: String) { val userName = "nexus" + 7 remote(serverName, "root").def { - createUser(userName, copyAuthorizedKeysFromCurrentUser = true, sudo = true) + createUser(userName, copyAuthorizedSshKeysFromCurrentUser = true, sudo = true) } remote(serverName, userName).requireAll { provisionNexusWithDocker() diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt index d83dcfb..f1cefe8 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/base/User.kt @@ -6,6 +6,7 @@ import org.domaindrivenarchitecture.provs.core.Secret import org.domaindrivenarchitecture.provs.core.processors.RemoteProcessor import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createDirs import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileExists +import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.userHome import org.domaindrivenarchitecture.provs.ubuntu.git.provisionGit import org.domaindrivenarchitecture.provs.ubuntu.keys.base.gpgFingerprint import org.domaindrivenarchitecture.provs.ubuntu.keys.provisionKeysCurrentUser @@ -25,7 +26,7 @@ fun Prov.createUser( userName: String, password: Secret? = null, sudo: Boolean = false, - copyAuthorizedKeysFromCurrentUser: Boolean = false + copyAuthorizedSshKeysFromCurrentUser: Boolean = false ): ProvResult = requireAll { if (!userExists(userName)) { cmd("sudo adduser --gecos \"First Last,RoomNumber,WorkPhone,HomePhone\" --disabled-password --home /home/$userName $userName") @@ -34,13 +35,15 @@ fun Prov.createUser( if (sudo) { makeUserSudoerWithNoSudoPasswordRequired(userName) } - val authorizedKeysFile = "~/.ssh/authorized_keys" - if (copyAuthorizedKeysFromCurrentUser && fileExists(authorizedKeysFile)) { - createDirs("/home/$userName/.ssh") - val newAuthorizedKeysFile = "/home/$userName/.ssh/authorized_keys" - cmd("sudo cp $authorizedKeysFile $newAuthorizedKeysFile") - cmd("chown $userName $newAuthorizedKeysFile") - + val authorizedKeysFile = userHome() + ".ssh/authorized_keys" + if (copyAuthorizedSshKeysFromCurrentUser && fileExists(authorizedKeysFile)) { + val sshPathForNewUser = "/home/$userName/.ssh" + createDirs(sshPathForNewUser, sudo = true) + cmd("chown $userName $sshPathForNewUser", sudo = true) + + val newAuthorizedKeysFile = "$sshPathForNewUser/authorized_keys" + cmd("cp $authorizedKeysFile $newAuthorizedKeysFile", sudo = true) + cmd("chown $userName $newAuthorizedKeysFile", sudo = true) } ProvResult(true) // dummy } diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt index fdb1134..c7b021f 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/ubuntu/user/ProvisionUserKtTest.kt @@ -1,12 +1,17 @@ package org.domaindrivenarchitecture.provs.ubuntu.user import org.domaindrivenarchitecture.provs.test.defaultTestContainer +import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.createFile +import org.domaindrivenarchitecture.provs.ubuntu.filesystem.base.fileContent import org.domaindrivenarchitecture.provs.ubuntu.keys.* import org.domaindrivenarchitecture.provs.ubuntu.secret.SecretSourceType import org.domaindrivenarchitecture.provs.ubuntu.user.base.configureUser +import org.domaindrivenarchitecture.provs.ubuntu.user.base.createUser +import org.domaindrivenarchitecture.provs.ubuntu.user.base.userExists +import org.domaindrivenarchitecture.provs.ubuntu.user.base.userIsInGroupSudo +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Test -import org.junit.jupiter.api.condition.EnabledOnOs -import org.junit.jupiter.api.condition.OS internal class ProvisionUserKtTest { @@ -29,4 +34,40 @@ internal class ProvisionUserKtTest { // then assert(res.success) } + + @Test + fun createUser() { + // given + val a = defaultTestContainer() + val newUser = "testnewuser3" + a.createFile("~/.ssh/authorized_keys", "newdummykey") + + // when + val res = a.createUser(newUser, copyAuthorizedSshKeysFromCurrentUser = true) + + // then + assertTrue(res.success) + assertTrue(a.userExists(newUser)) + assertTrue(!a.userIsInGroupSudo(newUser)) + assertEquals("newdummykey", a.fileContent("/home/$newUser/.ssh/authorized_keys", sudo = true)) + } + + @Test + fun createUserWithSudo() { + // given + val a = defaultTestContainer() + val newUser = "testnewsudouser3" + a.createFile("~/.ssh/authorized_keys","newdummykey") + + // when + val res = a.createUser(newUser, sudo = true, copyAuthorizedSshKeysFromCurrentUser = true) + + // then + assertTrue(res.success) + assertTrue(a.userExists(newUser)) + assertEquals("newdummykey", a.fileContent("/home/$newUser/.ssh/authorized_keys", sudo = true)) + + // new user can sudo + assertTrue(a.cmd("sudo -H -u $newUser bash -c 'sudo echo \"I am \$USER, with uid \$UID\"' ").success) + } } \ No newline at end of file