Skip to content

Commit 087bb51

Browse files
author
Colin
committed
Rename Jira connector module to Atlassian
1 parent 6936797 commit 087bb51

9 files changed

Lines changed: 118 additions & 50 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ Sift records the matching rule, exact matched value and surrounding line, not a
9292
- `Stratus.Sift.Contracts` defines versioned scan requests, targets, progress, observations and summaries.
9393
- `Stratus.Sift.Core` contains the scanner domain, validators, content extraction, matching engine, and bundled rule catalogue.
9494
- `Stratus.Sift.FileSystem` enumerates files, folders, access controls, and exposure.
95-
- `Stratus.Sift.Connectors` contains the Microsoft 365, Slack, Slack export, Jira, and Confluence source modules.
95+
- `Stratus.Sift.Connectors` contains the Microsoft 365, Slack, Slack export, and Atlassian Cloud source modules. The Atlassian module scans both Jira and Confluence.
9696
- `Stratus.Sift.Cli` provides local, domain, network, Microsoft 365, Slack, Slack export, Atlassian, and saved-result analysis commands.
9797
- `tests` covers command parsing, SMB discovery, connectors, rule matching, evidence output, and resumable output.
9898
- `eng` contains release and public-boundary verification scripts.

src/Stratus.Sift.Cli/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ internal static IHost CreateHost()
9090
builder.Services.AddTransient<IConnector, Stratus.Sift.Connectors.SharePoint.SharePointConnector>();
9191
builder.Services.AddTransient<IConnector, Stratus.Sift.Connectors.Slack.SlackConnector>();
9292
builder.Services.AddTransient<IConnector, Stratus.Sift.Connectors.Slack.SlackExportConnector>();
93-
builder.Services.AddTransient<IConnector, Stratus.Sift.Connectors.Jira.JiraConnector>();
93+
builder.Services.AddTransient<IConnector, Stratus.Sift.Connectors.Atlassian.AtlassianConnector>();
9494

9595
return builder.Build();
9696
}

src/Stratus.Sift.Connectors/Jira/JiraApiClient.cs renamed to src/Stratus.Sift.Connectors/Atlassian/AtlassianApiClient.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
using System.Text.Json.Nodes;
44
using Microsoft.Extensions.Logging;
55

6-
namespace Stratus.Sift.Connectors.Jira;
6+
namespace Stratus.Sift.Connectors.Atlassian;
77

8-
internal sealed class JiraApiClient
8+
internal sealed class AtlassianApiClient
99
{
1010
internal const int MaximumJsonDepth = 256;
1111

1212
private readonly ILogger? _logger;
1313

14-
internal JiraApiClient(HttpClient httpClient, Uri baseUri, ILogger? logger = null)
14+
internal AtlassianApiClient(HttpClient httpClient, Uri baseUri, ILogger? logger = null)
1515
{
1616
HttpClient = httpClient;
1717
BaseUri = baseUri;

src/Stratus.Sift.Connectors/Jira/JiraConnector.cs renamed to src/Stratus.Sift.Connectors/Atlassian/AtlassianConnector.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,26 @@
55
using Stratus.Sift.Connectors.Interfaces;
66
using Stratus.Sift.Core;
77

8-
namespace Stratus.Sift.Connectors.Jira;
8+
namespace Stratus.Sift.Connectors.Atlassian;
99

10-
public sealed class JiraConnector : IConnector
10+
public sealed class AtlassianConnector : IConnector
1111
{
1212
private readonly HttpClient _httpClient;
13-
private readonly ILogger<JiraConnector>? _logger;
14-
private JiraApiClient? _jiraApi;
15-
private JiraApiClient? _confluenceApi;
13+
private readonly ILogger? _logger;
14+
private AtlassianApiClient? _jiraApi;
15+
private AtlassianApiClient? _confluenceApi;
1616
private Uri? _siteUri;
1717
private HashSet<string>? _projectFilter;
1818
private HashSet<string>? _spaceFilter;
1919
private string? _additionalJql;
2020
private IReadOnlyDictionary<string, string> _customFields = new Dictionary<string, string>();
2121

22-
public JiraConnector(HttpClient httpClient, ILogger<JiraConnector>? logger = null)
22+
public AtlassianConnector(HttpClient httpClient, ILogger<AtlassianConnector>? logger = null)
23+
: this(httpClient, (ILogger?)logger)
24+
{
25+
}
26+
27+
internal AtlassianConnector(HttpClient httpClient, ILogger? logger)
2328
{
2429
_httpClient = httpClient;
2530
_logger = logger;
@@ -78,8 +83,8 @@ public async Task InitializeAsync(Dictionary<string, string> configuration, Canc
7883
confluenceApiBaseUri = new Uri($"https://api.atlassian.com/ex/confluence/{Uri.EscapeDataString(cloudId)}/");
7984
}
8085

81-
_jiraApi = new JiraApiClient(_httpClient, jiraApiBaseUri, _logger);
82-
_confluenceApi = new JiraApiClient(_httpClient, confluenceApiBaseUri, _logger);
86+
_jiraApi = new AtlassianApiClient(_httpClient, jiraApiBaseUri, _logger);
87+
_confluenceApi = new AtlassianApiClient(_httpClient, confluenceApiBaseUri, _logger);
8388
try
8489
{
8590
using var _ = await _jiraApi.GetJsonAsync("rest/api/3/myself", cancellationToken);
@@ -202,7 +207,7 @@ private async Task AddConfluenceDrivesAsync(List<IRemoteDrive> drives, Cancellat
202207

203208
private async Task<string> DiscoverCloudIdAsync(Uri siteUri, CancellationToken cancellationToken)
204209
{
205-
var discoveryApi = new JiraApiClient(_httpClient, new Uri("https://api.atlassian.com/"), _logger);
210+
var discoveryApi = new AtlassianApiClient(_httpClient, new Uri("https://api.atlassian.com/"), _logger);
206211
using var document = await discoveryApi.GetJsonAsync("oauth/token/accessible-resources", cancellationToken);
207212
foreach (var resource in document.RootElement.EnumerateArray())
208213
{

src/Stratus.Sift.Connectors/Jira/ConfluenceDrive.cs renamed to src/Stratus.Sift.Connectors/Atlassian/ConfluenceDrive.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
using Stratus.Sift.Connectors.Services;
55
using Stratus.Sift.Core.Enums;
66

7-
namespace Stratus.Sift.Connectors.Jira;
7+
namespace Stratus.Sift.Connectors.Atlassian;
88

99
internal sealed class ConfluenceDrive : IRemoteDrive
1010
{
1111
private const string NewestFirstSort = "-modified-date";
1212

13-
private readonly JiraApiClient _api;
13+
private readonly AtlassianApiClient _api;
1414
private readonly Uri _siteUri;
1515
private readonly string _spaceKey;
1616

17-
internal ConfluenceDrive(JiraApiClient api, Uri siteUri, string spaceId, string spaceKey, string spaceName)
17+
internal ConfluenceDrive(AtlassianApiClient api, Uri siteUri, string spaceId, string spaceKey, string spaceName)
1818
{
1919
_api = api;
2020
_siteUri = siteUri;
@@ -69,7 +69,7 @@ public async Task<string> ProcessChangesAsync(
6969
using var document = await _api.GetJsonAsync(path, cancellationToken);
7070
foreach (var content in document.RootElement.GetProperty("results").EnumerateArray())
7171
{
72-
var contentId = JiraConnector.GetScalarString(content, "id") ?? string.Empty;
72+
var contentId = AtlassianConnector.GetScalarString(content, "id") ?? string.Empty;
7373
if (string.IsNullOrWhiteSpace(contentId)) continue;
7474
var updated = GetNestedString(content, "version", "createdAt");
7575
newest = MaxTimestamp(newest, updated);
@@ -96,15 +96,15 @@ private async Task EmitContentAsync(
9696
string contentType,
9797
Func<IRemoteFile, Task> onChange)
9898
{
99-
var id = JiraConnector.GetScalarString(content, "id")!;
100-
var title = JiraConnector.GetScalarString(content, "title") ?? id;
99+
var id = AtlassianConnector.GetScalarString(content, "id")!;
100+
var title = AtlassianConnector.GetScalarString(content, "title") ?? id;
101101
var builder = new StringBuilder();
102102
Append(builder, "Space", _spaceKey);
103103
Append(builder, "Content type", contentType);
104104
Append(builder, "Title", title);
105105
Append(builder, "Content ID", id);
106-
Append(builder, "Author", JiraConnector.GetScalarString(content, "authorId"));
107-
Append(builder, "Created", JiraConnector.GetScalarString(content, "createdAt"));
106+
Append(builder, "Author", AtlassianConnector.GetScalarString(content, "authorId"));
107+
Append(builder, "Created", AtlassianConnector.GetScalarString(content, "createdAt"));
108108
Append(builder, "Updated", GetNestedString(content, "version", "createdAt"));
109109
var body = GetBodyText(content);
110110
if (!string.IsNullOrWhiteSpace(body)) builder.AppendLine().AppendLine(body);
@@ -152,7 +152,7 @@ await onChange(new SimpleRemoteFile(
152152
using var document = await _api.GetJsonAsync(path, cancellationToken);
153153
foreach (var comment in document.RootElement.GetProperty("results").EnumerateArray())
154154
{
155-
var id = JiraConnector.GetScalarString(comment, "id") ?? string.Empty;
155+
var id = AtlassianConnector.GetScalarString(comment, "id") ?? string.Empty;
156156
if (string.IsNullOrWhiteSpace(id) || !visited.Add(id)) continue;
157157
var updated = GetNestedString(comment, "version", "createdAt");
158158
newest = MaxTimestamp(newest, updated);
@@ -201,12 +201,12 @@ await onChange(new SimpleRemoteFile(
201201
using var document = await _api.GetJsonAsync(path, cancellationToken);
202202
foreach (var attachment in document.RootElement.GetProperty("results").EnumerateArray())
203203
{
204-
var id = JiraConnector.GetScalarString(attachment, "id") ?? string.Empty;
204+
var id = AtlassianConnector.GetScalarString(attachment, "id") ?? string.Empty;
205205
if (string.IsNullOrWhiteSpace(id)) continue;
206206
var updated = GetNestedString(attachment, "version", "createdAt")
207-
?? JiraConnector.GetScalarString(attachment, "createdAt");
207+
?? AtlassianConnector.GetScalarString(attachment, "createdAt");
208208
newest = MaxTimestamp(newest, updated);
209-
var name = JiraConnector.GetScalarString(attachment, "title") ?? id;
209+
var name = AtlassianConnector.GetScalarString(attachment, "title") ?? id;
210210
if (string.IsNullOrWhiteSpace(boundary) || IsAfter(updated, boundary))
211211
{
212212
var size = attachment.TryGetProperty("fileSize", out var sizeElement) && sizeElement.TryGetInt64(out var parsedSize)
@@ -221,7 +221,7 @@ await onChange(new SimpleRemoteFile(
221221
$"atlassian://{_siteUri.Host}/confluence/{_spaceKey}/{collection}/{contentId}/attachments/{name}",
222222
GetWebUrl(attachment, $"wiki/spaces/{Uri.EscapeDataString(_spaceKey)}"),
223223
size,
224-
JiraConnector.GetScalarString(attachment, "mediaType"),
224+
AtlassianConnector.GetScalarString(attachment, "mediaType"),
225225
_api.HttpClient,
226226
downloadUri));
227227
}
@@ -282,7 +282,7 @@ internal static string GetBodyText(JsonElement element)
282282
{
283283
using var document = JsonDocument.Parse(
284284
raw,
285-
new JsonDocumentOptions { MaxDepth = JiraApiClient.MaximumJsonDepth });
285+
new JsonDocumentOptions { MaxDepth = AtlassianApiClient.MaximumJsonDepth });
286286
return JiraDrive.GetFlexibleValueText(document.RootElement);
287287
}
288288
catch (JsonException)
@@ -297,7 +297,7 @@ internal static string GetBodyText(JsonElement element)
297297
private string GetWebUrl(JsonElement element, string fallback)
298298
{
299299
var link = element.TryGetProperty("_links", out var links)
300-
? JiraConnector.GetScalarString(links, "webui")
300+
? AtlassianConnector.GetScalarString(links, "webui")
301301
: null;
302302
if (Uri.TryCreate(link, UriKind.Absolute, out var absolute)) return absolute.AbsoluteUri;
303303
var path = string.IsNullOrWhiteSpace(link) ? fallback : link.TrimStart('/');
@@ -307,7 +307,7 @@ private string GetWebUrl(JsonElement element, string fallback)
307307

308308
private static string? GetNestedString(JsonElement element, string property, string nestedProperty)
309309
=> element.TryGetProperty(property, out var nested) && nested.ValueKind == JsonValueKind.Object
310-
? JiraConnector.GetScalarString(nested, nestedProperty)
310+
? AtlassianConnector.GetScalarString(nested, nestedProperty)
311311
: null;
312312

313313
private static string? ParseDelta(string? token)

src/Stratus.Sift.Connectors/Jira/JiraDrive.cs renamed to src/Stratus.Sift.Connectors/Atlassian/JiraDrive.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
using Stratus.Sift.Connectors.Services;
66
using Stratus.Sift.Core.Enums;
77

8-
namespace Stratus.Sift.Connectors.Jira;
8+
namespace Stratus.Sift.Connectors.Atlassian;
99

1010
internal sealed class JiraDrive : IRemoteDrive
1111
{
@@ -19,7 +19,7 @@ internal sealed class JiraDrive : IRemoteDrive
1919
"self", "id", "key", "accountId", "iconUrl", "avatarUrls", "type"
2020
};
2121

22-
private readonly JiraApiClient _api;
22+
private readonly AtlassianApiClient _api;
2323
private readonly Uri _siteUri;
2424
private readonly string _projectKey;
2525
private readonly string? _additionalJql;
@@ -28,7 +28,7 @@ internal sealed class JiraDrive : IRemoteDrive
2828
private readonly string[] _searchFields;
2929

3030
internal JiraDrive(
31-
JiraApiClient api,
31+
AtlassianApiClient api,
3232
Uri siteUri,
3333
string projectId,
3434
string projectKey,
@@ -116,8 +116,8 @@ private async Task EmitIssueAsync(
116116
Func<IRemoteFile, Task> onChange,
117117
CancellationToken cancellationToken)
118118
{
119-
var issueId = JiraConnector.GetScalarString(issue, "id") ?? Guid.NewGuid().ToString("N");
120-
var key = JiraConnector.GetScalarString(issue, "key") ?? issueId;
119+
var issueId = AtlassianConnector.GetScalarString(issue, "id") ?? Guid.NewGuid().ToString("N");
120+
var key = AtlassianConnector.GetScalarString(issue, "key") ?? issueId;
121121
var fields = issue.GetProperty("fields");
122122
var issueUrl = new Uri(_siteUri, $"browse/{Uri.EscapeDataString(key)}").AbsoluteUri;
123123
var builder = new StringBuilder();
@@ -156,13 +156,13 @@ await onChange(new SimpleRemoteFile(
156156

157157
foreach (var attachment in attachments.EnumerateArray())
158158
{
159-
var id = JiraConnector.GetScalarString(attachment, "id");
159+
var id = AtlassianConnector.GetScalarString(attachment, "id");
160160
if (string.IsNullOrWhiteSpace(id))
161161
{
162162
continue;
163163
}
164164

165-
var name = JiraConnector.GetScalarString(attachment, "filename") ?? id;
165+
var name = AtlassianConnector.GetScalarString(attachment, "filename") ?? id;
166166
var downloadUri = new Uri(_api.BaseUri, $"rest/api/3/attachment/content/{Uri.EscapeDataString(id)}");
167167
var size = attachment.TryGetProperty("size", out var sizeElement) && sizeElement.TryGetInt64(out var parsedSize)
168168
? (long?)parsedSize
@@ -173,7 +173,7 @@ await onChange(new SimpleRemoteFile(
173173
$"atlassian://{_siteUri.Host}/jira/{_projectKey}/{key}/attachments/{name}",
174174
issueUrl,
175175
size,
176-
JiraConnector.GetScalarString(attachment, "mimeType"),
176+
AtlassianConnector.GetScalarString(attachment, "mimeType"),
177177
_api.HttpClient,
178178
downloadUri));
179179
}
@@ -240,8 +240,8 @@ private string BuildJql(string? updatedTimestamp)
240240
{
241241
using var document = JsonDocument.Parse(deltaToken);
242242
var root = document.RootElement;
243-
var filter = JiraConnector.GetScalarString(root, "filter");
244-
var updated = JiraConnector.GetScalarString(root, "updated");
243+
var filter = AtlassianConnector.GetScalarString(root, "filter");
244+
var updated = AtlassianConnector.GetScalarString(root, "updated");
245245
return string.Equals(filter, _filterHash, StringComparison.Ordinal) && DateTimeOffset.TryParse(updated, out _)
246246
? updated
247247
: null;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Microsoft.Extensions.Logging;
2+
using Stratus.Sift.Connectors.Interfaces;
3+
4+
namespace Stratus.Sift.Connectors.Jira;
5+
6+
/// <summary>
7+
/// Compatibility name for the connector that scans both Jira and Confluence.
8+
/// </summary>
9+
[Obsolete("Use Stratus.Sift.Connectors.Atlassian.AtlassianConnector instead.")]
10+
public sealed class JiraConnector : IConnector
11+
{
12+
private readonly Atlassian.AtlassianConnector _inner;
13+
14+
public JiraConnector(HttpClient httpClient, ILogger<JiraConnector>? logger = null)
15+
{
16+
_inner = new Atlassian.AtlassianConnector(httpClient, logger);
17+
}
18+
19+
public string ProviderName => _inner.ProviderName;
20+
21+
public Task InitializeAsync(
22+
Dictionary<string, string> configuration,
23+
CancellationToken cancellationToken = default)
24+
=> _inner.InitializeAsync(configuration, cancellationToken);
25+
26+
public Task<IEnumerable<IRemoteDrive>> GetDrivesAsync(CancellationToken cancellationToken = default)
27+
=> _inner.GetDrivesAsync(cancellationToken);
28+
}

0 commit comments

Comments
 (0)