diff options
Diffstat (limited to 'Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs')
| -rw-r--r-- | Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs | 114 |
1 files changed, 107 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 index f0dc0f2ba..0d35bd776 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/DataStoreController.cs @@ -3,17 +3,36 @@ 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 : ApiController + 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() @@ -21,10 +40,57 @@ namespace Tango.MachineService.Controllers _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."); + } + + 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.FSE_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()) @@ -35,12 +101,17 @@ namespace Tango.MachineService.Controllers if (machineGuid == null) { - return ThrowException<List<DataStoreWebItem>>(new KeyNotFoundException(), HttpStatusCode.NotFound, "The specified machine serial number could not be found."); + 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) @@ -64,16 +135,31 @@ namespace Tango.MachineService.Controllers } } } + catch (HttpResponseException ex) + { + throw ex; + } catch (Exception ex) { - return ThrowException<List<DataStoreWebItem>>(ex, HttpStatusCode.InternalServerError, ex.FlattenMessage()); + throw CreateHttpException(ex, HttpStatusCode.InternalServerError); } } + [JwtWebApiTokenFilter] public void Put([FromBody]DataStoreWebPutItem item) { try { + if (!RequestToken.Object.Permissions.Contains(Permissions.FSE_DataStoreWrite)) + { + throw CreateHttpException(new AuthenticationException("The current user was not authorized to write to the data store."), HttpStatusCode.BadRequest); + } + + 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()) @@ -84,13 +170,18 @@ namespace Tango.MachineService.Controllers if (machineGuid == null) { - ThrowException<List<DataStoreWebItem>>(new KeyNotFoundException(), HttpStatusCode.NotFound, "The specified machine serial number could not be found."); + 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.FSE_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; @@ -110,6 +201,11 @@ namespace Tango.MachineService.Controllers if (dbItem == null) { + if (!RequestToken.Object.Permissions.Contains(Permissions.FSE_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; @@ -124,15 +220,19 @@ namespace Tango.MachineService.Controllers db.SaveChanges(); } } + catch (HttpResponseException ex) + { + throw ex; + } catch (Exception ex) { - ThrowException<List<DataStoreWebItem>>(ex, HttpStatusCode.InternalServerError, ex.FlattenMessage()); + throw CreateHttpException(ex, HttpStatusCode.InternalServerError); } } - private T ThrowException<T>(Exception ex, HttpStatusCode code, String message = null) + private HttpResponseException CreateHttpException(Exception ex, HttpStatusCode code, String message = null) { - throw new HttpResponseException(new HttpResponseMessage(code) + return new HttpResponseException(new HttpResponseMessage(code) { Content = new StringContent(message != null ? message : ex.Message), ReasonPhrase = ex.FlattenMessage() |
