Skip to content

Commit 58918a7

Browse files
committed
[1.0.2] Add Checks for Existing Users, Create #checkCredentials
1 parent ec6f145 commit 58918a7

File tree

3 files changed

+85
-65
lines changed

3 files changed

+85
-65
lines changed

build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ plugins {
1313
}
1414

1515
group = "io.codemc.api"
16-
version = "1.0.1"
16+
version = "1.0.2"
1717
description = "Official API for CodeMC Jenkins & Nexus Services"
1818

1919
repositories {

src/main/kotlin/io/codemc/api/jenkins/jenkins.kt

+38-32
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,23 @@ const val NEXUS_CREDENTIALS_DESCRIPTION = "Your Nexus Login Details"
6161

6262
internal suspend fun createCredentials(username: String, password: String): Boolean {
6363
// Create Credentials Domain
64-
val domainConfig = RESOURCE_CACHE[CREDENTIALS_DOMAIN] ?: return false
65-
val domain = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/createDomain") {
66-
POST(HttpRequest.BodyPublishers.ofString(domainConfig))
64+
val checkDomain = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/domain/Services/config.xml") {
65+
GET()
6766

6867
header("Authorization", "Basic ${client.authValue()}")
69-
header("Content-Type", "application/xml")
7068
}
7169

72-
if (domain.statusCode() != 200) return false
70+
if (checkDomain.statusCode() == 404) {
71+
val domainConfig = RESOURCE_CACHE[CREDENTIALS_DOMAIN] ?: return false
72+
val domain = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/createDomain") {
73+
POST(HttpRequest.BodyPublishers.ofString(domainConfig))
74+
75+
header("Authorization", "Basic ${client.authValue()}")
76+
header("Content-Type", "application/xml")
77+
}
78+
79+
if (domain.statusCode() != 200) return false
80+
}
7381

7482
// Create Credentials Store
7583
val storeConfig = (RESOURCE_CACHE[CREDENTIALS] ?: return false)
@@ -85,49 +93,43 @@ internal suspend fun createCredentials(username: String, password: String): Bool
8593
header("Content-Type", "application/xml")
8694
}
8795

88-
return store.statusCode() == 200
96+
// Either successful or already exists
97+
return store.statusCode() == 200 || store.statusCode() == 409
8998
}
9099

91100
/**
92-
* Changes the Jenkins password for a user.
101+
* Checks if the Jenkins credentials exist, and creates them if they don't.
93102
* @param username The username of the user.
94-
* @param newPassword The new password.
95-
* @return `true` if the password was changed, `false` otherwise.
103+
* @param password The password of the user.
96104
*/
97-
fun changeJenkinsPassword(username: String, newPassword: String): Boolean = runBlocking(Dispatchers.IO) {
98-
// Create Credentials Domain
105+
fun checkCredentials(username: String, password: String) = runBlocking(Dispatchers.IO) {
106+
// Check Domain
99107
val checkDomain = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/domain/Services/config.xml") {
100108
GET()
101109

102110
header("Authorization", "Basic ${client.authValue()}")
103111
}
104112

105-
if (checkDomain.statusCode() == 404) {
106-
val domainConfig = RESOURCE_CACHE[CREDENTIALS_DOMAIN] ?: return@runBlocking false
107-
val domain = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/createDomain") {
108-
POST(HttpRequest.BodyPublishers.ofString(domainConfig))
109-
110-
header("Authorization", "Basic ${client.authValue()}")
111-
header("Content-Type", "application/xml")
112-
}
113+
// Check Credential Store
114+
val checkStore = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/domain/Services/credential/$NEXUS_CREDENTIALS_ID/config.xml") {
115+
GET()
113116

114-
if (domain.statusCode() != 200) return@runBlocking false
117+
header("Authorization", "Basic ${client.authValue()}")
115118
}
116119

117-
val config = (RESOURCE_CACHE[CREDENTIALS] ?: return@runBlocking false)
118-
.replace("{ID}", NEXUS_CREDENTIALS_ID)
119-
.replace("{DESCRIPTION}", NEXUS_CREDENTIALS_DESCRIPTION)
120-
.replace("{USERNAME}", username.lowercase())
121-
.replace("{PASSWORD}", newPassword)
122-
123-
val res = req("${jenkinsConfig.url}/job/$username/credentials/store/folder/domain/Services/credential/$NEXUS_CREDENTIALS_ID/config.xml") {
124-
POST(HttpRequest.BodyPublishers.ofString(config))
125-
126-
header("Authorization", "Basic ${client.authValue()}")
127-
header("Content-Type", "application/xml")
120+
if (checkDomain.statusCode() == 404 || checkStore.statusCode() == 404) {
121+
createCredentials(username, password)
128122
}
123+
}
129124

130-
return@runBlocking res.statusCode() == 200
125+
/**
126+
* Changes the Jenkins password for a user.
127+
* @param username The username of the user.
128+
* @param newPassword The new password.
129+
* @return `true` if the password was changed, `false` otherwise.
130+
*/
131+
fun changeJenkinsPassword(username: String, newPassword: String): Boolean = runBlocking(Dispatchers.IO) {
132+
return@runBlocking createCredentials(username, newPassword)
131133
}
132134

133135
/**
@@ -137,6 +139,8 @@ fun changeJenkinsPassword(username: String, newPassword: String): Boolean = runB
137139
* @return `true` if the user was created, `false` otherwise.
138140
*/
139141
fun createJenkinsUser(username: String, password: String): Boolean = runBlocking(Dispatchers.IO) {
142+
if (getJenkinsUser(username).isNotEmpty()) return@runBlocking false
143+
140144
val config0 = RESOURCE_CACHE[USER_CONFIG] ?: return@runBlocking false
141145

142146
val config = config0
@@ -184,6 +188,8 @@ fun createJenkinsJob(
184188
isFreestyle: Boolean,
185189
config: (String) -> String = { it }
186190
): Boolean {
191+
if (getJenkinsJob(username, jobName).isNotEmpty()) return false
192+
187193
val template = (if (isFreestyle) RESOURCE_CACHE[JOB_FREESTYLE] else RESOURCE_CACHE[JOB_MAVEN])
188194
?.replace("{PROJECT_URL}", repoLink) ?: return false
189195

src/main/kotlin/io/codemc/api/nexus/nexus.kt

+46-32
Original file line numberDiff line numberDiff line change
@@ -81,49 +81,58 @@ fun ping(): Boolean = runBlocking {
8181
fun createNexus(name: String, password: String) = runBlocking(Dispatchers.IO) {
8282
// Create User Repository
8383
val id = name.lowercase()
84-
val repo = createMavenRepository(name)
85-
val repoResponse = nexus("$API_URL/repositories/maven/hosted") {
86-
POST(HttpRequest.BodyPublishers.ofString(repo))
87-
header("Content-Type", "application/json")
88-
}
8984

90-
if (repoResponse.statusCode() != 201) return@runBlocking false
85+
if (getNexusRepository(id) == null) {
86+
val repo = createMavenRepository(name)
87+
val repoResponse = nexus("$API_URL/repositories/maven/hosted") {
88+
POST(HttpRequest.BodyPublishers.ofString(repo))
89+
header("Content-Type", "application/json")
90+
}
91+
92+
if (repoResponse.statusCode() != 201) return@runBlocking false
93+
}
9194

9295
// Add Role
93-
val role = buildJsonObject {
94-
put("id", id)
95-
put("name", name)
96-
put("description", "Role for $name")
97-
putJsonArray("privileges") {
98-
addAll(getNexusRoles(id))
96+
if (getNexusRole(id) == null) {
97+
val role = buildJsonObject {
98+
put("id", id)
99+
put("name", name)
100+
put("description", "Role for $name")
101+
putJsonArray("privileges") {
102+
addAll(getNexusRoles(id))
103+
}
104+
}.toString()
105+
106+
val roleReq = nexus("$API_URL/security/roles") {
107+
POST(HttpRequest.BodyPublishers.ofString(role))
108+
header("Content-Type", "application/json")
99109
}
100-
}.toString()
101110

102-
val roleReq = nexus("$API_URL/security/roles") {
103-
POST(HttpRequest.BodyPublishers.ofString(role))
104-
header("Content-Type", "application/json")
111+
if (roleReq.statusCode() != 200) return@runBlocking false
105112
}
106113

107-
if (roleReq.statusCode() != 200) return@runBlocking false
108-
109114
// Add User with Role
110-
val user = buildJsonObject {
111-
put("userId", id)
112-
put("firstName", name)
113-
put("lastName", "User")
114-
put("emailAddress", "$name@users.noreply.github.com") // Can't actually receive mail
115-
put("status", "active")
116-
put("password", password)
117-
putJsonArray("roles") {
118-
add(id)
115+
if (getNexusUser(id) == null) {
116+
val user = buildJsonObject {
117+
put("userId", id)
118+
put("firstName", name)
119+
put("lastName", "User")
120+
put("emailAddress", "$name@users.noreply.github.com") // Can't actually receive mail
121+
put("status", "active")
122+
put("password", password)
123+
putJsonArray("roles") {
124+
add(id)
125+
}
126+
}.toString()
127+
128+
val userRes = nexus("$API_URL/security/users") {
129+
POST(HttpRequest.BodyPublishers.ofString(user))
130+
header("Content-Type", "application/json")
119131
}
120-
}.toString()
121132

122-
val userRes = nexus("$API_URL/security/users") {
123-
POST(HttpRequest.BodyPublishers.ofString(user))
124-
header("Content-Type", "application/json")
133+
if (userRes.statusCode() != 201) return@runBlocking false
125134
}
126-
return@runBlocking userRes.statusCode() == 200
135+
return@runBlocking true
127136
}
128137

129138
/**
@@ -133,6 +142,11 @@ fun createNexus(name: String, password: String) = runBlocking(Dispatchers.IO) {
133142
* @return `true` if the change was successful, `false` otherwise
134143
*/
135144
fun changeNexusPassword(name: String, newPassword: String) = runBlocking(Dispatchers.IO) {
145+
if (getNexusUser(name) == null) {
146+
createNexus(name, newPassword)
147+
return@runBlocking true
148+
}
149+
136150
val id = name.lowercase()
137151
val res = nexus("$API_URL/security/users/$id/change-password") {
138152
PUT(HttpRequest.BodyPublishers.ofString(newPassword))

0 commit comments

Comments
 (0)