aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Web
diff options
context:
space:
mode:
authorMirta <mirta@twine-s.com>2020-11-23 16:13:53 +0200
committerMirta <mirta@twine-s.com>2020-11-23 16:13:53 +0200
commit91c007adced573e09b77ab4be4a5aba623a816cc (patch)
tree250221fc2def7d59f1393be8394f766faf576656 /Software/Visual_Studio/Web
parent4e9af2b852eb3b9eecfa09e9bc76869558e183cb (diff)
parent50a3c0b857b4aa88a9e3970d69256f12b5b24eb8 (diff)
downloadTango-91c007adced573e09b77ab4be4a5aba623a816cc.tar.gz
Tango-91c007adced573e09b77ab4be4a5aba623a816cc.zip
Merge branch 'master' of https://twinetfs.visualstudio.com/Tango/_git/Tango
Diffstat (limited to 'Software/Visual_Studio/Web')
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs331
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs19
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtWebApiTokenFilter.cs72
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Nswag/DataStoreClient.nswag140
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs2
-rw-r--r--Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj17
6 files changed, 574 insertions, 7 deletions
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs
new file mode 100644
index 000000000..383a59850
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs
@@ -0,0 +1,331 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Authentication;
+using System.Web.Http;
+using Tango.BL.Builders;
+using Tango.BL.Entities;
+using Tango.BL.Enumerations;
+using Tango.Core.Cryptography;
+using Tango.DataStore;
+using Tango.DataStore.EF;
+using Tango.DataStore.Web;
+using Tango.MachineService.Filters;
+using Tango.Web.Controllers;
+using Tango.Web.Helpers;
+using Tango.Web.Security;
+using static Tango.MachineService.Controllers.DataStoreController;
+
+namespace Tango.MachineService.Controllers
+{
+ public class DataStoreController : TangoController<TokenObject>
+ {
+ public class TokenObject
+ {
+ public String UserGuid { get; set; }
+ public List<Permissions> Permissions { get; set; }
+
+ public TokenObject()
+ {
+ Permissions = new List<Permissions>();
+ }
+ }
+
+ private IDataStoreManager _manager;
+
+ public DataStoreController()
+ {
+ _manager = new EFDataStoreManager();
+ }
+
+ [HttpPost]
+ public LoginResponse Login(LoginRequest request)
+ {
+ User user = null;
+
+ IHashGenerator hash = new BasicHashGenerator();
+ var password = hash.Encrypt(request.Password);
+
+ using (var db = ObservablesContextHelper.CreateContext())
+ {
+ user = new UserBuilder(db).Set(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == password).WithRolesAndPermissions().WithDeleted().Build();
+
+ if (user == null)
+ {
+ throw new AuthenticationException("Invalid email or password.");
+ }
+
+ if (user.Deleted)
+ {
+ throw new AuthenticationException("Your account has been disabled. Please contact your administrator.");
+ }
+
+ if (!user.HasPermission(Permissions.DataStoreRead))
+ {
+ throw new AuthenticationException("You are not authorized to access the data store.");
+ }
+
+ var token = WebToken<TokenObject>.CreateNew(MachineServiceConfig.JWT_TOKEN_SECRET, new TokenObject()
+ {
+ UserGuid = user.Guid,
+ Permissions = user.Permissions.Select(x => (Permissions)x.Code).ToList()
+ }, DateTime.UtcNow.AddDays(1));
+
+ return new LoginResponse()
+ {
+ Token = token.AccessToken,
+ ExpirationUTC = token.Expiration.Value,
+ };
+ }
+ }
+
+ [JwtWebApiTokenFilter]
+ public List<DataStoreWebItem> Get(String sn = null, String collection = null, String key = null)
+ {
+ try
+ {
+ if (!RequestToken.Object.Permissions.Contains(Permissions.DataStoreRead))
+ {
+ throw CreateHttpException(new AuthenticationException("The current user was not authorized to read from the data store."), HttpStatusCode.Unauthorized);
+ }
+
+ if (key != null && collection == null)
+ {
+ throw CreateHttpException(new ArgumentException(), HttpStatusCode.BadRequest, "When specifying a key, collection must be specified.");
+ }
+
+ ValidateCollectionAndKey(collection, key);
+
+ using (var db = ObservablesContextHelper.CreateContext())
+ {
+ if (sn != null)
+ {
+ var machineGuid = db.Machines.Where(x => x.SerialNumber == sn).Select(x => x.Guid).FirstOrDefault();
+
+ if (machineGuid == null)
+ {
+ throw CreateHttpException(new KeyNotFoundException(), HttpStatusCode.NotFound, "The specified machine serial number could not be found.");
+ }
+
+ var localItems = db.DataStoreItems.Where(x => !x.IsDeleted).Where(x => x.MachineGuid == machineGuid && (collection == null || x.CollectionName == collection) && (key == null || x.Key == key)).ToList();
+ var globalItems = db.GlobalDataStoreItems.Where(x => (collection == null || x.CollectionName == collection) && (key == null || x.Key == key)).ToList();
+
+ if (localItems.Count == 0 && globalItems.Count == 0 && key != null)
+ {
+ throw CreateHttpException(new KeyNotFoundException(), HttpStatusCode.NotFound, "The specified key was not found on the data store.");
+ }
+
+ List<DataStoreWebItem> finalList = new List<DataStoreWebItem>();
+
+ foreach (var localItem in localItems)
+ {
+ var globalItem = globalItems.FirstOrDefault(x => x.CollectionName == localItem.CollectionName && x.Key == localItem.Key);
+ finalList.Add(localItem.ToWebItem(globalItem));
+ globalItems.Remove(globalItem);
+ }
+
+ finalList.AddRange(globalItems.Select(x => x.ToWebItem()));
+
+ return finalList;
+ }
+ else
+ {
+ var globalItems = db.GlobalDataStoreItems.Where(x => (collection == null || x.CollectionName == collection) && (key == null || x.Key == key)).ToList();
+
+ var finalList = globalItems.Select(x => x.ToWebItem()).ToList();
+
+ return finalList;
+ }
+ }
+ }
+ catch (HttpResponseException ex)
+ {
+ throw ex;
+ }
+ catch (Exception ex)
+ {
+ throw CreateHttpException(ex, HttpStatusCode.InternalServerError);
+ }
+ }
+
+ [JwtWebApiTokenFilter]
+ public void Put([FromBody]DataStoreWebPutItem item)
+ {
+ try
+ {
+ if (!RequestToken.Object.Permissions.Contains(Permissions.DataStoreWrite))
+ {
+ throw CreateHttpException(new AuthenticationException("The current user was not authorized to write to the data store."), HttpStatusCode.Unauthorized);
+ }
+
+ if (item.Collection == null || item.Key == null)
+ {
+ throw CreateHttpException(new AuthenticationException("Collection and key must be specified."), HttpStatusCode.BadRequest);
+ }
+
+ ValidateCollectionAndKey(item.Collection, item.Key);
+
+ using (var db = ObservablesContextHelper.CreateContext())
+ {
+ if (item.MachineSerialNumber != null)
+ {
+ var machineGuid = db.Machines.Where(x => x.SerialNumber == item.MachineSerialNumber).Select(x => x.Guid).FirstOrDefault();
+
+ if (machineGuid == null)
+ {
+ throw CreateHttpException(new KeyNotFoundException("The specified machine serial number could not be found."), HttpStatusCode.NotFound);
+ }
+
+ DataStoreItem dbItem = db.DataStoreItems.FirstOrDefault(x => x.CollectionName == item.Collection && x.Key == item.Key);
+
+ if (dbItem == null)
+ {
+ if (!RequestToken.Object.Permissions.Contains(Permissions.DataStoreCreate))
+ {
+ throw CreateHttpException(new AuthenticationException("The current user was not authorized to create new items on the data store."), HttpStatusCode.Unauthorized);
+ }
+
+ dbItem = new DataStoreItem();
+ dbItem.Key = item.Key;
+ dbItem.CollectionName = item.Collection;
+ dbItem.MachineGuid = machineGuid;
+ db.DataStoreItems.Add(dbItem);
+ }
+
+ dbItem.DataType = (int)item.DataType;
+ dbItem.IsDeleted = false;
+ dbItem.IsSynchronized = false;
+ dbItem.LastUpdated = DateTime.UtcNow;
+ dbItem.Value = EFDataStoreHelper.CreateBytes(item.DataType, DataStoreHelper.ParseDataStoreValue(item.DataType, item.Value.ToStringSafe(), item.ProtoMessageType));
+ }
+ else
+ {
+ if (!RequestToken.Object.Permissions.Contains(Permissions.DataStoreCreateWriteGlobal))
+ {
+ throw CreateHttpException(new AuthenticationException("The current user was not authorized to write to the global data store."), HttpStatusCode.Unauthorized);
+ }
+
+ GlobalDataStoreItem dbItem = db.GlobalDataStoreItems.FirstOrDefault(x => x.CollectionName == item.Collection && x.Key == item.Key);
+
+ if (dbItem == null)
+ {
+ if (!RequestToken.Object.Permissions.Contains(Permissions.DataStoreCreate))
+ {
+ throw CreateHttpException(new AuthenticationException("The current user was not authorized to create new items on the data store."), HttpStatusCode.Unauthorized);
+ }
+
+ dbItem = new GlobalDataStoreItem();
+ dbItem.Key = item.Key;
+ dbItem.CollectionName = item.Collection;
+ db.GlobalDataStoreItems.Add(dbItem);
+ }
+
+ dbItem.DataType = (int)item.DataType;
+ dbItem.LastUpdated = DateTime.UtcNow;
+ dbItem.Value = EFDataStoreHelper.CreateBytes(item.DataType, DataStoreHelper.ParseDataStoreValue(item.DataType, item.Value.ToStringSafe(), item.ProtoMessageType));
+ }
+
+ db.SaveChanges();
+ }
+ }
+ catch (HttpResponseException ex)
+ {
+ throw ex;
+ }
+ catch (Exception ex)
+ {
+ throw CreateHttpException(ex, HttpStatusCode.InternalServerError);
+ }
+ }
+
+ private HttpResponseException CreateHttpException(Exception ex, HttpStatusCode code, String message = null)
+ {
+ return new HttpResponseException(new HttpResponseMessage(code)
+ {
+ Content = new StringContent(message != null ? message : ex.Message),
+ ReasonPhrase = ex.FlattenMessage()
+ });
+ }
+
+ private void ValidateCollectionAndKey(String collection = null, String key = null)
+ {
+ if (collection != null)
+ {
+ if (!DataStoreHelper.ValidateCollectionOrKeyName(collection))
+ {
+ throw new ArgumentException("Collection name contains invalid characters.");
+ }
+ }
+
+ if (key != null)
+ {
+ if (!DataStoreHelper.ValidateCollectionOrKeyName(key))
+ {
+ throw new ArgumentException("Item key contains invalid characters.");
+ }
+ }
+ }
+
+ }
+
+ #region Extension Methods
+
+ public static class IDataStoreExtensions
+ {
+ public static DataStoreWebItem ToWebItem(this DataStoreItem item, GlobalDataStoreItem globalItem = null)
+ {
+ IDataStoreItem dsItem = item.ToDataStoreItem();
+ DataStoreWebItem webItem = new DataStoreWebItem();
+ webItem.Collection = item.CollectionName;
+ webItem.Type = globalItem != null ? DataStoreWebItemType.Overrides : DataStoreWebItemType.Local;
+ webItem.DataType = dsItem.Type;
+ webItem.Date = dsItem.Date;
+ webItem.Key = dsItem.Key;
+ webItem.LocalValue = dsItem.Value;
+
+ if (webItem.LocalValue is DataStoreProtoObject protoObject)
+ {
+ webItem.LocalValue = protoObject.Message;
+ webItem.ProtoMessageType = protoObject.MessageType;
+ }
+
+ if (globalItem != null)
+ {
+ var dsGlobalItem = globalItem.ToDataStoreItem();
+
+ webItem.GlobalValue = dsGlobalItem.Value;
+
+ if (webItem.GlobalValue is DataStoreProtoObject protoObjectGlobal)
+ {
+ webItem.GlobalValue = protoObjectGlobal.Message;
+ webItem.ProtoMessageType = protoObjectGlobal.MessageType;
+ }
+ }
+
+ return webItem;
+ }
+
+ public static DataStoreWebItem ToWebItem(this GlobalDataStoreItem item)
+ {
+ IDataStoreItem dsItem = item.ToDataStoreItem();
+ DataStoreWebItem webItem = new DataStoreWebItem();
+ webItem.Collection = item.CollectionName;
+ webItem.Type = DataStoreWebItemType.Global;
+ webItem.DataType = dsItem.Type;
+ webItem.Date = dsItem.Date;
+ webItem.Key = dsItem.Key;
+ webItem.GlobalValue = dsItem.Value;
+
+ if (webItem.GlobalValue is DataStoreProtoObject protoObject)
+ {
+ webItem.GlobalValue = protoObject.Message;
+ webItem.ProtoMessageType = protoObject.MessageType;
+ }
+
+ return webItem;
+ }
+ }
+ #endregion
+}
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
index fbc4f8a0a..161caaf23 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs
@@ -105,7 +105,7 @@ namespace Tango.MachineService.Controllers
var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
- var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
+ var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid && !x.Disabled).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
response.Version = latest_machine_version.Version;
response.FirmwareVersion = latest_machine_version.FirmwareVersion;
@@ -186,6 +186,15 @@ namespace Tango.MachineService.Controllers
LogManager.Log(ex, $"Error resetting synchronized job runs for machine '{machine.SerialNumber}'.");
}
+ try
+ {
+ b.DataStoreItems.Where(x => x.MachineGuid == machine.Guid).Update(x => new DataStoreItem() { IsSynchronized = false });
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error resetting synchronized data store items for machine '{machine.SerialNumber}'.");
+ }
+
//Reset Events.
//b.MachinesEvents.Where(x => x.MachineGuid == machine.Guid).Update(x => new MachinesEvent() { IsSynchronized = false });
//Reset Jobs.
@@ -218,7 +227,7 @@ namespace Tango.MachineService.Controllers
var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
- var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
+ var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid && !x.Disabled).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
response.Version = latest_machine_version.Version;
response.FirmwareVersion = latest_machine_version.FirmwareVersion;
@@ -337,9 +346,9 @@ namespace Tango.MachineService.Controllers
{
var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid);
- var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
+ var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid && !x.Disabled).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault();
- if (Version.Parse(latest_machine_version.Version) != Version.Parse(request.Version))
+ if (Version.Parse(latest_machine_version.Version) > Version.Parse(request.Version))
{
response.IsUpdateAvailable = true;
}
@@ -755,7 +764,7 @@ namespace Tango.MachineService.Controllers
//Send DataStore Items
if (request.RequestDataStoreItems)
{
- var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList();
+ var dataStoreItems = db.DataStoreItems.Where(x => x.MachineGuid == machine.Guid && !x.IsSynchronized & !x.IsDeleted).Take(request.MaxDataStoreItems).OrderByDescending(x => x.LastUpdated).ToList();
foreach (var item in dataStoreItems)
{
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtWebApiTokenFilter.cs b/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtWebApiTokenFilter.cs
new file mode 100644
index 000000000..89169fc48
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Filters/JwtWebApiTokenFilter.cs
@@ -0,0 +1,72 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Authentication;
+using System.Web;
+using System.Web.Http;
+using System.Web.Http.Controllers;
+using System.Web.Http.Filters;
+using Tango.Transport.Web;
+using Tango.Web.Security;
+
+namespace Tango.MachineService.Filters
+{
+ public class JwtWebApiTokenFilter : ActionFilterAttribute
+ {
+ public bool AllowExpired { get; private set; }
+
+ public JwtWebApiTokenFilter()
+ {
+
+ }
+
+ public JwtWebApiTokenFilter(bool allowExpired)
+ {
+ AllowExpired = allowExpired;
+ }
+
+ public override void OnActionExecuting(HttpActionContext actionContext)
+ {
+ try
+ {
+ var authorizationHeader = actionContext.Request.Headers.Authorization;
+
+ if (authorizationHeader != null && authorizationHeader.Parameter != null)
+ {
+ try
+ {
+ WebToken.Validate(MachineServiceConfig.JWT_TOKEN_SECRET, authorizationHeader.Parameter);
+ }
+ catch (JWT.TokenExpiredException)
+ {
+ if (!AllowExpired)
+ {
+ throw new TokenExpiredException("Token expired.");
+ }
+ }
+ catch (JWT.SignatureVerificationException)
+ {
+ throw new InvalidTokenException("Invalid token.");
+ }
+ }
+ else
+ {
+ throw new AuthenticationException("No token specified.");
+ }
+ }
+ catch (Exception ex)
+ {
+ throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized)
+ {
+ Content = new StringContent(ex.Message),
+ ReasonPhrase = ex.FlattenMessage()
+ });
+ }
+
+ base.OnActionExecuting(actionContext);
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Nswag/DataStoreClient.nswag b/Software/Visual_Studio/Web/Tango.MachineService/Nswag/DataStoreClient.nswag
new file mode 100644
index 000000000..c7aeb10a3
--- /dev/null
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Nswag/DataStoreClient.nswag
@@ -0,0 +1,140 @@
+{
+ "runtime": "Default",
+ "defaultVariables": "",
+ "documentGenerator": {
+ "webApiToOpenApi": {
+ "controllerNames": [
+ "Tango.MachineService.Controllers.DataStoreController"
+ ],
+ "isAspNetCore": false,
+ "resolveJsonOptions": false,
+ "defaultUrlTemplate": "api/{controller}/{action}",
+ "addMissingPathParameters": false,
+ "includedVersions": null,
+ "defaultPropertyNameHandling": "Default",
+ "defaultReferenceTypeNullHandling": "Null",
+ "defaultDictionaryValueReferenceTypeNullHandling": "NotNull",
+ "defaultResponseReferenceTypeNullHandling": "NotNull",
+ "defaultEnumHandling": "Integer",
+ "flattenInheritanceHierarchy": false,
+ "generateKnownTypes": true,
+ "generateEnumMappingDescription": false,
+ "generateXmlObjects": false,
+ "generateAbstractProperties": false,
+ "generateAbstractSchemas": true,
+ "ignoreObsoleteProperties": false,
+ "allowReferencesWithProperties": false,
+ "excludedTypeNames": [],
+ "serviceHost": null,
+ "serviceBasePath": null,
+ "serviceSchemes": [],
+ "infoTitle": "My Title",
+ "infoDescription": null,
+ "infoVersion": "1.0.0",
+ "documentTemplate": null,
+ "documentProcessorTypes": [],
+ "operationProcessorTypes": [],
+ "typeNameGeneratorType": null,
+ "schemaNameGeneratorType": null,
+ "contractResolverType": null,
+ "serializerSettingsType": null,
+ "useDocumentProvider": true,
+ "documentName": "v1",
+ "aspNetCoreEnvironment": null,
+ "createWebHostBuilderMethod": null,
+ "startupType": null,
+ "allowNullableBodyParameters": true,
+ "output": null,
+ "outputType": "Swagger2",
+ "assemblyPaths": [
+ "$(assembly)"
+ ],
+ "assemblyConfig": null,
+ "referencePaths": [],
+ "useNuGetCache": false
+ }
+ },
+ "codeGenerators": {
+ "openApiToCSharpClient": {
+ "clientBaseClass": null,
+ "configurationClass": null,
+ "generateClientClasses": true,
+ "generateClientInterfaces": false,
+ "injectHttpClient": true,
+ "disposeHttpClient": true,
+ "protectedMethods": [],
+ "generateExceptionClasses": true,
+ "exceptionClass": "ApiException",
+ "wrapDtoExceptions": true,
+ "useHttpClientCreationMethod": false,
+ "httpClientType": "System.Net.Http.HttpClient",
+ "useHttpRequestMessageCreationMethod": false,
+ "useBaseUrl": true,
+ "generateBaseUrlProperty": true,
+ "generateSyncMethods": true,
+ "exposeJsonSerializerSettings": false,
+ "clientClassAccessModifier": "public",
+ "typeAccessModifier": "public",
+ "generateContractsOutput": false,
+ "contractsNamespace": null,
+ "contractsOutputFilePath": null,
+ "parameterDateTimeFormat": "s",
+ "parameterDateFormat": "yyyy-MM-dd",
+ "generateUpdateJsonSerializerSettingsMethod": true,
+ "useRequestAndResponseSerializationSettings": false,
+ "serializeTypeInformation": false,
+ "queryNullValue": "",
+ "className": "DataStoreClient",
+ "operationGenerationMode": "MultipleClientsFromOperationId",
+ "additionalNamespaceUsages": [],
+ "additionalContractNamespaceUsages": [],
+ "generateOptionalParameters": false,
+ "generateJsonMethods": false,
+ "enforceFlagEnums": false,
+ "parameterArrayType": "System.Collections.Generic.IEnumerable",
+ "parameterDictionaryType": "System.Collections.Generic.IDictionary",
+ "responseArrayType": "System.Collections.Generic.ICollection",
+ "responseDictionaryType": "System.Collections.Generic.IDictionary",
+ "wrapResponses": false,
+ "wrapResponseMethods": [],
+ "generateResponseClasses": true,
+ "responseClass": "SwaggerResponse",
+ "namespace": "Tango.DataStore.Web",
+ "requiredPropertiesMustBeDefined": true,
+ "dateType": "System.DateTimeOffset",
+ "jsonConverters": null,
+ "anyType": "object",
+ "dateTimeType": "System.DateTimeOffset",
+ "timeType": "System.TimeSpan",
+ "timeSpanType": "System.TimeSpan",
+ "arrayType": "System.Collections.Generic.ICollection",
+ "arrayInstanceType": "System.Collections.ObjectModel.Collection",
+ "dictionaryType": "System.Collections.Generic.IDictionary",
+ "dictionaryInstanceType": "System.Collections.Generic.Dictionary",
+ "arrayBaseType": "System.Collections.ObjectModel.Collection",
+ "dictionaryBaseType": "System.Collections.Generic.Dictionary",
+ "classStyle": "Poco",
+ "generateDefaultValues": true,
+ "generateDataAnnotations": true,
+ "excludedTypeNames": [],
+ "excludedParameterNames": [],
+ "handleReferences": false,
+ "generateImmutableArrayProperties": false,
+ "generateImmutableDictionaryProperties": false,
+ "jsonSerializerSettingsTransformationMethod": null,
+ "inlineNamedArrays": false,
+ "inlineNamedDictionaries": false,
+ "inlineNamedTuples": true,
+ "inlineNamedAny": false,
+ "generateDtoTypes": true,
+ "generateOptionalPropertiesAsNullable": false,
+ "templateDirectory": null,
+ "typeNameGeneratorType": null,
+ "propertyNameGeneratorType": null,
+ "enumNameGeneratorType": null,
+ "serviceHost": null,
+ "serviceSchemes": null,
+ "output": "$(output)"
+ }
+ }
+} \ No newline at end of file
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs
index 41fa77771..e4f5879f5 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Properties/AssemblyInfo.cs
@@ -24,4 +24,4 @@ using System.Runtime.InteropServices;
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: AssemblyVersion("3.0.6.0")]
+[assembly: AssemblyVersion("3.0.8.0")]
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
index c662b1e87..bccd84cad 100644
--- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
+++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj
@@ -316,11 +316,13 @@
</Compile>
<Compile Include="App_Start\BundleConfig.cs" />
<Compile Include="App_Start\FilterConfig.cs" />
+ <Compile Include="Controllers\DataStoreController.cs" />
<Compile Include="Controllers\FSEAccountController.cs" />
<Compile Include="Controllers\FSEDownloadsController.cs" />
<Compile Include="Controllers\DownloadsController.cs" />
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\FSEController.cs" />
+ <Compile Include="Filters\JwtWebApiTokenFilter.cs" />
<Compile Include="Filters\JwtTokenFilter.cs" />
<Compile Include="Hubs\ExternalBridgeHub.cs" />
<Compile Include="MachineServiceConfig.cs" />
@@ -341,6 +343,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Views\FSEAccount\ResetPasswordVM.cs" />
<Compile Include="Views\FSEDownloads\IndexViewModel.cs" />
+ <Content Include="Nswag\DataStoreClient.nswag" />
<None Include="Security\RefreshTokenEncoder.cs" />
<None Include="Security\RefreshTokenEntity.cs" />
<None Include="Security\RefreshTokensManager.cs" />
@@ -402,6 +405,18 @@
</Content>
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\..\DataStore\Tango.DataStore.EF\Tango.DataStore.EF.csproj">
+ <Project>{88d9906b-8fc4-4fe0-b7eb-127a0a8fcee4}</Project>
+ <Name>Tango.DataStore.EF</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\DataStore\Tango.DataStore.Web\Tango.DataStore.Web.csproj">
+ <Project>{a9828548-af43-4ce4-8b13-50e99f9c9cf7}</Project>
+ <Name>Tango.DataStore.Web</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\DataStore\Tango.DataStore\Tango.DataStore.csproj">
+ <Project>{e0364dfa-0721-4637-9d32-9d22aac109d6}</Project>
+ <Name>Tango.DataStore</Name>
+ </ProjectReference>
<ProjectReference Include="..\..\FSE\Tango.FSE.Web\Tango.FSE.Web.csproj">
<Project>{d6f7d31d-7f8c-45e2-ae0a-fbbd1f5f9d5f}</Project>
<Name>Tango.FSE.Web</Name>
@@ -490,7 +505,7 @@
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
</WebProjectProperties>
</FlavorProperties>
- <UserProperties BuildVersion_StartDate="2000/1/1" BuildVersion_UseGlobalSettings="False" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" />
+ <UserProperties BuildVersion_AssemblyInfoFilename="Properties\AssemblyInfo.cs" BuildVersion_UpdateAssemblyVersion="True" BuildVersion_BuildVersioningStyle="None.None.Increment.TimeStamp" BuildVersion_UseGlobalSettings="False" BuildVersion_StartDate="2000/1/1" />
</VisualStudio>
</ProjectExtensions>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">