improved Jira support and working on salesforce rule, which is broken atm

This commit is contained in:
Mick Grove 2025-12-16 16:53:02 -08:00
commit d155a33334
4 changed files with 215 additions and 35 deletions

View file

@ -187,7 +187,7 @@ semver = "1.0.27"
globset = "0.4.18"
jsonwebtoken = "9.3.1"
ipnet = "2.11.0"
jira_query = "1.6.0"
gouqi = { version = "0.20.0", features = ["async"] }
oci-client = { version = "0.15", default-features = false, features = ["rustls-tls"] }
walkdir = "2.5.0"
p256 = "0.13.2"
@ -249,7 +249,6 @@ codegen-units = 256
[patch.crates-io]
vectorscan-rs = { path = "vendor/vectorscan-rs/vectorscan-rs" }
vectorscan-rs-sys = { path = "vendor/vectorscan-rs/vectorscan-rs-sys" }
jira_query = { path = "vendor/jira_query" }
[profile.profiling]
inherits = "release"

View file

@ -4,7 +4,7 @@ rules:
pattern: |
(?xi)
\b
(
(
00
[A-Z0-9]{13}
!
@ -49,17 +49,198 @@ rules:
id: kingfisher.salesforce.2
pattern: |
(?xi)
\b
\b
(?:https?://)?
(
[0-9A-Z-]{5,128}
)
\.
\\
my\.salesforce\.com
\b
\b
min_entropy: 2.5
confidence: medium
visible: false
examples:
- https://example123.my.salesforce.com
- mydomainname.my.salesforce.com
- mydomainname.my.salesforce.com
- name: Salesforce Consumer Key and Secret with Token URL
id: kingfisher.salesforce.3
pattern: |
(?xi)(?s)
(?:salesforce|sforce)
(?:.|[\n\r]){0,256}?
\bconsumer\s{0,8}key\b
(?:.|[\n\r]){0,32}?
\b
(?P<CONSUMER_KEY>
[A-Z0-9+/=._-]{16,256}
)
\b.*?
(?:.|[\n\r]){0,256}?
\bconsumer\s{0,8}secret\b
(?:.|[\n\r]){0,32}?
\b
(?P<CONSUMER_SECRET>
[A-Za-z0-9+/=._-]{16,256}
)
.*?
\btoken\s{0,8}url\b
(?:.|[\n\r]){0,16}?
(?P<TOKEN_URL>
https?://
[A-Za-z0-9.-]{3,253}
/
(?:services/oauth2/token|oauth/login/[\w-]+/token|oauth2/(?:v1/)?token|oauth/token|[\w]{1,10}/oauth/token)
)
min_entropy: 3.3
confidence: medium
examples:
- |
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://login.example.com/oauth/login/v2/authorize?authHint=SALESFORCE_OAUTH2&amp;authType=oauth2&amp;prompt=login</authorizeUrl>
<consumerKey>012cbddfa6b05ec1941143c0d37a036291492be9f2df0b42c5c0c220198185de</consumerKey>
<consumerSecret>REDACTED_CONSUMER_SECRET_1</consumerSecret>
<friendlyName>ExampleProviderOne</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>OpenIdConnect</providerType>
<sendAccessTokenInHeader>true</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://login.example.com/oauth/login/v2/token</tokenUrl>
</AuthProvider>
- |
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://api.example.net/oauth/authorize</authorizeUrl>
<consumerKey>REDACTED_CONSUMER_KEY_2</consumerKey>
<consumerSecret>REDACTED_CONSUMER_SECRET_2</consumerSecret>
<friendlyName>ExampleBatchConnect</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>OpenIdConnect</providerType>
<sendAccessTokenInHeader>true</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://api.example.net/oauth/token</tokenUrl>
</AuthProvider>
- |
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://api.example.net/oauth/authorize</authorizeUrl>
<consumerKey>REDACTED_CONSUMER_KEY_3</consumerKey>
<consumerSecret>REDACTED_CONSUMER_SECRET_3</consumerSecret>
<friendlyName>ExampleConnect</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>OpenIdConnect</providerType>
<sendAccessTokenInHeader>true</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://api.example.net/oauth/token</tokenUrl>
</AuthProvider>
validation:
type: Http
content:
request:
method: POST
url: "{{ TOKEN_URL | default: 'https://login.salesforce.com/services/oauth2/token' }}"
headers:
Content-Type: application/x-www-form-urlencoded
body: grant_type=client_credentials&client_id={{ CONSUMER_KEY | url_encode }}&client_secret={{ CONSUMER_SECRET | url_encode }}
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: StatusMatch
status: [400, 401, 403]
negative: true
- type: JsonValid
- type: WordMatch
words: ["access_token", "token_type"]
match_all_words: true
- name: Salesforce Consumer Key and Secret
id: kingfisher.salesforce.4
pattern: |
(?xi)(?s)
(?:salesforce|sforce)
(?:.|[\n\r]){0,256}?
\bconsumer\s{0,8}key\b
(?:.|[\n\r]){0,32}?
\b
(?P<CONSUMER_KEY>
[A-Z0-9+/=._-]{16,256}
)
\b.*?
(?:.|[\n\r]){0,256}?
\bconsumer\s{0,8}secret\b
(?:.|[\n\r]){0,32}?
\b
(?P<CONSUMER_SECRET>
[A-Za-z0-9+/=._-]{16,256}
)
min_entropy: 3.3
confidence: medium
examples:
- |
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://login.example.com/oauth/login/v2/authorize?authHint=SALESFORCE_OAUTH2&amp;authType=oauth2&amp;prompt=login</authorizeUrl>
<consumerKey>012cbddfa6b05ec1941143c0d37a036291492be9f2df0b42c5c0c220198185de</consumerKey>
<consumerSecret>REDACTED_CONSUMER_SECRET_1</consumerSecret>
<friendlyName>ExampleProviderOne</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>OpenIdConnect</providerType>
<sendAccessTokenInHeader>true</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://login.example.com/oauth/login/v2/token</tokenUrl>
</AuthProvider>
- |
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://api.example.net/oauth/authorize</authorizeUrl>
<consumerKey>REDACTED_CONSUMER_KEY_2</consumerKey>
<consumerSecret>REDACTED_CONSUMER_SECRET_2</consumerSecret>
<friendlyName>ExampleBatchConnect</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>OpenIdConnect</providerType>
<sendAccessTokenInHeader>true</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://api.example.net/oauth/token</tokenUrl>
</AuthProvider>
- |
<?xml version="1.0" encoding="UTF-8"?>
<AuthProvider xmlns="http://soap.sforce.com/2006/04/metadata">
<authorizeUrl>https://api.example.net/oauth/authorize</authorizeUrl>
<consumerKey>REDACTED_CONSUMER_KEY_3</consumerKey>
<consumerSecret>REDACTED_CONSUMER_SECRET_3</consumerSecret>
<friendlyName>ExampleConnect</friendlyName>
<includeOrgIdInIdentifier>false</includeOrgIdInIdentifier>
<providerType>OpenIdConnect</providerType>
<sendAccessTokenInHeader>true</sendAccessTokenInHeader>
<sendClientCredentialsInHeader>false</sendClientCredentialsInHeader>
<sendSecretInApis>true</sendSecretInApis>
<tokenUrl>https://api.example.net/oauth/token</tokenUrl>
</AuthProvider>
validation:
type: Http
content:
request:
method: POST
url: "https://login.salesforce.com/services/oauth2/token"
headers:
Content-Type: application/x-www-form-urlencoded
body: grant_type=client_credentials&client_id={{ CONSUMER_KEY | url_encode }}&client_secret={{ CONSUMER_SECRET | url_encode }}
response_matcher:
- report_response: true
- type: StatusMatch
status: [200]
- type: StatusMatch
status: [400, 401, 403]
negative: true
- type: JsonValid
- type: WordMatch
words: ["access_token", "token_type"]
match_all_words: true

View file

@ -1,10 +1,11 @@
use anyhow::{Context, Result};
use jira_query::{Auth, JiraInstance, Pagination};
use gouqi::{r#async::Jira, Credentials, SearchOptions};
use reqwest::Client;
use std::path::PathBuf;
use url::Url;
// Re-export the Issue type from jira_query so callers don't depend on the crate.
pub use jira_query::Issue as JiraIssue;
// Re-export the Issue type from gouqi so callers don't depend on the crate.
pub use gouqi::Issue as JiraIssue;
pub async fn fetch_issues(
jira_url: Url,
jql: &str,
@ -19,20 +20,19 @@ pub async fn fetch_issues(
.build()
.context("Failed to build HTTP client")?;
let mut jira = JiraInstance::at(base.to_string())? // no trailing slash here
.with_client(client)
.paginate(Pagination::MaxResults(max_results as u32));
let credentials = match std::env::var("KF_JIRA_TOKEN") {
Ok(token) => Credentials::Bearer(token),
Err(_) => Credentials::Anonymous,
};
if let Ok(token) = std::env::var("KF_JIRA_TOKEN") {
jira = jira.authenticate(Auth::ApiKey(token));
}
let jira = Jira::from_client(base.to_string(), credentials, client)?;
let issues = jira.search(jql).await?;
Ok(issues)
let search_options = SearchOptions::builder().max_results(max_results as u64).build();
let results = jira.search().list(jql, &search_options).await?;
Ok(results.issues)
}
use std::path::PathBuf;
pub async fn download_issues_to_dir(
jira_url: Url,
jql: &str,

View file

@ -5,27 +5,27 @@
// * Fallback - system allocator (`system-alloc` feature)
// ────────────────────────────────────────────────────────────
// --- jemalloc (opt-in) ---
#[cfg(feature = "use-jemalloc")]
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
// // --- jemalloc (opt-in) ---
// #[cfg(feature = "use-jemalloc")]
// #[global_allocator]
// static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
// --- mimalloc (default) ---
#[cfg(all(not(feature = "use-jemalloc"), not(feature = "system-alloc")))]
#[global_allocator]
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
// --- system allocator (explicit opt-out) ---
#[cfg(feature = "system-alloc")]
use std::alloc::System;
#[cfg(feature = "system-alloc")]
#[global_allocator]
static GLOBAL: System = System;
// // --- mimalloc (default) ---
// #[cfg(all(not(feature = "use-jemalloc"), not(feature = "system-alloc")))]
// #[global_allocator]
// static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
// // --- system allocator (explicit opt-out) ---
// #[cfg(feature = "system-alloc")]
// use std::alloc::System;
// #[cfg(feature = "system-alloc")]
// #[global_allocator]
// static GLOBAL: System = System;
use std::alloc::System;
#[global_allocator]
static GLOBAL: System = System;
use std::{
io::{IsTerminal, Read, Write},
sync::{Arc, Mutex},