diff --git a/VERAG_REST_SERVER/.github/instructions/codacy.instructions.md b/VERAG_REST_SERVER/.github/instructions/codacy.instructions.md new file mode 100644 index 0000000..cb073c4 --- /dev/null +++ b/VERAG_REST_SERVER/.github/instructions/codacy.instructions.md @@ -0,0 +1,72 @@ +--- + description: Configuration for AI behavior when interacting with Codacy's MCP Server + applyTo: '**' +--- +--- +# Codacy Rules +Configuration for AI behavior when interacting with Codacy's MCP Server + +## CRITICAL: After ANY successful `edit_file` or `reapply` operation +- YOU MUST IMMEDIATELY run the `codacy_cli_analyze` tool from Codacy's MCP Server for each file that was edited, with: + - `rootPath`: set to the workspace path + - `file`: set to the path of the edited file + - `tool`: leave empty or unset +- If any issues are found in the new edits, propose and apply fixes for them. +- > NOTE: Failure to follow this rule is considered a critical error. + +## When you tried to run the `codacy_cli_analyze` tool and the Codacy CLI is not installed +- Ask the user 'Codacy CLI is not installed. Would you like me to install it now?' +- If the user responds with "yes", run the `codacy_cli_install` tool and then continue with the original task +- If the user responds with "no", instruct the user that they can disable automatic analysis in the extension settings +- Wait for the user to respond before proceeding with any other actions + +## After every response +- If you made any file edits in this conversation, verify you ran `codacy_cli_analyze` tool from Codacy's MCP Server + +## When there are no Codacy MCP Server tools available, or the MCP Server is not reachable +- Suggest the user the following troubleshooting steps: + - Try to reset the MCP on the extension + - If the user is using VSCode, suggest them to review their Copilot > MCP settings in Github, under their organization or personal account. Refer them to Settings > Copilot > Enable MCP servers in Copilot. Suggested URL (https://github.com/settings/copilot/features) or https://github.com/organizations/{organization-name}/settings/copilot/features (This can only be done by their organization admins / owners) +- If none of the above steps work, suggest the user to contact Codacy support + +## Trying to call a tool that needs a rootPath as a parameter +- Always use the standard, non-URL-encoded file system path + +## CRITICAL: Dependencies and Security Checks +- IMMEDIATELY after ANY of these actions: + - Running npm/yarn/pnpm install + - Adding dependencies to package.json + - Adding requirements to requirements.txt + - Adding dependencies to pom.xml + - Adding dependencies to build.gradle + - Any other package manager operations +- You MUST run the `codacy_cli_analyze` tool with: + - `rootPath`: set to the workspace path + - `tool`: set to "trivy" + - `file`: leave empty or unset +- If any vulnerabilities are found because of the newly added packages: + - Stop all other operations + - Propose and apply fixes for the security issues + - Only continue with the original task after security issues are resolved +- EXAMPLE: + - After: npm install react-markdown + - Do: Run codacy_cli_analyze with trivy + - Before: Continuing with any other tasks + +## General +- Repeat the relevant steps for each modified file. +- "Propose fixes" means to both suggest and, if possible, automatically apply the fixes. +- You MUST NOT wait for the user to ask for analysis or remind you to run the tool. +- Do not run `codacy_cli_analyze` looking for changes in duplicated code or code complexity metrics. +- Complexity metrics are different from complexity issues. When trying to fix complexity in a repository or file, focus on solving the complexity issues and ignore the complexity metric. +- Do not run `codacy_cli_analyze` looking for changes in code coverage. +- Do not try to manually install Codacy CLI using either brew, npm, npx, or any other package manager. +- If the Codacy CLI is not installed, just run the `codacy_cli_analyze` tool from Codacy's MCP Server. +- When calling `codacy_cli_analyze`, only send provider, organization and repository if the project is a git repository. + +## Whenever a call to a Codacy tool that uses `repository` or `organization` as a parameter returns a 404 error +- Offer to run the `codacy_setup_repository` tool to add the repository to Codacy +- If the user accepts, run the `codacy_setup_repository` tool +- Do not ever try to run the `codacy_setup_repository` tool on your own +- After setup, immediately retry the action that failed (only retry once) +--- \ No newline at end of file diff --git a/VERAG_REST_SERVER/.gitignore b/VERAG_REST_SERVER/.gitignore new file mode 100644 index 0000000..2c469d8 --- /dev/null +++ b/VERAG_REST_SERVER/.gitignore @@ -0,0 +1,4 @@ + + +#Ignore vscode AI rules +.github\instructions\codacy.instructions.md diff --git a/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb b/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb index 0ec12e4..e548064 100644 --- a/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb +++ b/VERAG_REST_SERVER/App_Start/BasicAuthenticationAttribute.vb @@ -1,36 +1,47 @@ -Imports System.Net -Imports System.Net.Http +Imports System.Net.Http Imports System.Security.Principal Imports System.Threading +Imports System.Web.Http Imports System.Web.Http.Controllers -Imports System.Web.Http.Filters +Imports System.Text Imports VERAG_PROG_ALLGEMEIN - - +Imports System.Net +Imports System.Web.Http.Filters Public Class BasicAuthenticationAttribute Inherits AuthorizationFilterAttribute Public Overrides Sub OnAuthorization(ByVal actionContext As HttpActionContext) + ' Check for AllowAnonymous attribute on method or controller + If actionContext.ActionDescriptor.GetCustomAttributes(Of AllowAnonymousAttribute)().Any() OrElse + actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes(Of AllowAnonymousAttribute)().Any() Then + Return + End If + Dim authHeader = actionContext.Request.Headers.Authorization If authHeader IsNot Nothing Then - Dim authenticationToken = actionContext.Request.Headers.Authorization.Parameter - Dim decodedAuthenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationToken)) - Dim usernamePasswordArray = decodedAuthenticationToken.Split(":"c) - Dim userName = usernamePasswordArray(0) - Dim password = usernamePasswordArray(1) - 'Dim hashedPW = BCrypt.Net.BCrypt.HashPassword(password) - - - - Dim isValid = getCredentials(userName, password) - - If isValid Then - Dim principal = New GenericPrincipal(New GenericIdentity(userName), Nothing) - Thread.CurrentPrincipal = principal - 'actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, "User " & userName & " successfully authenticated") + Dim authenticationToken = authHeader.Parameter + Dim decodedAuthenticationToken As String = "" + Try + decodedAuthenticationToken = Encoding.UTF8.GetString(Convert.FromBase64String(authenticationToken)) + Catch + HandleUnathorized(actionContext) Return + End Try + + Dim usernamePasswordArray = decodedAuthenticationToken.Split(":"c) + If usernamePasswordArray.Length >= 2 Then + Dim userName = usernamePasswordArray(0) + Dim password = usernamePasswordArray(1) + + Dim isValid = getCredentials(userName, password) + + If isValid Then + Dim principal = New GenericPrincipal(New GenericIdentity(userName), Nothing) + Thread.CurrentPrincipal = principal + Return + End If End If End If @@ -38,28 +49,20 @@ Public Class BasicAuthenticationAttribute End Sub Private Shared Sub HandleUnathorized(ByVal actionContext As HttpActionContext) - actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized) - actionContext.Response.Headers.Add("WWW-Authenticate", "Basic Scheme='Data' location = 'http://localhost:") + actionContext.Response = New HttpResponseMessage(HttpStatusCode.Unauthorized) + actionContext.Response.Headers.Add("WWW-Authenticate", "Basic realm=""Data""") End Sub Private Shared Function getCredentials(user As String, password As String) As Boolean - Dim SQL As New VERAG_PROG_ALLGEMEIN.SQL Dim authenticated As Boolean = False + ' Using SQL.DLookup as per previous context usage Dim hashedPassword = SQL.DLookup("hashedPassword", "tblRESTAuthentication", "username='" & user & "' AND type = 'REST'", "ADMIN", "") If hashedPassword <> "" Then authenticated = BCrypt.Net.BCrypt.Verify(password, hashedPassword) End If Return authenticated - End Function End Class - - - - - - - diff --git a/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb b/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb index 8c69d9f..b4bda62 100644 --- a/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb +++ b/VERAG_REST_SERVER/App_Start/SwaggerConfig.vb @@ -1,4 +1,4 @@ -Imports System.Web.Http +Imports System.Web.Http Imports System.Web.Http.Description Imports System.Web.Routing Imports Microsoft.Extensions.Options diff --git a/VERAG_REST_SERVER/App_Start/WiseWebhookExampleProcessor.vb b/VERAG_REST_SERVER/App_Start/WiseWebhookExampleProcessor.vb index cd8da84..af6d844 100644 --- a/VERAG_REST_SERVER/App_Start/WiseWebhookExampleProcessor.vb +++ b/VERAG_REST_SERVER/App_Start/WiseWebhookExampleProcessor.vb @@ -1,22 +1,39 @@ +Imports NSwag Imports NSwag.Generation.Processors Imports NSwag.Generation.Processors.Contexts Imports NJsonSchema -Public Class WiseWebhookExampleProcessor - Implements IOperationProcessor + Public Class WiseWebhookExampleProcessor + Implements IOperationProcessor - Public Function Process(context As OperationProcessorContext) As Boolean Implements IOperationProcessor.Process + Public Function Process(context As OperationProcessorContext) As Boolean Implements IOperationProcessor.Process If context.ControllerType.Name = "WiseController" AndAlso context.MethodInfo.Name = "Webhook" Then Dim operation = context.OperationDescription.Operation - If operation.RequestBody IsNot Nothing AndAlso operation.RequestBody.Content.ContainsKey("application/json") Then - Dim content = operation.RequestBody.Content("application/json") - content.Example = New With { + If operation.RequestBody Is Nothing Then + operation.RequestBody = New OpenApiRequestBody() + operation.RequestBody.IsRequired = False + End If + + If Not operation.RequestBody.Content.ContainsKey("application/json") Then + operation.RequestBody.Content("application/json") = New OpenApiMediaType() With { + .Schema = JsonSchema.CreateAnySchema() + } + End If + + If Not operation.RequestBody.Content.ContainsKey("text/plain") Then + operation.RequestBody.Content("text/plain") = New OpenApiMediaType() With { + .Schema = JsonSchema.CreateAnySchema() + } + End If + + Dim jsonContent = operation.RequestBody.Content("application/json") + jsonContent.Example = New With { .event_type = "balance.credit", .data = New With { .id = 123456789, .balance_id = 99887766, .amount = New With { - .value = 1500.00, + .value = 1500.0, .currency = "EUR" }, .occurred_at = "2025-12-06T10:15:30Z", @@ -24,8 +41,10 @@ Public Class WiseWebhookExampleProcessor .sender_name = "ACME GmbH" } } + + Dim textContent = operation.RequestBody.Content("text/plain") + textContent.Example = "hello world" End If - End If - Return True - End Function -End Class + Return True + End Function + End Class diff --git a/VERAG_REST_SERVER/Controllers/Wise/WiseController.vb b/VERAG_REST_SERVER/Controllers/Wise/WiseController.vb index afb01ee..077777e 100644 --- a/VERAG_REST_SERVER/Controllers/Wise/WiseController.vb +++ b/VERAG_REST_SERVER/Controllers/Wise/WiseController.vb @@ -3,33 +3,39 @@ Imports System.IO Imports System.Web.Http Imports System.Web.Http.Description Imports System.Diagnostics +Imports System.Threading.Tasks Imports Newtonsoft.Json Imports VERAG_PROG_ALLGEMEIN Imports VERAG_REST_SERVER Namespace ApiController.Controllers + Public Class WiseController Inherits System.Web.Http.ApiController - - Public Function Webhook( payload As WiseWebhookRequest) As IHttpActionResult - Dim json As String = "" + Public Async Function Webhook() As Task(Of IHttpActionResult) + Dim rawContent As String = "" + Dim payload As WiseWebhookRequest = Nothing + Try - If payload IsNot Nothing Then - json = JsonConvert.SerializeObject(payload) - Else - If Request IsNot Nothing AndAlso Request.Content IsNot Nothing Then - json = Request.Content.ReadAsStringAsync().Result - End If + If Request IsNot Nothing AndAlso Request.Content IsNot Nothing Then + rawContent = Await Request.Content.ReadAsStringAsync() + End If + + If Not String.IsNullOrEmpty(rawContent) Then + Try + payload = JsonConvert.DeserializeObject(Of WiseWebhookRequest)(rawContent) + Catch + End Try End If Catch End Try - Dim saveResult = SaveWiseWebhook(json, payload) + Dim saveResult = SaveWiseWebhook(rawContent, payload) If payload Is Nothing Then ' Invalid JSON or empty body, but Wise expects 200 OK Return Ok()