Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Dropping a requirement of a major version of a dependency is a new contract.
[Unreleased]: https://github.com/atlassian/infrastructure/compare/release-4.18.0...master
### Added
- `JiraUserPasswordOverridingDatabase` to support providing custom admin password during database setup [JPERF-729]
- Add static `Database.overridePassword` (a Kotlin extension).

[JPERF-729]: https://ecosystem.atlassian.net/browse/JPERF-729

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import org.apache.logging.log4j.Logger
import java.net.URI
import java.util.function.Function

class JiraUserPasswordOverridingDatabase internal constructor(
class JiraUserPasswordOverridingDatabase private constructor(
private val databaseDelegate: Database,
private val sqlClient: SshSqlClient,
private val username: String,
private val jiraDatabaseSchemaName: String,
private val userPasswordPlainText: String,
private val userPasswordEncryptorProvider: JiraUserPasswordEncryptorProvider
private val plainTextPassword: String,
private val passwordEncryption: Function<String, String>,
private val sqlClient: SshSqlClient,
private val schema: String
) : Database {
private val logger: Logger = LogManager.getLogger(this::class.java)

Expand All @@ -26,61 +26,57 @@ class JiraUserPasswordOverridingDatabase internal constructor(
ssh: SshConnection
) {
databaseDelegate.start(jira, ssh)
val userPasswordEncryptor = userPasswordEncryptorProvider.getEncryptor(ssh, sqlClient)
val password = userPasswordEncryptor.getEncryptedPassword(userPasswordPlainText)
sqlClient.runSql(ssh, "UPDATE ${jiraDatabaseSchemaName}.cwd_user SET credential='$password' WHERE user_name='$username';")
logger.debug("Password for user '$username' updated to '${userPasswordPlainText}'")
val methodSelect = "SELECT attribute_value FROM $schema.cwd_directory_attribute" +
" WHERE attribute_name = 'user_encryption_method';"
val encryptionMethod = sqlClient.runSql(ssh, methodSelect).output
val password = when {
encryptionMethod.contains("plaintext") -> plainTextPassword
encryptionMethod.contains("atlassian-security") -> passwordEncryption.apply(plainTextPassword)
else -> throw RuntimeException("Unknown jira user password encryption type")
}
val passwordUpdate = "UPDATE $schema.cwd_user SET credential='$password'" +
" WHERE user_name='$username';"
sqlClient.runSql(ssh, passwordUpdate)
logger.debug("Password for user '$username' updated to '$plainTextPassword'")
}


class Builder(
private var databaseDelegate: Database,
private var userPasswordPlainText: String,
private var userPasswordEncryptorProvider: JiraUserPasswordEncryptorProvider
private var passwordEncryption: Function<String, String>
) {
private var sqlClient: SshSqlClient = SshMysqlClient()
private var jiraDatabaseSchemaName: String = "jiradb"
private var schema: String = "jiradb"
private var username: String = "admin"
private var plainTextPassword: String = "admin"

fun databaseDelegate(databaseDelegate: Database) = apply { this.databaseDelegate = databaseDelegate }
fun username(username: String) = apply { this.username = username }
fun userPasswordPlainText(userPassword: String) = apply { this.userPasswordPlainText = userPassword }
fun plainTextPassword(passwordPlainText: String) = apply { this.plainTextPassword = passwordPlainText }
fun sqlClient(sqlClient: SshSqlClient) = apply { this.sqlClient = sqlClient }
fun jiraDatabaseSchemaName(jiraDatabaseSchemaName: String) = apply { this.jiraDatabaseSchemaName = jiraDatabaseSchemaName }
fun userPasswordEncryptorProvider(userPasswordEncryptorProvider: JiraUserPasswordEncryptorProvider) =
apply { this.userPasswordEncryptorProvider = userPasswordEncryptorProvider }
fun schema(jiraDatabaseSchemaName: String) = apply { this.schema = jiraDatabaseSchemaName }
fun passwordEncryption(passwordEncryption: Function<String, String>) =
apply { this.passwordEncryption = passwordEncryption }

fun build() = JiraUserPasswordOverridingDatabase(
databaseDelegate = databaseDelegate,
sqlClient = sqlClient,
username = username,
userPasswordPlainText = userPasswordPlainText,
jiraDatabaseSchemaName = jiraDatabaseSchemaName,
userPasswordEncryptorProvider = userPasswordEncryptorProvider
plainTextPassword = plainTextPassword,
passwordEncryption = passwordEncryption,
schema = schema
)
}

}

/**
* @param passwordEncryptFunction Based on [retrieving-the-jira-administrator](https://confluence.atlassian.com/jira/retrieving-the-jira-administrator-192836.html)
* @param passwordEncryption Based on [retrieving-the-jira-administrator](https://confluence.atlassian.com/jira/retrieving-the-jira-administrator-192836.html)
* to encode the password in Jira format use [com.atlassian.crowd.password.encoder.AtlassianSecurityPasswordEncoder](https://docs.atlassian.com/atlassian-crowd/4.2.2/com/atlassian/crowd/password/encoder/AtlassianSecurityPasswordEncoder.html)
* from the [com.atlassian.crowd.crowd-password-encoders](https://mvnrepository.com/artifact/com.atlassian.crowd/crowd-password-encoders/4.2.2).
*
*/
fun Database.withAdminPassword(adminPasswordPlainText: String, passwordEncryptFunction: Function<String, String>): Database {
val jiraDatabaseSchemaName = "jiradb"
val sqlClient = SshMysqlClient()
return JiraUserPasswordOverridingDatabase.Builder(
databaseDelegate = this,
userPasswordPlainText = adminPasswordPlainText,
userPasswordEncryptorProvider = DefaultJiraUserPasswordEncryptorProvider(
jiraDatabaseSchemaName = jiraDatabaseSchemaName,
plainTextPasswordEncryptor = PlainTextJiraUserPasswordEncryptor(),
encryptedPasswordEncryptor = EncryptedJiraUserPasswordEncryptor(passwordEncryptFunction)
)
)
.jiraDatabaseSchemaName(jiraDatabaseSchemaName)
.sqlClient(sqlClient)
.build()
}
fun Database.overridePassword(
passwordEncryption: Function<String, String>
): JiraUserPasswordOverridingDatabase.Builder = JiraUserPasswordOverridingDatabase.Builder(
databaseDelegate = this,
passwordEncryption = passwordEncryption
)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.atlassian.performance.tools.infrastructure.api.database.passwordoverride

import com.atlassian.performance.tools.infrastructure.api.database.Database
import com.atlassian.performance.tools.infrastructure.database.SshSqlClient
import com.atlassian.performance.tools.infrastructure.mock.MockSshSqlClient
import com.atlassian.performance.tools.infrastructure.mock.RememberingDatabase
import com.atlassian.performance.tools.infrastructure.mock.RememberingSshConnection
Expand All @@ -10,6 +9,7 @@ import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import java.net.URI
import java.util.function.Function

class JiraUserPasswordOverridingDatabaseTest {

Expand All @@ -27,21 +27,18 @@ class JiraUserPasswordOverridingDatabaseTest {
underlyingDatabase = RememberingDatabase()
sshConnection = RememberingSshConnection()
sqlClient = MockSshSqlClient()
database = JiraUserPasswordOverridingDatabase
.Builder(
databaseDelegate = underlyingDatabase,
userPasswordPlainText = samplePassword,
userPasswordEncryptorProvider = object : JiraUserPasswordEncryptorProvider {
override fun getEncryptor(ssh: SshConnection, sqlClient: SshSqlClient): JiraUserPasswordEncryptor {
return object : JiraUserPasswordEncryptor {
override fun getEncryptedPassword(plainTextPassword: String) = expectedEncryptedPassword
}
}
}
)
database = underlyingDatabase.overridePassword(Function { expectedEncryptedPassword })
.plainTextPassword(samplePassword)
.sqlClient(sqlClient)
.jiraDatabaseSchemaName("jira")
.schema("jira")
.build()
sqlClient.queueReturnedSqlCommandResult(
SshConnection.SshResult(
exitStatus = 0,
output = "atlassian-security",
errorOutput = ""
)
)
}

@Test
Expand Down Expand Up @@ -74,7 +71,7 @@ class JiraUserPasswordOverridingDatabaseTest {
// then
assertThat(sqlClient.getLog())
.`as`("sql queries executed")
.containsExactly(
.contains(
"UPDATE jira.cwd_user SET credential='${expectedEncryptedPassword}' WHERE user_name='admin';"
)
}
Expand Down