Skip to content

Commit

Permalink
Impersonate as SYSTEM to fetch projects for triggering builds
Browse files Browse the repository at this point in the history
  • Loading branch information
Kiryushin-Andrey committed Apr 16, 2024
1 parent 9198d05 commit c9c3d0b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.jetbrains.space.jenkins.trigger
import groovy.json.JsonOutput
import hudson.ExtensionList
import hudson.model.CauseAction
import hudson.security.ACL
import io.ktor.http.*
import io.ktor.utils.io.charsets.*
import jenkins.model.Jenkins
Expand Down Expand Up @@ -80,54 +81,56 @@ fun SpaceWebhookEndpoint.doProcess(request: StaplerRequest, response: StaplerRes
*/
@OptIn(ExperimentalSpaceSdkApi::class)
private suspend fun ProcessingScope.processWebhookCallback(payload: WebhookRequestPayload): SpaceHttpResponse {
val allJobs = Jenkins.get().getAllItems(TriggeredItem::class.java)
val (job, trigger) = allJobs.findBySpaceWebhookId(payload.webhookId)
?: run {
// fallback to fetching and parsing webhook name
clientWithClientCredentials().fetchWebhookById(payload.webhookId)
?.let { getTriggerId(it) }
?.let { allJobs.findByTriggerId(it) }
.also {
if (it != null) {
it.second.ensureSpaceWebhook(it.first.fullDisplayName)
} else {
LOGGER.warning("Trigger found for webhook id = ${payload.webhookId} found by fallback to webhook name")
return ACL.as2(ACL.SYSTEM2).use {
val allJobs = Jenkins.get().getAllItems(TriggeredItem::class.java)
val (job, trigger) = allJobs.findBySpaceWebhookId(payload.webhookId)
?: run {
// fallback to fetching and parsing webhook name
clientWithClientCredentials().fetchWebhookById(payload.webhookId)
?.let { getTriggerId(it) }
?.let { allJobs.findByTriggerId(it) }
.also {
if (it != null) {
it.second.ensureSpaceWebhook(it.first.fullDisplayName)
} else {
LOGGER.warning("Trigger found for webhook id = ${payload.webhookId} found by fallback to webhook name")
}
}
}
}
?: run {
LOGGER.warning("No registered trigger found for webhook id = ${payload.webhookId}")
}
?: run {
LOGGER.warning("No registered trigger found for webhook id = ${payload.webhookId}")
return SpaceHttpResponse.RespondWithCode(HttpStatusCode.BadRequest)
}

val triggerItem = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job)
if (triggerItem == null) {
LOGGER.info("Cannot trigger item of type ${job::class.qualifiedName}")
return SpaceHttpResponse.RespondWithCode(HttpStatusCode.BadRequest)
}

val triggerItem = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job)
if (triggerItem == null) {
LOGGER.info("Cannot trigger item of type ${job::class.qualifiedName}")
return SpaceHttpResponse.RespondWithCode(HttpStatusCode.BadRequest)
}
val spacePluginConfiguration = ExtensionList.lookup(SpacePluginConfiguration::class.java).singleOrNull()
?: error("Space plugin configuration cannot be resolved")

val spacePluginConfiguration = ExtensionList.lookup(SpacePluginConfiguration::class.java).singleOrNull()
?: error("Space plugin configuration cannot be resolved")
val spaceConnection = spacePluginConfiguration.getConnectionByClientId(payload.clientId)
?: error("Space connection cannot be found for client id specified in webhook payload")

val spaceConnection = spacePluginConfiguration.getConnectionByClientId(payload.clientId)
?: error("Space connection cannot be found for client id specified in webhook payload")
// deep check of event properties and trigger conditions to ensure that build should be triggered
val result = getTriggeredBuildCause(trigger, payload.payload, spaceConnection)
when (result) {

Check warning on line 119 in src/main/java/org/jetbrains/space/jenkins/trigger/SpaceWebhookEndpoint.kt

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 84-119 are not covered by tests
is WebhookEventResult.RunBuild -> {
val causeAction = CauseAction(result.cause)
triggerItem.scheduleBuild2(triggerItem.quietPeriod, causeAction)
SpaceHttpResponse.RespondWithOk
}

// deep check of event properties and trigger conditions to ensure that build should be triggered
val result = getTriggeredBuildCause(trigger, payload.payload, spaceConnection)
return when (result) {
is WebhookEventResult.RunBuild -> {
val causeAction = CauseAction(result.cause)
triggerItem.scheduleBuild2(triggerItem.quietPeriod, causeAction)
SpaceHttpResponse.RespondWithOk
}
is WebhookEventResult.UnexpectedEvent -> {
trigger.ensureSpaceWebhook(job.fullDisplayName)
SpaceHttpResponse.RespondWithCode(HttpStatusCode.BadRequest)
}

is WebhookEventResult.UnexpectedEvent -> {
trigger.ensureSpaceWebhook(job.fullDisplayName)
SpaceHttpResponse.RespondWithCode(HttpStatusCode.BadRequest)
is WebhookEventResult.IgnoredEvent ->
SpaceHttpResponse.RespondWithCode(HttpStatusCode.Accepted)
}

is WebhookEventResult.IgnoredEvent ->
SpaceHttpResponse.RespondWithCode(HttpStatusCode.Accepted)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import hudson.model.Queue.Task
import hudson.model.queue.ScheduleResult.Created
import hudson.model.queue.ScheduleResult.Existing
import hudson.model.queue.ScheduleResult.Refused
import hudson.security.ACL
import io.ktor.http.*
import jenkins.model.Jenkins
import jenkins.triggers.SCMTriggerItem
Expand Down Expand Up @@ -40,7 +41,7 @@ suspend fun ProcessingScope.startSafeMerge(clientId: String, command: SafeMergeC
val spaceConnection = getSpaceConnectionByClientId(clientId)
?: return SpaceHttpResponse.RespondWithCode(HttpStatusCode.Unauthorized)

val job = Jenkins.get().getItemByFullName(command.project)
val job = ACL.as2(ACL.SYSTEM2).use { Jenkins.get().getItemByFullName(command.project) }

Check warning on line 44 in src/main/java/org/jetbrains/space/jenkins/trigger/safeMergeCommands.kt

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 44 is not covered by tests
?: return SpaceHttpResponse.RespondWithCode(HttpStatusCode.NotFound)

(job as? Queue.Task)
Expand Down

0 comments on commit c9c3d0b

Please sign in to comment.