Merge branch 'Release0.2'
This commit is contained in:
commit
fe5bcd3256
5
CardReaderService/CardReaderService.conf
Normal file
5
CardReaderService/CardReaderService.conf
Normal file
@ -0,0 +1,5 @@
|
||||
[program:CardReaderService]
|
||||
command=mono-service CardReaderService.exe --no-daemon
|
||||
directory=/DIRECTORYTOSET/CardReaderService
|
||||
stdout_logfile=/DIRECTORYTOSET/CardReaderService/out.log
|
||||
redirect_stderr=true
|
||||
@ -3,9 +3,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderService", "CardReaderService.csproj", "{5F30E8E4-5107-4C99-ADFF-38D735DC113D}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderService", "CardReaderService\CardReaderService.csproj", "{5F30E8E4-5107-4C99-ADFF-38D735DC113D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderServiceHost", "..\CardReaderServiceHost\CardReaderServiceHost.csproj", "{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CardReaderServiceHost", "CardReaderServiceHost\CardReaderServiceHost.csproj", "{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logger", "Logger\Logger.csproj", "{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux Conf", "Linux Conf", "{F9053F37-761D-45EE-9153-46776B083DBA}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
CardReaderService.conf = CardReaderService.conf
|
||||
install.sh = install.sh
|
||||
uninstall.sh = uninstall.sh
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -21,6 +30,10 @@ Global
|
||||
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6E48913F-9D8C-4132-93A7-C7B1C6DD5264}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="DataCenterServiceEndpoint" value="http://localhost:1234"/>
|
||||
|
||||
10
CardReaderService/CardReaderService/CardDataPost.cs
Normal file
10
CardReaderService/CardReaderService/CardDataPost.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System;
|
||||
|
||||
namespace CardReaderService
|
||||
{
|
||||
public class CardDataPost
|
||||
{
|
||||
public DateTime UtcTimeStamp { get; set; }
|
||||
public string CardUId { get; set; }
|
||||
}
|
||||
}
|
||||
@ -9,9 +9,10 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CardReaderService</RootNamespace>
|
||||
<AssemblyName>CardReaderService</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -33,12 +34,12 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="pcsc-sharp, Version=3.6.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>packages\PCSC.3.6.0\lib\net40\pcsc-sharp.dll</HintPath>
|
||||
<Reference Include="PCSC, Version=4.2.0.0, Culture=neutral, PublicKeyToken=13b76e54a2ee80a7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PCSC.4.2.0\lib\net40\PCSC.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
@ -53,6 +54,10 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CardDataPost.cs" />
|
||||
<Compile Include="ConfigurationManager.cs" />
|
||||
<Compile Include="ConfigurationProperty.cs" />
|
||||
<Compile Include="ConfigurationType.cs" />
|
||||
<Compile Include="ConfigureService.cs" />
|
||||
<Compile Include="DataCenterHelper.cs" />
|
||||
<Compile Include="Service1.cs">
|
||||
@ -68,6 +73,12 @@
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Logger\Logger.csproj">
|
||||
<Project>{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}</Project>
|
||||
<Name>Logger</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
38
CardReaderService/CardReaderService/ConfigurationManager.cs
Normal file
38
CardReaderService/CardReaderService/ConfigurationManager.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace CardReaderService
|
||||
{
|
||||
public class ConfigurationManager
|
||||
{
|
||||
public ConfigurationProperty GetConfiguration(string configName)
|
||||
{
|
||||
var cfgManager = GetConfigManager();
|
||||
if (cfgManager.AppSettings.Settings.AllKeys.Contains(configName))
|
||||
{
|
||||
var cfg = cfgManager.AppSettings.Settings[configName];
|
||||
return new ConfigurationProperty
|
||||
{
|
||||
Group=string.Empty,
|
||||
Id="NOTIMPLEMENTED",
|
||||
Name = cfg.Key,
|
||||
Value = cfg.Value,
|
||||
ReadOnly = false,
|
||||
Source = "CardReaderService",
|
||||
Type = ConfigurationType.STRING
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Configuration GetConfigManager()
|
||||
{
|
||||
return System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigFilePath);
|
||||
}
|
||||
|
||||
public string ConfigFilePath => new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath;
|
||||
}
|
||||
}
|
||||
55
CardReaderService/CardReaderService/ConfigurationProperty.cs
Normal file
55
CardReaderService/CardReaderService/ConfigurationProperty.cs
Normal file
@ -0,0 +1,55 @@
|
||||
namespace CardReaderService
|
||||
{
|
||||
/// <summary>
|
||||
/// An object used to detail an element that can be configured in the system.
|
||||
/// </summary>
|
||||
public class ConfigurationProperty
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique Id for the configuration property.
|
||||
/// </summary>
|
||||
public string Id { get; set; }
|
||||
/// <summary>
|
||||
/// The display name of the configuration
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The group under which this configuration falls (e.g.: TCP Settings - "TCP" or similar.)
|
||||
/// </summary>
|
||||
/// <remarks>Application Specific grouping.</remarks>
|
||||
public string Group { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The actual value of the Configuration property
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The source of the configuration properties.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Using this property allows aggregation of configuration settings
|
||||
/// by any configuration managers
|
||||
/// </remarks>
|
||||
/// <example>{TYPE}.getType().Name (or other suitably unique identifier)</example>
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The type of the configuration
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This can be used for UI proofing/validation to ensure a user
|
||||
/// enters expected format (e.g.: enters a date time for a datetime type)
|
||||
/// </remarks>
|
||||
public ConfigurationType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether the configuration setting can be set by user or is readonly
|
||||
/// </summary>
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
//TODO: in future, add access level, could go read level/edit level
|
||||
//public UserAccessLevel UserLevel {get;set;}
|
||||
}
|
||||
}
|
||||
33
CardReaderService/CardReaderService/ConfigurationType.cs
Normal file
33
CardReaderService/CardReaderService/ConfigurationType.cs
Normal file
@ -0,0 +1,33 @@
|
||||
namespace CardReaderService
|
||||
{
|
||||
/// <summary>
|
||||
/// The type of the configuration.
|
||||
/// </summary>
|
||||
public enum ConfigurationType
|
||||
{
|
||||
/// <summary>
|
||||
/// No Type - shouldnt be used, but default for enum
|
||||
/// </summary>
|
||||
NONE,
|
||||
/// <summary>
|
||||
/// a string type configuration (could also be used for complex objects, e.g.: a json string/object).
|
||||
/// </summary>
|
||||
STRING,
|
||||
/// <summary>
|
||||
/// A whole number configuration
|
||||
/// </summary>
|
||||
INT,
|
||||
/// <summary>
|
||||
/// A number config with a decimal component
|
||||
/// </summary>
|
||||
DECIMAL,
|
||||
/// <summary>
|
||||
/// A Date Time Configuration
|
||||
/// </summary>
|
||||
DATETIME,
|
||||
/// <summary>
|
||||
/// A Boolean/TrueFalse configuration property (e.g.: On Off)
|
||||
/// </summary>
|
||||
BOOL
|
||||
}
|
||||
}
|
||||
@ -1,36 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Logger;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CardReaderService
|
||||
{
|
||||
static class DataCenterHelper
|
||||
{
|
||||
static DataCenterHelper()
|
||||
{
|
||||
}
|
||||
|
||||
public static void Post(CardDataPost postObject, string url)
|
||||
{
|
||||
var endpointConfig = ConfigurationManager.AppSettings["DataCenterServiceEndpoint"] ??
|
||||
"http://localhost:8800";
|
||||
var cfgMgr = new ConfigurationManager();
|
||||
//using ConfigurationManager means we can change the value at runtime without having to restart the service.
|
||||
var endpointConfig = cfgMgr.GetConfiguration("DataCenterServiceEndpoint")?.Value?? "http://localhost:8800";
|
||||
|
||||
MessageLogger.Log("Targeting Endpoint: " + endpointConfig);
|
||||
using (var client = new HttpClient())
|
||||
{
|
||||
var jsonObject = JsonConvert.SerializeObject(postObject);
|
||||
var content = new StringContent(jsonObject, Encoding.UTF8, "application/json");
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Writing");
|
||||
MessageLogger.Log("Writing uid: "+ postObject.CardUId + " to the server.");
|
||||
var fullUrl = endpointConfig + url;
|
||||
MessageLogger.Log("Writing to URL: " + fullUrl);
|
||||
var response = client.PostAsync(fullUrl, content).Result;
|
||||
Console.WriteLine("Written");
|
||||
MessageLogger.Log("Successfully written to server");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Console.WriteLine("exceptioning");
|
||||
//ignore
|
||||
MessageLogger.Log("Failed to send log to server.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,9 +44,4 @@ namespace CardReaderService
|
||||
return Task.Run(() => Post(postObject, url));
|
||||
}
|
||||
}
|
||||
|
||||
public class CardDataPost
|
||||
{
|
||||
public string CardUId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
using PCSC;
|
||||
using System;
|
||||
using System.CodeDom;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Logger;
|
||||
using PCSC.Monitoring;
|
||||
|
||||
namespace CardReaderService
|
||||
{
|
||||
@ -12,14 +15,15 @@ namespace CardReaderService
|
||||
{
|
||||
private Thread _mainWorkThread;
|
||||
private bool _stopMainWorkerThread;
|
||||
private AutoResetEvent _mainWorkerTerminationSignal;
|
||||
private string _readerName = "";
|
||||
private readonly ManualResetEvent _mre;
|
||||
|
||||
private string _readerName = string.Empty;
|
||||
private SCardMonitor _cardMonitor;
|
||||
private bool _initialised=false;
|
||||
|
||||
public Service1()
|
||||
{
|
||||
InitializeComponent();
|
||||
_mre = new ManualResetEvent(false);
|
||||
}
|
||||
|
||||
public void Start()
|
||||
@ -27,44 +31,54 @@ namespace CardReaderService
|
||||
OnStart(new string[] { });
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
StartWorkerThread();
|
||||
}
|
||||
|
||||
private bool WeHaveValidCardReader()
|
||||
{
|
||||
if (_cardMonitor == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Console.WriteLine(_cardMonitor.GetCurrentState(0));
|
||||
if (_cardMonitor.GetCurrentState(0) == SCRState.Unknown
|
||||
|| _cardMonitor.GetCurrentState(0) == SCRState.Unavailable
|
||||
|| _cardMonitor.GetCurrentState(0) == (SCRState.Ignore | SCRState.Unavailable)
|
||||
//|| _cardMonitor.GetCurrentState(0) == SCRState.Unaware //if we say this is an invalid state, we cause a memory leak where we create a duplicate card monitor, subscribe and overwrite.
|
||||
)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
public new void Stop()
|
||||
{
|
||||
OnStop();
|
||||
base.Stop();
|
||||
}
|
||||
|
||||
protected override void OnStart(string[] args)
|
||||
{
|
||||
MessageLogger.Log("Starting.. ");
|
||||
var ctxFactory = ContextFactory.Instance;
|
||||
using (var context = ctxFactory.Establish(SCardScope.System))
|
||||
{
|
||||
MessageLogger.Log("Getting Card Readers");
|
||||
var readerNames = context.GetReaders();
|
||||
if (NoReaderAvailable(readerNames))
|
||||
{
|
||||
MessageLogger.Log("No Card Reader available, Exiting..");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageLogger.Log("Choosing first available reader: " + readerNames.First());
|
||||
_readerName = readerNames.First();
|
||||
_cardMonitor = new SCardMonitor(ctxFactory, SCardScope.System);
|
||||
_cardMonitor.CardInserted += CardMonitor_CardInserted;
|
||||
_cardMonitor.StatusChanged += CardMonitorOnStatusChanged;
|
||||
_cardMonitor.Start(_readerName);
|
||||
}
|
||||
StartWorkerThread();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnStop()
|
||||
{
|
||||
MessageLogger.Log("Stopping..");
|
||||
_stopMainWorkerThread = true;
|
||||
_mainWorkerTerminationSignal.Set();
|
||||
_mre.Set();
|
||||
if (_mainWorkThread != null && _mainWorkThread.IsAlive)
|
||||
{
|
||||
_mainWorkThread.Join(3000);
|
||||
if (_mainWorkThread.IsAlive)
|
||||
{
|
||||
_mainWorkThread.Interrupt();
|
||||
}
|
||||
}
|
||||
if (_cardMonitor != null)
|
||||
{
|
||||
_cardMonitor.CardInserted -= CardMonitor_CardInserted;
|
||||
_cardMonitor.StatusChanged -= CardMonitorOnStatusChanged;
|
||||
_cardMonitor.Cancel();
|
||||
_cardMonitor.Dispose();
|
||||
_cardMonitor = null;
|
||||
@ -79,96 +93,110 @@ namespace CardReaderService
|
||||
Name = "CardServiceMainThread",
|
||||
IsBackground = false
|
||||
};
|
||||
_mainWorkerTerminationSignal = new AutoResetEvent(false);
|
||||
_mainWorkThread.Start();
|
||||
}
|
||||
|
||||
private void _cardMonitor_CardInserted(object sender, CardStatusEventArgs e)
|
||||
private void CardMonitor_CardInserted(object sender, CardStatusEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ctxFac = ContextFactory.Instance;
|
||||
using (var ctx = ctxFac.Establish(SCardScope.System))
|
||||
{
|
||||
var reader = new SCardReader(ctx);
|
||||
var pioSendPci = new IntPtr();
|
||||
byte[] rcvBuffer = new byte[256];
|
||||
|
||||
if (_readerName == string.Empty)
|
||||
{
|
||||
Console.WriteLine("Reader name is somehow empty... WTF!");
|
||||
MessageLogger.Log("Reader name is somehow empty... WTF!");
|
||||
_stopMainWorkerThread = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var err = reader.Connect(_readerName, SCardShareMode.Shared, SCardProtocol.T0 | SCardProtocol.T1);
|
||||
|
||||
var err = reader.Connect(_readerName, SCardShareMode.Shared, SCardProtocol.Any);
|
||||
if (err == SCardError.Success)
|
||||
{
|
||||
var uIdcmd = new byte[] { 0xFF, 0xCA, 0x00, 0x00, 0x00 };
|
||||
var pci = SCardPCI.GetPci(reader.ActiveProtocol);
|
||||
|
||||
err = reader.Transmit(pci, CardCommands.GetUid, ref rcvBuffer);
|
||||
|
||||
err = reader.Transmit(pioSendPci, uIdcmd, ref rcvBuffer);
|
||||
if (err == SCardError.Success)
|
||||
{
|
||||
var uid = ConvertByteUIDToString(rcvBuffer);
|
||||
var atrString = ConvertByteUIDToString(e.Atr);
|
||||
Console.WriteLine("Card Inserted, ATR: " + atrString + ", and UID is: " + uid);
|
||||
|
||||
CardDataPost postObj = new CardDataPost { CardUId = uid };
|
||||
MessageLogger.Log("Card Inserted, ATR: " + atrString + ", and UID is: " + uid);
|
||||
|
||||
CardDataPost postObj = new CardDataPost { CardUId = uid, UtcTimeStamp = DateTime.UtcNow };
|
||||
DataCenterHelper.PostAsync(postObj, "/api/swipedata");
|
||||
Console.WriteLine("Posted to Server");
|
||||
MessageLogger.Log("Posted to Server");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageLogger.Log("Failed to Read UID, Error: " + err);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Reader failed to connect, error: " + Enum.GetName(typeof(SCardError), err));
|
||||
MessageLogger.Log("Reader failed to connect, error: " + Enum.GetName(typeof(SCardError), err));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageLogger.Log("Exception has occurred in Card Inserted Event handler. Exception: "+ ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private void MainWorkerThread()
|
||||
{
|
||||
var minimumLoopTimemS = 5000;
|
||||
|
||||
while (!_stopMainWorkerThread)
|
||||
{
|
||||
if (!WeHaveValidCardReader())
|
||||
{ //only do this if we don't have a valid card reader
|
||||
if (_initialised)
|
||||
if (_cardMonitor == null)
|
||||
{
|
||||
//card reader no longer available, tidy up.
|
||||
_cardMonitor.Cancel();
|
||||
_cardMonitor.CardInserted -= _cardMonitor_CardInserted;
|
||||
_cardMonitor.Dispose();
|
||||
_cardMonitor = null;
|
||||
_initialised = false;
|
||||
}
|
||||
Console.WriteLine("Starting.. Getting available readers");
|
||||
var ctxFactory = ContextFactory.Instance;
|
||||
using (var context = ctxFactory.Establish(SCardScope.System))
|
||||
{
|
||||
var readerNames = context.GetReaders();
|
||||
if (!NoReaderAvailable(readerNames))
|
||||
if (NoReaderAvailable(readerNames))
|
||||
{
|
||||
//we have a reader available, so initialise!
|
||||
Console.WriteLine("Choosing first available reader: " + readerNames.First());
|
||||
_readerName = readerNames.First();
|
||||
_cardMonitor = new SCardMonitor(ctxFactory, SCardScope.System);
|
||||
_cardMonitor.CardInserted += _cardMonitor_CardInserted;
|
||||
_cardMonitor.Start(_readerName);
|
||||
|
||||
_initialised = true;
|
||||
MessageLogger.Log("No Card Reader available, Waiting..");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("No Card Reader is available..");
|
||||
MessageLogger.Log("Choosing first available reader: " + readerNames.First());
|
||||
_readerName = readerNames.First();
|
||||
_cardMonitor = new SCardMonitor(ctxFactory, SCardScope.System);
|
||||
_cardMonitor.CardInserted += CardMonitor_CardInserted;
|
||||
_cardMonitor.StatusChanged += CardMonitorOnStatusChanged;
|
||||
_cardMonitor.Start(_readerName);
|
||||
}
|
||||
}
|
||||
}
|
||||
_mainWorkerTerminationSignal.WaitOne(3000);
|
||||
//dont actually need to do anything.. but cannot exit right away?
|
||||
_mre.WaitOne(minimumLoopTimemS);
|
||||
}
|
||||
}
|
||||
|
||||
private void CardMonitorOnStatusChanged(object sender, StatusChangeEventArgs e)
|
||||
{
|
||||
if ((e.NewState & SCRState.Unavailable) == SCRState.Unavailable && (e.NewState & SCRState.Ignore) == SCRState.Ignore)
|
||||
{
|
||||
Console.WriteLine("Card Reader Disconnected");
|
||||
_cardMonitor.CardInserted -= CardMonitor_CardInserted;
|
||||
_cardMonitor.Cancel();
|
||||
_cardMonitor.Dispose();
|
||||
_cardMonitor = null;
|
||||
_readerName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private string ConvertByteUIDToString(byte[] uid)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
foreach (var b in uid)
|
||||
{
|
||||
@ -183,4 +211,9 @@ namespace CardReaderService
|
||||
return readerNames == null || readerNames.Count < 1;
|
||||
}
|
||||
}
|
||||
|
||||
internal class CardCommands
|
||||
{
|
||||
public static readonly byte[] GetUid = {0xFF, 0xCA, 0x00, 0x00, 0x08};
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="PCSC" version="3.6.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net45" />
|
||||
<package id="PCSC" version="4.2.0" targetFramework="net45" />
|
||||
</packages>
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
@ -9,9 +9,10 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CardReaderServiceHost</RootNamespace>
|
||||
<AssemblyName>CardReaderServiceHost</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -33,8 +34,8 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\CardReaderService\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
@ -52,6 +53,18 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\CardReaderService.conf">
|
||||
<Link>CardReaderService.conf</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="..\install.sh">
|
||||
<Link>install.sh</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="..\uninstall.sh">
|
||||
<Link>uninstall.sh</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="App.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -9,7 +9,7 @@ namespace CardReaderServiceHost
|
||||
{
|
||||
Service1 service1 = new Service1();
|
||||
service1.Start();
|
||||
Console.WriteLine("Service Running...");
|
||||
Console.WriteLine("Service Running... Enter To Stop");
|
||||
Console.ReadLine();
|
||||
service1.Stop();
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net45" />
|
||||
</packages>
|
||||
55
CardReaderService/Logger/Logger.csproj
Normal file
55
CardReaderService/Logger/Logger.csproj
Normal file
@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{42EFE386-DC2E-455A-BA81-5FC9CEE45D02}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Logger</RootNamespace>
|
||||
<AssemblyName>Logger</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</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>
|
||||
<ItemGroup>
|
||||
<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>
|
||||
<Compile Include="MessageLogger.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
20
CardReaderService/Logger/MessageLogger.cs
Normal file
20
CardReaderService/Logger/MessageLogger.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Logger
|
||||
{
|
||||
public class MessageLogger
|
||||
{
|
||||
private static string _logPath = "log.txt";
|
||||
|
||||
public static void Log(string message)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
File.AppendAllText(_logPath, string.Format("{0} | {1}{2}", DateTime.Now, message, Environment.NewLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
36
CardReaderService/Logger/Properties/AssemblyInfo.cs
Normal file
36
CardReaderService/Logger/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Logger")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Logger")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2017")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("42efe386-dc2e-455a-ba81-5fc9cee45d02")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
7
CardReaderService/dependencies.txt
Normal file
7
CardReaderService/dependencies.txt
Normal file
@ -0,0 +1,7 @@
|
||||
install:
|
||||
- pcscd
|
||||
- supervisor
|
||||
- mono-complete
|
||||
|
||||
copy CardReaderService.conf to /home/osboxes/CardReaderService
|
||||
|
||||
25
CardReaderService/install.sh
Normal file
25
CardReaderService/install.sh
Normal file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "No arguments supplied, supply the base path"
|
||||
fi
|
||||
echo "Installing dependencies"
|
||||
apt-get install mono-complete pcscd supervisor -y
|
||||
|
||||
echo "Modifying supervisor conf file"
|
||||
sed -i "s|/DIRECTORYTOSET|$1|g" CardReaderService.conf
|
||||
|
||||
echo "Installing service configuration file"
|
||||
cp CardReaderService.conf /etc/supervisor/conf.d/
|
||||
|
||||
echo "Installing applicaton"
|
||||
mkdir $1/CardReaderService
|
||||
cp ./*.* $1/CardReaderService
|
||||
cd $1/CardReaderService
|
||||
rm *.pdb
|
||||
rm *.vshost.exe
|
||||
rm *.vshost.exe.config
|
||||
rm *.vshost.exe.manifest
|
||||
echo "Starting application........."
|
||||
service supervisor restart
|
||||
|
||||
12
CardReaderService/uninstall.sh
Normal file
12
CardReaderService/uninstall.sh
Normal file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "No arguments supplied, supply the base path"
|
||||
fi
|
||||
echo "Stopping service...."
|
||||
service supervisor stop
|
||||
rm -f /etc/supervisor/conf.d/CardReaderService.conf
|
||||
echo "Removing Application.."
|
||||
rm -r -f $1/CardReaderService
|
||||
echo "Removing application dependencies.."
|
||||
apt-get remove pcscd supervisor mono-complete -y
|
||||
@ -1,10 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml"/>
|
||||
<add key="DataCenterServiceEndpoint" value="http://localhost:8800"/>
|
||||
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml" />
|
||||
<add key="DataCenterServiceEndpoint" value="http://localhost:8800" />
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.4.0" newVersion="3.3.4.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@ -9,9 +9,10 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>CardReaderService</RootNamespace>
|
||||
<AssemblyName>CardReaderService</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@ -57,12 +58,12 @@
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.3.2.2.0\lib\net45-full\Ninject.dll</HintPath>
|
||||
<Reference Include="Ninject, Version=3.3.4.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.3.3.4\lib\net45\Ninject.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Extensions.Xml, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.Xml.3.2.0.0\lib\net45-full\Ninject.Extensions.Xml.dll</HintPath>
|
||||
<Reference Include="Ninject.Extensions.Xml, Version=3.3.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.Xml.3.3.0\lib\net45\Ninject.Extensions.Xml.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="pcsc-sharp, Version=3.6.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
@ -85,6 +86,7 @@
|
||||
<Compile Include="ConfigureService.cs" />
|
||||
<Compile Include="DataCenterHelper.cs" />
|
||||
<Compile Include="DefaultComponents\DefaultLogger.cs" />
|
||||
<Compile Include="DefaultComponents\LogFileLogger.cs" />
|
||||
<Compile Include="NinjectHelper.cs" />
|
||||
<Compile Include="CardReaderService.cs">
|
||||
<SubType>Component</SubType>
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Interfaces;
|
||||
|
||||
namespace CardReaderService.DefaultComponents
|
||||
{
|
||||
class LogFileLogger: ILogger
|
||||
{
|
||||
public bool IsDebugEnabled => true;
|
||||
public bool IsErrorEnabled => true;
|
||||
public bool IsFatalEnabled => true;
|
||||
public bool IsInfoEnabled => true;
|
||||
public bool IsTraceEnabled => true;
|
||||
public bool IsWarnEnabled => true;
|
||||
|
||||
public void Debug(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
}
|
||||
|
||||
public void Debug(string format, params object[] args)
|
||||
{
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Debug(Exception exception, string format, params object[] args)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Error(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
}
|
||||
|
||||
public void Error(string format, params object[] args)
|
||||
{
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Error(Exception exception, string format, params object[] args)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Fatal(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
}
|
||||
|
||||
public void Fatal(string format, params object[] args)
|
||||
{
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Fatal(Exception exception, string format, params object[] args)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Info(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
}
|
||||
|
||||
public void Info(string format, params object[] args)
|
||||
{
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Info(Exception exception, string format, params object[] args)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Trace(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
}
|
||||
|
||||
public void Trace(string format, params object[] args)
|
||||
{
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Trace(Exception exception, string format, params object[] args)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Warn(Exception exception)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
}
|
||||
|
||||
public void Warn(string format, params object[] args)
|
||||
{
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void Warn(Exception exception, string format, params object[] args)
|
||||
{
|
||||
Log(exception.ToString());
|
||||
Log(string.Format(format, args));
|
||||
}
|
||||
|
||||
private static string _logPath = "log.txt";
|
||||
|
||||
public static void Log(string message)
|
||||
{
|
||||
System.IO.File.WriteAllText(_logPath, string.Format("{0} | {1}", DateTime.Now, message));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<module name="NinjectAssemblies">
|
||||
<bind service="Interfaces.ILogger, Interfaces"
|
||||
to="NLogLogger.NLogger, NLogLogger" scope="singleton" />
|
||||
to="CardReaderService.DefaultComponents.LogFileLogger, CardReaderService" scope="singleton" />
|
||||
</module>
|
||||
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="Ninject" version="3.2.2.0" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.Xml" version="3.2.0.0" targetFramework="net452" />
|
||||
<package id="PCSC" version="3.6.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net45" />
|
||||
<package id="Ninject" version="3.3.4" targetFramework="net45" />
|
||||
<package id="Ninject.Extensions.Xml" version="3.3.0" targetFramework="net45" />
|
||||
<package id="PCSC" version="3.6.0" targetFramework="net45" />
|
||||
</packages>
|
||||
@ -1,10 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
</startup>
|
||||
<appSettings>
|
||||
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml"/>
|
||||
<add key="DataCenterServiceEndpoint" value="http://localhost:1234"/>
|
||||
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml" />
|
||||
<add key="DataCenterServiceEndpoint" value="http://localhost:1234" />
|
||||
</appSettings>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.4.0" newVersion="3.3.4.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@ -54,7 +54,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\CardReaderService\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
|
||||
@ -30,8 +30,18 @@
|
||||
<Component Id="SmartCardServiceConfig" Guid="{73D2E31D-F256-457C-AFD5-EC456CDAD7E8}" KeyPath="yes">
|
||||
<ServiceControl Id="SmartCardServiceStarter"
|
||||
Start="install"
|
||||
Stop="install"
|
||||
Name="SCardSvr"
|
||||
Wait="yes" />
|
||||
<ServiceConfig Id="SmartCardServiceSetToAuto"
|
||||
DelayedAutoStart="0" OnInstall="yes" ServiceName="SCardSvr"/>
|
||||
</Component>
|
||||
<Component Id="SCardAutoStart" Permanent="yes" KeyPath="yes" Guid="{75582D3C-C985-4BC9-A0A8-621A52C7E95E}">
|
||||
<RegistryKey Root="HKLM"
|
||||
Key="SYSTEM\CurrentControlSet\Services\SCardSvr"
|
||||
Action="create">
|
||||
<RegistryValue Type="integer" Name="Start" Value="2"/>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
<Component Id="CardReaderServiceExe" Guid="{24C9D834-21E2-476D-8302-EF35730D0BA8}">
|
||||
<File Id="CardReaderService.exe"
|
||||
@ -61,6 +71,7 @@
|
||||
ThirdFailureActionType="restart"
|
||||
ResetPeriodInDays="1"
|
||||
RestartServiceDelayInSeconds="10" />
|
||||
<ServiceDependency Id="SCardSvr" Group="no"/>
|
||||
</ServiceInstall>
|
||||
</Component>
|
||||
<Component Id="CardReaderServiceExeConfig" Guid="{E20D23BC-C8E7-49F8-962C-DE856A84258E}">
|
||||
|
||||
@ -9,8 +9,9 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ConfigurationHandler</RootNamespace>
|
||||
<AssemblyName>ConfigurationHandler</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
||||
@ -12,7 +12,7 @@ namespace Interfaces
|
||||
/// Returns <see cref="UserList"/> with full list of users,
|
||||
/// plus a total user count. Pagination options are supported.
|
||||
/// </returns>
|
||||
UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1);
|
||||
UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1, SortOptions sort = SortOptions.None);
|
||||
/// <summary>
|
||||
/// Search the user list for the following string
|
||||
/// </summary>
|
||||
@ -96,10 +96,12 @@ namespace Interfaces
|
||||
/// <see cref="Identifier"/> object with the Unique Id triggering the event
|
||||
/// </param>
|
||||
/// <param name="logId">The resultant Id of the inserted TimeLog</param>
|
||||
/// <param name="logTime">Optional - To set the log time of the swipe.
|
||||
/// <remarks>Particularly useful for buffering logs in nodes if they cannot contact server for whatever reason to minimise data loss</remarks></param>
|
||||
/// <returns>
|
||||
/// <see cref="OperationResponse"/> to indicate procedure status.
|
||||
/// </returns>
|
||||
LogEventResponse LogEventTime(Identifier identifier, out int logId);
|
||||
LogEventResponse LogEventTime(Identifier identifier, out int logId, DateTime logTime = default(DateTime));
|
||||
|
||||
OperationResponse CreateGroup(Group group, out int groupId);
|
||||
List<Group> GetGroups(int userId = -1);
|
||||
@ -110,5 +112,9 @@ namespace Interfaces
|
||||
OperationResponse DeleteLog(TimeLog log);
|
||||
OperationResponse CreateLog(TimeLog log);
|
||||
OperationResponse UpdateLog(TimeLog log);
|
||||
|
||||
Policy GetPolicy();
|
||||
|
||||
void SavePolicy(Policy policy);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,9 @@
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Interfaces</RootNamespace>
|
||||
<AssemblyName>Interfaces</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@ -69,7 +70,9 @@
|
||||
<Compile Include="IdentifierList.cs" />
|
||||
<Compile Include="ManualLog.cs" />
|
||||
<Compile Include="OperationResponse.cs" />
|
||||
<Compile Include="Policy.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SortOptions.cs" />
|
||||
<Compile Include="TimeLog.cs" />
|
||||
<Compile Include="TimeLogList.cs" />
|
||||
<Compile Include="User.cs" />
|
||||
|
||||
18
DataCenter_Windows/WindowsDataCenter/Interfaces/Policy.cs
Normal file
18
DataCenter_Windows/WindowsDataCenter/Interfaces/Policy.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Interfaces
|
||||
{
|
||||
public class Policy
|
||||
{
|
||||
public DateTime ChangeDate { get; set; }
|
||||
public string ChangeDescription { get; set; }
|
||||
public string ChangeAuthor { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string Markdown { get; set; }
|
||||
public string Html { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Interfaces
|
||||
{
|
||||
public enum SortOptions
|
||||
{
|
||||
None,
|
||||
FirstNameAscending,
|
||||
FirstNameDescending,
|
||||
LastNameAscending,
|
||||
LastNameDescending,
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Interfaces
|
||||
{
|
||||
@ -14,13 +15,15 @@ namespace Interfaces
|
||||
public int TotalUserCount { get; set; }
|
||||
public List<User> Users { get; set; }
|
||||
|
||||
public SortOptions SelectedSortOption { get; set; }
|
||||
|
||||
public int PageCount
|
||||
{
|
||||
get
|
||||
{
|
||||
if (TotalUserCount < PageSize)
|
||||
return 1;
|
||||
return (TotalUserCount / PageSize);
|
||||
return (int)Math.Ceiling(Convert.ToDouble(TotalUserCount) / Convert.ToDouble(PageSize));
|
||||
}
|
||||
}
|
||||
public Group GroupFilter { get; set; }
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
using Interfaces;
|
||||
|
||||
namespace SQLiteRepository.Converters
|
||||
{
|
||||
static class IdentifierConverter
|
||||
{
|
||||
public static Identifier ConvertToIdentifierDto(CardUniqueId ident)
|
||||
{
|
||||
return new Identifier
|
||||
{
|
||||
Id = ident.Id,
|
||||
UniqueId = ident.CardUId,
|
||||
IsAssociatedToUser = ident.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID,
|
||||
LastUsed = ident.LastUsed.DateTime
|
||||
};
|
||||
}
|
||||
|
||||
public static CardUniqueId ConvertFromIdentifierDto(Identifier ident, int userId)
|
||||
{
|
||||
return new CardUniqueId
|
||||
{
|
||||
CardUId = ident.UniqueId,
|
||||
Id = ident.Id,
|
||||
UserId_FK = userId,
|
||||
LastUsed = ident.LastUsed
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
using Interfaces;
|
||||
|
||||
namespace SQLiteRepository.Converters
|
||||
{
|
||||
static class LogDirectionConverter
|
||||
{
|
||||
public static LogDirection ConvertToLogDirectionDto(LogDirectionDb direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case LogDirectionDb.IN:
|
||||
return LogDirection.IN;
|
||||
case LogDirectionDb.OUT:
|
||||
return LogDirection.OUT;
|
||||
default:
|
||||
return LogDirection.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static LogDirectionDb ConvertFromLogDirectionDto(LogDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case LogDirection.IN:
|
||||
return LogDirectionDb.IN;
|
||||
case LogDirection.OUT:
|
||||
return LogDirectionDb.OUT;
|
||||
default:
|
||||
return LogDirectionDb.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static LogDirectionDb InvertLogDirectionDb(LogDirectionDb direction)
|
||||
{
|
||||
return (LogDirectionDb)(int)InvertLogDirection((LogDirection)(int)direction);
|
||||
}
|
||||
|
||||
public static LogDirection InvertLogDirection(LogDirection direction)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case LogDirection.IN:
|
||||
return LogDirection.OUT;
|
||||
case LogDirection.OUT:
|
||||
return LogDirection.IN;
|
||||
default:
|
||||
return LogDirection.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
using Interfaces;
|
||||
|
||||
namespace SQLiteRepository.Converters
|
||||
{
|
||||
static class LogSourceConverter
|
||||
{
|
||||
public static LogSource ConvertToLogSourceDto(LogSourceDb source)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case LogSourceDb.IDENTIFIER:
|
||||
return LogSource.IDENTIFIER;
|
||||
case LogSourceDb.TRAYAPP:
|
||||
return LogSource.TRAYAPP;
|
||||
case LogSourceDb.UI:
|
||||
return LogSource.UI;
|
||||
default:
|
||||
return LogSource.UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
public static LogSourceDb ConvertFromLogSourceDto(LogSource source)
|
||||
{
|
||||
switch (source)
|
||||
{
|
||||
case LogSource.IDENTIFIER:
|
||||
return LogSourceDb.IDENTIFIER;
|
||||
case LogSource.TRAYAPP:
|
||||
return LogSourceDb.TRAYAPP;
|
||||
case LogSource.UI:
|
||||
return LogSourceDb.UI;
|
||||
default:
|
||||
return LogSourceDb.UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
using Interfaces;
|
||||
|
||||
namespace SQLiteRepository.Converters
|
||||
{
|
||||
static class PolicyConverter
|
||||
{
|
||||
public static Policy ConvertToPolicyDto(PolicyDb policyDb)
|
||||
{
|
||||
if (policyDb == null) return null;
|
||||
return new Policy
|
||||
{
|
||||
ChangeDescription = policyDb.ChangeDescription,
|
||||
ChangeDate = policyDb.ChangeDate.UtcDateTime,
|
||||
Html = policyDb.Html,
|
||||
Version = policyDb.Version,
|
||||
ChangeAuthor = policyDb.ChangeAuthor,
|
||||
Markdown = policyDb.Markdown
|
||||
};
|
||||
}
|
||||
|
||||
public static PolicyDb ConvertFromPolicyDto(Policy policy)
|
||||
{
|
||||
if (policy == null) return null;
|
||||
return new PolicyDb
|
||||
{
|
||||
ChangeDescription = policy.ChangeDescription,
|
||||
ChangeDate = policy.ChangeDate,
|
||||
Html = policy.Html,
|
||||
Version = policy.Version,
|
||||
ChangeAuthor = policy.ChangeAuthor,
|
||||
Markdown = policy.Markdown
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Interfaces;
|
||||
|
||||
namespace SQLiteRepository.Converters
|
||||
{
|
||||
static class TimeLogConverter
|
||||
{
|
||||
public static TimeLog ConvertToTimeLogDto(TimeLogDb log)
|
||||
{
|
||||
return new TimeLog
|
||||
{
|
||||
CalendarWeek = log.CalendarWeek,
|
||||
Direction = LogDirectionConverter.ConvertToLogDirectionDto(log.Direction),
|
||||
EventTime = log.SwipeEventDateTime,
|
||||
Id = log.Id,
|
||||
IdentifierId = log.IdentifierId,
|
||||
UserId = log.UserId_FK,
|
||||
Source = LogSourceConverter.ConvertToLogSourceDto(log.Source),
|
||||
Year = log.Year
|
||||
};
|
||||
}
|
||||
|
||||
public static TimeLogDb ConvertFromTimeLogDto(TimeLog log)
|
||||
{
|
||||
return new TimeLogDb
|
||||
{
|
||||
CalendarWeek = log.CalendarWeek,
|
||||
Year = log.Year,
|
||||
UserId_FK = log.UserId,
|
||||
IdentifierId = log.IdentifierId,
|
||||
Direction = LogDirectionConverter.ConvertFromLogDirectionDto(log.Direction),
|
||||
Id = log.Id,
|
||||
Source = LogSourceConverter.ConvertFromLogSourceDto(log.Source),
|
||||
SwipeEventDateTime = log.EventTime
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Interfaces;
|
||||
|
||||
namespace SQLiteRepository.Converters
|
||||
{
|
||||
static class UserConverter
|
||||
{
|
||||
public static User ConvertToUserDto(UserIdentity user)
|
||||
{
|
||||
return new User
|
||||
{
|
||||
UserId = user.Id,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
IsContractor = user.IsContractor,
|
||||
HoursPerWeek = user.HoursPerWeek,
|
||||
};
|
||||
}
|
||||
|
||||
public static UserIdentity ConvertFromUserDto(User user)
|
||||
{
|
||||
return new UserIdentity
|
||||
{
|
||||
Id = user.UserId,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
HoursPerWeek = user.HoursPerWeek,
|
||||
IsContractor = user.IsContractor
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SQLiteRepository.Extensions
|
||||
{
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
public static IEnumerable<TSource> Exclude<TSource, TKey>(this IEnumerable<TSource> source,
|
||||
IEnumerable<TSource> exclude, Func<TSource, TKey> keySelector)
|
||||
{
|
||||
var excludedSet = new HashSet<TKey>(exclude.Select(keySelector));
|
||||
return source.Where(item => !excludedSet.Contains(keySelector(item)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using SQLite.Net.Attributes;
|
||||
|
||||
namespace SQLiteRepository
|
||||
{
|
||||
internal class PolicyDb
|
||||
{
|
||||
[PrimaryKey, AutoIncrement]
|
||||
public int Id { get; set; }
|
||||
public DateTimeOffset ChangeDate { get; set; }
|
||||
|
||||
public string ChangeDescription { get; set; }
|
||||
|
||||
public string ChangeAuthor { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public string Markdown { get; set; }
|
||||
|
||||
public string Html { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,9 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Design;
|
||||
using System.Linq;
|
||||
|
||||
namespace SQLiteRepository
|
||||
{
|
||||
internal static class SQLiteProcedures
|
||||
{
|
||||
public const string GET_LOGS_IN_LAST_X_MINUTES =
|
||||
"select * from TimeLogDb where " + nameof(TimeLogDb.SwipeEventDateTime) + " > ? AND " +
|
||||
"select * from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.SwipeEventDateTime) + " > ? AND " +
|
||||
nameof(TimeLogDb.UserId_FK) + "=?";
|
||||
|
||||
public const string GET_TIMELOGS =
|
||||
@ -22,9 +27,7 @@ namespace SQLiteRepository
|
||||
+ "select " + nameof(GroupDb.GroupId)
|
||||
+ " from " + nameof(GroupDb)
|
||||
+ " where " + nameof(GroupDb.GroupName) + " = 'Archived') )"
|
||||
+ "order by "
|
||||
+ nameof(UserIdentity.LastName) + " collate nocase, "
|
||||
+ nameof(UserIdentity.FirstName) + " collate nocase";
|
||||
+ "order by ? collate nocase ?, ? collate nocase ?";
|
||||
|
||||
public const string GET_ALL_USERS_PAGINATE =
|
||||
"select * from " + nameof(UserIdentity) + " ut "
|
||||
@ -38,18 +41,18 @@ namespace SQLiteRepository
|
||||
+ "select " + nameof(GroupDb.GroupId)
|
||||
+ " from " + nameof(GroupDb)
|
||||
+ " where " + nameof(GroupDb.GroupName) + " = 'Archived') )"
|
||||
+ "order by "
|
||||
+ nameof(UserIdentity.LastName) + " collate nocase, "
|
||||
+ nameof(UserIdentity.FirstName) + " collate nocase "
|
||||
+ "limit ? offset ?";
|
||||
+ " order by "
|
||||
+ "{0} collate nocase {1}, "
|
||||
+ "{2} collate nocase {3} "
|
||||
+ "limit {4} offset {5}";
|
||||
|
||||
public const string GET_ALL_USERS_BY_GROUP =
|
||||
"select u." + nameof(UserIdentity.Id) + ", u." + nameof(UserIdentity.FirstName) + ", u." +
|
||||
nameof(UserIdentity.LastName) + ", u." + nameof(UserIdentity.HoursPerWeek) + ", u." +
|
||||
nameof(UserIdentity.IsContractor) + " from " + nameof(UserIdentity) + " u left join " +
|
||||
nameof(UserGroupJoinDb) + " ugj on ugj." + nameof(UserGroupJoinDb.UserId_FK) + " = u." +
|
||||
nameof(UserIdentity.Id) + " where ugj." + nameof(UserGroupJoinDb.GroupId_FK) + "=? order by u." +
|
||||
nameof(UserIdentity.LastName) + " collate nocase, u." + nameof(UserIdentity.LastName) + " collate nocase";
|
||||
nameof(UserIdentity.Id) + " where ugj." + nameof(UserGroupJoinDb.GroupId_FK) + "= {0} " +
|
||||
"order by u.{1} collate nocase {2}, u.{3} collate nocase {4}";
|
||||
|
||||
public const string GET_USER_BY_ID =
|
||||
"select * from " + nameof(UserIdentity) + " where " + nameof(UserIdentity.Id) + "=?";
|
||||
@ -60,6 +63,9 @@ namespace SQLiteRepository
|
||||
public const string GET_CARDS_BY_UNIQUE_ID =
|
||||
"select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.CardUId) + "=?";
|
||||
|
||||
public const string GET_CARDS_BY_UNIQUE_ID_LIST =
|
||||
"select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.CardUId) + " in (#IN#)";
|
||||
|
||||
public const string GET_UNASSIGNED_CARD_LIST =
|
||||
"select * from " + nameof(CardUniqueId) + " where " + nameof(CardUniqueId.UserId_FK) + "=?";
|
||||
|
||||
@ -88,9 +94,82 @@ namespace SQLiteRepository
|
||||
nameof(TimeLogDb.SwipeEventDateTime) + " desc LIMIT 1";
|
||||
|
||||
public const string GET_TOTAL_USER_COUNT =
|
||||
"select Max(" + nameof(UserIdentity.Id) + ") from " + nameof(UserIdentity);
|
||||
"select count(1) from " + nameof(UserIdentity) + " ut "
|
||||
+ "where "
|
||||
+ "EXISTS( select " + nameof(GroupDb.GroupId)
|
||||
+ " from " + nameof(GroupDb)
|
||||
+ " where " + nameof(GroupDb.GroupName) + " = 'Archived') "
|
||||
+ "AND NOT EXISTS( select * from " + nameof(UserGroupJoinDb) + " ugp where "
|
||||
+ nameof(UserGroupJoinDb.UserId_FK) + " = ut.Id"
|
||||
+ " and " + nameof(UserGroupJoinDb.GroupId_FK) + " = ( "
|
||||
+ "select " + nameof(GroupDb.GroupId)
|
||||
+ " from " + nameof(GroupDb)
|
||||
+ " where " + nameof(GroupDb.GroupName) + " = 'Archived') )";
|
||||
//"select Max(" + nameof(UserIdentity.Id) + ") from " + nameof(UserIdentity);
|
||||
|
||||
public const string GET_USER_CONTRACTED_HOURS =
|
||||
"select " + nameof(UserIdentity.HoursPerWeek) + " From UserIdentity where " + nameof(UserIdentity.Id) + "=?";
|
||||
|
||||
public const string GET_GROUPS = "select gp."+ nameof(GroupDb.GroupId)+ ", gp."+nameof(GroupDb.GroupName)+", " +
|
||||
"sum(case when gp." + nameof(GroupDb.GroupId) + " = ujdb." + nameof(UserGroupJoinDb.GroupId_FK) + " then 1 else 0 end) as " + nameof(GroupDb.AssignedUserCount) +
|
||||
" from " + nameof(GroupDb) + " gp" +
|
||||
" left join " + nameof(UserGroupJoinDb) + " ujdb " +
|
||||
"on ujdb." + nameof(UserGroupJoinDb.GroupId_FK) + " = gp." + nameof(GroupDb.GroupId) +
|
||||
" group by gp." + nameof(GroupDb.GroupId);
|
||||
|
||||
public const string GET_GROUPS_FOR_USER = "select gdb." + nameof(GroupDb.GroupId) + ", gdb." + nameof(GroupDb.GroupName) + ", gdb." + nameof(GroupDb.AssignedUserCount) + "" +
|
||||
" from " + nameof(GroupDb) + " gdb" +
|
||||
" left join " + nameof(UserGroupJoinDb) + " ujdb" +
|
||||
" on gdb." + nameof(GroupDb.GroupId) + " = ujdb." + nameof(UserGroupJoinDb.GroupId_FK) +
|
||||
" where ujdb." + nameof(UserGroupJoinDb.UserId_FK) + " = ?";
|
||||
|
||||
public const string GET_GROUP_BY_ID =
|
||||
"select * from " + nameof(GroupDb) + " where " + nameof(GroupDb.GroupId) + " =?";
|
||||
|
||||
public const string UPDATE_GROUP = "update " + nameof(GroupDb) + " set " + nameof(GroupDb.GroupName) +
|
||||
"=? where " + nameof(GroupDb.GroupId) + "=?";
|
||||
|
||||
public const string GET_GROUP_BY_NAME =
|
||||
"select 1 from " + nameof(GroupDb)+" where "+nameof(GroupDb.GroupName)+"= ?";
|
||||
|
||||
public const string GET_TIMELOG_ENTRY =
|
||||
"select * from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "=?";
|
||||
|
||||
public const string DELETE_TIMELOG_ENTRY =
|
||||
"delete from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "=?";
|
||||
|
||||
public const string DELETE_TIMELOG_ENTRIES =
|
||||
"delete from " + nameof(TimeLogDb) + " where " + nameof(TimeLogDb.Id) + "in (#IN#)";
|
||||
|
||||
public const string UPDATE_TIMELOG_ENTRY = "update " + nameof(TimeLogDb)
|
||||
+ " set " + nameof(TimeLogDb.UserId_FK) + "=?, "
|
||||
+ nameof(TimeLogDb.Direction) + "=?,"
|
||||
+ nameof(TimeLogDb.SwipeEventDateTime) + "=?,"
|
||||
+ nameof(TimeLogDb.CalendarWeek) + "=?,"
|
||||
+ nameof(TimeLogDb.Year) + "=?,"
|
||||
+ nameof(TimeLogDb.Source) + "=? "
|
||||
+ "where " + nameof(TimeLogDb.Id) + "=?";
|
||||
|
||||
public const string GET_DB_VERSION = "select * from " + nameof(DbVersion);
|
||||
|
||||
/// <summary>
|
||||
/// This works on the tokenisation of the query string.
|
||||
/// where the list of params is to be inserted, the query should have #IN#
|
||||
/// </summary>
|
||||
/// <param name="query">the query to add the list of parameters to</param>
|
||||
/// <param name="args">the parameters to add to the query.</param>
|
||||
/// <returns></returns>
|
||||
public static string FormatInQuery(string query, List<string> args)
|
||||
{
|
||||
if (!query.Contains("#IN#"))
|
||||
{
|
||||
throw new ArgumentException("query doesnt contain any #IN# tokenisation");
|
||||
}
|
||||
//Convert to a comma separated list e.g.: val1,val2,val3
|
||||
//but we need to use string.. so.. enclose in single quotes 'val1','val2'..etc
|
||||
var argsFormatted = string.Join(",", args.Select(x=>$"'{x}'"));
|
||||
|
||||
return query.Replace("#IN#", argsFormatted);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,8 @@ using System.Reflection;
|
||||
using Interfaces;
|
||||
using SQLite.Net;
|
||||
using SQLite.Net.Platform.Win32;
|
||||
using SQLiteRepository.Converters;
|
||||
using SQLiteRepository.Extensions;
|
||||
using SQLiteRepository.Properties;
|
||||
|
||||
namespace SQLiteRepository
|
||||
@ -16,12 +18,14 @@ namespace SQLiteRepository
|
||||
{
|
||||
private readonly SQLiteConnection _connection;
|
||||
private readonly ILogger _logger;
|
||||
private string _path = "flexitimedb.db";
|
||||
private readonly string _path;
|
||||
private const string DATABASE_NAME = "flexitimedb.db";
|
||||
private const string UPGRADE_SCRIPT_PREFIX = "SQLiteRepository.UpgradeScripts.";
|
||||
|
||||
public SQLiteRepository(ILogger logger)
|
||||
{
|
||||
_path =
|
||||
new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), "flexitimedb.db"))
|
||||
new Uri(Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().CodeBase), DATABASE_NAME))
|
||||
.LocalPath;
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
_logger = logger;
|
||||
@ -34,96 +38,20 @@ namespace SQLiteRepository
|
||||
_connection.CreateTable<GroupDb>();
|
||||
_connection.CreateTable<UserGroupJoinDb>();
|
||||
_connection.CreateTable<DbVersion>();
|
||||
_connection.CreateTable<PolicyDb>();
|
||||
|
||||
_logger.Trace("Initialised SQLite Repository");
|
||||
_logger.Trace("Checking For Upgrades");
|
||||
CheckForDbUpgrade();
|
||||
}
|
||||
|
||||
private void CheckForDbUpgrade()
|
||||
{
|
||||
var data = _connection.Query<DbVersion>("select * from DbVersion");
|
||||
if (!data.Any())
|
||||
{
|
||||
//Pre-Upgrade database, need upgrading
|
||||
_logger.Trace("Pre version 0.2 RC database found, performing update..");
|
||||
ExecuteUpgradeFromVersion("0.1"); //execute 0.2 upgrade scripts onwards.
|
||||
}
|
||||
else
|
||||
{
|
||||
var installedVersion = new Version(data.First().VersionNumber);
|
||||
var currentVersion = new Version(AssemblyInfo.ASSEMBLY_VERSION);
|
||||
if (currentVersion.CompareTo(installedVersion) > 0) //greater than 0 - current version is newer
|
||||
{
|
||||
_logger.Trace("Installed Database Version: {0} is older than current version {1}");
|
||||
ExecuteUpgradeFromVersion(installedVersion.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteUpgradeFromVersion(string installedVersion)
|
||||
{
|
||||
const string PREFIX = "SQLiteRepository.UpgradeScripts.";
|
||||
var instVers = new Version(installedVersion);
|
||||
//so we have established that each script for upgrade will be <version>.sql, so now start at lowest version and work up!
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var upgradeScripts = assembly.GetManifestResourceNames()
|
||||
.Where(x=>x.StartsWith(PREFIX))
|
||||
.OrderBy(x=>new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, ""))))
|
||||
.Where(x =>
|
||||
{
|
||||
var scriptVersion = new Version(Path.GetFileNameWithoutExtension(x.Replace(PREFIX, ""))).CompareTo(instVers);
|
||||
return scriptVersion > 0;
|
||||
}
|
||||
)
|
||||
.ToList();
|
||||
//now have an ordered list of upgrade script files, so execute in order!
|
||||
foreach (var upgradeScript in upgradeScripts)
|
||||
{
|
||||
using (var stream = assembly.GetManifestResourceStream(upgradeScript))
|
||||
using(var str = new StreamReader(stream))
|
||||
{
|
||||
var script = str.ReadToEnd();
|
||||
_logger.Trace("Executing upgrade script with name: {0}", upgradeScript);
|
||||
_connection.Execute(script);
|
||||
}
|
||||
}
|
||||
SetDbVersion(AssemblyInfo.ASSEMBLY_VERSION);
|
||||
}
|
||||
|
||||
private void SetDbVersion(string vers)
|
||||
{
|
||||
_connection.DeleteAll<DbVersion>();
|
||||
_connection.Insert(new DbVersion {VersionNumber = vers});
|
||||
_logger.Trace("Set Database version to: {0}", vers);
|
||||
}
|
||||
|
||||
public UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1)
|
||||
public UserList GetUsers(int pageNumber = -1, int pageSize = -1, int groupId = -1, SortOptions sort = SortOptions.None)
|
||||
{
|
||||
var ret = new UserList();
|
||||
List<UserIdentity> users;
|
||||
int userCount;
|
||||
if (pageNumber != -1 && pageSize != -1)
|
||||
{
|
||||
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS_PAGINATE,
|
||||
pageSize, (pageNumber - 1) * pageSize);
|
||||
userCount = _connection.ExecuteScalar<int>(SQLiteProcedures.GET_TOTAL_USER_COUNT);
|
||||
}
|
||||
else if (groupId != -1)
|
||||
{
|
||||
users =
|
||||
_connection.Query<UserIdentity>(
|
||||
SQLiteProcedures.GET_ALL_USERS_BY_GROUP,
|
||||
groupId);
|
||||
userCount = users.Count;
|
||||
}
|
||||
else
|
||||
{
|
||||
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS);
|
||||
userCount = users.Count;
|
||||
}
|
||||
List<UserIdentity> users = GetUserList(groupId, pageSize, pageNumber, sort);
|
||||
|
||||
var userCount = GetUserCount();
|
||||
|
||||
if (!users.Any())
|
||||
{
|
||||
if (pageNumber == -1 && pageSize == -1)
|
||||
{
|
||||
ret.PageNumber = 1;
|
||||
@ -134,12 +62,15 @@ namespace SQLiteRepository
|
||||
ret.PageNumber = pageNumber;
|
||||
ret.PageSize = pageSize;
|
||||
}
|
||||
|
||||
if (!users.Any())
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
var userObj = ChangeToUserObject(user);
|
||||
var userObj = UserConverter.ConvertToUserDto(user);
|
||||
|
||||
userObj.AssociatedIdentifiers = GetAssociatedIdentifiers(user.Id);
|
||||
userObj.State = GetUserState(GetLogDirection(user.Id));
|
||||
@ -147,16 +78,7 @@ namespace SQLiteRepository
|
||||
userObj.Groups = GetGroups(user.Id);
|
||||
ret.Users.Add(userObj);
|
||||
}
|
||||
if (pageNumber == -1 && pageSize == -1)
|
||||
{
|
||||
ret.PageSize = 10;
|
||||
ret.PageNumber = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.PageSize = pageSize;
|
||||
ret.PageNumber = pageNumber;
|
||||
}
|
||||
|
||||
ret.TotalUserCount = userCount;
|
||||
return ret;
|
||||
}
|
||||
@ -180,26 +102,20 @@ namespace SQLiteRepository
|
||||
|
||||
foreach (var user in users)
|
||||
{
|
||||
var userObj = ChangeToUserObject(user);
|
||||
var userObj = UserConverter.ConvertToUserDto(user);
|
||||
var cards = _connection.Query<CardUniqueId>(
|
||||
SQLiteProcedures.GET_CARDS_BY_USER_ID,
|
||||
user.Id);
|
||||
|
||||
foreach (var card in cards)
|
||||
{
|
||||
userObj.AssociatedIdentifiers.Add(new Identifier()
|
||||
{
|
||||
UniqueId = card.CardUId,
|
||||
IsAssociatedToUser = true,
|
||||
Id = card.Id
|
||||
});
|
||||
userObj.AssociatedIdentifiers.Add(IdentifierConverter.ConvertToIdentifierDto(card));
|
||||
}
|
||||
userObj.State = GetUserState(GetLogDirection(user.Id));
|
||||
ret.Users.Add(userObj);
|
||||
}
|
||||
//TODO: figure out paging here. - should there be any?
|
||||
ret.PageSize = 20;
|
||||
ret.PageNumber = 1;
|
||||
ret.PageNumber = (int)Math.Ceiling((double)ret.Users.Count / (double)ret.PageSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -217,7 +133,7 @@ namespace SQLiteRepository
|
||||
if (!users.Any()) return ret;
|
||||
|
||||
var user = users.First();
|
||||
ret = ChangeToUserObject(user);
|
||||
ret = UserConverter.ConvertToUserDto(user);
|
||||
ret.Groups = GetGroups();
|
||||
var usersGroups = GetGroups(user.Id);
|
||||
foreach (var group in usersGroups)
|
||||
@ -230,7 +146,7 @@ namespace SQLiteRepository
|
||||
|
||||
foreach (var card in cards)
|
||||
{
|
||||
ret.AssociatedIdentifiers.Add(new Identifier { UniqueId = card.CardUId, IsAssociatedToUser = true, Id = card.Id });
|
||||
ret.AssociatedIdentifiers.Add(IdentifierConverter.ConvertToIdentifierDto(card));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -298,86 +214,53 @@ namespace SQLiteRepository
|
||||
|
||||
foreach (var card in cardQuery)
|
||||
{
|
||||
ret.data.Add(new Identifier
|
||||
{
|
||||
Id = card.Id,
|
||||
IsAssociatedToUser = card.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID,
|
||||
UniqueId = card.CardUId,
|
||||
LastUsed = card.LastUsed.DateTime
|
||||
});
|
||||
ret.data.Add(IdentifierConverter.ConvertToIdentifierDto(card));
|
||||
// new Identifier
|
||||
//{
|
||||
// Id = card.Id,
|
||||
// IsAssociatedToUser = card.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID,
|
||||
// UniqueId = card.CardUId,
|
||||
// LastUsed = card.LastUsed.DateTime
|
||||
//});
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void ClearUnassignedIdentifiers()
|
||||
{
|
||||
var unassignedIdentifiers = _connection.Query<CardUniqueId>(SQLiteProcedures.GET_UNASSIGNED_CARD_LIST);
|
||||
|
||||
//remove the logs from the timelog db
|
||||
_connection.Query<TimeLogDb>(
|
||||
SQLiteProcedures.FormatInQuery(SQLiteProcedures.DELETE_TIMELOG_ENTRIES,
|
||||
unassignedIdentifiers.Select(x => x.Id.ToString()).ToList()));
|
||||
|
||||
//now remove the unassigned identifiers/cards
|
||||
_connection.Execute(
|
||||
SQLiteProcedures.CLEAR_UNASSIGNED_CARDS,
|
||||
Constants.UNASSIGNED_CARD_USER_ID);
|
||||
}
|
||||
|
||||
//TODO: Check time logs table on update to ensure associated cards/unique identifiers are removed/added as appropriate.
|
||||
public OperationResponse UpdateUser(User user, out int userIdResult)
|
||||
{
|
||||
//if(user.UserId <=0) return OperationResponse.FAILED;
|
||||
|
||||
var ret = OperationResponse.NONE;
|
||||
var cardIds = new List<int>();
|
||||
|
||||
//Get a list of current associated identifiers, convert into a list of Identifier Objects..
|
||||
var currentCards =
|
||||
_connection.Query<CardUniqueId>(SQLiteProcedures.GET_CARDS_BY_USER_ID, user.UserId)
|
||||
.Select(x => new Identifier { Id = x.Id, IsAssociatedToUser = true, UniqueId = x.CardUId });
|
||||
var cardsToRemove = currentCards.Except(user.AssociatedIdentifiers).Select(x => x.Id).ToList();
|
||||
|
||||
#region GetUnique Identifiers
|
||||
foreach (var card in user.AssociatedIdentifiers)
|
||||
{
|
||||
var existingCard = _connection.Query<CardUniqueId>(
|
||||
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID, card.UniqueId);
|
||||
|
||||
if (!existingCard.Any())
|
||||
{
|
||||
var cardInsert = new CardUniqueId { CardUId = card.UniqueId, UserId_FK = -1 };
|
||||
_connection.Insert(cardInsert);
|
||||
cardIds.Add(cardInsert.Id);
|
||||
if (ret < OperationResponse.CREATED)
|
||||
ret = OperationResponse.CREATED; //only change it if my status supercedes.
|
||||
}
|
||||
else
|
||||
{
|
||||
cardIds.Add(existingCard.First().Id);
|
||||
if (ret < OperationResponse.UPDATED)
|
||||
ret = OperationResponse.UPDATED;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
.Select(IdentifierConverter.ConvertToIdentifierDto).ToList();
|
||||
var cardsToRemove = currentCards.Exclude(user.AssociatedIdentifiers, x => x.Id).Select(x => x.Id).ToList();
|
||||
|
||||
#region Update/Create User
|
||||
int userId;
|
||||
|
||||
if (user.UserId != -1)
|
||||
{
|
||||
//edit..
|
||||
_connection.Query<UserIdentity>(
|
||||
SQLiteProcedures.UPDATE_USER_DETAILS,
|
||||
user.FirstName,
|
||||
user.LastName,
|
||||
user.HoursPerWeek,
|
||||
user.IsContractor,
|
||||
user.UserId
|
||||
);
|
||||
UpdateUserDetails(user.FirstName, user.LastName, user.HoursPerWeek, user.IsContractor, user.UserId);
|
||||
userId = user.UserId;
|
||||
}
|
||||
else
|
||||
{
|
||||
var userInsert = new UserIdentity
|
||||
{
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
HoursPerWeek = user.HoursPerWeek,
|
||||
IsContractor = user.IsContractor
|
||||
};
|
||||
var userInsert = UserConverter.ConvertFromUserDto(user);
|
||||
_connection.Insert(userInsert);
|
||||
userId = userInsert.Id;
|
||||
if (ret < OperationResponse.CREATED)
|
||||
@ -385,19 +268,32 @@ namespace SQLiteRepository
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Update Card/Unique Id entries.
|
||||
foreach (var cardId in cardIds)
|
||||
#region GetUnique Identifiers
|
||||
|
||||
var existingCards = _connection.Query<CardUniqueId>(SQLiteProcedures.FormatInQuery(
|
||||
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID_LIST,
|
||||
user.AssociatedIdentifiers.Select(x => x.UniqueId.ToString()).ToList()));
|
||||
|
||||
foreach (var card in user.AssociatedIdentifiers)
|
||||
{
|
||||
_connection.Query<CardUniqueId>(
|
||||
SQLiteProcedures.UPDATE_CARD_USER_ID,
|
||||
userId, cardId);
|
||||
}
|
||||
foreach (var card in cardsToRemove)
|
||||
if (existingCards.All(x => x.CardUId != card.UniqueId))
|
||||
{
|
||||
_connection.Query<CardUniqueId>(
|
||||
SQLiteProcedures.UPDATE_CARD_USER_ID,
|
||||
-1, card);
|
||||
//this card is not currently in the system..
|
||||
var cardInsert = IdentifierConverter.ConvertFromIdentifierDto(card, user.UserId);
|
||||
_connection.Insert(cardInsert);
|
||||
existingCards.Add(cardInsert);
|
||||
if (ret < OperationResponse.CREATED)
|
||||
ret = OperationResponse.CREATED; //only change it if my status supercedes.
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Update Card/Unique Id entries/associations
|
||||
//make sure all identifiers are associated to the right user
|
||||
UpdateIdentifierUserId(existingCards.Select(x => x.Id).ToList(), userId);
|
||||
|
||||
//make sure to remove all identifiers that have been deselected in edit are removed from user
|
||||
UpdateIdentifierUserId(cardsToRemove, Constants.UNASSIGNED_CARD_USER_ID);
|
||||
#endregion
|
||||
|
||||
#region Update Group Associations
|
||||
@ -410,8 +306,20 @@ namespace SQLiteRepository
|
||||
return ret;
|
||||
}
|
||||
|
||||
public LogEventResponse LogEventTime(Identifier identifier, out int logId)
|
||||
public LogEventResponse LogEventTime(Identifier identifier, out int logId, DateTime logTime = default(DateTime))
|
||||
{
|
||||
#region Set the LogTime before we start querying anything.
|
||||
if (logTime == default(DateTime))
|
||||
{
|
||||
logTime = DateTime.UtcNow;
|
||||
_logger.Debug("Using own log time: {0}", logTime.ToString("o"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug("Using supplied log time: {0}", logTime.ToString("o"));
|
||||
}
|
||||
#endregion
|
||||
|
||||
var ret = new LogEventResponse();
|
||||
var cardIdQuery = _connection.Query<CardUniqueId>(
|
||||
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID,
|
||||
@ -428,15 +336,15 @@ namespace SQLiteRepository
|
||||
UpdateIdentifierLastUsed(DateTimeOffset.UtcNow, ident.Id);
|
||||
logId = -1;
|
||||
//dont try to log any timelogs against this card, as it is unassigned to a user.
|
||||
ret.ProcessResponse=OperationResponse.SUCCESS;
|
||||
ret.ProcessResponse = OperationResponse.SUCCESS;
|
||||
ret.Direction = LogDirection.UNKNOWN;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: log when more than one comes back. should NEVER happen but....
|
||||
|
||||
ident = cardIdQuery.First();
|
||||
}
|
||||
_logger.Warn("More than 1 Identifier returned with ID {0}, card ids returned: {2}",
|
||||
ident.CardUId,
|
||||
string.Join(",", cardIdQuery.Select(x => x.CardUId).ToList()));
|
||||
#endregion
|
||||
|
||||
// Get The User Direction (are they going in or out)?
|
||||
@ -465,7 +373,7 @@ namespace SQLiteRepository
|
||||
#endregion
|
||||
|
||||
#region Get the current time (for swiping). and calendar week/year to help recall the data.
|
||||
var logTime = DateTime.UtcNow;
|
||||
|
||||
var calendarWeek = GetIso8601CalendarWeek(logTime);
|
||||
var year = logTime.Year;
|
||||
#endregion
|
||||
@ -490,10 +398,14 @@ namespace SQLiteRepository
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Groups*/
|
||||
//TODO: check group name can only be entered once.
|
||||
public OperationResponse CreateGroup(Group group, out int groupId)
|
||||
{
|
||||
var query = _connection.Query<GroupDb>(SQLiteProcedures.GET_GROUP_BY_NAME, group.Name);
|
||||
if (query.Any())
|
||||
{
|
||||
groupId = query[0].GroupId;
|
||||
return OperationResponse.NONE;
|
||||
}
|
||||
var groupDb = new GroupDb { GroupName = group.Name };
|
||||
var resp = _connection.Insert(groupDb);
|
||||
groupId = groupDb.GroupId;
|
||||
@ -506,22 +418,12 @@ namespace SQLiteRepository
|
||||
List<GroupDb> query;
|
||||
if (userId == -1)
|
||||
{
|
||||
query = _connection.Query<GroupDb>("select gp.GroupId, gp.GroupName, " +
|
||||
"sum(case when gp.GroupId = ujdb.GroupId_FK then 1 else 0 end) as AssignedUserCount " +
|
||||
"from GroupDb gp " +
|
||||
"left join UserGroupJoinDb ujdb " +
|
||||
"on ujdb.GroupId_FK = gp.GroupId " +
|
||||
"group by gp.GroupId");
|
||||
query = _connection.Query<GroupDb>(SQLiteProcedures.GET_GROUPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
query =
|
||||
_connection.Query<GroupDb>(
|
||||
"select gdb.GroupId, gdb.GroupName, gdb.AssignedUserCount" +
|
||||
" from GroupDb gdb" +
|
||||
" left join UserGroupJoinDb ujdb" +
|
||||
" on gdb.GroupId = ujdb.GroupId_FK" +
|
||||
" where ujdb.UserId_FK = ?",
|
||||
_connection.Query<GroupDb>(SQLiteProcedures.GET_GROUPS_FOR_USER,
|
||||
userId);
|
||||
}
|
||||
foreach (var group in query)
|
||||
@ -538,7 +440,7 @@ namespace SQLiteRepository
|
||||
|
||||
public Group GetGroup(int groupId)
|
||||
{
|
||||
var query = _connection.Query<GroupDb>("select * from GroupDb where GroupId = ?", groupId);
|
||||
var query = _connection.Query<GroupDb>(SQLiteProcedures.GET_GROUP_BY_ID, groupId);
|
||||
if (query.Any())
|
||||
{
|
||||
var group = query.First();
|
||||
@ -554,8 +456,7 @@ namespace SQLiteRepository
|
||||
|
||||
public OperationResponse UpdateGroup(Group group)
|
||||
{
|
||||
//TODO: I would probably prefer to do this manually....
|
||||
var resp = _connection.Query<GroupDb>("update GroupDb set GroupName=? where GroupId=?", group.Name, group.Id);
|
||||
_connection.Query<GroupDb>(SQLiteProcedures.UPDATE_GROUP, @group.Name, @group.Id);
|
||||
|
||||
return OperationResponse.UPDATED;
|
||||
}
|
||||
@ -569,34 +470,26 @@ namespace SQLiteRepository
|
||||
public OperationResponse DeleteLog(TimeLog log)
|
||||
{
|
||||
var query = _connection.Query<TimeLogDb>(
|
||||
"select * from TimeLogDb where Id=?", log.Id);
|
||||
SQLiteProcedures.GET_TIMELOG_ENTRY, log.Id);
|
||||
|
||||
if (!query.Any())
|
||||
return OperationResponse.FAILED;
|
||||
|
||||
UpdateExistingLogDirections(log);
|
||||
|
||||
_connection.ExecuteScalar<TimeLogDb>("delete from TimeLogDb where Id=?", log.Id);
|
||||
_connection.ExecuteScalar<TimeLogDb>(SQLiteProcedures.DELETE_TIMELOG_ENTRY, log.Id);
|
||||
|
||||
return OperationResponse.DELETED;
|
||||
}
|
||||
|
||||
public OperationResponse CreateLog(TimeLog log)
|
||||
{
|
||||
var calendarWeek = GetIso8601CalendarWeek(log.EventTime.UtcDateTime);
|
||||
var year = log.EventTime.Year;
|
||||
log.CalendarWeek = calendarWeek;
|
||||
log.Year = year;
|
||||
var dbLog = new TimeLogDb
|
||||
{
|
||||
SwipeEventDateTime = log.EventTime,
|
||||
Direction = (LogDirectionDb)(int)log.Direction,
|
||||
Year = year,
|
||||
CalendarWeek = calendarWeek,
|
||||
Source = (LogSourceDb)(int)log.Source,
|
||||
UserId_FK = log.UserId,
|
||||
IdentifierId = ConvertSourceToIdentifierId(log.Source),
|
||||
};
|
||||
log.CalendarWeek = GetIso8601CalendarWeek(log.EventTime.UtcDateTime);
|
||||
log.Year = log.EventTime.Year;
|
||||
|
||||
var dbLog = TimeLogConverter.ConvertFromTimeLogDto(log);
|
||||
dbLog.IdentifierId = ConvertSourceToIdentifierId(log.Source);
|
||||
|
||||
#region update in/out directions for manual logs.
|
||||
UpdateExistingLogDirections(log);
|
||||
#endregion
|
||||
@ -608,8 +501,9 @@ namespace SQLiteRepository
|
||||
public OperationResponse UpdateLog(TimeLog log)
|
||||
{
|
||||
var query = _connection.Query<TimeLogDb>(
|
||||
"select * from TimeLogDb where Id=?", log.Id);
|
||||
if(!query.Any())
|
||||
SQLiteProcedures.GET_TIMELOG_ENTRY, log.Id);
|
||||
|
||||
if (!query.Any())
|
||||
return OperationResponse.FAILED;
|
||||
|
||||
if (log.CalendarWeek > 52 || log.CalendarWeek < 1)
|
||||
@ -621,13 +515,160 @@ namespace SQLiteRepository
|
||||
log.Year = log.EventTime.Year;
|
||||
}
|
||||
_connection.ExecuteScalar<TimeLogDb>(
|
||||
"update TimeLogDb set UserId_FK=?, Direction=?,SwipeEventDateTime=?,CalendarWeek=?,Year=?,Source=? where Id=?",
|
||||
log.UserId, (LogDirectionDb) (int) log.Direction, log.EventTime, log.CalendarWeek, log.Year,
|
||||
(LogSourceDb) (int) log.Source, log.Id);
|
||||
SQLiteProcedures.UPDATE_TIMELOG_ENTRY,
|
||||
log.UserId, (LogDirectionDb)(int)log.Direction, log.EventTime, log.CalendarWeek, log.Year,
|
||||
(LogSourceDb)(int)log.Source, log.Id);
|
||||
|
||||
return OperationResponse.UPDATED;
|
||||
}
|
||||
|
||||
public Policy GetPolicy()
|
||||
{
|
||||
var query = $"select * from {nameof(PolicyDb)}";
|
||||
var policies = _connection.Query<PolicyDb>(query);
|
||||
|
||||
|
||||
return PolicyConverter.ConvertToPolicyDto(policies.OrderByDescending(x => x.Version).FirstOrDefault());
|
||||
}
|
||||
|
||||
public void SavePolicy(Policy policy)
|
||||
{
|
||||
if (string.IsNullOrEmpty(policy.Version))
|
||||
{
|
||||
policy.Version = (GetNextPolicyVersion() + 1).ToString();
|
||||
}
|
||||
var policyDb = PolicyConverter.ConvertFromPolicyDto(policy);
|
||||
_connection.Insert(policyDb);
|
||||
}
|
||||
|
||||
private int GetNextPolicyVersion()
|
||||
{
|
||||
var query = $"select Max({nameof(PolicyDb.Id)}) from {nameof(PolicyDb)}";
|
||||
|
||||
var id = _connection.ExecuteScalar<int>(query);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
private int GetUserCount()
|
||||
{
|
||||
return _connection.ExecuteScalar<int>(SQLiteProcedures.GET_TOTAL_USER_COUNT);
|
||||
}
|
||||
|
||||
private List<UserIdentity> GetUserList(int groupId = -1, int pageSize = -1, int pageNumber = -1, SortOptions sort = SortOptions.None)
|
||||
{
|
||||
List<UserIdentity> users;
|
||||
|
||||
var orderByFirst = nameof(UserIdentity.LastName);
|
||||
var firstOrderDir = "ASC";
|
||||
var orderBySecond = nameof(UserIdentity.FirstName);
|
||||
var secondOrderDir = "ASC";
|
||||
|
||||
if (sort != SortOptions.None)
|
||||
{
|
||||
switch (sort)
|
||||
{
|
||||
case SortOptions.FirstNameAscending:
|
||||
orderByFirst = nameof(UserIdentity.FirstName);
|
||||
firstOrderDir = "ASC";
|
||||
orderBySecond = nameof(UserIdentity.LastName);
|
||||
secondOrderDir = "ASC";
|
||||
break;
|
||||
case SortOptions.FirstNameDescending:
|
||||
orderByFirst = nameof(UserIdentity.FirstName);
|
||||
firstOrderDir = "DESC";
|
||||
orderBySecond = nameof(UserIdentity.LastName);
|
||||
secondOrderDir = "ASC";
|
||||
break;
|
||||
case SortOptions.LastNameDescending:
|
||||
firstOrderDir = "DESC";
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (pageNumber != -1 && pageSize != -1)
|
||||
{
|
||||
var qString = string.Format(SQLiteProcedures.GET_ALL_USERS_PAGINATE, orderByFirst, firstOrderDir,
|
||||
orderBySecond, secondOrderDir, pageSize, (pageNumber - 1) * pageSize);
|
||||
users = _connection.Query<UserIdentity>(qString);
|
||||
}
|
||||
else if (groupId != -1)
|
||||
{
|
||||
var qString = string.Format(SQLiteProcedures.GET_ALL_USERS_BY_GROUP, groupId,
|
||||
orderByFirst, firstOrderDir,
|
||||
orderBySecond, secondOrderDir);
|
||||
users =
|
||||
_connection.Query<UserIdentity>(qString);
|
||||
}
|
||||
else
|
||||
{
|
||||
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS,
|
||||
orderByFirst, firstOrderDir,
|
||||
orderBySecond, secondOrderDir);
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
private void CheckForDbUpgrade()
|
||||
{
|
||||
var data = _connection.Query<DbVersion>(SQLiteProcedures.GET_DB_VERSION);
|
||||
if (!data.Any())
|
||||
{
|
||||
//Pre-Upgrade database, need upgrading
|
||||
_logger.Trace("Pre version 0.2 RC database found, performing update..");
|
||||
ExecuteUpgradeFromVersion("0.1"); //execute 0.2 upgrade scripts onwards.
|
||||
}
|
||||
else
|
||||
{
|
||||
var installedVersion = new Version(data.First().VersionNumber);
|
||||
var currentVersion = new Version(AssemblyInfo.ASSEMBLY_VERSION);
|
||||
if (currentVersion.CompareTo(installedVersion) > 0) //greater than 0 - current version is newer
|
||||
{
|
||||
_logger.Trace("Installed Database Version: {0} is older than current version {1}");
|
||||
ExecuteUpgradeFromVersion(installedVersion.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ExecuteUpgradeFromVersion(string installedVersion)
|
||||
{
|
||||
var instVers = new Version(installedVersion);
|
||||
//so we have established that each script for upgrade will be <version>.sql, so now start at lowest version and work up!
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
var upgradeScripts = assembly.GetManifestResourceNames()
|
||||
.Where(x => x.StartsWith(UPGRADE_SCRIPT_PREFIX))
|
||||
.OrderBy(x =>
|
||||
new Version(Path.GetFileNameWithoutExtension(x.Replace(UPGRADE_SCRIPT_PREFIX, string.Empty))))
|
||||
.Where(x =>
|
||||
{
|
||||
var scriptVersion =
|
||||
new Version(Path.GetFileNameWithoutExtension(x.Replace(UPGRADE_SCRIPT_PREFIX, string.Empty)))
|
||||
.CompareTo(instVers);
|
||||
return scriptVersion > 0;
|
||||
})
|
||||
.ToList();
|
||||
//now have an ordered list of upgrade script files, so execute in order!
|
||||
foreach (var upgradeScript in upgradeScripts)
|
||||
{
|
||||
using (var stream = assembly.GetManifestResourceStream(upgradeScript))
|
||||
using (var str = new StreamReader(stream))
|
||||
{
|
||||
var script = str.ReadToEnd();
|
||||
_logger.Trace("Executing upgrade script with name: {0}", upgradeScript);
|
||||
_connection.Execute(script);
|
||||
}
|
||||
}
|
||||
SetDbVersion(AssemblyInfo.ASSEMBLY_VERSION);
|
||||
}
|
||||
|
||||
private void SetDbVersion(string vers)
|
||||
{
|
||||
_connection.DeleteAll<DbVersion>();
|
||||
_connection.Insert(new DbVersion { VersionNumber = vers });
|
||||
_logger.Trace("Set Database version to: {0}", vers);
|
||||
}
|
||||
|
||||
private DateTime GetLastLogDateTime(TimeLogDb timeLog)
|
||||
{
|
||||
if (timeLog != null)
|
||||
@ -705,7 +746,7 @@ namespace SQLiteRepository
|
||||
EventTime = x.SwipeEventDateTime,
|
||||
UserId = x.UserId_FK,
|
||||
Year = x.Year
|
||||
}).OrderBy(x=>x.EventTime.UtcDateTime).ToList();
|
||||
}).OrderBy(x => x.EventTime.UtcDateTime).ToList();
|
||||
|
||||
var dict = new Dictionary<DayOfWeek, DailyLogs>();
|
||||
var logList = new List<DailyLogs>();
|
||||
@ -717,7 +758,7 @@ namespace SQLiteRepository
|
||||
}
|
||||
|
||||
//add the logs to the respective day of the week.
|
||||
foreach (var log in timeLogs.OrderBy(x=>x.EventTime))
|
||||
foreach (var log in timeLogs.OrderBy(x => x.EventTime))
|
||||
{
|
||||
dict[log.EventTime.DayOfWeek].Logs.Add(log);
|
||||
}
|
||||
@ -797,7 +838,7 @@ namespace SQLiteRepository
|
||||
else
|
||||
{
|
||||
// we have a time log from today already, so just do the opposite of what we last did!
|
||||
logDirection = InvertLogDirectionDb(lastEntry.Direction);
|
||||
logDirection = LogDirectionConverter.InvertLogDirectionDb(lastEntry.Direction);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -823,7 +864,7 @@ namespace SQLiteRepository
|
||||
|
||||
private void UpdateIdentifierLastUsed(DateTimeOffset dt, int cardId)
|
||||
{
|
||||
var res = _connection.ExecuteScalar<CardUniqueId>(SQLiteProcedures.UPDATE_CARD_LAST_USED,
|
||||
_connection.ExecuteScalar<CardUniqueId>(SQLiteProcedures.UPDATE_CARD_LAST_USED,
|
||||
dt,
|
||||
cardId);
|
||||
}
|
||||
@ -872,18 +913,6 @@ namespace SQLiteRepository
|
||||
return dt.Date.CompareTo(DateTime.Today.Date) < 0;
|
||||
}
|
||||
|
||||
private User ChangeToUserObject(UserIdentity user)
|
||||
{
|
||||
return new User
|
||||
{
|
||||
UserId = user.Id,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
HoursPerWeek = user.HoursPerWeek,
|
||||
IsContractor = user.IsContractor
|
||||
};
|
||||
}
|
||||
|
||||
private void UpdateExistingLogDirections(TimeLog log)
|
||||
{
|
||||
//need to make this generic so that both create and delete will update the log directions.. but ARGH.
|
||||
@ -901,29 +930,34 @@ namespace SQLiteRepository
|
||||
var currentlogDirection = log.Direction;
|
||||
for (var i = 0; i < logs.Count; i++)
|
||||
{
|
||||
logs[i].Direction = InvertLogDirection(currentlogDirection);
|
||||
logs[i].Direction = LogDirectionConverter.InvertLogDirection(currentlogDirection);
|
||||
UpdateLog(logs[i]);
|
||||
currentlogDirection = logs[i].Direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private LogDirectionDb InvertLogDirectionDb(LogDirectionDb direction)
|
||||
private void UpdateIdentifierUserId(List<int> cardsToUpdate, int userId)
|
||||
{
|
||||
return (LogDirectionDb) (int) InvertLogDirection((LogDirection) (int) direction);
|
||||
foreach (var card in cardsToUpdate)
|
||||
{
|
||||
_connection.Query<CardUniqueId>(
|
||||
SQLiteProcedures.UPDATE_CARD_USER_ID,
|
||||
userId, card);
|
||||
}
|
||||
}
|
||||
|
||||
private LogDirection InvertLogDirection(LogDirection direction)
|
||||
private void UpdateUserDetails(string firstName, string lastName, float hoursPerWeek, bool isContractor,
|
||||
int userId)
|
||||
{
|
||||
switch (direction)
|
||||
{
|
||||
case LogDirection.IN:
|
||||
return LogDirection.OUT;
|
||||
case LogDirection.OUT:
|
||||
return LogDirection.IN;
|
||||
default:
|
||||
return LogDirection.UNKNOWN;
|
||||
}
|
||||
_connection.Query<UserIdentity>(
|
||||
SQLiteProcedures.UPDATE_USER_DETAILS,
|
||||
firstName,
|
||||
lastName,
|
||||
hoursPerWeek,
|
||||
isContractor,
|
||||
userId
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,9 +78,17 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CardUniqueId.cs" />
|
||||
<Compile Include="Converters\IdentifierConverter.cs" />
|
||||
<Compile Include="Converters\LogDirectionConverter.cs" />
|
||||
<Compile Include="Converters\LogSourceConverter.cs" />
|
||||
<Compile Include="Converters\PolicyConverter.cs" />
|
||||
<Compile Include="Converters\TimeLogConverter.cs" />
|
||||
<Compile Include="Converters\UserConverter.cs" />
|
||||
<Compile Include="DBVersion.cs" />
|
||||
<Compile Include="Extensions\Extensions.cs" />
|
||||
<Compile Include="GroupDb.cs" />
|
||||
<Compile Include="LogSourceDb.cs" />
|
||||
<Compile Include="PolicyDb.cs" />
|
||||
<Compile Include="SQLiteRepository.cs" />
|
||||
<Compile Include="Constants.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
@ -101,10 +109,10 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<EmbeddedResource Include="UpgradeScripts\0.2.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="UpgradeScripts\0.2.sql" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets')" />
|
||||
|
||||
@ -1 +1,3 @@
|
||||
insert into GroupDb values ((select max(groupId) from GroupDb)+1,'Archived',0)
|
||||
insert into GroupDb(GroupId, GroupName, AssignedUserCount)
|
||||
select (select max(GroupId) from GroupDb)+1, 'Archived', 0
|
||||
WHERE NOT EXISTS(select * from GroupDb where GroupName='Archived');
|
||||
@ -3,9 +3,9 @@
|
||||
<appSettings>
|
||||
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml" />
|
||||
<add key="DefaultPageSize" value="20" />
|
||||
<add key="WebsiteHttpPort" value="8800"/>
|
||||
<add key="WebsiteHttpPort" value="8800" />
|
||||
<add key="SwipeTimeGap" value="3" />
|
||||
<add key="BugSubmissionEmailAddress" value="incoming+WattsC/FlexiTimeTrackerTool@incoming.gitlab.com"/>
|
||||
<add key="BugSubmissionEmailAddress" value="incoming+WattsC/FlexiTimeTrackerTool+24qrefn8e1urhl4iqct7we2jl@gitlab.com" />
|
||||
</appSettings>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
@ -18,7 +18,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.1.0.0" newVersion="3.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
@ -36,6 +36,18 @@
|
||||
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.4.0" newVersion="3.3.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject.Web.Common" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.1.0" newVersion="3.3.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject.Web.Common.OwinHost" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.1.0" newVersion="3.3.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@ -0,0 +1,66 @@
|
||||
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(WindowsDataCenter.App_Start.NinjectWebCommon), "Start")]
|
||||
[assembly: WebActivatorEx.ApplicationShutdownMethodAttribute(typeof(WindowsDataCenter.App_Start.NinjectWebCommon), "Stop")]
|
||||
|
||||
namespace WindowsDataCenter.App_Start
|
||||
{
|
||||
using System;
|
||||
using System.Web;
|
||||
|
||||
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
|
||||
|
||||
using Ninject;
|
||||
using Ninject.Web.Common;
|
||||
using Ninject.Web.Common.WebHost;
|
||||
|
||||
public static class NinjectWebCommon
|
||||
{
|
||||
private static readonly Bootstrapper bootstrapper = new Bootstrapper();
|
||||
|
||||
/// <summary>
|
||||
/// Starts the application
|
||||
/// </summary>
|
||||
public static void Start()
|
||||
{
|
||||
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule));
|
||||
DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule));
|
||||
bootstrapper.Initialize(CreateKernel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the application.
|
||||
/// </summary>
|
||||
public static void Stop()
|
||||
{
|
||||
bootstrapper.ShutDown();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the kernel that will manage your application.
|
||||
/// </summary>
|
||||
/// <returns>The created kernel.</returns>
|
||||
private static IKernel CreateKernel()
|
||||
{
|
||||
var kernel = new StandardKernel();
|
||||
try
|
||||
{
|
||||
kernel.Bind<Func<IKernel>>().ToMethod(ctx => () => new Bootstrapper().Kernel);
|
||||
kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>();
|
||||
RegisterServices(kernel);
|
||||
return kernel;
|
||||
}
|
||||
catch
|
||||
{
|
||||
kernel.Dispose();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load your modules or register your services here!
|
||||
/// </summary>
|
||||
/// <param name="kernel">The kernel.</param>
|
||||
private static void RegisterServices(IKernel kernel)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
namespace WindowsDataCenter
|
||||
using System;
|
||||
|
||||
namespace WindowsDataCenter
|
||||
{
|
||||
public class CardData
|
||||
{
|
||||
public DateTime? UtcTimeStamp { get; set; }
|
||||
public string CardUId { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
using System.Reflection;
|
||||
using System.Web.Http;
|
||||
using WindowsDataCenter.Helpers;
|
||||
using Interfaces;
|
||||
|
||||
namespace WindowsDataCenter
|
||||
@ -7,6 +8,12 @@ namespace WindowsDataCenter
|
||||
[RoutePrefix("api/app")]
|
||||
public class ApplicationController:ApiController
|
||||
{
|
||||
private IRepository _repo;
|
||||
public ApplicationController(IRepository repo)
|
||||
{
|
||||
_repo = repo;
|
||||
}
|
||||
|
||||
[Route("")]
|
||||
public IHttpActionResult GetAppDetails()
|
||||
{
|
||||
@ -22,5 +29,23 @@ namespace WindowsDataCenter
|
||||
|
||||
return Ok(appDetails);
|
||||
}
|
||||
|
||||
[Route("policy")]
|
||||
[HttpGet]
|
||||
[CacheControl(MaxAge = 0)]
|
||||
public IHttpActionResult GetPolicy()
|
||||
{
|
||||
Policy policy = _repo.GetPolicy();
|
||||
return Json(policy);
|
||||
}
|
||||
|
||||
[Route("policy")]
|
||||
[HttpPost]
|
||||
[CacheControl(MaxAge = 0)]
|
||||
public IHttpActionResult SavePolicy(Policy policy)
|
||||
{
|
||||
_repo.SavePolicy(policy);
|
||||
return Ok(new {}); //empty to ensure ajax triggers Success..
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,13 @@ namespace WindowsDataCenter
|
||||
public IHttpActionResult PostData([FromBody] CardData cData)
|
||||
{
|
||||
int logId;
|
||||
var resp = _repo.LogEventTime(new Identifier {UniqueId = cData.CardUId}, out logId);
|
||||
|
||||
var id = new Identifier {UniqueId = cData.CardUId};
|
||||
|
||||
var resp = cData.UtcTimeStamp.HasValue
|
||||
? _repo.LogEventTime(id, out logId, cData.UtcTimeStamp.Value)
|
||||
: _repo.LogEventTime(id, out logId);
|
||||
|
||||
_logger.Trace("Received new \"Swipe Event\" for UId: {0} at {1}, direction is : {2}", cData.CardUId,
|
||||
DateTime.UtcNow, resp.Direction);
|
||||
return Ok(new {Id = logId, resp.Direction});
|
||||
|
||||
@ -30,17 +30,18 @@ namespace WindowsDataCenter
|
||||
public IHttpActionResult GetUsers([FromUri] string query = ""
|
||||
, [FromUri] int pageSize = -1
|
||||
, [FromUri] int pageNumber = -1
|
||||
, [FromUri] int groupId = -1)
|
||||
, [FromUri] int groupId = -1
|
||||
, [FromUri] SortOptions sort = SortOptions.None)
|
||||
{
|
||||
_logger.Trace("GetUsers called with arguments >> query: {0}, pageSize: {1}, pageNumber: {2}, groupFilter: {3}", query, pageSize, pageNumber, groupId);
|
||||
_logger.Trace("GetUsers called with arguments >> query: {0}, pageSize: {1}, pageNumber: {2}, groupFilter: {3}, sort: {4}", query, pageSize, pageNumber, groupId, sort);
|
||||
|
||||
pageNumber = pageNumber == -1 ? 1 : pageNumber;
|
||||
pageSize = GetPageSize(pageSize);
|
||||
var userList = query != string.Empty
|
||||
? _repo.Search(query)
|
||||
: groupId != -1
|
||||
? _repo.GetUsers(groupId: groupId)
|
||||
: _repo.GetUsers(pageNumber, pageSize);
|
||||
? _repo.GetUsers(groupId: groupId, sort:sort)
|
||||
: _repo.GetUsers(pageNumber, pageSize, sort:sort);
|
||||
_logger.Trace("Got UserList from Repository, UserCount: {0}", userList.UserCount);
|
||||
if (query != string.Empty)
|
||||
{
|
||||
@ -57,6 +58,7 @@ namespace WindowsDataCenter
|
||||
|
||||
userList.PageNumber = pageNumber;
|
||||
userList.PageSize = pageSize;
|
||||
userList.SelectedSortOption = sort;
|
||||
|
||||
_logger.Trace("Returning UserList from GetUsers.");
|
||||
var msg = Request.CreateResponse(HttpStatusCode.OK, userList);
|
||||
@ -93,8 +95,7 @@ namespace WindowsDataCenter
|
||||
{
|
||||
int userId;
|
||||
_repo.UpdateUser(user, out userId);
|
||||
//TODO return ID.
|
||||
return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent("unknownIdTODO")});
|
||||
return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK) {Content = new StringContent(userId.ToString())});
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
|
||||
@ -55,14 +55,19 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<DocumentationFile>bin\ReleaseInstallers\WindowsDataCenter.XML</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Castle.Core.4.2.0\lib\net45\Castle.Core.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="DalSoft.WebApi.HelpPage, Version=0.0.7.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DalSoft.WebApi.HelpPage.0.0.7.0\lib\net451\DalSoft.WebApi.HelpPage.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||
<Reference Include="Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
@ -89,36 +94,44 @@
|
||||
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.3.2.2.0\lib\net45-full\Ninject.dll</HintPath>
|
||||
<Reference Include="Ninject, Version=3.3.4.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.3.3.4\lib\net45\Ninject.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Extensions.ContextPreservation, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.ContextPreservation.3.2.0.0\lib\net45-full\Ninject.Extensions.ContextPreservation.dll</HintPath>
|
||||
<Reference Include="Ninject.Extensions.ContextPreservation, Version=3.3.1.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.ContextPreservation.3.3.1\lib\net45\Ninject.Extensions.ContextPreservation.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Extensions.NamedScope, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.NamedScope.3.2.0.0\lib\net45-full\Ninject.Extensions.NamedScope.dll</HintPath>
|
||||
<Reference Include="Ninject.Extensions.Factory, Version=3.3.2.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.Factory.3.3.2\lib\net45\Ninject.Extensions.Factory.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Extensions.Xml, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.Xml.3.2.0.0\lib\net45-full\Ninject.Extensions.Xml.dll</HintPath>
|
||||
<Reference Include="Ninject.Extensions.NamedScope, Version=3.3.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.NamedScope.3.3.0\lib\net45\Ninject.Extensions.NamedScope.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Web.Common, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.Common.3.2.3.0\lib\net45-full\Ninject.Web.Common.dll</HintPath>
|
||||
<Reference Include="Ninject.Extensions.Xml, Version=3.3.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Extensions.Xml.3.3.0\lib\net45\Ninject.Extensions.Xml.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Web.Common.OwinHost, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.Common.OwinHost.3.2.3.0\lib\net45-full\Ninject.Web.Common.OwinHost.dll</HintPath>
|
||||
<Reference Include="Ninject.Web.Common, Version=3.3.1.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.Common.3.3.1\lib\net45\Ninject.Web.Common.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Web.WebApi, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.WebApi.3.2.4.0\lib\net45-full\Ninject.Web.WebApi.dll</HintPath>
|
||||
<Reference Include="Ninject.Web.Common.OwinHost, Version=3.3.1.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.Common.OwinHost.3.3.1\lib\net45\Ninject.Web.Common.OwinHost.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Web.WebApi.OwinHost, Version=3.2.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.WebApi.OwinHost.3.2.4.0\lib\net45-full\Ninject.Web.WebApi.OwinHost.dll</HintPath>
|
||||
<Reference Include="Ninject.Web.Common.WebHost, Version=3.3.1.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.Common.WebHost.3.3.1\lib\net45\Ninject.Web.Common.WebHost.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Web.WebApi, Version=3.3.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.WebApi.3.3.0\lib\net45\Ninject.Web.WebApi.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Ninject.Web.WebApi.OwinHost, Version=3.3.0.0, Culture=neutral, PublicKeyToken=c7192dc5380945e7, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Ninject.Web.WebApi.OwinHost.3.3.0\lib\net45\Ninject.Web.WebApi.OwinHost.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||
@ -154,6 +167,10 @@
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.0.0\lib\net45\System.Web.Http.WebHost.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.Razor.3.0.0\lib\net45\System.Web.Razor.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@ -162,11 +179,12 @@
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\WebActivatorEx.2.0\lib\net40\WebActivatorEx.dll</HintPath>
|
||||
<HintPath>..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App_Start\Ninject.Web.Common.cs" />
|
||||
<Compile Include="CardData.cs" />
|
||||
<Compile Include="Controllers\ApplicationController.cs" />
|
||||
<Compile Include="Controllers\CardsController.cs" />
|
||||
@ -196,6 +214,9 @@
|
||||
<Compile Include="Controllers\ValuesController.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\HelpPage.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Minifier\MinifierConfig.xml" />
|
||||
<Content Include="NinjectConfig.xml">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
@ -221,6 +242,9 @@
|
||||
<Content Include="www\css\bootstrap.min.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\css\highlightjs.min.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\css\knockout.contextmenu.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@ -245,9 +269,27 @@
|
||||
<Content Include="www\js\bootstrap.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\css\easymde.min.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\js\easymde.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\js\highlightjs.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\js\htmlparser.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\js\knockout.contextmenu.js">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\js\marked.min.js">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\js\PolicyObject.js">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="www\spa.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@ -309,9 +351,6 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Help\DalSoft.WebApi.HelpPage.Views\HelpPage.css">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="sqlite3.def" />
|
||||
<Content Include="sqlite3.dll" />
|
||||
</ItemGroup>
|
||||
@ -330,6 +369,9 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>call "$(ProjectDir)Minifier\Minify.bat" "$(SolutionDir)"</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets" Condition="Exists('..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
@ -337,9 +379,6 @@
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\System.Data.SQLite.Core.1.0.104.0\build\net451\System.Data.SQLite.Core.targets'))" />
|
||||
</Target>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>call "$(ProjectDir)Minifier\Minify.bat" "$(SolutionDir)"</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Castle.Core" version="4.2.0" targetFramework="net452" />
|
||||
<package id="DalSoft.WebApi.HelpPage" version="0.0.7.0" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.Razor" version="3.0.0" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi" version="5.0.0" targetFramework="net452" />
|
||||
@ -8,23 +9,25 @@
|
||||
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.3" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.OwinSelfHost" version="5.2.3" targetFramework="net452" />
|
||||
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.FileSystems" version="3.0.1" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net452" />
|
||||
<package id="Microsoft.Owin.StaticFiles" version="3.0.1" targetFramework="net452" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net452" />
|
||||
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
|
||||
<package id="Ninject" version="3.2.2.0" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.ContextPreservation" version="3.2.0.0" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.NamedScope" version="3.2.0.0" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.Xml" version="3.2.0.0" targetFramework="net452" />
|
||||
<package id="Ninject.Web.Common" version="3.2.3.0" targetFramework="net452" />
|
||||
<package id="Ninject.Web.Common.OwinHost" version="3.2.3.0" targetFramework="net452" />
|
||||
<package id="Ninject.Web.WebApi" version="3.2.4.0" targetFramework="net452" />
|
||||
<package id="Ninject.Web.WebApi.OwinHost" version="3.2.4.0" targetFramework="net452" />
|
||||
<package id="Ninject" version="3.3.4" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.ContextPreservation" version="3.3.1" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.Factory" version="3.3.2" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.NamedScope" version="3.3.0" targetFramework="net452" />
|
||||
<package id="Ninject.Extensions.Xml" version="3.3.0" targetFramework="net452" />
|
||||
<package id="Ninject.Web.Common" version="3.3.1" targetFramework="net452" />
|
||||
<package id="Ninject.Web.Common.OwinHost" version="3.3.1" targetFramework="net452" />
|
||||
<package id="Ninject.Web.Common.WebHost" version="3.3.1" targetFramework="net452" />
|
||||
<package id="Ninject.Web.WebApi" version="3.3.0" targetFramework="net452" />
|
||||
<package id="Ninject.Web.WebApi.OwinHost" version="3.3.0" targetFramework="net452" />
|
||||
<package id="Owin" version="1.0" targetFramework="net452" />
|
||||
<package id="RazorEngine" version="3.7.2" targetFramework="net452" />
|
||||
<package id="System.Data.SQLite.Core" version="1.0.104.0" targetFramework="net452" />
|
||||
<package id="WebActivatorEx" version="2.0" targetFramework="net452" />
|
||||
<package id="WebActivatorEx" version="2.2.0" targetFramework="net452" />
|
||||
</packages>
|
||||
@ -9,8 +9,11 @@
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js" type="text/javascript"></script>
|
||||
<script src="https://cdn.jsdelivr.net/momentjs/2.10.6/moment.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/sammy.js/0.7.6/sammy.js" type="text/javascript"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||
<link rel="stylesheet" href="css/easymde.min.css" />
|
||||
<link rel="stylesheet" href="css/highlightjs.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default">
|
||||
@ -37,14 +40,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div id="GroupAdminPage" class="container">
|
||||
<div id="GroupAdminPage" class="container">
|
||||
<div class="row">
|
||||
<h2 class="col-md-4">Groups</h2>
|
||||
<button class="col-md-1 btn btn-default pull-right" style="margin-top: 20px;" data-bind="click: $root.newGroupForm">
|
||||
<span class="glyphicon glyphicon-plus"></span>
|
||||
</button>
|
||||
</div>
|
||||
<hr/>
|
||||
<hr />
|
||||
<div class="row">
|
||||
<div data-bind="with: groupsList, css:{'col-md-8': !$root.groupFormHidden(), 'col-md-12':$root.groupFormHidden()}">
|
||||
<table class="table table-striped">
|
||||
@ -68,15 +71,17 @@
|
||||
<input type="hidden" name="id" data-bind="value: Id">
|
||||
<div class="form-group">
|
||||
<label for="groupNameEdit">Group Name</label>
|
||||
<input for="Name" type="text" class="form-control" id="groupNameEdit" placeholder="Group Name" data-bind="value: Name"/>
|
||||
<input for="Name" type="text" class="form-control" id="groupNameEdit" placeholder="Group Name" data-bind="value: Name" />
|
||||
</div>
|
||||
<button pageDestination="Users" class="btn btn-secondary" type="button"
|
||||
data-bind="click: $root.hideGroupForm">Cancel</button>
|
||||
data-bind="click: $root.hideGroupForm">
|
||||
Cancel
|
||||
</button>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="CardManagement" class="container">
|
||||
<div class="row">
|
||||
<h2 class="col-md-4">Unassigned Cards</h2>
|
||||
@ -103,7 +108,64 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="PolicyManagement" class="container">
|
||||
<div id="row">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#edit" data-toggle="tab">Edit</a></li>
|
||||
<li><a href="#preview" data-toggle="tab">Preview</a></li>
|
||||
</ul>
|
||||
<div class="tab-content" style="max-height: 500px; min-height: 400px;overflow-y: auto">
|
||||
<div id="edit" class="tab-pane fade in active">
|
||||
<textarea id="policyEditor"></textarea>
|
||||
</div>
|
||||
<div id="preview" class="tab-pane fade in">
|
||||
<div data-bind="html: policyData.html" class="well-lg"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-primary pull-right" data-toggle="modal" data-target="#saveDialog">Save</button><!--data-bind="click: $root.policySave"-->
|
||||
<button class="btn btn-secondary pull-right" data-bind="click: $root.policyReload">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="saveDialog" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4>Change Details</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Change Author</th>
|
||||
<td><input class="form-control" id="changeAuthorInput" type="text" data-bind="value: policyData.ChangeAuthor" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Change Date</th>
|
||||
<td><input class="form-control" id="changeDatePicker" type="datetime-local" data-bind="value: policyData.ChangeDate" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Version</th>
|
||||
<td><input class="form-control" id="versionInput" type="text" data-bind="value: policyData.Version" readonly /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Change Description</th>
|
||||
<td><input class="form-control" id="changeDescription" type="text" data-bind="value: policyData.ChangeDescription" /></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary pull-right" data-bind="click: $root.policySave">Save</button>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="js/PolicyObject.js" type="text/javascript"></script>
|
||||
<script src="Helpers.min.js" type="text/javascript"></script>
|
||||
<script src="js/easymde.min.js" type="text/javascript"></script>
|
||||
<script src="js/highlightjs.min.js" type="text/javascript"></script>
|
||||
<script src="js/htmlparser.min.js" type="text/javascript"></script>
|
||||
<script src="js/marked.min.js"></script>
|
||||
<script src="admin.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
@ -4,6 +4,70 @@
|
||||
self.groupEditItem = ko.observable(null);
|
||||
self.unassignedCardList = ko.observable(null);
|
||||
self.helpers = new Helpers();
|
||||
self.policyMarkdown = "";
|
||||
self.policyData = new policy();
|
||||
self.renderer = new marked.Renderer();
|
||||
self.renderer.blockquote = function(quote) {
|
||||
return "<blockquote class=\"blockquote\">" + quote + "</blockquote>";
|
||||
};
|
||||
self.renderer.heading = function (text, level) {
|
||||
|
||||
var parserHandler = new Tautologistics.NodeHtmlParser.DefaultHandler(function (error) {
|
||||
if (error)
|
||||
throw new Error("Cannot parse \"" + text + "\" in markdown file.");
|
||||
});
|
||||
var parser = new Tautologistics.NodeHtmlParser.Parser(parserHandler);
|
||||
|
||||
parser.parseComplete(text);
|
||||
var escaped = "unknown";
|
||||
|
||||
if (parserHandler.dom.length > 0) {
|
||||
escaped = parserHandler.dom[0].raw.toLowerCase().trim().replace(/ /g, "-");
|
||||
}
|
||||
|
||||
return "<h" + level + " id=\"" + escaped + "\">"
|
||||
// NOTE: We're setting display none INLINE, so you have
|
||||
// to override with !important if you want it to show.
|
||||
+ " <a class=\"heading-anchor\" style=\"display:none;\" href=\"#" + escaped + '">'
|
||||
+ " <i class=\"oi oi-link-intact\"></i>"
|
||||
+ " </a>"
|
||||
+ text
|
||||
+ "</h" + level + ">";
|
||||
};
|
||||
self.renderer.table = function(header, body) {
|
||||
return "<table class=\"table\">" +
|
||||
"<thead class=\"thead-default\">" +
|
||||
header +
|
||||
"</thead>" +
|
||||
"<tbody>" +
|
||||
body +
|
||||
"</tbody>" +
|
||||
"</table>";
|
||||
};
|
||||
/*
|
||||
* Adds highlight.js classes to `code` blocks
|
||||
*/
|
||||
self.renderer.code = function(code, language) {
|
||||
|
||||
var valid = !!(language && hljs.getLanguage(language));
|
||||
var highlighted = valid ? hljs.highlight(language, code).value : code
|
||||
|
||||
return "<pre><code class=\"hljs lang-" + language + "\">" + highlighted + "</code></pre>";
|
||||
};
|
||||
self.editor = new EasyMDE({
|
||||
element: document.getElementById("policyEditor"),
|
||||
showIcons: ["bold", "italic", "strikethrough", "heading", "heading-smaller", "heading-bigger", "heading-1", "heading-2", "heading-3", "code", "quote", "unordered-list", "ordered-list", "clean-block", "link", "table", "horizontal-rule", "guide", "table"],
|
||||
hideIcons: ["preview", "side-by-side", "fullscreen"],
|
||||
renderingConfig: {
|
||||
markedOptions: {
|
||||
renderer: self.renderer
|
||||
}
|
||||
}
|
||||
});
|
||||
self.editor.codemirror.on("changes",
|
||||
function () {
|
||||
self.policyData.html(self.editor.options.previewRender(self.editor.value()));
|
||||
});
|
||||
self.uiPages = {
|
||||
overview: "overview",
|
||||
group: "groups",
|
||||
@ -14,7 +78,9 @@
|
||||
getGroups: "/api/groups",
|
||||
editGroup: "/api/groups/edit",
|
||||
getUnassignedCards: "/api/cards/unassigned",
|
||||
clearUnassignedCards: "/api/cards/unassigned"
|
||||
clearUnassignedCards: "/api/cards/unassigned",
|
||||
getPolicy:"/api/app/policy",
|
||||
savePolicy:"/api/app/policy"
|
||||
};
|
||||
self.clearGroupForm = function () {
|
||||
self.helpers.goToMenuOption(self.uiPages.group);
|
||||
@ -50,7 +116,7 @@
|
||||
false);
|
||||
$.ajax({
|
||||
url: url,
|
||||
type: 'DELETE',
|
||||
type: "DELETE",
|
||||
success: function () {
|
||||
console.log("deleted " + groupId);
|
||||
self.hideGroupForm();
|
||||
@ -100,6 +166,34 @@
|
||||
self.padNumber = function (number) {
|
||||
return (number < 10 ? "0" : "") + number;
|
||||
};
|
||||
self.policySave = function () {
|
||||
var url = self.helpers.createRequestUrl(self.apiEndpoints.savePolicy, null, false);
|
||||
self.policyData.Markdown(self.editor.value()); //make sure we update it, as it doesnt push the value back into the variable
|
||||
//console.log(self.policyData());
|
||||
$.post(url, self.policyData(), function() {
|
||||
}, "json") //todo: check this serialisation as the object is now complex.
|
||||
.done(function() {
|
||||
self.policyReload();
|
||||
}).fail(function(resp, status, error) {
|
||||
var errorObj = self.helpers.processRequestFailure(resp, status, error);
|
||||
console.log(errorObj);
|
||||
});
|
||||
};
|
||||
self.policyReload = function() {
|
||||
var url = self.helpers.createRequestUrl(self.apiEndpoints.getPolicy,
|
||||
[], false, false);
|
||||
$.getJSON(url, function (res) {
|
||||
//console.log(res);
|
||||
self.editor.value(res.Markdown);
|
||||
res.Version = (parseInt(res.Version) + 1).toString();
|
||||
self.policyData.update(res);
|
||||
$('#saveDialog').modal('hide');
|
||||
}).fail(function (resp, status, error) {
|
||||
console.log("error - policyReload");
|
||||
var errObj = self.helpers.processRequestFailure(resp, status, error);
|
||||
self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "policyReload");
|
||||
});
|
||||
};
|
||||
self.convertToDisplayDateTime = function (dateValue) {
|
||||
var date = new Date(dateValue); // dd MM YY HH:mm:ss e.g.: 01 Mar 17 17:34:02
|
||||
return date.getDate() + " "
|
||||
@ -114,6 +208,7 @@
|
||||
this.get("#overview", function () {
|
||||
self.getGroups();
|
||||
self.getUnassignedCardData();
|
||||
self.policyReload();
|
||||
});
|
||||
this.post("#editgroup", function () {
|
||||
self.submitGroupEdit(self.groupEditItem());
|
||||
|
||||
File diff suppressed because one or more lines are too long
7
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/css/easymde.min.css
vendored
Normal file
7
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/css/easymde.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/css/highlightjs.min.css
vendored
Normal file
1
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/css/highlightjs.min.css
vendored
Normal file
@ -0,0 +1 @@
|
||||
.hljs{display:block;overflow-x:auto;padding:.5em;background:#F0F0F0}.hljs,.hljs-subst{color:#444}.hljs-comment{color:#888888}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
|
||||
@ -86,8 +86,23 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-md-1"></th>
|
||||
<th class="col-md-3">First Name</th>
|
||||
<th class="col-md-3">Last Name</th>
|
||||
<th class="col-md-3">
|
||||
<div class="col-md-1">
|
||||
<a href="#users?sort=firstAsc"><span data-bind="css:{ 'text-warning': $root.sortIsActive('firstAsc')}" class="glyphicon glyphicon-chevron-up"></span></a>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<a href="#users?sort=firstDesc"><span data-bind="css:{ 'text-warning': $root.sortIsActive('firstDesc')}" class="glyphicon glyphicon-chevron-down"></span></a>
|
||||
</div>
|
||||
<span class="col-md-9">First Name</span>
|
||||
</th>
|
||||
<th class="col-md-3">
|
||||
<div class="col-md-1">
|
||||
<a href="#users?sort=lastAsc"><span data-bind="css:{ 'text-warning': $root.sortIsActive('lastAsc')}" class="glyphicon glyphicon-chevron-up"></span></a>
|
||||
</div>
|
||||
<div class="col-md-1">
|
||||
<a href="#users?sort=lastDesc"><span data-bind="css:{ 'text-warning': $root.sortIsActive('lastDesc')}"class="glyphicon glyphicon-chevron-down"></span></a>
|
||||
</div>
|
||||
<span class="col-md-9">Last Name</span></th>
|
||||
<th class="col-md-1 text-center">Contractor</th>
|
||||
<th/>
|
||||
<th/>
|
||||
@ -303,6 +318,11 @@
|
||||
</menu>-->
|
||||
</div>
|
||||
|
||||
<div class="container" data-bind="with: policyData">
|
||||
<div class="row" data-bind="html:Html">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="aboutDialog" class="modal fade" role="dialog" data-bind="with: appDetails">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
@ -330,6 +350,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Dialog to create a manual time entry-->
|
||||
<div id="manualLogDialog" class="modal fade" role="dialog" data-bind="with: manualLog">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
@ -350,7 +371,8 @@
|
||||
optionsText: function(item) { return item.Text },
|
||||
optionsValue: function(item){ return item.value },
|
||||
value: Direction,
|
||||
optionsCaption: 'Choose...'"></select>
|
||||
optionsCaption: 'Choose...'"
|
||||
required></select>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
function policy(data) {
|
||||
var self = this;
|
||||
if (typeof data === "undefined") {
|
||||
data = createDefaultPolicy();
|
||||
}
|
||||
self.changeDate = ko.observable(data.changeDate);
|
||||
self.description = ko.observable(data.description);
|
||||
self.changeAuthor = ko.observable(data.changeAuthor);
|
||||
self.version = ko.observable(data.version);
|
||||
self.markdown = ko.observable(data.markdown);
|
||||
self.html = ko.observable(data.html);
|
||||
function createDefaultPolicy() {
|
||||
return {
|
||||
changeDate: moment().format(),
|
||||
description: "",
|
||||
changeAuthor: "",
|
||||
version: -1,
|
||||
markdown: "",
|
||||
html: ""
|
||||
};
|
||||
}
|
||||
self.update = function(data) {
|
||||
self.changeDate(data.changeDate);
|
||||
self.description(data.description);
|
||||
self.changeAuthor(data.changeAuthor);
|
||||
self.version(data.version);
|
||||
self.markdown(data.markdown);
|
||||
self.html(data.html);
|
||||
}
|
||||
}
|
||||
7
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/easymde.min.js
vendored
Normal file
7
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/easymde.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/highlightjs.min.js
vendored
Normal file
2
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/highlightjs.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
22
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/htmlparser.min.js
vendored
Normal file
22
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/htmlparser.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/marked.min.js
vendored
Normal file
6
DataCenter_Windows/WindowsDataCenter/WindowsDataCenter/www/js/marked.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,8 +1,14 @@
|
||||
function DataVM() {
|
||||
const SortOptions = {
|
||||
LastAsc: "LastNameAscending",
|
||||
LastDesc: "LastNameDescending",
|
||||
FirstAsc: "FirstNameAscending",
|
||||
FirstDesc: "FirstNameDescending"
|
||||
};
|
||||
function DataVM() {
|
||||
"use strict";
|
||||
var self = this;
|
||||
self.helpers = new Helpers();
|
||||
self.menuOptions = ["Home"];
|
||||
self.menuOptions = ["Home", "Policy"];
|
||||
self.possibleLogDirections = ko.observableArray([
|
||||
{ Text: "In", value: 1 },
|
||||
{ Text: "Out", value: 2 }
|
||||
@ -19,6 +25,11 @@
|
||||
self.selectedCalendarWeek = ko.observable(0);
|
||||
self.errorData = ko.observable(null);
|
||||
self.manualLog = ko.observable(null);
|
||||
self.policyData = ko.observable(null);
|
||||
self.policyChangeDate = ko.observable(null);
|
||||
self.policyChangeAuthor = ko.observable(null);
|
||||
self.policyVersion = ko.observable(null);
|
||||
self.selectedSort = ko.observable(null);
|
||||
self.apiEndpoints = {
|
||||
root: "http://localhost:8800",
|
||||
getUserList: "/api/users",
|
||||
@ -29,7 +40,8 @@
|
||||
getGroups: "/api/groups",
|
||||
getAppDetails: "/api/app",
|
||||
manualLogsCreate: "/api/logs/create",
|
||||
manualLogsDelete: "/api/logs/delete"
|
||||
manualLogsDelete: "/api/logs/delete",
|
||||
getPolicy: "/api/app/policy"
|
||||
};
|
||||
self.uiPages = {
|
||||
users: "users",
|
||||
@ -216,25 +228,32 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
self.getUserList = function (pageSize, pageNumber, groupId) {
|
||||
var args = null;
|
||||
self.getUserList = function (pageSize, pageNumber, groupId, sort) {
|
||||
var args = [];
|
||||
if (pageSize && pageNumber) {
|
||||
args = [
|
||||
args.push(
|
||||
{
|
||||
key: "pageSize",
|
||||
value: pageSize
|
||||
},
|
||||
});
|
||||
args.push(
|
||||
{
|
||||
key: "pageNumber",
|
||||
value: pageNumber
|
||||
});
|
||||
}
|
||||
];
|
||||
} else if(groupId) {
|
||||
args = [
|
||||
if (groupId) {
|
||||
args.push(
|
||||
{
|
||||
key: "groupId",
|
||||
value: groupId
|
||||
}];
|
||||
});
|
||||
}
|
||||
if (sort) {
|
||||
args.push({
|
||||
key: "sort",
|
||||
value: sort
|
||||
});
|
||||
}
|
||||
var url = self.helpers.createRequestUrl(self.apiEndpoints.getUserList, args, false);
|
||||
$.getJSON(url, function (res) {
|
||||
@ -256,9 +275,9 @@
|
||||
self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getUserList");
|
||||
});
|
||||
};
|
||||
self.searchUsers = function(query) {
|
||||
self.searchUsers = function(query, sort) {
|
||||
var url = self.helpers.createRequestUrl(self.apiEndpoints.getUserList,
|
||||
[{ key: "query", value: query }], false, false);
|
||||
[{ key: "query", value: query }, {key:"sort",value:sort}], false, false);
|
||||
$.getJSON(url,
|
||||
function(res) {
|
||||
self.userList(res);
|
||||
@ -336,13 +355,25 @@
|
||||
self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getGroups");
|
||||
});
|
||||
};
|
||||
self.getPolicyData = function () {
|
||||
var url = self.helpers.createRequestUrl(self.apiEndpoints.getPolicy, null, false);
|
||||
$.getJSON(url, function (res) {
|
||||
console.log(res);
|
||||
self.policyData(res);
|
||||
}).fail(function (resp, status, error) {
|
||||
console.log("error - getPolicyData");
|
||||
var errObj = self.helpers.processRequestFailure(resp, status, error);
|
||||
self.assignErrorObject(errObj.errorCode, errObj.errorMessage, "getPolicyData");
|
||||
});
|
||||
|
||||
};
|
||||
self.createManualLog = function(newLog) {
|
||||
var url = self.helpers.createRequestUrl(self.apiEndpoints.manualLogsCreate, null, false, false);
|
||||
$.post(url, newLog, function () {
|
||||
}, "json")
|
||||
.done(function () {
|
||||
self.manualLog(null);
|
||||
$('#manualLogDialog').modal("hide");
|
||||
$("#manualLogDialog").modal("hide");
|
||||
location.reload(); //stay on this users logs page, but just reload the timelogs.
|
||||
})
|
||||
.fail(function (resp, status, error) {
|
||||
@ -379,17 +410,18 @@
|
||||
self.assignUpdateHandler();
|
||||
};
|
||||
function createlog(data, event) {
|
||||
var logDateInitVal = moment(self.selectedTimeLogDate()).add((data.Day - 1), 'days').toISOString();
|
||||
self.manualLog({
|
||||
CalendarWeek:-1,
|
||||
Direction:-1,
|
||||
EventTime: new Date().toISOString(),
|
||||
EventTime: logDateInitVal,
|
||||
Id: -1,
|
||||
IdentifierId: -1,
|
||||
UserId: self.chosenTimeLogUserId,
|
||||
Year: 0
|
||||
});
|
||||
$('#manualLogDialog').modal("show");
|
||||
self.initialiseManualLogDateTimePicker(self.selectedTimeLogDate());
|
||||
self.initialiseManualLogDateTimePicker(logDateInitVal);
|
||||
self.assignUpdateHandler();
|
||||
};
|
||||
function deleteLog(data) {
|
||||
@ -408,28 +440,63 @@
|
||||
maxDate: moment(date).endOf("week")
|
||||
});
|
||||
};
|
||||
function convertSortOption(opt) {
|
||||
if (!opt) {
|
||||
return null
|
||||
}
|
||||
if (opt === "firstAsc") {
|
||||
return SortOptions.FirstAsc;
|
||||
}
|
||||
if (opt === "firstDesc") {
|
||||
return SortOptions.FirstDesc;
|
||||
}
|
||||
if (opt === "lastAsc") {
|
||||
return SortOptions.LastAsc;
|
||||
}
|
||||
if (opt === "lastDesc") {
|
||||
return SortOptions.LastDesc;
|
||||
}
|
||||
};
|
||||
self.sortIsActive = function (option) {
|
||||
if (option === "firstAsc" && self.userList().SelectedSortOption === SortOptions.FirstAsc) {
|
||||
return true;
|
||||
}
|
||||
if (option === "firstDesc" && self.userList().SelectedSortOption === SortOptions.FirstDesc) {
|
||||
return true;
|
||||
}
|
||||
if (option === "lastAsc" && self.userList().SelectedSortOption === SortOptions.LastAsc) {
|
||||
return true;
|
||||
}
|
||||
if (option === "lastDesc" && self.userList().SelectedSortOption === SortOptions.LastDesc) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
Sammy(function () {
|
||||
this.get("#users", function () {
|
||||
var query = this.params.query;
|
||||
var pageSize = this.params.pageSize;
|
||||
var pageNumber = this.params.pageNumber;
|
||||
var groupId = this.params.groupId;
|
||||
var sort = convertSortOption(this.params.sort);
|
||||
console.log(sort);
|
||||
self.chosenMenuItemId("Home");
|
||||
self.groupsList(null);
|
||||
self.chosenUserDetails(null);
|
||||
self.userList(null);
|
||||
self.userTimeLogData(null);
|
||||
self.policyData(null);
|
||||
self.manualLog(null);
|
||||
if (self.appDetails() === null) {
|
||||
self.getAppDetails();
|
||||
}
|
||||
self.getGroups(function (data) { self.groupsList(data); });
|
||||
if (query)
|
||||
self.searchUsers(query);
|
||||
self.searchUsers(query, sort);
|
||||
else if (groupId && groupId > 0)
|
||||
self.getUserList(null, null, groupId);
|
||||
self.getUserList(null, null, groupId, sort);
|
||||
else
|
||||
self.getUserList(pageSize, pageNumber);
|
||||
self.getUserList(pageSize, pageNumber, null,sort);
|
||||
});
|
||||
this.get("#userData/:userId", function () {
|
||||
self.chosenMenuItemId("Data");
|
||||
@ -437,6 +504,7 @@
|
||||
self.chosenUserDetails(null);
|
||||
self.userList(null);
|
||||
self.userTimeLogData(null);
|
||||
self.policyData(null);
|
||||
self.manualLog(null);
|
||||
self.getUserDetails(this.params.userId);
|
||||
self.getUnassignedCardData();
|
||||
@ -454,12 +522,14 @@
|
||||
self.userList(null);
|
||||
self.userTimeLogData(null);
|
||||
self.manualLog(null);
|
||||
self.policyData(null);
|
||||
self.getTimeLogData(this.params.userId, self.selectedTimeLogDate());
|
||||
});
|
||||
this.get("#newUser", function () {
|
||||
self.chosenMenuItemId("newUser");
|
||||
self.userList(null);
|
||||
self.userTimeLogData(null);
|
||||
self.policyData(null);
|
||||
self.chosenUserDetails({
|
||||
"UserId": -1,
|
||||
"FirstName": null,
|
||||
@ -478,6 +548,16 @@
|
||||
this.get("#stats", function () {
|
||||
self.goToMenuOption("users");
|
||||
});
|
||||
this.get("#Policy",
|
||||
function () {
|
||||
self.groupsList(null);
|
||||
self.chosenUserDetails(null);
|
||||
self.userList(null);
|
||||
self.userTimeLogData(null);
|
||||
self.manualLog(null);
|
||||
|
||||
self.getPolicyData();
|
||||
});
|
||||
this.post("#edituser", function () {
|
||||
$.each(self.chosenUserDetails().AssociatedIdentifiers,
|
||||
function (k, v) {
|
||||
@ -496,7 +576,6 @@
|
||||
this.post("#manualLog",
|
||||
function() {
|
||||
self.createManualLog(self.manualLog());
|
||||
|
||||
$('#manualLogDialog').modal("hide");
|
||||
//self.goToTimeLogs(self.chosenTimeLogUserId, null, [{ key: "selectedDate", value: self.selectedTimeLogDate() }]);
|
||||
});
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<add key="NLogConfigFilePath" value="Configs/NLogConfig.xml" />
|
||||
<add key="DefaultPageSize" value="20" />
|
||||
<add key="SwipeTimeGap" value="3" />
|
||||
<add key="BugSubmissionEmailAddress" value="incoming+WattsC/FlexiTimeTrackerTool+24qrefn8e1urhl4iqct7we2jl@gitlab.com"/>
|
||||
<add key="BugSubmissionEmailAddress" value="incoming+WattsC/FlexiTimeTrackerTool+24qrefn8e1urhl4iqct7we2jl@gitlab.com" />
|
||||
</appSettings>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
|
||||
@ -31,6 +31,18 @@
|
||||
<assemblyIdentity name="System.Web.Http.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.4.0" newVersion="3.3.4.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject.Web.Common" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.1.0" newVersion="3.3.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Ninject.Web.Common.OwinHost" publicKeyToken="c7192dc5380945e7" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.1.0" newVersion="3.3.1.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
@ -57,6 +57,10 @@
|
||||
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.FileSystems, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Owin.FileSystems.3.0.1\lib\net45\Microsoft.Owin.FileSystems.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.Host.HttpListener, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
|
||||
BIN
Tools/Sentinel.zip
Normal file
BIN
Tools/Sentinel.zip
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user