diff --git a/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config b/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config
index eb4eb95..1a32a56 100644
--- a/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config
+++ b/F4SDM42WebApi/C4ITF4SDM42WebApi.dll.host.config
@@ -2,12 +2,7 @@
-
-
-
-
-
diff --git a/F4SDM42WebApi/DependencyRegistrator.cs b/F4SDM42WebApi/DependencyRegistrator.cs
deleted file mode 100644
index b1c8a05..0000000
--- a/F4SDM42WebApi/DependencyRegistrator.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using System.Web.Http;
-using System.Web.Http.Description;
-
-using Matrix42.Hosting.Contracts;
-
-namespace C4IT.F4SD.Properties
-{
- public sealed class DependencyRegistrator : DependencyRegistratorBase, IDependencyRegistrator
- {
- public void Register(IDependencyContainer container, IDependencyResolver resolver)
- {
- container.RegisterSingletonType((Type _) => new ApiExplorer(new HttpConfiguration()));
- }
- }
-}
diff --git a/F4SDM42WebApi/F4SD - M42WebApi.csproj b/F4SDM42WebApi/F4SD - M42WebApi.csproj
index 2bcc94e..80c5320 100644
--- a/F4SDM42WebApi/F4SD - M42WebApi.csproj
+++ b/F4SDM42WebApi/F4SD - M42WebApi.csproj
@@ -13,7 +13,7 @@
false
6673a25d-33d6-4072-91d9-abed4be1a966
C4ITF4SD*.*
- 1.4.0.8
+ 1.4.0.9
true
@@ -46,6 +46,10 @@
M42Libraries\26.1\Matrix42.Pandora.Contracts.dll
false
+
+ M42Libraries\26.1\Matrix42.Persistence.Contracts.dll
+ false
+
M42Libraries\26.1\Matrix42.Services.Description.Contracts.dll
false
@@ -62,10 +66,6 @@
M42Libraries\26.1\System.Net.Http.Formatting.dll
false
-
- M42Libraries\26.1\System.Web.Http.dll
- false
-
M42Libraries\26.1\update4u.SPS.DataLayer.dll
false
@@ -82,7 +82,6 @@
-
diff --git a/F4SDM42WebApi/F4SDHelperService.cs b/F4SDM42WebApi/F4SDHelperService.cs
index 49f7cc8..1807523 100644
--- a/F4SDM42WebApi/F4SDHelperService.cs
+++ b/F4SDM42WebApi/F4SDHelperService.cs
@@ -1931,7 +1931,7 @@ namespace C4IT.F4SD
{
await Task.Delay(0);
List journalEntries = new List();
- var entries = F4SDM42WebApiController.defaultInstance._journalService.GetJournalList(activityEOID, false, 0, 50, "{2}", 120);
+ var entries = F4SDM42WebApiController.defaultInstance.GetJournalService().GetJournalList(activityEOID, false, 0, 50, "{2}", 120);
LogEntry($"{entries.Length} Journal entries found for ObjectID={activityEOID}", LogLevels.Debug);
for (int i = 0; i < entries.Length; i++)
{
@@ -2618,18 +2618,6 @@ namespace C4IT.F4SD
retVal.User = m42Users[0];
- var user = F4SDM42WebApiController.defaultInstance._userProfile.GetInteractiveUserInfo(retVal.User.Id);
- if (user != null)
- {
- retVal.User.Id = user.Id;
- retVal.User.Currency = user.Currency;
- retVal.User.Email = user.Email;
- retVal.User.FirstName = user.FirstName;
- retVal.User.LastName = user.LastName;
- retVal.User.Phone = user.Phone;
- retVal.User.Photo = user.Photo;
- }
-
retVal.Roles = await getRoleMembershipById(retVal.User.Id);
retVal.User.IsAdmin = retVal.Roles?.Where(i => i.Id == Administrators).FirstOrDefault() != null;
return retVal;
diff --git a/F4SDM42WebApi/F4SDM42WebApiController.cs b/F4SDM42WebApi/F4SDM42WebApiController.cs
index 7cb47f2..196e3bd 100644
--- a/F4SDM42WebApi/F4SDM42WebApiController.cs
+++ b/F4SDM42WebApi/F4SDM42WebApiController.cs
@@ -5,11 +5,15 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Reflection;
+using System.Threading;
using System.Threading.Tasks;
using Matrix42.Common;
+using Matrix42.Contracts.Common.Security;
using Matrix42.Contracts.ServiceManagement.ServiceContracts;
+using Matrix42.Hosting.Contracts;
using Matrix42.Pandora.Contracts;
+using Matrix42.Persistence.Contracts;
using Matrix42.Services.Description.Contracts;
using Matrix42.WebApi.Contracts;
using Matrix42.WebApi.Contracts.OData;
@@ -33,24 +37,20 @@ namespace C4IT.F4SD
internal readonly GlobalConfigurationProvider _globalConfigurationProvider;
//public readonly IObjectService _objectService;
//public readonly IFragmentService _fragmentService;
- public readonly IJournalService _journalService;
- internal readonly IEntityDataService _entityDataService;
- internal readonly IPandoraUserProfile _userProfile;
+ private readonly IDependencyResolver _resolver;
private readonly F4SDHelperService _f4stHelperService;
public string BaseUrl => Request?.RequestUri == null ? string.Empty : $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}";
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
- public F4SDM42WebApiController(IEntityDataService entityDataService, IJournalService journalService, IPandoraUserProfile userProfile)
+ public F4SDM42WebApiController(IDependencyResolver resolver)
{
+ _resolver = resolver ?? throw new ArgumentNullException(nameof(resolver));
defaultInstance = this;
_globalConfigurationProvider = GlobalConfigurationProvider.Instance;
_f4stHelperService = new F4SDHelperService();
EnsureInitialized();
- _entityDataService = entityDataService ?? throw new ArgumentNullException(nameof(entityDataService));
- _journalService = journalService ?? throw new ArgumentNullException(nameof(journalService));
- _userProfile = userProfile ?? throw new ArgumentNullException(nameof(userProfile));
}
private static readonly object initLock = new object();
@@ -74,6 +74,25 @@ namespace C4IT.F4SD
catch { };
}
+ internal IJournalService GetJournalService()
+ {
+ return GetRequiredService();
+ }
+
+ private IEnumerationProvider GetEnumerationProvider()
+ {
+ return GetRequiredService();
+ }
+
+ private T GetRequiredService() where T : class
+ {
+ var service = _resolver.TryGet();
+ if (service != null)
+ return service;
+
+ throw new InvalidOperationException($"Required Matrix42 service is not registered: {typeof(T).FullName}");
+ }
+
[Route("getDirectLinkCreateTicket"), HttpGet]
public async Task getDirectLinkCreateTicket(string sid = "", string assetname = "")
{
@@ -277,7 +296,7 @@ namespace C4IT.F4SD
public async Task getPickup(string name, [FromUri] EntityEnumerationVisibilityMode mode = EntityEnumerationVisibilityMode.None, [FromUri] Int32 group = -1)
{
await Task.Delay(0);
- EntityEnumeration enumerationTemp = _entityDataService.GetEnumeration(name, mode);
+ EntityEnumeration enumerationTemp = GetEnumeration(name, mode);
var vals = enumerationTemp.Values;
if (group > -1)
@@ -303,8 +322,11 @@ namespace C4IT.F4SD
[Route("getMyRoleMemberships"), HttpGet]
public async Task getMyRoleMemberships()
{
- var User = _userProfile.GetInteractiveUserInfo();
- var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { User.Id });
+ var userId = GetCurrentUserId();
+ if (userId == Guid.Empty)
+ return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.Unauthorized, "Cannot determine the interactive Matrix42 user.");
+
+ var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { userId });
return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter));
}
@@ -371,6 +393,94 @@ namespace C4IT.F4SD
public string Queues { get; set; }
}
+ private EntityEnumeration GetEnumeration(string name, EntityEnumerationVisibilityMode mode)
+ {
+ var dataTable = GetEnumerationProvider().GetEnumeration(name, GetVisibilityFilter(mode));
+ if (dataTable == null)
+ throw new InvalidOperationException($"Enumeration '{name}' was not found.");
+
+ var valueColumn = FindColumn(dataTable, "Value") ?? FindNumericColumn(dataTable);
+ if (string.IsNullOrEmpty(valueColumn))
+ throw new InvalidOperationException($"Enumeration '{name}' does not contain a numeric value column.");
+
+ var displayColumn = FindColumn(dataTable, "DisplayString")
+ ?? FindColumn(dataTable, "DisplayExpression")
+ ?? FindColumn(dataTable, "Name")
+ ?? valueColumn;
+ var hiddenColumn = FindColumn(dataTable, "Hidden");
+
+ var values = dataTable.Rows.Cast()
+ .Select(row => new EntityEnumerationValue
+ {
+ Value = ConvertHelper.ParseInt(row[valueColumn], 0),
+ DisplayString = Convert.ToString(row[displayColumn]),
+ Hidden = hiddenColumn != null && ConvertHelper.ParseInt(row[hiddenColumn], 0) == 1,
+ Extentions = dataTable.Columns.Cast()
+ .ToDictionary(column => column.ColumnName, column => row[column])
+ })
+ .ToArray();
+
+ return new EntityEnumeration
+ {
+ Name = name,
+ Values = values
+ };
+ }
+
+ private static bool? GetVisibilityFilter(EntityEnumerationVisibilityMode mode)
+ {
+ switch (mode)
+ {
+ case EntityEnumerationVisibilityMode.Visible:
+ return true;
+ case EntityEnumerationVisibilityMode.Hidden:
+ return false;
+ default:
+ return null;
+ }
+ }
+
+ private static string FindColumn(DataTable dataTable, string columnName)
+ {
+ return dataTable.Columns.Cast()
+ .FirstOrDefault(column => string.Equals(column.ColumnName, columnName, StringComparison.OrdinalIgnoreCase))
+ ?.ColumnName;
+ }
+
+ private static string FindNumericColumn(DataTable dataTable)
+ {
+ var excludedNames = new HashSet(StringComparer.OrdinalIgnoreCase)
+ {
+ "Hidden",
+ "Position",
+ "StateGroup"
+ };
+
+ return dataTable.Columns.Cast()
+ .FirstOrDefault(column => !excludedNames.Contains(column.ColumnName) && IsNumericType(column.DataType))
+ ?.ColumnName;
+ }
+
+ private static bool IsNumericType(Type type)
+ {
+ return type == typeof(byte)
+ || type == typeof(short)
+ || type == typeof(int)
+ || type == typeof(long)
+ || type == typeof(sbyte)
+ || type == typeof(ushort)
+ || type == typeof(uint)
+ || type == typeof(ulong);
+ }
+
+ private static Guid GetCurrentUserId()
+ {
+ var principal = Thread.CurrentPrincipal as IM42Principal;
+ return principal?.InteractivePrincipal?.M42Identity?.UserFragmentID
+ ?? principal?.M42Identity?.UserFragmentID
+ ?? Guid.Empty;
+ }
+
private static List ParseQueues(string queues)
{
return (queues ?? string.Empty)