jira

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ChangeItem

type ChangeItem struct {
	Field      string `json:"field"`
	FromString string `json:"fromString"`
	ToString   string `json:"toString"`
}

ChangeItem is one entry in the changelog.

type Changelog

type Changelog struct {
	Items []ChangeItem `json:"items"`
}

Changelog carries the before/after values of changed fields.

type Client

type Client interface {
	CreateIssue(ctx context.Context, input CreateIssueInput) (*CreateIssueResult, error)
	TestConnection(ctx context.Context) error
}

Client defines the interface for Jira REST API operations.

type CreateIssueInput

type CreateIssueInput struct {
	ProjectKey  string
	Summary     string
	Description string
	IssueType   string
	Priority    string
	Labels      []string
}

CreateIssueInput contains fields for creating a Jira issue.

type CreateIssueResult

type CreateIssueResult struct {
	ID        string
	Key       string
	BrowseURL string
}

CreateIssueResult contains the response from creating a Jira issue.

type CreateTicketInput

type CreateTicketInput struct {
	TenantID   string `json:"tenant_id"`
	FindingID  string `json:"finding_id"`
	ProjectKey string `json:"project_key"` // e.g. "SEC"
	IssueType  string `json:"issue_type"`  // e.g. "Bug"
}

CreateTicketInput is the payload for auto-creating a Jira ticket from a finding.

type FindingByIDReader

type FindingByIDReader interface {
	GetByID(ctx context.Context, tenantID, findingID shared.ID) (*vulnerability.Finding, error)
}

FindingByIDReader is the narrow Finding-repo surface the hook uses to look up the scanner that originally produced the finding.

type FixAppliedHook

type FixAppliedHook func(ctx context.Context, tenantID, findingID shared.ID) error

FixAppliedHook is called when a Jira webhook transitions a finding into the fix_applied state. Typical implementation: enqueue a verification scan on the finding's asset. Wired via SetPostFixAppliedHook; nil → no action (legacy behaviour).

Implementations MUST be idempotent — the B3 rate-limiting guard in the implementation layer decides whether to actually enqueue a scan (e.g. max one per finding per 24h).

type LinkTicketInput

type LinkTicketInput struct {
	TenantID  string `json:"tenant_id"`
	FindingID string `json:"finding_id"`
	TicketKey string `json:"ticket_key"` // e.g. "PROJ-123"
	TicketURL string `json:"ticket_url"` // e.g. "https://myorg.atlassian.net/browse/PROJ-123"
}

LinkTicketInput is the payload for linking a Jira ticket to a finding.

type RescanHook

type RescanHook struct {
	// contains filtered or unexported fields
}

RescanHook wraps the verification trigger with a per-finding cooldown. Install via SyncService.SetPostFixAppliedHook(hook.Hook).

func NewRescanHook

func NewRescanHook(
	actions VerificationScanRequester,
	repo FindingByIDReader,
	log *logger.Logger,
) *RescanHook

NewRescanHook wires the deps + cooldown.

func (*RescanHook) Hook

func (h *RescanHook) Hook(ctx context.Context, tenantID, findingID shared.ID) error

Hook is the callback installed on SyncService. Matches the FixAppliedHook function signature in jira_sync_service.go.

func (*RescanHook) SetCooldown

func (h *RescanHook) SetCooldown(d time.Duration)

SetCooldown overrides the default 24h cooldown. Useful for tests.

type SyncService

type SyncService struct {
	// contains filtered or unexported fields
}

SyncService handles bidirectional sync between findings and Jira tickets.

Capabilities:

  1. POST /findings/{id}/link-ticket — manually link a Jira ticket to a finding
  2. POST /findings/{id}/create-ticket — auto-create Jira ticket from finding
  3. POST /webhooks/incoming/jira — receive Jira status-change webhooks

func NewSyncService

func NewSyncService(findingRepo vulnerability.FindingRepository, jiraClient Client, log *logger.Logger) *SyncService

NewSyncService creates a new SyncService.

func (*SyncService) CreateTicketFromFinding

func (s *SyncService) CreateTicketFromFinding(ctx context.Context, input CreateTicketInput) (*TicketInfo, error)

CreateTicketFromFinding auto-creates a Jira ticket from a finding and links it.

func (*SyncService) HandleJiraWebhook

func (s *SyncService) HandleJiraWebhook(ctx context.Context, tenantID shared.ID, payload WebhookPayload) error

HandleJiraWebhook processes an inbound Jira webhook and syncs finding status.

Status mapping:

Jira "In Progress"  → finding "in_progress"
Jira "In Review"    → finding "in_progress"
Jira "Done"         → finding "fix_applied"  (triggers verification flow)
Jira "Resolved"     → finding "fix_applied"
Jira "Closed"       → finding "fix_applied"

func (*SyncService) LinkTicket

func (s *SyncService) LinkTicket(ctx context.Context, input LinkTicketInput) error

LinkTicket adds a Jira ticket reference to a finding's work_item_uris. Idempotent — re-adding the same URL is a no-op at the domain level.

func (*SyncService) SetPostFixAppliedHook

func (s *SyncService) SetPostFixAppliedHook(h FixAppliedHook)

SetPostFixAppliedHook wires the verification-scan trigger. Safe to call after construction; nil value disables the hook.

func (*SyncService) UnlinkTicket

func (s *SyncService) UnlinkTicket(ctx context.Context, tenantIDStr, findingIDStr, ticketURL string) error

UnlinkTicket removes a Jira ticket reference from a finding.

type TicketInfo

type TicketInfo struct {
	FindingID string    `json:"finding_id"`
	TicketKey string    `json:"ticket_key"`
	TicketURL string    `json:"ticket_url"`
	LinkedAt  time.Time `json:"linked_at"`
}

TicketInfo is returned by LinkTicket to the HTTP handler for the response body.

type VerificationScanRequester

type VerificationScanRequester interface {
	RequestVerificationScan(ctx context.Context, tenantID, userID string, input app.RequestVerificationScanInput) (*app.RequestVerificationScanResult, error)
}

VerificationScanRequester is the narrow surface the hook needs from FindingActionsService. Kept as an interface so the hook is testable without standing up the full finding-actions graph. *FindingActionsService satisfies it directly.

type WebhookIssue

type WebhookIssue struct {
	Key    string                 `json:"key"`  // e.g. "PROJ-123"
	Self   string                 `json:"self"` // e.g. "https://myorg.atlassian.net/rest/api/2/issue/10001"
	Fields map[string]interface{} `json:"fields"`
}

WebhookIssue represents the issue block inside a Jira webhook payload.

type WebhookPayload

type WebhookPayload struct {
	WebhookEvent string       `json:"webhookEvent"` // "jira:issue_updated"
	Issue        WebhookIssue `json:"issue"`
	Changelog    *Changelog   `json:"changelog,omitempty"`
}

WebhookPayload is the envelope sent by Jira issue-updated webhooks. See https://developer.atlassian.com/cloud/jira/platform/webhooks/

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL