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,65 +1,68 @@
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 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 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")
Return
End If
End If
End If
HandleUnathorized(actionContext)
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,3 +1,4 @@
Imports NSwag
Imports NSwag.Generation.Processors
Imports NSwag.Generation.Processors.Contexts
Imports NJsonSchema
@@ -8,15 +9,31 @@ Public Class WiseWebhookExampleProcessor
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,7 +41,9 @@ Public Class WiseWebhookExampleProcessor
.sender_name = "ACME GmbH"
}
}
End If
Dim textContent = operation.RequestBody.Content("text/plain")
textContent.Example = "hello world"
End If
Return True
End Function

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