Skip to content

CM-42036 - Add AI remediations for IaC and SAST #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/lint_build_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ jobs:
with:
vs-version: '[17.0, )'

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.x # dotnet 9 breaks "dotnet format" command: https://github.com/dotnet/sdk/issues/43017

- name: Format check
run: dotnet format --verify-no-changes --verbosity diagnostic

Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

## [Unreleased]

## [1.7.0] - 2024-12-11

- Add AI remediations for IaC and SAST

## [1.6.1] - 2024-10-31

- Code refactoring
Expand Down Expand Up @@ -69,6 +73,8 @@

The first public release of the extension.

[1.7.0]: https://github.com/cycodehq/visual-studio-extension/releases/tag/v1.7.0

[1.6.1]: https://github.com/cycodehq/visual-studio-extension/releases/tag/v1.6.1

[1.6.0]: https://github.com/cycodehq/visual-studio-extension/releases/tag/v1.6.0
Expand Down Expand Up @@ -97,4 +103,4 @@ The first public release of the extension.

[1.0.0]: https://github.com/cycodehq/visual-studio-extension/releases/tag/v1.0.0

[Unreleased]: https://github.com/cycodehq/visual-studio-extension/compare/v1.6.1...HEAD
[Unreleased]: https://github.com/cycodehq/visual-studio-extension/compare/v1.7.0...HEAD
6 changes: 6 additions & 0 deletions global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"sdk": {
"version": "8.0.404",
"rollForward": "latestFeature"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="Cycode.7e1a0714-9b3b-4e0e-9c0a-d23fb20ab86e" Version="1.6.1" Language="en-US" Publisher="cycodehq" />
<Identity Id="Cycode.7e1a0714-9b3b-4e0e-9c0a-d23fb20ab86e" Version="1.7.0" Language="en-US" Publisher="cycodehq" />
<DisplayName>Cycode</DisplayName>
<Description xml:space="preserve">Cycode for Visual Studio IDE</Description>
<MoreInfo>https://github.com/cycodehq/visual-studio-extension</MoreInfo>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
<Metadata>
<Identity Id="Cycode.f2c5020e-67a2-46f8-a888-609412fd59db" Version="1.6.1" Language="en-US" Publisher="cycodehq" />
<Identity Id="Cycode.f2c5020e-67a2-46f8-a888-609412fd59db" Version="1.7.0" Language="en-US" Publisher="cycodehq" />
<DisplayName>Cycode</DisplayName>
<Description xml:space="preserve">Cycode for Visual Studio IDE</Description>
<MoreInfo>https://github.com/cycodehq/visual-studio-extension</MoreInfo>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
#nullable enable

using Newtonsoft.Json;

namespace Cycode.VisualStudio.Extension.Shared.Cli.DTO;

public class AuthCheckResult {
public class AiRemediationResult {
[JsonProperty(Required = Required.Always)]
public bool Result { get; set; }

[JsonProperty(Required = Required.Always)]
public string? Message { get; set; }

Check warning on line 10 in src/extension/Cycode.VisualStudio.Extension.Shared/Cli/DTO/AiRemediationResult.cs

View workflow job for this annotation

GitHub Actions / lint_build_publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonProperty(Required = Required.AllowNull)]
public AuthCheckResultData? Data { get; set; }
public AiRemediationResultData? Data { get; set; }

Check warning on line 13 in src/extension/Cycode.VisualStudio.Extension.Shared/Cli/DTO/AiRemediationResult.cs

View workflow job for this annotation

GitHub Actions / lint_build_publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
}

public class AuthCheckResultData {
public class AiRemediationResultData {
[JsonProperty(Required = Required.Always)]
public string? UserId { get; set; }
public string Remediation { get; set; }

[JsonProperty(Required = Required.Always)]
public string? TenantId { get; set; }
public bool IsFixAvailable { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Cycode.VisualStudio.Extension.Shared.Cli.DTO.ScanResult;

public abstract class DetectionBase {
public string Id { get; set; }
public string Severity { get; set; }
public abstract DetectionDetailsBase GetDetectionDetails();
public abstract string GetFormattedMessage();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Newtonsoft.Json;

namespace Cycode.VisualStudio.Extension.Shared.Cli.DTO;

public class StatusResult {
[JsonProperty(Required = Required.Always)]
public string Program { get; set; }

[JsonProperty(Required = Required.Always)]
public string Version { get; set; }

[JsonProperty(Required = Required.Always)]
public bool IsAuthenticated { get; set; }

[JsonProperty(Required = Required.AllowNull)]
public string? UserId { get; set; }

Check warning on line 16 in src/extension/Cycode.VisualStudio.Extension.Shared/Cli/DTO/StatusResult.cs

View workflow job for this annotation

GitHub Actions / lint_build_publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonProperty(Required = Required.AllowNull)]
public string? TenantId { get; set; }

Check warning on line 19 in src/extension/Cycode.VisualStudio.Extension.Shared/Cli/DTO/StatusResult.cs

View workflow job for this annotation

GitHub Actions / lint_build_publish

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

[JsonProperty(Required = Required.Always)]
public SupportedModulesStatus SupportedModules { get; set; }
}

public class SupportedModulesStatus {
// TODO(MarshalX): respect enabled/disabled scanning modules
[JsonProperty(Required = Required.Always)]
public bool SecretScanning { get; set; }
[JsonProperty(Required = Required.Always)]
public bool ScaScanning { get; set; }
[JsonProperty(Required = Required.Always)]
public bool IacScanning { get; set; }
[JsonProperty(Required = Required.Always)]
public bool SastScanning { get; set; }
[JsonProperty(Required = Required.Always)]
public bool AiLargeLanguageModel { get; set; }
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
xmlns:toolWindows="clr-namespace:Cycode.VisualStudio.Extension.Shared.Components.ToolWindows">

<StackPanel Margin="20" Orientation="Vertical" HorizontalAlignment="Center">
<TextBlock Margin="0,0,0,10" TextWrapping="Wrap">
<Run>Cycode extension requires pre-installed authentication to work.</Run>
</TextBlock>

<Button Margin="0,0,0,10" Content="Authenticate" Click="AuthClickAsync"
Width="150" Height="30" Name="AuthBtn" HorizontalAlignment="Center" />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
Expand Down Expand Up @@ -54,6 +51,18 @@
x:Name="CycodeGuidelines"
Grid.Row="8" Grid.Column="0" Grid.ColumnSpan="2"
Title="Cycode Guidelines" />

<common:MarkdownBlock
x:Name="AiRemediation"
Grid.Row="9" Grid.Column="0" Grid.ColumnSpan="2"
Title="AI Remediation" />
<common:Hr Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="2" />
<Button Grid.Row="11" Grid.Column="1"
Content="Generate AI Remediation"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0 0 10 10"
Click="GenerateAiRemediationButton_OnClickAsync" />
</Grid>
</ScrollViewer>
</UserControl>
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
using System.IO;
using System.Windows;
using Cycode.VisualStudio.Extension.Shared.Cli.DTO;
using Cycode.VisualStudio.Extension.Shared.Cli.DTO.ScanResult.Iac;
using Cycode.VisualStudio.Extension.Shared.Helpers;
using Cycode.VisualStudio.Extension.Shared.Icons;
using Cycode.VisualStudio.Extension.Shared.Services;

namespace Cycode.VisualStudio.Extension.Shared.Components.ViolationCards;

public partial class IacViolationCardControl {
private const int _customRemediationGuidelinesRowIndex = 7;
private const int _cycodeRemediationGuidelinesRowIndex = 8;
private const int _aiRemediationRowIndex = 9;
private readonly ICycodeService _cycodeService = ServiceLocator.GetService<ICycodeService>();

private readonly IacDetection _detection;

public IacViolationCardControl(IacDetection detection) {
InitializeComponent();
_detection = detection;

Header.Icon.Source = ExtensionIcons.GetCardSeverityBitmapSource(detection.Severity);
Header.Title.Text = detection.GetFormattedMessage();
Expand All @@ -34,5 +42,17 @@ public IacViolationCardControl(IacDetection detection) {
CycodeGuidelines.Markdown = detection.DetectionDetails.RemediationGuidelines;
GridHelper.ShowRow(Grid, _cycodeRemediationGuidelinesRowIndex);
}

GridHelper.HideRow(Grid, _aiRemediationRowIndex);
}

private async void GenerateAiRemediationButton_OnClickAsync(object sender, RoutedEventArgs e) {
await _cycodeService.GetAiRemediationAsync(_detection.Id, OnSuccess);
return;

void OnSuccess(AiRemediationResultData remediationResult) {
AiRemediation.Markdown = remediationResult.Remediation;
GridHelper.ShowRow(Grid, _aiRemediationRowIndex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@
x:Name="CycodeGuidelines"
Grid.Row="10" Grid.Column="0" Grid.ColumnSpan="2"
Title="Cycode Guidelines" />

<common:MarkdownBlock
x:Name="AiRemediation"
Grid.Row="11" Grid.Column="0" Grid.ColumnSpan="2"
Title="AI Remediation" />
<common:Hr Grid.Row="12" Grid.Column="0" Grid.ColumnSpan="2" />
<Button Grid.Row="13" Grid.Column="1"
Content="Generate AI Remediation"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0 0 10 10"
Click="GenerateAiRemediationButton_OnClickAsync" />
</Grid>
</ScrollViewer>
</UserControl>
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using Cycode.VisualStudio.Extension.Shared.Cli.DTO;
using Cycode.VisualStudio.Extension.Shared.Cli.DTO.ScanResult.Sast;
using Cycode.VisualStudio.Extension.Shared.Helpers;
using Cycode.VisualStudio.Extension.Shared.Icons;
using Cycode.VisualStudio.Extension.Shared.Services;

namespace Cycode.VisualStudio.Extension.Shared.Components.ViolationCards;

public partial class SastViolationCardControl {
private const int _customRemediationGuidelinesRowIndex = 9;
private const int _cycodeRemediationGuidelinesRowIndex = 10;
private const int _aiRemediationRowIndex = 11;
private readonly ICycodeService _cycodeService = ServiceLocator.GetService<ICycodeService>();

private readonly SastDetection _detection;

public SastViolationCardControl(SastDetection detection) {
InitializeComponent();
_detection = detection;

Header.Icon.Source = ExtensionIcons.GetCardSeverityBitmapSource(detection.Severity);
Header.Title.Text = detection.GetFormattedMessage();
Expand Down Expand Up @@ -53,5 +61,17 @@ public SastViolationCardControl(SastDetection detection) {
CycodeGuidelines.Markdown = detection.DetectionDetails.RemediationGuidelines;
GridHelper.ShowRow(Grid, _cycodeRemediationGuidelinesRowIndex);
}

GridHelper.HideRow(Grid, _aiRemediationRowIndex);
}

private async void GenerateAiRemediationButton_OnClickAsync(object sender, RoutedEventArgs e) {
await _cycodeService.GetAiRemediationAsync(_detection.Id, OnSuccess);
return;

void OnSuccess(AiRemediationResultData remediationResult) {
AiRemediation.Markdown = remediationResult.Remediation;
GridHelper.ShowRow(Grid, _aiRemediationRowIndex);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Cycode.VisualStudio.Extension.Shared;

public static class Constants {
public const string AppName = "visual_studio_extension";
public const string RequiredCliVersion = "1.11.0";
public const string RequiredCliVersion = "2.1.0";

public const string CycodeDomain = "cycode.com";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Cli\CliUtilities.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\CliWrapper.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\AuthCheckResult.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\AiRemediationResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\AuthResult.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\CliError.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\CliIgnoreType.cs"/>
Expand All @@ -36,7 +36,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\ScanResult\Secret\SecretDetection.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\ScanResult\Secret\SecretDetectionDetails.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\ScanResult\Secret\SecretScanResult.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\VersionResult.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\DTO\StatusResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Cli\ErrorCode.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\ErrorHandling.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Cli\ExitCode.cs"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public class ExtensionState {
public string CliVer { get; set; } = null;
public string CliHash { get; set; } = null;
public long? CliLastUpdateCheckedAt { get; set; } = null;
public bool IsAiLargeLanguageModelEnabled { get; set; } = false;
}
Loading
Loading