diff options
| author | Avi Levkovich <avi@twine-s.com> | 2020-05-13 13:27:01 +0300 |
|---|---|---|
| committer | Avi Levkovich <avi@twine-s.com> | 2020-05-13 13:27:01 +0300 |
| commit | 15dfc2cdcbc2e518c09c1ee75f32ff149d4a337d (patch) | |
| tree | 4c0b49773706b85282e6f6b1ec3d2e949d3ca22e /Software/Visual_Studio/Web/Tango.MachineService | |
| parent | 6a49e917c587dcbbfe8175b8dde73840b7d105fc (diff) | |
| parent | cd750d626d3780990797faf09446033bbaa4311c (diff) | |
| download | Tango-15dfc2cdcbc2e518c09c1ee75f32ff149d4a337d.tar.gz Tango-15dfc2cdcbc2e518c09c1ee75f32ff149d4a337d.zip | |
commit merge
Diffstat (limited to 'Software/Visual_Studio/Web/Tango.MachineService')
20 files changed, 658 insertions, 27 deletions
diff --git a/Software/Visual_Studio/Web/Tango.MachineService/App_Start/RouteConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService/App_Start/RouteConfig.cs index 613e83e72..51f476be5 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/App_Start/RouteConfig.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/App_Start/RouteConfig.cs @@ -14,6 +14,17 @@ namespace Tango.MachineService routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( + name: "fse", + url: "fse", + defaults: new + { + controller = "FSEDownloads", + action = "Index", + id = UrlParameter.Optional + } + ); + + routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Downloads", action = "Index", id = UrlParameter.Optional } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEAccountController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEAccountController.cs new file mode 100644 index 000000000..b7728af6a --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEAccountController.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Tango.BL; +using Tango.MachineService.Filters; +using Tango.MachineService.Models; +using Tango.Web.Helpers; +using System.Data.Entity; +using Tango.Web.Storage; +using System.IO; +using Microsoft.WindowsAzure.Storage.Blob; +using System.Net.Http; +using System.Net; +using System.Net.Http.Headers; +using System.Net.Mime; +using Tango.MachineService.Views.FSEAccount; + +namespace Tango.MachineService.Controllers +{ + public class FSEAccountController : Controller + { + private static Random rnd = new Random(); + + public ActionResult ResetPassword(String id) + { + ResetPasswordVM vm = new ResetPasswordVM(); + vm.FullName = "Full Name"; + vm.Password = "Password"; + + var reset = FSEController.PendingPasswordResets.SingleOrDefault(x => x.ID == id); + + if (reset != null) + { + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var user = db.Users.SingleOrDefault(x => x.Guid == reset.UserGuid); + + if (user != null) + { + String newPass = GenerateRandomPassword(); + user.Password = Tango.BL.Entities.User.GetPasswordHash(newPass); + user.PasswordChangeRequired = true; + vm.Password = newPass; + vm.FullName = reset.FullName; + db.SaveChanges(); + } + } + } + + return View(vm); + } + + private String GenerateRandomPassword() + { + String pass = String.Empty; + + for (int i = 0; i < 4; i++) + { + pass += rnd.Next(0, 9).ToString(); + } + + return pass; + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs index bb3ef588f..e471ed20c 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEController.cs @@ -1,10 +1,13 @@ -using System; +using SendGrid; +using SendGrid.Helpers.Mail; +using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Security.Authentication; using System.Threading.Tasks; +using System.Web; using System.Web.Http; using Tango.BL; using Tango.BL.Builders; @@ -20,22 +23,32 @@ using Tango.Web.Security; using Tango.Web.SMO; using Tango.Web.SQLServer; using Tango.Web.Storage; +using System.Data.Entity; +using static Tango.MachineService.Controllers.FSEController; namespace Tango.MachineService.Controllers { - public class FSEController : TangoController + public class FSEController : TangoController<TokenObject> { public class TokenObject { public String UserGuid { get; set; } } - /// <summary> - /// Login to the service. - /// </summary> - /// <param name="request">The request.</param> - /// <returns></returns> - /// <exception cref="AuthenticationException"></exception> + public class PasswordReset + { + public String ID { get; set; } + public String UserGuid { get; set; } + public String FullName { get; set; } + } + + public static List<PasswordReset> PendingPasswordResets { get; set; } + + static FSEController() + { + PendingPasswordResets = new List<PasswordReset>(); + } + [HttpPost] public LoginResponse Login(LoginRequest request) { @@ -83,22 +96,6 @@ namespace Tango.MachineService.Controllers AccessTokenExpiration = accessToken.ExpiresOn.UtcDateTime }; - - //Enforce Machine Studio Version ? - //if (MachineServiceConfig.ENFORCE_MACHINE_STUDIO_VERSION) - //{ - // using (var db = ObservablesContextHelper.CreateContext()) - // { - // var latest_version = db.MachineStudioVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); - - // if (latest_version != null && Version.Parse(latest_version.Version) != client_version) - // { - // versionChangeRequired = true; - // requiredVersion = latest_version.Version; - // } - // } - //} - //Return data source return new LoginResponse() { @@ -179,5 +176,152 @@ namespace Tango.MachineService.Controllers return response; } + + [HttpPost] + [JwtTokenFilter] + public CheckForUpdatesResponse CheckForUpdates(CheckForUpdatesRequest request) + { + CheckForUpdatesResponse response = new CheckForUpdatesResponse(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var versions = db.FseVersions.ToList(); + + FseVersion latestVersion = null; + + latestVersion = versions.OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + + Version currentVersion = Version.Parse(request.Version); + + 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 BlobStorageManager(); + var container = manager.GetContainer(MachineServiceConfig.FSE_VERSIONS_CONTAINER); + //var blob = container.GetBlockBlobReference(latestVersion.BlobName); + var installerBlob = container.GetBlockBlobReference(latestVersion.InstallerBlobName); + + //response.BlobAddress = blob.GenerateReadSignature(TimeSpan.FromMinutes(60)); + + if (!String.IsNullOrWhiteSpace(MachineServiceConfig.CDN_ENDPOINT)) + { + //response.CdnAddress = MachineServiceConfig.CDN_ENDPOINT + blob.Uri.AbsolutePath; + response.InstallerCdnAddress = MachineServiceConfig.CDN_ENDPOINT + installerBlob.Uri.AbsolutePath; + } + + response.IsUpdateAvailable = true; + response.Version = latestVersion.Version; + response.Comments = latestVersion.Comments; + } + } + + return response; + } + + [HttpPost] + [JwtTokenFilter] + public RefreshTokenResponse RefreshToken(RefreshTokenRequest request) + { + SQLServerManager sqlServer = new SQLServerManager(); + var accessToken = sqlServer.GetAccessToken(); + + return new RefreshTokenResponse() + { + AccessToken = accessToken.AccessToken, + Expiration = accessToken.ExpiresOn.UtcDateTime, + }; + } + + [HttpPost] + [JwtTokenFilter] + public UserInvitationEmailResponse SendUserInvitationEmail(UserInvitationEmailRequest request) + { + User user; + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + user = db.Users.Include(x => x.Contact).SingleOrDefault(x => x.Guid == request.UserGuid); + + if (user == null) + { + throw new InvalidOperationException("User not found."); + } + } + + var client = new SendGridClient(MachineServiceConfig.SEND_GRID_API_KEY); + SendGridMessage msg = new SendGridMessage(); + msg.SetFrom("info@twine-s.com", "Twine Solutions LTD"); + msg.AddTo(user.Email); + msg.Subject = "Welcome To Tango FSE"; + msg.SetTemplateId("d-2af42ed0ea3c44b3abaa61016223555a"); + + var dynamicTemplateData = new + { + DownloadUrl = $"{request.MachineServiceAddress}/fse", + FullName = user.Contact.FirstName, + Password = request.Password, + }; + + msg.SetTemplateData(dynamicTemplateData); + + var result = client.SendEmailAsync(msg).GetAwaiter().GetResult(); + + if (result.StatusCode != HttpStatusCode.Accepted) + { + throw new HttpException(result.StatusCode.ToString()); + } + + return new UserInvitationEmailResponse(); + } + + [HttpPost] + public ForgotPasswordResponse SendForgotPasswordEmail(ForgotPasswordRequest request) + { + User user; + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + user = db.Users.Include(x => x.Contact).SingleOrDefault(x => x.Email.ToLower() == request.Email.ToLower()); + + if (user == null) + { + throw new InvalidOperationException("User not found."); + } + } + + String resetId = Guid.NewGuid().ToString(); + + var client = new SendGridClient(MachineServiceConfig.SEND_GRID_API_KEY); + SendGridMessage msg = new SendGridMessage(); + msg.SetFrom("info@twine-s.com", "Twine Solutions LTD"); + msg.AddTo(request.Email); + msg.Subject = "Tango FSE Password Reset"; + msg.SetTemplateId("d-18065487dae4456b8684d4b47a91e4a6"); + + var dynamicTemplateData = new + { + ResetPasswordUrl = $"{request.MachineServiceAddress}/FSEAccount/ResetPassword?id={resetId}", + FullName = user.Contact.FirstName, + }; + + msg.SetTemplateData(dynamicTemplateData); + + var result = client.SendEmailAsync(msg).GetAwaiter().GetResult(); + + if (result.StatusCode != HttpStatusCode.Accepted) + { + throw new HttpException(result.StatusCode.ToString()); + } + + PendingPasswordResets.Add(new PasswordReset() + { + ID = resetId, + UserGuid = user.Guid, + FullName = user.Contact.FirstName, + }); + + return new ForgotPasswordResponse(); + } } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEDownloadsController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEDownloadsController.cs new file mode 100644 index 000000000..52eb2bbb5 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/FSEDownloadsController.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using Tango.BL; +using Tango.MachineService.Filters; +using Tango.MachineService.Models; +using Tango.Web.Helpers; +using System.Data.Entity; +using Tango.Web.Storage; +using System.IO; +using Microsoft.WindowsAzure.Storage.Blob; +using System.Net.Http; +using System.Net; +using System.Net.Http.Headers; +using System.Net.Mime; +using Tango.MachineService.Views.FSEDownloads; + +namespace Tango.MachineService.Controllers +{ + public class FSEDownloadsController : Controller + { + public ActionResult Index() + { + IndexViewModel model = new IndexViewModel(); + + using (var db = ObservablesContextHelper.CreateContext()) + { + var versions = db.FseVersions.ToList().OrderByDescending(x => Version.Parse(x.Version)).Take(6).ToList(); + + var manager = new BlobStorageManager(); + var container = manager.GetContainer(MachineServiceConfig.FSE_VERSIONS_CONTAINER); + + foreach (var item in versions) + { + var installerBlob = container.GetBlockBlobReference(item.InstallerBlobName); + + model.Downloads.Add(new FSEDownload() + { + Name = $"Tango FSE v{Version.Parse(item.Version).ToString(3)}", + Version = Version.Parse(item.Version).ToString(3), + Comments = item.Comments, + Date = item.LastUpdated.ToString("dddd, dd MMMM yyyy"), + Address = MachineServiceConfig.CDN_ENDPOINT + installerBlob.Uri.AbsolutePath + }); + } + + if (model.Downloads.Count > 0) + { + var latest = model.Downloads.First(); + model.Downloads.Remove(latest); + model.LatestDownload = latest; + } + } + + return View(model); + } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2049df665..28acb3647 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -344,11 +344,14 @@ namespace Tango.MachineService.Controllers response.IsUpdateAvailable = true; } - if (!String.IsNullOrWhiteSpace(request.FirmwareVersion)) + if (!machine.IsDemo && machine.SetupFirmware) { - if (Version.Parse(latest_machine_version.FirmwareVersion) > Version.Parse(request.FirmwareVersion)) + if (!String.IsNullOrWhiteSpace(request.FirmwareVersion)) { - response.IsUpdateAvailable = true; + if (Version.Parse(latest_machine_version.FirmwareVersion) > Version.Parse(request.FirmwareVersion)) + { + response.IsUpdateAvailable = true; + } } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/abstract1.png b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/abstract1.png Binary files differnew file mode 100644 index 000000000..236545ae9 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/abstract1.png diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/abstract2.png b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/abstract2.png Binary files differnew file mode 100644 index 000000000..2742c71e5 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/abstract2.png diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/download.png b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/download.png Binary files differnew file mode 100644 index 000000000..b5d626701 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/download.png diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/machine_full.png b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/machine_full.png Binary files differnew file mode 100644 index 000000000..ec4890e2e --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/machine_full.png diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/password_reset.png b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/password_reset.png Binary files differnew file mode 100644 index 000000000..c1d42d7c4 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/password_reset.png diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/twine_logo_colored.png b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/twine_logo_colored.png Binary files differnew file mode 100644 index 000000000..2204585dc --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Images/fse/twine_logo_colored.png diff --git a/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs b/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs index 431d64200..bdddbab8f 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/MachineServiceConfig.cs @@ -11,6 +11,7 @@ namespace Tango.MachineService { public static String TANGO_VERSIONS_CONTAINER => ConfigurationManager.AppSettings[nameof(TANGO_VERSIONS_CONTAINER)].ToString(); public static String MACHINE_STUDIO_VERSIONS_CONTAINER => ConfigurationManager.AppSettings[nameof(MACHINE_STUDIO_VERSIONS_CONTAINER)].ToString(); + public static String FSE_VERSIONS_CONTAINER => ConfigurationManager.AppSettings[nameof(FSE_VERSIONS_CONTAINER)].ToString(); public static bool ENFORCE_MACHINE_STUDIO_VERSION => bool.Parse(ConfigurationManager.AppSettings[nameof(ENFORCE_MACHINE_STUDIO_VERSION)].ToString()); public static String JWT_TOKEN_SECRET => ConfigurationManager.AppSettings[nameof(JWT_TOKEN_SECRET)].ToString(); public static String REFRESH_TOKENS_TABLE_NAME => ConfigurationManager.AppSettings[nameof(REFRESH_TOKENS_TABLE_NAME)].ToString(); @@ -20,6 +21,9 @@ namespace Tango.MachineService public static String TFS_COLLECTION_URL => ConfigurationManager.AppSettings[nameof(TFS_COLLECTION_URL)].ToString(); public static String TFS_PERSONAL_TOKEN => ConfigurationManager.AppSettings[nameof(TFS_PERSONAL_TOKEN)].ToString(); + public static String FSE_TFS_USER_EMAIL => ConfigurationManager.AppSettings[nameof(FSE_TFS_USER_EMAIL)].ToString(); + + public static String SEND_GRID_API_KEY => ConfigurationManager.AppSettings[nameof(SEND_GRID_API_KEY)].ToString(); } }
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Styles/FSE/FSELayout.css b/Software/Visual_Studio/Web/Tango.MachineService/Styles/FSE/FSELayout.css new file mode 100644 index 000000000..8c268d7c8 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Styles/FSE/FSELayout.css @@ -0,0 +1,175 @@ +body { + margin: 0; + padding: 0; + overflow-x: hidden; + font-family: 'Segoe UI'; +} + +.fse_primary_background { + background-color: #303030; +} + +.fse_primary_accent_background { + background-color: #009FE7; +} + +.fse_border_background { + background-color: #404040; +} + +.fse_gray_foreground { + color: #808080; +} + +.fse_primary_background_light { + background-color: #404040; +} + +.fse_primary_foreground { + color: #EEEEEE; +} + +.fse_primary_accent { + color: #009FE7; +} + +.fse_header_back { + position: fixed; + padding: 20px; + box-shadow: black 1px 1px 10px 1px; + z-index: 100; + width: 100%; +} + +.fse_machine_logo { + position: absolute; + left: 20px; + top: 20px; + width: 120px; + float: left; +} + +.fse_twine_logo { + height: 80px; + display: block; + margin: auto auto; +} + +.fse_container { + position: absolute; + margin-top: 100px; + overflow: hidden; + clear: both; + width:100%; +} + +.fse_side_abstract { + position: fixed; + width: 60px; + height: 100%; + float: left; + background-image: url('../../Images/fse/abstract1.png'); + background-repeat: repeat; +} + +.fse_side_abstract_top { + position: absolute; + box-shadow: black 0px 3px 10px 2px; + width: 100%; +} + +.fse_history_downloads_container { + float: left; + margin-left: 150px; + margin-top: 20px; + width: 500px; +} + +.fse_history_download { + clear: both; + margin-top: 60px; +} + +.fse_download_title { + vertical-align: baseline middle; +} + +.fse_download_image { + height: 32px; +} + +.fse_download_name { + margin-top: 5px; + margin-left: 5px; + vertical-align: top; + display: inline-block; +} + +.fse_download_date { + float: right; + margin-top: 5px; + vertical-align: top; + display: inline-block; +} + +.fse_download_separator { + clear: both; + height: 1px; + margin-top: 5px; +} + +.fse_download_commets { + font-size: 12px; + margin-top: 10px; +} + +.fse_download_link { + float: right; + text-decoration: none; + padding: 3px 15px; + border-radius: 2px; + font-size: 14px; +} + +.fse_latest_version_container { + border-radius: 5px; + float: left; + margin-top: 100px; + margin-left: 200px; + width: 400px; + text-align: center; + box-shadow: black 0px 0px 5px 0px; +} + +.fse_download_image_latest { + width: 64px; + margin-top: 20px; +} + +.fse_download_title_latest { + margin-top: 10px; + font-size: 20px; + font-weight: 400; + text-align: center; +} + +.fse_download_button_latest { + display: block; + padding: 15px 20px; + margin: 30px; + margin-top: 90px; + font-weight: 700; + border-radius: 25px; + text-decoration: none; + box-shadow: black 0px 0px 5px 0px; +} + +.fse_title { + position: absolute; + display: inline-block; + float: left; + margin-left: 140px; + margin-top: 20px; + font-size: 25px; + font-weight: 400; +} diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj index ee5f3440e..9b25a25a8 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj +++ b/Software/Visual_Studio/Web/Tango.MachineService/Tango.MachineService.csproj @@ -188,6 +188,9 @@ <Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL"> <HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath> </Reference> + <Reference Include="SendGrid"> + <HintPath>..\..\Referenced Assemblies\SendGrid\SendGrid.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.Data" /> <Reference Include="System.Data.DataSetExtensions" /> @@ -313,6 +316,8 @@ </Compile> <Compile Include="App_Start\BundleConfig.cs" /> <Compile Include="App_Start\FilterConfig.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" /> @@ -333,6 +338,8 @@ </Compile> <Compile Include="Models\SessionVariables.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Views\FSEAccount\ResetPasswordVM.cs" /> + <Compile Include="Views\FSEDownloads\IndexViewModel.cs" /> <None Include="Security\RefreshTokenEncoder.cs" /> <None Include="Security\RefreshTokenEntity.cs" /> <None Include="Security\RefreshTokensManager.cs" /> @@ -340,6 +347,16 @@ <Compile Include="Security\TokenManager.cs" /> <Compile Include="Startup.cs" /> <Compile Include="Views\Downloads\IndexViewModel.cs" /> + <Content Include="Images\fse\abstract1.png" /> + <Content Include="Images\fse\abstract2.png" /> + <Content Include="Images\fse\download.png" /> + <Content Include="Images\fse\machine_full.png" /> + <Content Include="Images\fse\password_reset.png" /> + <Content Include="Images\fse\twine_logo_colored.png" /> + <Content Include="Styles\FSE\FSELayout.css" /> + <Content Include="Views\FSEDownloads\Index.cshtml" /> + <Content Include="Views\Shared\_FSELayout.cshtml" /> + <Content Include="Views\FSEAccount\ResetPassword.cshtml" /> </ItemGroup> <ItemGroup> <Content Include="Global.asax" /> diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEAccount/ResetPassword.cshtml b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEAccount/ResetPassword.cshtml new file mode 100644 index 000000000..f0281d462 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEAccount/ResetPassword.cshtml @@ -0,0 +1,26 @@ +@model Tango.MachineService.Views.FSEAccount.ResetPasswordVM + +@{ + Layout = "~/Views/Shared/_FSELayout.cshtml"; +} + +<style> + .center-div { + position:relative; + clear: both; + margin-top: 100px; + text-align:center; + } +</style> + +<div class="center-div"> + <img src="~/Images/fse/password_reset.png" /> + <h2>Hello @Model.FullName,</h2> + <br /> + <h3>Your Tango FSE password was successfully reset</h3> + <div>Your new temporary password is:</div> + <div style="color:darkorange;font-weight:400">@Model.Password</div> + <br/> + <div style="color:gray">Please login to your account using the Tango FSE software to complete the process</div> +</div> + diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEAccount/ResetPasswordVM.cs b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEAccount/ResetPasswordVM.cs new file mode 100644 index 000000000..c1a1a3106 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEAccount/ResetPasswordVM.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Tango.MachineService.Views.FSEAccount +{ + public class ResetPasswordVM + { + public String FullName { get; set; } + public String Password { get; set; } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEDownloads/Index.cshtml b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEDownloads/Index.cshtml new file mode 100644 index 000000000..7353ab76e --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEDownloads/Index.cshtml @@ -0,0 +1,39 @@ +@model Tango.MachineService.Views.FSEDownloads.IndexViewModel + +@{ + Layout = "~/Views/Shared/_FSELayout.cshtml"; +} + + +<div class="fse_history_downloads_container"> + + @foreach (var item in Model.Downloads) + { + <div class="fse_history_download"> + <div class="fse_download_title"> + <img class="fse_download_image" src="~/Images/fse/download.png" /> + <span class="fse_download_name">@item.Name</span> + <span class="fse_download_date">@item.Date</span> + </div> + <div class="fse_download_separator fse_border_background"> + + </div> + <div class="fse_download_commets fse_gray_foreground"> + @item.Comments + </div> + + <a class="fse_download_link fse_primary_background_light fse_primary_accent" href="@item.Address"> + Download + </a> + </div> + } +</div> + +<div class="fse_latest_version_container fse_primary_background_light"> + <img class="fse_download_image_latest" src="~/Images/fse/download.png" /> + <div class="fse_download_title_latest">Download Latest Version</div> + <div class="fse_download_title_latest fse_primary_accent" style="margin-top:5px;">v@(Model.LatestDownload.Version)</div> + <div class="fse_download_commets fse_gray_foreground">@Model.LatestDownload.Comments</div> + <a class="fse_download_button_latest fse_primary_accent_background fse_primary_foreground" href="@Model.LatestDownload.Address">DOWNLOAD</a> +</div> + diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEDownloads/IndexViewModel.cs b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEDownloads/IndexViewModel.cs new file mode 100644 index 000000000..398b5fcc1 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Views/FSEDownloads/IndexViewModel.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; + +namespace Tango.MachineService.Views.FSEDownloads +{ + public class IndexViewModel + { + public List<FSEDownload> Downloads { get; set; } + public FSEDownload LatestDownload { get; set; } + + public IndexViewModel() + { + Downloads = new List<FSEDownload>(); + } + } + + public class FSEDownload + { + public String Name { get; set; } + public String Version { get; set; } + public String Date { get; set; } + public String Comments { get; set; } + public String Address { get; set; } + } +}
\ No newline at end of file diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Views/Shared/_FSELayout.cshtml b/Software/Visual_Studio/Web/Tango.MachineService/Views/Shared/_FSELayout.cshtml new file mode 100644 index 000000000..15ca9f651 --- /dev/null +++ b/Software/Visual_Studio/Web/Tango.MachineService/Views/Shared/_FSELayout.cshtml @@ -0,0 +1,42 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width" /> + <title>@ViewBag.Title</title> + @*@Styles.Render("~/Content/css")*@ + @*@Scripts.Render("~/bundles/modernizr")*@ + + <link rel="stylesheet" href="~/Styles/FSE/FSELayout.css"> + @RenderSection("styles", required: false) +</head> +<body class="fse_primary_background fse_primary_foreground"> + + <header class="header"></header> + + <div> + + <div id="fseAbstract" class="fse_side_abstract"> + <div class="fse_side_abstract_top"> + + </div> + </div> + + <div class="fse_header_back fse_primary_background_light"> + <img src="~/Images/fse/machine_full.png" class="fse_machine_logo" /> + <span class="fse_title">Tango FSE</span> + <img src="~/Images/fse/twine_logo_colored.png" class="fse_twine_logo" /> + </div> + + <div> + <div class="fse_container"> + @RenderBody() + </div> + </div> + </div> + + @Scripts.Render("~/bundles/jquery") + @*@Scripts.Render("~/bundles/bootstrap")*@ + @RenderSection("scripts", required: false) +</body> +</html> diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Web.config b/Software/Visual_Studio/Web/Tango.MachineService/Web.config index 291145d36..9cfdc9ccd 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Web.config +++ b/Software/Visual_Studio/Web/Tango.MachineService/Web.config @@ -23,6 +23,7 @@ <add key="APP_SECRET" value="54)019A7wv+#86l*PQcQWYKu%fd4Dv!@G=VhCiDI5rD+H4BTH" /> <add key="TANGO_VERSIONS_CONTAINER" value="tango-versions-dev" /> <add key="MACHINE_STUDIO_VERSIONS_CONTAINER" value="machine-studio-versions-dev" /> + <add key="FSE_VERSIONS_CONTAINER" value="fse-versions-dev" /> <add key="DEPLOYMENT_SLOT" value="DEV" /> <add key="ENVIRONMENT_GROUP" value="Tango DEV" /> <add key="ENFORCE_MACHINE_STUDIO_VERSION" value="false" /> @@ -35,6 +36,8 @@ <add key="TFS_COLLECTION_URL" value="https://twinetfs.visualstudio.com" /> <add key="TFS_PERSONAL_TOKEN" value="pyulwgs7m3v7pizz3oxusypdkdfw43txggo5mjwu2ouyv2qwprhq" /> <add key="FSE_TFS_USER_EMAIL" value="fse@twine-s.com" /> + + <add key="SEND_GRID_API_KEY" value="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" /> </appSettings> <!-- For a description of web.config changes see http://go.microsoft.com/fwlink/?LinkId=235367. |
