using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Net; using System.Net.Http; using System.Reflection; using System.Threading.Tasks; using Matrix42.Common; using Matrix42.Contracts.ServiceManagement.ServiceContracts; using Matrix42.Hosting.Contracts; using Matrix42.Pandora.Contracts; using Matrix42.Services.Description.Contracts; using Matrix42.WebApi.Contracts; using Matrix42.WebApi.Contracts.OData; using update4u.SPS.Utility.GlobalConfiguration; using C4IT.F4SDM; using C4IT.FASD.Base; using C4IT.Logging; using static C4IT.Logging.cLogManager; namespace C4IT.F4SD { [RoutePrefix("api/C4ITF4SDWebApi")] public partial class F4SDM42WebApiController : ApiController { public static bool IsInitialized { get; private set; } = false; public static F4SDM42WebApiController defaultInstance; //private readonly IIncidentService _incidentService; internal readonly GlobalConfigurationProvider _globalConfigurationProvider; public readonly IJournalService _journalService; //public readonly IObjectService _objectService; //public readonly IFragmentService _fragmentService; internal readonly IEntityDataService _entityDataService; internal readonly IPandoraUserProfile _userProfile; 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(IDependencyResolver resolver) { defaultInstance = this; _globalConfigurationProvider = GlobalConfigurationProvider.Instance; _f4stHelperService = new F4SDHelperService(); EnsureInitialized(); _entityDataService = ResolveOptional(resolver); _journalService = ResolveOptional(resolver); _userProfile = ResolveOptional(resolver); } private static T ResolveOptional(IDependencyResolver resolver) where T : class { if (resolver == null) return null; try { if (!resolver.IsRegistered()) return null; } catch { } try { return resolver.TryGet(); } catch (Exception ex) { LogOptionalDependencyFailure(typeof(T), ex); return null; } } private static void LogOptionalDependencyFailure(Type dependencyType, Exception exception) { try { LogEntry($"Matrix42 dependency '{dependencyType.FullName}' could not be resolved.", LogLevels.Warning); LogException(exception); } catch { } } private HttpResponseMessage CreateMissingDependencyResponse(Type dependencyType) { return HttpResponseExtensions.CreateResponse( Request, HttpStatusCode.ServiceUnavailable, $"Matrix42 dependency '{dependencyType.FullName}' is not registered for this extension context."); } private static readonly object initLock = new object(); private static void EnsureInitialized() { try { lock (initLock) { if (IsInitialized || F4SDM42LogsWebApiController.IsInitialized) return; var Ass = Assembly.GetExecutingAssembly(); var LM = cLogManagerFile.CreateInstance(LocalMachine: true, A: Ass); var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); cLogManager.DefaultLogger.LogAssemblyInfo(Ass); IsInitialized = true; LogMethodEnd(CM); } } catch { }; } [Route("getDirectLinkCreateTicket"), HttpGet] public async Task getDirectLinkCreateTicket(string sid = "", string assetname = "") { await Task.Delay(0); return await _f4stHelperService.getDirectLinkCreateTicket(sid, assetname); } [Route("getDirectLinkF4SD"), HttpGet] public async Task getDirectLinkF4SD(Guid EOID, string Type) { return await _f4stHelperService.getDirectLinkF4SD(EOID, Type); } [Obsolete] [Route("getTicketList"), HttpGet] public async Task> getTicketList( string sid, int hours, int queueoption = 0, string queues = "" ) { var decodedPairs = ParseQueues(queues); // Nun weiterreichen an Service return await _f4stHelperService.getTicketListByUser( sid, hours, queueoption, decodedPairs ); } [Route("getTicketListForUser"), HttpGet] public async Task> getTicketListForUser( Guid userId, int hours, int queueoption = 0, string queues = "" ) { var decodedPairs = ParseQueues(queues); // Nun weiterreichen an Service return await _f4stHelperService.getTicketListByUser( userId, hours, queueoption, decodedPairs ); } [Route("getTicketDetails"), HttpGet] public async Task getTicketDetails(Guid objectId) { var tickets = await _f4stHelperService.getTicketDetails(new List() { objectId }); if (tickets.Count > 0) return tickets[0]; else return null; } [Route("getTicketHistory"), HttpGet] public async Task> getTicketHistory(Guid objectId) { return await _f4stHelperService.GetJournalEntries(objectId); } [Obsolete] [Route("getTicketOverviewCounts"), HttpGet] public async Task getTicketOverviewCounts( string sid, string scope = "personal", string keys = "", int queueoption = 0, string queues = "" ) { var parsedKeys = (keys ?? string.Empty) .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(key => key.Trim()) .Where(key => !string.IsNullOrWhiteSpace(key)) .ToList(); var decodedQueues = ParseQueues(queues); return await _f4stHelperService.getTicketOverviewCounts(sid, scope, parsedKeys, queueoption, decodedQueues); } [Route("getTicketOverviewCountsForUser"), HttpGet] public async Task getTicketOverviewCountsForUser( Guid userId, string scope = "personal", string keys = "", int queueoption = 0, string queues = "" ) { var parsedKeys = (keys ?? string.Empty) .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) .Select(key => key.Trim()) .Where(key => !string.IsNullOrWhiteSpace(key)) .ToList(); var decodedQueues = ParseQueues(queues); return await _f4stHelperService.getTicketOverviewCounts(userId, scope, parsedKeys, queueoption, decodedQueues); } [Obsolete] [Route("getTicketOverviewCountsByRoles"), HttpPost] public async Task getTicketOverviewCountsByRoles([FromBody] TicketOverviewCountsByRolesRequest request) { var parsedKeys = (request?.Keys ?? new List()) .Where(key => !string.IsNullOrWhiteSpace(key)) .Select(key => key.Trim()) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); var roleGuids = (request?.RoleGuids ?? new List()) .Where(roleId => roleId != Guid.Empty) .Distinct() .ToList(); var decodedQueues = ParseQueues(request?.Queues ?? string.Empty); return await _f4stHelperService.getTicketOverviewCountsByRoles( request?.Sid, roleGuids, parsedKeys, request?.QueueOption ?? 0, decodedQueues ); } [Route("getTicketOverviewCountsByRolesForUser"), HttpPost] public async Task getTicketOverviewCountsByRolesForUser([FromBody] TicketOverviewCountsByRolesForUserRequest request) { var parsedKeys = (request?.Keys ?? new List()) .Where(key => !string.IsNullOrWhiteSpace(key)) .Select(key => key.Trim()) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); var roleGuids = (request?.RoleGuids ?? new List()) .Where(roleId => roleId != Guid.Empty) .Distinct() .ToList(); var decodedQueues = ParseQueues(request?.Queues ?? string.Empty); return await _f4stHelperService.getTicketOverviewCountsByRoles( request.userId, roleGuids, parsedKeys, request?.QueueOption ?? 0, decodedQueues ); } [Obsolete] [Route("getTicketOverviewRelations"), HttpGet] public async Task> getTicketOverviewRelations( string sid, string scope = "personal", string key = "", int count = 0, int queueoption = 0, string queues = "" ) { var decodedQueues = ParseQueues(queues); return await _f4stHelperService.getTicketOverviewRelations(sid, scope, key, count, queueoption, decodedQueues); } [Route("getTicketOverviewRelationsForUser"), HttpGet] public async Task> getTicketOverviewRelations( Guid userId, string scope = "personal", string key = "", int count = 0, int queueoption = 0, string queues = "" ) { var decodedQueues = ParseQueues(queues); return await _f4stHelperService.getTicketOverviewRelations(userId, scope, key, count, queueoption, decodedQueues); } /* [Route("updateActivitySolution/{objectId}"), HttpPost] public async Task updateActivitySolution(Guid objectId, [FromBody] string SolutionHtml) { return new HttpResponseMessage { StatusCode = await _f4stHelperService.updateActivitySolution(objectId, SolutionHtml) ? HttpStatusCode.NoContent : HttpStatusCode.BadRequest, }; } */ [Route("getPickup/{name}"), HttpGet] //[CacheOutput(UseETAG = true)] public async Task getPickup(string name, [FromUri] EntityEnumerationVisibilityMode mode = EntityEnumerationVisibilityMode.None, [FromUri] Int32 group = -1) { await Task.Delay(0); if (_entityDataService == null) return CreateMissingDependencyResponse(typeof(IEntityDataService)); EntityEnumeration enumerationTemp = _entityDataService.GetEnumeration(name, mode); var vals = enumerationTemp.Values; if (group > -1) { vals = vals.Where(row => !row.Extentions.TryGetValue("StateGroup", out var stateGroup) || (ConvertHelper.ParseInt(stateGroup, 0) == group)).ToArray(); } string[] columns = new string[] { "position" }; foreach (var item in vals) { item.Extentions = item.Extentions.Where(x => columns.Contains(x.Key.ToLower())).ToDictionary(x => x.Key, x => x.Value); } EntityEnumeration enumeration = new EntityEnumeration { Name = enumerationTemp.Name, Values = vals.ToArray() }; //CacheOutputAttribute.RegisterResponseEtag($"enum_{enumeration.Name}_{(int)mode}", $"{enumeration.Name}_{(int)mode}", cultureInvariant: false, userInvariant: true, val); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, enumeration); } [Route("getMyRoleMemberships"), HttpGet] public async Task getMyRoleMemberships() { if (_userProfile == null) return CreateMissingDependencyResponse(typeof(IPandoraUserProfile)); var User = _userProfile.GetInteractiveUserInfo(); var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { User.Id }); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter)); } [Route("getRoleMemberships"), HttpGet] public async Task getRoleMemberships([FromUri] GetRoleMembershipsRequest req) { var filter = ""; if (req.Id != null && req.Id.Value != Guid.Empty) { filter = AsqlHelper.BuildInCondition("ID", new Guid[] { req.Id.Value }); } else if (!string.IsNullOrEmpty(req.Sid)) { filter = AsqlHelper.BuildInCondition("Accounts.T(SPSAccountClassAD).Sid", new string[] { req.Sid }); } else if (!string.IsNullOrEmpty(req.Upn)) { filter = AsqlHelper.BuildInCondition("Accounts.T(SPSAccountClassAD).UserPrincipalName", new string[] { req.Upn }); } if (!string.IsNullOrEmpty(filter)) { return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter)); } else { return null; } } [Route("getRoleMemberships/{userId}"), HttpGet] public async Task getRoleMembershipForUser(Guid userId) { var filter = AsqlHelper.BuildInCondition("ID", new Guid[] { userId }); return HttpResponseExtensions.CreateResponse(Request, HttpStatusCode.OK, await _f4stHelperService.UserPermissionsInfo(filter)); } [Obsolete] public class GetRoleMembershipsRequest { public Guid? Id { get; set; } public string Sid { get; set; } public string Upn { get; set; } public GetRoleMembershipsRequest() { } } [Obsolete] public class TicketOverviewCountsByRolesRequest { public string Sid { get; set; } public List RoleGuids { get; set; } = new List(); public List Keys { get; set; } = new List(); public int? QueueOption { get; set; } public string Queues { get; set; } } public class TicketOverviewCountsByRolesForUserRequest { public Guid userId { get; set; } public List RoleGuids { get; set; } = new List(); public List Keys { get; set; } = new List(); public int? QueueOption { get; set; } public string Queues { get; set; } } private static List ParseQueues(string queues) { return (queues ?? string.Empty) .Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries) .Select(part => { var decodedPart = WebUtility.UrlDecode(part)?.Trim(); if (string.IsNullOrWhiteSpace(decodedPart)) return null; var name = decodedPart; string idStr = null; var separatorIndex = decodedPart.IndexOf(':'); if (separatorIndex >= 0) { name = decodedPart.Substring(0, separatorIndex).Trim(); idStr = decodedPart.Substring(separatorIndex + 1).Trim(); } var queue = new cApiM42TicketQueueInfo(); if (!string.IsNullOrWhiteSpace(name)) queue.QueueName = name; if (!string.IsNullOrWhiteSpace(idStr)) { if (!Guid.TryParse(idStr, out var guid)) return null; queue.QueueID = guid; queue.QueueName = null; } if (queue.QueueID == Guid.Empty && string.IsNullOrWhiteSpace(queue.QueueName)) return null; return queue; }) .Where(q => q != null) .ToList(); } [Route("isAlive"), HttpGet] public HttpResponseMessage isAlive() { return new HttpResponseMessage(HttpStatusCode.NoContent); } [Route("loglevel"), HttpGet] public async Task setDebugMode(string debug = "0") { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { await Task.Delay(0); DefaultLogger.Manager.Level = debug == "1" || debug.Equals("true", StringComparison.OrdinalIgnoreCase) ? LogLevels.Debug : LogLevels.Info; return DefaultLogger.Manager.Level.ToString(); } catch (Exception E) { LogException(E); return null; } finally { LogMethodEnd(CM); } } [Route("log"), HttpGet] public HttpResponseMessage getLog(string download = "0", int count = 50, string filter = "") { try { return _f4stHelperService.privGetLog(download, count, Request, filter); } catch (Exception E) { LogException(E); return null; } } } [RoutePrefix("api/C4ITF4SDWebApi/Logs")] public partial class F4SDM42LogsWebApiController : ApiController { private readonly F4SDHelperService _f4stHelperService; public static bool IsInitialized { get; private set; } = false; private static readonly object initLock = new object(); private static void EnsureInitialized() { try { lock (initLock) { if (IsInitialized || F4SDM42WebApiController.IsInitialized) return; var Ass = Assembly.GetExecutingAssembly(); var LM = cLogManagerFile.CreateInstance(LocalMachine: true, A: Ass); var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); cLogManager.DefaultLogger.LogAssemblyInfo(Ass); IsInitialized = true; LogMethodEnd(CM); } } catch { }; } public F4SDM42LogsWebApiController() { _f4stHelperService = new F4SDHelperService(); EnsureInitialized(); } [Route(""), HttpGet] public IEnumerable getLog2(ODataQueryOptions queryOptions) { try { return ApplyLogFilter(_f4stHelperService.privGetLog2(), queryOptions); } catch (Exception E) { LogException(E); return null; } } [Route("$count")] [HttpGet] public int Log2Count(ODataQueryOptions queryOptions) { return ApplyLogFilter(_f4stHelperService.privGetLog2(), queryOptions).Count(); } [Route("{id}")] [OperationType(OperationType.GetObject)] public cM42LogEntry GetClass(int id) { return _f4stHelperService.privGetLog2(id); } private static IEnumerable ApplyLogFilter(IEnumerable entries, ODataQueryOptions queryOptions) { var result = entries ?? Enumerable.Empty(); 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 string TableName { get; set; } public List Columns { get; set; } = new List(); public cGetPropertyBody() { } } }