feat: support Matrix42 26.1 sandboxed web api

This commit is contained in:
Meik
2026-06-26 11:44:34 +02:00
parent 690ad4f615
commit 6c6ac272cd
8 changed files with 267 additions and 305 deletions

88
.gitignore vendored
View File

@@ -1,81 +1,13 @@
# --------------------------------------------------------------------------------------------------
# Core Visual Studio / .NET build outputs
# --------------------------------------------------------------------------------------------------
bin/ bin/
obj/ obj/
[Bb]uild/
[Dd]ebug*/
[Rr]elease*/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
_ReSharper.*/
*.user
*.userosscache
*.suo
*.cache
*.pdb
*.mpdb
*.opendb
*.VC.db
*.vscode/
# --------------------------------------------------------------------------------------------------
# Package artefacts (NuGet, npm, etc.)
# --------------------------------------------------------------------------------------------------
/packages/
*.nupkg
*.snupkg
*.nuspec
package-lock.json
packages.config
npm-debug.log*
yarn-error.log
# --------------------------------------------------------------------------------------------------
# TFS / TFVC specific files and folders
# --------------------------------------------------------------------------------------------------
$tf/
*$tf/
*.tf
*.tfs
.tfignore
# --------------------------------------------------------------------------------------------------
# IDE tooling and workspace settings
# --------------------------------------------------------------------------------------------------
.vs/ .vs/
.vscode/ *.user
*.swp packages/
*.sln.docstates F4SDHelper/packages.config
*.VC.VC.opendb F4SDM42WebApi/packages.config
.idea/ F4SDM42WebApi/BasePackage/Assemblies/
.DS_Store F4SDM42WebApi/Root/InstalledPackages/
Thumbs.db F4SDHelper/bin/
F4SDHelper/obj/
# -------------------------------------------------------------------------------------------------- F4SDM42WebApi/bin/
# Test results and profiling data F4SDM42WebApi/obj/
# --------------------------------------------------------------------------------------------------
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*.trx
*.coverage
*.coveragexml
*.opencover.xml
*.dotCover
BenchmarkDotNet.Artifacts/
# --------------------------------------------------------------------------------------------------
# Miscellaneous recommended ignores
# --------------------------------------------------------------------------------------------------
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
*.tmp
*.temp
*.log
*.bak
*.orig
*.scc

View File

@@ -1,63 +1,25 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFramework>net8.0</TargetFramework>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{EB95E1FB-7A9E-4894-BD28-2D0BE2715EBE}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>C4IT.F4SDM</RootNamespace> <RootNamespace>C4IT.F4SDM</RootNamespace>
<AssemblyName>C4ITF4SDM42WebApiHelper</AssemblyName> <AssemblyName>C4ITF4SDM42WebApiHelper</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <Nullable>disable</Nullable>
<FileAlignment>512</FileAlignment> <ImplicitUsings>disable</ImplicitUsings>
<Deterministic>true</Deterministic> <LangVersion>latestmajor</LangVersion>
<TargetFrameworkProfile /> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SccProjectName>SAK</SccProjectName> <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_and_copy|AnyCPU'">
<OutputPath>bin\Release_and_copy\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>..\F4SDM42WebApi\M42Libraries\26.1\Newtonsoft.Json.dll</HintPath>
<Private>false</Private>
</Reference> </Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\..\..\Common Code\Logging\C4IT.Logging.LogManager.cs"> <Compile Include="..\..\..\Common Code\Logging\C4IT.Logging.LogManager.cs">
<Link>Common\C4IT.Logging.LogManager.cs</Link> <Link>Common\C4IT.Logging.LogManager.cs</Link>
</Compile> </Compile>
@@ -67,11 +29,6 @@
<Compile Include="..\SharedAssemblyInfo.cs"> <Compile Include="..\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link> <Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile> </Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
<host xmlns="urn:m42/host.config">
<modules></modules>
<sections></sections>
</host>

View File

@@ -1,139 +1,93 @@
<?xml version="1.0" encoding="utf-8"?> <Project Sdk="Microsoft.NET.Sdk">
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <TargetFramework>net8.0</TargetFramework>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D8CBFFCA-0B43-4ACC-80EA-C944E7420CEE}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>C4IT.F4SDM</RootNamespace> <RootNamespace>C4IT.F4SDM</RootNamespace>
<AssemblyName>C4ITF4SDM42WebApi</AssemblyName> <AssemblyName>C4ITF4SDM42WebApi</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion> <RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
<FileAlignment>512</FileAlignment> <AppendRuntimeIdentifierToOutputPath>true</AppendRuntimeIdentifierToOutputPath>
<Deterministic>true</Deterministic> <Nullable>disable</Nullable>
<TargetFrameworkProfile /> <ImplicitUsings>disable</ImplicitUsings>
<SccProjectName>SAK</SccProjectName> <LangVersion>latestmajor</LangVersion>
<SccLocalPath>SAK</SccLocalPath> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<SccAuxPath>SAK</SccAuxPath> <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<SccProvider>SAK</SccProvider> <M42ExtensionId>d8cbffca-0b43-4acc-80ea-c944e7420cee</M42ExtensionId>
</PropertyGroup> <M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug_and_copy|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug_and_copy\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release_and_copy|AnyCPU'">
<OutputPath>bin\Release_and_copy\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<LangVersion>7.3</LangVersion>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Matrix42.Common, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Matrix42.Common">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.Common.dll</HintPath>
<HintPath>M42Libraries\Matrix42.Common.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Matrix42.Contracts.Common, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Matrix42.Contracts.Common">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.Contracts.Common.dll</HintPath>
<HintPath>M42Libraries\Matrix42.Contracts.Common.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Matrix42.Contracts.Platform, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Matrix42.Contracts.Platform">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.Contracts.Platform.dll</HintPath>
<HintPath>M42Libraries\Matrix42.Contracts.Platform.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Matrix42.Contracts.ServiceManagement, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Matrix42.Contracts.ServiceManagement">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.Contracts.ServiceManagement.dll</HintPath>
<HintPath>M42Libraries\Matrix42.Contracts.ServiceManagement.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Matrix42.Pandora.Contracts, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Matrix42.Hosting.Contracts">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.Hosting.Contracts.dll</HintPath>
<HintPath>M42Libraries\Matrix42.Pandora.Contracts.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Matrix42.Services.Description.Contracts, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Matrix42.Configuration.Global">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.Configuration.Global.dll</HintPath>
<HintPath>M42Libraries\Matrix42.Services.Description.Contracts.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> <Reference Include="Matrix42.Pandora.Contracts">
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath> <HintPath>M42Libraries\26.1\Matrix42.Pandora.Contracts.dll</HintPath>
<Private>false</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="Matrix42.Services.Description.Contracts">
<Reference Include="System.Core" /> <HintPath>M42Libraries\26.1\Matrix42.Services.Description.Contracts.dll</HintPath>
<Reference Include="System.IO.Compression" /> <Private>false</Private>
<Reference Include="System.Web" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>M42Libraries\System.Web.Http.dll</HintPath>
</Reference> </Reference>
<Reference Include="System.Web.OData, Version=5.9.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="Matrix42.WebApi.Contracts">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\Matrix42.WebApi.Contracts.dll</HintPath>
<HintPath>M42Libraries\System.Web.OData.dll</HintPath> <Private>false</Private>
</Reference> </Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="Newtonsoft.Json">
<Reference Include="System.Data.DataSetExtensions" /> <HintPath>M42Libraries\26.1\Newtonsoft.Json.dll</HintPath>
<Reference Include="Microsoft.CSharp" /> <Private>false</Private>
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="update4u.SPS.DataLayer, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>M42Libraries\update4u.SPS.DataLayer.dll</HintPath>
</Reference> </Reference>
<Reference Include="update4u.SPS.Utility, Version=12.0.3.3096, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="System.Net.Http.Formatting">
<SpecificVersion>False</SpecificVersion> <HintPath>M42Libraries\26.1\System.Net.Http.Formatting.dll</HintPath>
<HintPath>M42Libraries\update4u.SPS.Utility.dll</HintPath> <Private>false</Private>
</Reference>
<Reference Include="update4u.SPS.DataLayer">
<HintPath>M42Libraries\26.1\update4u.SPS.DataLayer.dll</HintPath>
<Private>false</Private>
</Reference>
<Reference Include="update4u.SPS.Utility">
<HintPath>M42Libraries\26.1\update4u.SPS.Utility.dll</HintPath>
<Private>false</Private>
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\F4SDHelper\F4SD - Helper.csproj" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
<Compile Include="cM42LogEntry.cs" /> <Compile Include="cM42LogEntry.cs" />
<Compile Include="F4SDHelperService.cs" /> <Compile Include="F4SDHelperService.cs" />
<Compile Include="F4SDM42WebApiController.cs" /> <Compile Include="F4SDM42WebApiController.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\SharedAssemblyInfo.cs">
<Link>Properties\SharedAssemblyInfo.cs</Link>
</Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\F4SDHelper\F4SD - Helper.csproj"> <None Update="C4ITF4SDM42WebApi.dll.host" CopyToOutputDirectory="PreserveNewest" />
<Project>{eb95e1fb-7a9e-4894-bd28-2d0be2715ebe}</Project>
<Name>F4SD - Helper</Name>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="deploy.ps1" />
<None Include="SignSourceFiles.cmd" />
</ItemGroup> </ItemGroup>
<Import Project="..\M42F4SDUUXWorkspace\M42F4SDUUXWorkspace.projitems" Label="Shared" /> <Import Project="..\M42F4SDUUXWorkspace\M42F4SDUUXWorkspace.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="M42SandboxedExtension.targets" Condition="Exists('M42SandboxedExtension.targets')" />
<PropertyGroup>
<PostBuildEvent>@echo powershell -ExecutionPolicy Unrestricted $(ProjectDir)deploy.ps1 -ProjectDir $(ProjectDir) -SolutionDir $(SolutionDir) -OutDir $(OutDir) -ConfigurationName $(ConfigurationName)</PostBuildEvent>
</PropertyGroup>
</Project> </Project>

View File

@@ -13,9 +13,9 @@ using System.Reflection;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using Matrix42.Common; using Matrix42.Common;
using Matrix42.WebApi.Contracts;
using update4u.SPS.DataLayer; using update4u.SPS.DataLayer;
using update4u.SPS.DataLayer.Transaction; using update4u.SPS.DataLayer.Transaction;
@@ -80,7 +80,7 @@ namespace C4IT.F4SD
{ {
LogEntry($"Generating F4SD URI for type: '{type}', GUID: '{EOID}'", LogLevels.Debug); LogEntry($"Generating F4SD URI for type: '{type}', GUID: '{EOID}'", LogLevels.Debug);
var builder = new UriBuilder(c4itf4sdmonLinkBase); var builder = new UriBuilder(c4itf4sdmonLinkBase);
var queryString = HttpUtility.ParseQueryString(builder.Query); var queryString = UrlQueryBuilder.Parse(builder.Query);
switch (type.ToLowerInvariant().Split('.').Last()) switch (type.ToLowerInvariant().Split('.').Last())
{ {
@@ -1663,7 +1663,7 @@ namespace C4IT.F4SD
presetParamsDyn.SPSActivityClassIncident.Asset = asset.Id; presetParamsDyn.SPSActivityClassIncident.Asset = asset.Id;
} }
var type = TicketAndServiceRequestEnabled ? "SPSActivityTypeTicket" : "SPSActivityTypeIncident"; var type = TicketAndServiceRequestEnabled ? "SPSActivityTypeTicket" : "SPSActivityTypeIncident";
var presetParams = HttpUtility.UrlEncode(JsonConvert.SerializeObject(presetParamsDyn)); var presetParams = WebUtility.UrlEncode(JsonConvert.SerializeObject(presetParamsDyn));
var directLink = string.Format(TicketDirectLinkCreateTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, type, presetParams); var directLink = string.Format(TicketDirectLinkCreateTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, type, presetParams);
return new DirectLink() return new DirectLink()
{ {
@@ -1848,7 +1848,7 @@ namespace C4IT.F4SD
viewOptionsDyn.type = CIName; viewOptionsDyn.type = CIName;
viewOptionsDyn.viewType = "action"; viewOptionsDyn.viewType = "action";
viewOptionsDyn.actionId = TicketCloseActionId; viewOptionsDyn.actionId = TicketCloseActionId;
var viewOptions = HttpUtility.UrlEncode(JsonConvert.SerializeObject(viewOptionsDyn)); var viewOptions = WebUtility.UrlEncode(JsonConvert.SerializeObject(viewOptionsDyn));
var ticketDirectLinkPreview = string.Format(TicketDirectLinkPreviewTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID); var ticketDirectLinkPreview = string.Format(TicketDirectLinkPreviewTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID);
var ticketDirectLinkEdit = string.Format(TicketDirectLinkEditTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID); var ticketDirectLinkEdit = string.Format(TicketDirectLinkEditTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID);
@@ -2305,7 +2305,7 @@ namespace C4IT.F4SD
} }
zipArchive.Dispose(); zipArchive.Dispose();
memoryStream.Position = 0L; memoryStream.Position = 0L;
HttpResponseMessage httpResponseMessage = request.CreateResponse(HttpStatusCode.OK); HttpResponseMessage httpResponseMessage = HttpResponseExtensions.CreateResponse(request, HttpStatusCode.OK);
httpResponseMessage.Content = new StreamContent(memoryStream); httpResponseMessage.Content = new StreamContent(memoryStream);
httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{ {
@@ -2727,4 +2727,41 @@ namespace C4IT.F4SD
Roles = new List<M42Role>(); Roles = new List<M42Role>();
} }
} }
internal sealed class UrlQueryBuilder
{
private readonly List<KeyValuePair<string, string>> _values = new List<KeyValuePair<string, string>>();
private UrlQueryBuilder()
{
}
public static UrlQueryBuilder Parse(string query)
{
var builder = new UrlQueryBuilder();
var normalizedQuery = (query ?? string.Empty).TrimStart('?');
foreach (var pair in normalizedQuery.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
{
var separatorIndex = pair.IndexOf('=');
var key = separatorIndex >= 0 ? pair.Substring(0, separatorIndex) : pair;
var value = separatorIndex >= 0 ? pair.Substring(separatorIndex + 1) : string.Empty;
builder.Add(WebUtility.UrlDecode(key), WebUtility.UrlDecode(value));
}
return builder;
}
public void Add(string key, string value)
{
if (!string.IsNullOrEmpty(key))
_values.Add(new KeyValuePair<string, string>(key, value ?? string.Empty));
}
public override string ToString()
{
return string.Join("&", _values.Select(pair => $"{WebUtility.UrlEncode(pair.Key)}={WebUtility.UrlEncode(pair.Value)}"));
}
}
} }

View File

@@ -6,16 +6,14 @@ using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.OData;
using System.Web.OData.Query;
using Matrix42.Common; using Matrix42.Common;
using Matrix42.Contracts.ServiceManagement.ServiceContracts; using Matrix42.Contracts.ServiceManagement.ServiceContracts;
using Matrix42.Hosting.Contracts;
using Matrix42.Pandora.Contracts; using Matrix42.Pandora.Contracts;
using Matrix42.Services.Description.Contracts; using Matrix42.Services.Description.Contracts;
using Matrix42.WebApi.Contracts;
using Matrix42.WebApi.Contracts.OData;
using update4u.SPS.Utility.GlobalConfiguration; using update4u.SPS.Utility.GlobalConfiguration;
using C4IT.F4SDM; using C4IT.F4SDM;
@@ -42,36 +40,25 @@ namespace C4IT.F4SD
private readonly F4SDHelperService _f4stHelperService; private readonly F4SDHelperService _f4stHelperService;
public string BaseUrl => $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}"; public string BaseUrl => Request?.RequestUri == null ? string.Empty : $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}";
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi"; public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
public F4SDM42WebApiController(
//IObjectService objectService, public F4SDM42WebApiController(IDependencyResolver resolver)
//IIncidentService incidentService,
IJournalService journalService
//IFragmentService fragmentService,
, IEntityDataService entityDataService
, IPandoraUserProfile userProfile
)
{ {
defaultInstance = this; defaultInstance = this;
//_objectService = objectService; _entityDataService = resolver?.TryGet<IEntityDataService>();
//_fragmentService = fragmentService; _journalService = resolver?.TryGet<IJournalService>();
//_incidentService = Guard.NullArgument(incidentService, "incidentService");
_entityDataService = entityDataService;
_journalService = journalService;
_globalConfigurationProvider = GlobalConfigurationProvider.Instance; _globalConfigurationProvider = GlobalConfigurationProvider.Instance;
_f4stHelperService = new F4SDHelperService(); _f4stHelperService = new F4SDHelperService();
_userProfile = userProfile; _userProfile = resolver?.TryGet<IPandoraUserProfile>();
EnsureInitialized();
} }
private static object initLock = new object(); private static readonly object initLock = new object();
protected override void Initialize(HttpControllerContext controllerContext) private static void EnsureInitialized()
{ {
base.Initialize(controllerContext);
try try
{ {
//System.Diagnostics.Debugger.Launch();
lock (initLock) lock (initLock)
{ {
if (IsInitialized || F4SDM42LogsWebApiController.IsInitialized) if (IsInitialized || F4SDM42LogsWebApiController.IsInitialized)
@@ -311,18 +298,18 @@ namespace C4IT.F4SD
Values = vals.ToArray() Values = vals.ToArray()
}; };
//CacheOutputAttribute.RegisterResponseEtag($"enum_{enumeration.Name}_{(int)mode}", $"{enumeration.Name}_{(int)mode}", cultureInvariant: false, userInvariant: true, val); //CacheOutputAttribute.RegisterResponseEtag($"enum_{enumeration.Name}_{(int)mode}", $"{enumeration.Name}_{(int)mode}", cultureInvariant: false, userInvariant: true, val);
return Request.CreateResponse(HttpStatusCode.OK, enumeration); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, enumeration);
} }
[Route("getMyRoleMemberships", Order = 2), HttpGet] [Route("getMyRoleMemberships"), HttpGet]
public async Task<HttpResponseMessage> getMyRoleMemberships() public async Task<HttpResponseMessage> getMyRoleMemberships()
{ {
var User = _userProfile.GetInteractiveUserInfo(); var User = _userProfile.GetInteractiveUserInfo();
var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { User.Id }); var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { User.Id });
return Request.CreateResponse(HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter)); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter));
} }
[Route("getRoleMemberships", Order = 1), HttpGet] [Route("getRoleMemberships"), HttpGet]
public async Task<HttpResponseMessage> getRoleMemberships([FromUri] GetRoleMembershipsRequest req) public async Task<HttpResponseMessage> getRoleMemberships([FromUri] GetRoleMembershipsRequest req)
{ {
var filter = ""; var filter = "";
@@ -342,7 +329,7 @@ namespace C4IT.F4SD
if (!string.IsNullOrEmpty(filter)) if (!string.IsNullOrEmpty(filter))
{ {
return Request.CreateResponse(HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter)); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter));
} }
else else
{ {
@@ -350,11 +337,11 @@ namespace C4IT.F4SD
} }
} }
[Route("getRoleMemberships/{userId}", Order = 1), HttpGet] [Route("getRoleMemberships/{userId}"), HttpGet]
public async Task<HttpResponseMessage> getRoleMembershipForUser(Guid userId) public async Task<HttpResponseMessage> getRoleMembershipForUser(Guid userId)
{ {
var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { userId }); var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { userId });
return Request.CreateResponse(HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter)); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter));
} }
[Obsolete] [Obsolete]
@@ -391,7 +378,7 @@ namespace C4IT.F4SD
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
.Select(part => .Select(part =>
{ {
var decodedPart = HttpUtility.UrlDecode(part)?.Trim(); var decodedPart = WebUtility.UrlDecode(part)?.Trim();
if (string.IsNullOrWhiteSpace(decodedPart)) if (string.IsNullOrWhiteSpace(decodedPart))
return null; return null;
@@ -477,10 +464,9 @@ namespace C4IT.F4SD
public static bool IsInitialized { get; private set; } = false; public static bool IsInitialized { get; private set; } = false;
private static object initLock = new object(); private static readonly object initLock = new object();
protected override void Initialize(HttpControllerContext controllerContext) private static void EnsureInitialized()
{ {
base.Initialize(controllerContext);
try try
{ {
lock (initLock) lock (initLock)
@@ -502,20 +488,15 @@ namespace C4IT.F4SD
public F4SDM42LogsWebApiController() public F4SDM42LogsWebApiController()
{ {
_f4stHelperService = new F4SDHelperService(); _f4stHelperService = new F4SDHelperService();
EnsureInitialized();
} }
[Route(""), HttpGet] [Route(""), HttpGet]
[EnableQuery]
public IEnumerable<cM42LogEntry> getLog2(ODataQueryOptions<cM42LogEntry> queryOptions) public IEnumerable<cM42LogEntry> getLog2(ODataQueryOptions<cM42LogEntry> queryOptions)
{ {
try try
{ {
IQueryable<cM42LogEntry> queryable = _f4stHelperService.privGetLog2().AsQueryable(); return ApplyLogFilter(_f4stHelperService.privGetLog2(), queryOptions);
if (queryOptions.Filter != null)
{
queryable = queryOptions.Filter.ApplyTo(queryable, new ODataQuerySettings()).Cast<cM42LogEntry>();
}
return queryable;
} }
catch (Exception E) catch (Exception E)
{ {
@@ -528,12 +509,7 @@ namespace C4IT.F4SD
[HttpGet] [HttpGet]
public int Log2Count(ODataQueryOptions<cM42LogEntry> queryOptions) public int Log2Count(ODataQueryOptions<cM42LogEntry> queryOptions)
{ {
IQueryable<cM42LogEntry> queryable = _f4stHelperService.privGetLog2().AsQueryable(); return ApplyLogFilter(_f4stHelperService.privGetLog2(), queryOptions).Count();
if (queryOptions.Filter != null)
{
queryable = queryOptions.Filter.ApplyTo(queryable, new ODataQuerySettings()).Cast<cM42LogEntry>();
}
return queryable.Count();
} }
[Route("{id}")] [Route("{id}")]
@@ -542,6 +518,28 @@ namespace C4IT.F4SD
{ {
return _f4stHelperService.privGetLog2(id); return _f4stHelperService.privGetLog2(id);
} }
private static IEnumerable<cM42LogEntry> ApplyLogFilter(IEnumerable<cM42LogEntry> entries, ODataQueryOptions<cM42LogEntry> queryOptions)
{
var result = entries ?? Enumerable.Empty<cM42LogEntry>();
var filter = queryOptions?.Filter;
if (!string.IsNullOrWhiteSpace(filter))
{
result = result.Where(entry =>
(entry.Message?.IndexOf(filter, StringComparison.OrdinalIgnoreCase) ?? -1) >= 0 ||
(entry.logLvl?.IndexOf(filter, StringComparison.OrdinalIgnoreCase) ?? -1) >= 0 ||
(entry.Theme?.IndexOf(filter, StringComparison.OrdinalIgnoreCase) ?? -1) >= 0);
}
if (queryOptions?.Skip != null)
result = result.Skip(queryOptions.Skip.Value);
if (queryOptions?.Top != null)
result = result.Take(queryOptions.Top.Value);
return result;
}
} }
public class cGetPropertyBody public class cGetPropertyBody

View File

@@ -0,0 +1,63 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<M42BasePackageAssembliesDir Condition="'$(M42BasePackageAssembliesDir)' == ''">$(MSBuildProjectDirectory)\BasePackage\Assemblies\</M42BasePackageAssembliesDir>
<M42RootAssembliesDir Condition="'$(M42RootAssembliesDir)' == '' AND '$(M42ExtensionId)' != ''">$(MSBuildProjectDirectory)\Root\InstalledPackages\Assemblies\$(M42ExtensionId)\</M42RootAssembliesDir>
<M42AssemblyPattern Condition="'$(M42AssemblyPattern)' == ''">$(MSBuildProjectName)*.*</M42AssemblyPattern>
<M42DefaultRids Condition="'$(M42DefaultRids)' == ''">win-x64;linux-x64</M42DefaultRids>
</PropertyGroup>
<Target Name="M42_BuildAllRids"
BeforeTargets="Build"
Condition="'$(RuntimeIdentifier)' == '' AND '$(M42SkipBuildAllRids)' != 'true'">
<ItemGroup>
<_M42RidList Include="$(M42DefaultRids)" />
</ItemGroup>
<MSBuild Projects="$(MSBuildProjectFullPath)"
Targets="Restore;Build"
Properties="RuntimeIdentifier=%(_M42RidList.Identity);Configuration=$(Configuration);AppendRuntimeIdentifierToOutputPath=true;M42SkipBuildAllRids=true"
BuildInParallel="true" />
<PropertyGroup>
<SkipBuild>true</SkipBuild>
</PropertyGroup>
</Target>
<Target Name="M42_PostBuild_CopyRidless"
AfterTargets="Build"
Condition="'$(RuntimeIdentifier)' == ''">
<ItemGroup>
<_M42FlatRoot Include="$(TargetDir)$(M42AssemblyPattern)" />
</ItemGroup>
<MakeDir Directories="$(M42BasePackageAssembliesDir)" />
<MakeDir Directories="$(M42RootAssembliesDir)" Condition="'$(M42RootAssembliesDir)' != ''" />
<Copy SourceFiles="@(_M42FlatRoot)"
DestinationFolder="$(M42BasePackageAssembliesDir)"
SkipUnchangedFiles="true" />
<Copy SourceFiles="@(_M42FlatRoot)"
DestinationFolder="$(M42RootAssembliesDir)"
SkipUnchangedFiles="true"
Condition="'$(M42RootAssembliesDir)' != ''" />
</Target>
<Target Name="M42_PostBuild_CopyRid"
AfterTargets="Build"
Condition="'$(RuntimeIdentifier)' != ''">
<ItemGroup>
<_M42Rid Include="$(TargetDir)**\$(M42AssemblyPattern)" />
</ItemGroup>
<MakeDir Directories="$(M42BasePackageAssembliesDir)$(RuntimeIdentifier)" />
<MakeDir Directories="$(M42RootAssembliesDir)$(RuntimeIdentifier)" Condition="'$(M42RootAssembliesDir)' != ''" />
<Copy SourceFiles="@(_M42Rid)"
DestinationFolder="$(M42BasePackageAssembliesDir)$(RuntimeIdentifier)\%(RecursiveDir)"
SkipUnchangedFiles="true" />
<Copy SourceFiles="@(_M42Rid)"
DestinationFolder="$(M42RootAssembliesDir)$(RuntimeIdentifier)\%(RecursiveDir)"
SkipUnchangedFiles="true"
Condition="'$(M42RootAssembliesDir)' != ''" />
</Target>
</Project>

View File

@@ -0,0 +1,16 @@
{
"Id": "d8cbffca-0b43-4acc-80ea-c944e7420cee",
"Vendor": "Consulting4IT GmbH",
"Name": "C4IT.F4SD.M42WebApi",
"Version": "1.3.0.0",
"Prerequisites": {
"MinimalRequiredProductVersion": "26.1.0",
"DependentPackages": []
},
"SetupDirectives": {
"MaintenanceMode": false,
"RecycleWebApplication": false,
"RestartM42WindowsServices": false
},
"Sandboxed": true
}