Verbesserung Auth, Webhook-Handling & Codacy-Integration

- BasicAuthenticationAttribute: AllowAnonymous-Handling ergänzt, Fehlerbehandlung für ungültige Header verbessert, WWW-Authenticate-Header korrigiert, Credential-Handling robuster gestaltet.
- WiseController: Webhook akzeptiert jetzt JSON und Text, asynchrone Verarbeitung, robustere Deserialisierung, <AllowAnonymous> auf Klassenebene.
- WiseWebhookExampleProcessor: OpenAPI/Swagger-Doku erweitert (application/json & text/plain, Beispiele, flexiblere Schemas).
- SwaggerConfig: Unsichtbares Zeichen entfernt.
- .gitignore: Codacy-spezifische Anweisungen ausgeschlossen.
- codacy.instructions.md: Neue Datei mit KI-Verhaltensregeln für Codacy-Analysen hinzugefügt.
This commit is contained in:
2025-12-10 15:12:02 +01:00
parent a6cbf6ab56
commit 5c8daaabc0
6 changed files with 157 additions and 53 deletions

View File

@@ -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)
---

4
VERAG_REST_SERVER/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
#Ignore vscode AI rules
.github\instructions\codacy.instructions.md

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
<RoutePrefix("wise")>
<AllowAnonymous>
Public Class WiseController
Inherits System.Web.Http.ApiController
<HttpPost>
<Route("webhook")>
<AllowAnonymous>
<ResponseType(GetType(Void))>
Public Function Webhook(<FromBody> 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()