using Microsoft.IdentityModel.Clients.ActiveDirectory; 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; using Tango.BL.Builders; using Tango.BL.Entities; using Tango.BL.Enumerations; using Tango.Core.Cryptography; using Tango.MachineService.Models; using Tango.MachineStudio.Common.Authentication; using System.Data.Entity; using Tango.MachineStudio.Common.Update; using Tango.Web.Controllers; using Tango.Web.Helpers; using Tango.Web.Storage; namespace Tango.MachineService.Controllers { public class MachineStudioController : JsonController { private static List _pendingUploads; static MachineStudioController() { _pendingUploads = new List(); } #region Update [HttpPost] public CheckForUpdatesResponse CheckForUpdates(CheckForUpdatesRequest request) { LogManager.Log("Request received..."); CheckForUpdatesResponse response = new CheckForUpdatesResponse(); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { //Load relation first... db.Roles.ToList(); db.Permissions.ToList(); db.UsersRoles.ToList(); db.RolesPermissions.ToList(); var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); if (user != null && user.HasPermission(Permissions.RunMachineStudio) || (request.Email == "ForceUpdate")) { var versions = db.MachineStudioVersions.ToList(); MachineStudioVersion latestVersion = null; if (request.AcceptBetaRelease) { latestVersion = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); } else { latestVersion = versions.Where(x => x.Stable).OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); } Version currentVersion = Version.Parse(request.Version); bool isForcedUpdate = versions.Exists(x => x.ForceUpdate && Version.Parse(x.Version) > currentVersion); String comments = String.Join(Environment.NewLine, versions.OrderBy(x => Version.Parse(x.Version)).Where(x => Version.Parse(x.Version) > currentVersion).Select(x => x.Comments)); if (latestVersion != null && Version.Parse(latestVersion.Version) > currentVersion) { var manager = new StorageManager(); var container = manager.GetContainer(MachineServiceConfig.MACHINE_STUDIO_VERSIONS_CONTAINER); var blob = container.GetBlockBlobReference(latestVersion.BlobName); response.BlobAddress = blob.GenerateReadSignature(TimeSpan.FromMinutes(60)); response.IsUpdateAvailable = true; response.Version = latestVersion.Version; response.Comments = latestVersion.Comments; response.ForcedUpdate = isForcedUpdate; response.IsStable = latestVersion.Stable; } } else { throw new AuthenticationException("Invalid user credentials."); } } return response; } [HttpPost] public UploadVersionResponse UploadVersion(UploadVersionRequest request) { UploadVersionResponse response = new UploadVersionResponse(); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { //Load relation first... db.Roles.ToList(); db.Permissions.ToList(); db.UsersRoles.ToList(); db.RolesPermissions.ToList(); var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower() && x.Password == request.Password); if (user != null && user.HasPermission(Permissions.PublishMachineStudioVersions)) { var latestVersion = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); Version currentVersion = Version.Parse(request.Version); if (latestVersion == null || currentVersion > Version.Parse(latestVersion.Version)) { String newVersionFileName = "Machine Studio Version" + " " + currentVersion.ToString() + ".zip"; var manager = new StorageManager(); var container = manager.GetContainer(MachineServiceConfig.MACHINE_STUDIO_VERSIONS_CONTAINER); var blob = container.CreateEmptyBlob(newVersionFileName); response.Token = Guid.NewGuid().ToString(); response.BlobAddress = blob.GenerateWriteSignature(TimeSpan.FromMinutes(30)); _pendingUploads.Add(new MachineStudioPendingUpload() { UserGuid = user.Guid, Comments = request.Comments, ForcedUpdate = request.ForcedUpdate, Token = response.Token, Version = request.Version, IsStable = request.IsStable, BlobName = blob.Name, }); } else { throw new ArgumentException("New version must be greater than latest version."); } } else { throw new AuthenticationException("Invalid user credentials."); } } return response; } [HttpPost] public UploadCompletedResponse NotifyUploadCompleted(UploadCompletedRequest request) { MachineStudioPendingUpload upload = _pendingUploads.FirstOrDefault(x => x.Token == request.Token); if (upload != null) { _pendingUploads.RemoveAll(x => x.Token == upload.Token); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { db.MachineStudioVersions.Add(new MachineStudioVersion() { Comments = upload.Comments, BlobName = upload.BlobName, UserGuid = upload.UserGuid, Version = upload.Version, ForceUpdate = upload.ForcedUpdate, Stable = upload.IsStable, }); db.SaveChanges(); } return new UploadCompletedResponse(); } else { throw new ArgumentException("Invalid Token."); } } [HttpPost] public LatestVersionResponse GetLatestVersion(LatestVersionRequest request) { using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { var version = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); return new LatestVersionResponse() { Version = version != null ? version.Version : "0.0.0.0" }; } } #endregion [HttpPost] public LoginResponse Login(LoginRequest request) { AuthenticationResult authResult = AzureDirectoryHelper.AuthenticateUser(request.Email, request.Password); using (ObservablesContext db = ObservablesContextHelper.CreateContext()) { db.Roles.ToList(); db.Permissions.ToList(); db.UsersRoles.ToList(); db.RolesPermissions.ToList(); var user = db.Users.SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower()); IHashGenerator g = new BasicHashGenerator(); if (user == null) { //Than add the user !! User new_user = new User(); new_user.Email = request.Email; new_user.Password = g.Encrypt(request.Password); new_user.Organization = db.Organizations.Include(x => x.Address).Single(x => x.Name == "Twine"); new_user.Address = new_user.Organization.Address.Clone(); new_user.Contact = new Contact() { FirstName = authResult.UserInfo.GivenName, LastName = authResult.UserInfo.FamilyName, FullName = authResult.UserInfo.GivenName + " " + authResult.UserInfo.FamilyName, Email = request.Email, }; new_user.Roles.Add(db.Roles.Single(x => (Roles)x.Code == Roles.User)); } else { user.Password = g.Encrypt(request.Password); } db.SaveChanges(); } return new LoginResponse() { DataSource = new Core.DataSource() { Address = MachineServiceConfig.DB_ADDRESS, Catalog = MachineServiceConfig.DB_CATALOG, Type = Core.DataSourceType.Azure, IntegratedSecurity = false, UserName = request.Email, Password = request.Password, } }; } } }