diff --git a/src/Yavsc.Server/ViewModels/Account/RegisterViewModel.cs b/src/Yavsc.Abstract/Authentication/RegisterViewModel.cs similarity index 94% rename from src/Yavsc.Server/ViewModels/Account/RegisterViewModel.cs rename to src/Yavsc.Abstract/Authentication/RegisterViewModel.cs index 5f6f3d5d..861813ce 100644 --- a/src/Yavsc.Server/ViewModels/Account/RegisterViewModel.cs +++ b/src/Yavsc.Abstract/Authentication/RegisterViewModel.cs @@ -1,10 +1,11 @@ using System.ComponentModel.DataAnnotations; using Yavsc.Attributes.Validation; +using Yavsc.Abstract; + using Yavsc; namespace Yavsc.ViewModels.Account { - using Yavsc; - public class RegisterViewModel + public class RegisterModel { [YaStringLength(2,Constants.MaxUserNameLength)] diff --git a/src/Yavsc.Server/Models/Auth/Scope.cs b/src/Yavsc.Abstract/Authentication/Scope.cs similarity index 100% rename from src/Yavsc.Server/Models/Auth/Scope.cs rename to src/Yavsc.Abstract/Authentication/Scope.cs diff --git a/src/Yavsc/Hubs/HubInputValidator.cs b/src/Yavsc.Abstract/Chat/HubInputValidator.cs similarity index 99% rename from src/Yavsc/Hubs/HubInputValidator.cs rename to src/Yavsc.Abstract/Chat/HubInputValidator.cs index 19409fd1..22d7ee80 100644 --- a/src/Yavsc/Hubs/HubInputValidator.cs +++ b/src/Yavsc.Abstract/Chat/HubInputValidator.cs @@ -21,6 +21,7 @@ using System; using System.Linq; +using Yavsc; namespace Yavsc { diff --git a/src/Yavsc.Abstract/Constants.cs b/src/Yavsc.Abstract/Constants.cs new file mode 100644 index 00000000..54f3346c --- /dev/null +++ b/src/Yavsc.Abstract/Constants.cs @@ -0,0 +1,65 @@ +using Yavsc.Models.Auth; + +namespace Yavsc +{ + + public static class Constants + { + public static readonly Scope[] SiteScopes = {  + new Scope { Id = "profile", Description = "Your profile informations" },   + new Scope { Id = "book" , Description ="Your booking interface"},   + new Scope { Id = "blog" , Description ="Your blogging interface"},   + new Scope { Id = "estimate" , Description ="Your estimation interface"},   + new Scope { Id = "contract" , Description ="Your contract signature access"},  + new Scope { Id = "admin" , Description ="Your administration rights on this site"},  + new Scope { Id = "moderation" , Description ="Your moderator interface"},  + new Scope { Id = "frontoffice" , Description ="Your front office interface" } + }; + + public const string CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company"; + public const string UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9._-]*$"; + public const string UserFileNamePatternRegExp = @"^([a-zA-Z0-9._-]*/)*[a-zA-Z0-9._-]+$"; + public const string AuthorizePath = "/authorize"; + public const string TokenPath = "/token"; + public const string LoginPath = "/signin"; + public const string LogoutPath = "/signout"; + + public const string UserInfoPath = "/api/me"; + + public const string SignalRPath = "/api/signalr"; + public const string LiveUserPath = "live"; + + public const string ApplicationAuthenticationSheme = "ServerCookie"; + public const string ExternalAuthenticationSheme = "ExternalCookie"; + public const string DefaultFactor = "Default"; + public const string MobileAppFactor = "Mobile Application"; + public const string EMailFactor = "Email"; + public const string SMSFactor = "SMS"; + public const string AdminGroupName = "Administrator"; + public const string PerformerGroupName = "Performer"; + public const string StarGroupName = "Star"; + public const string StarHunterGroupName = "StarHunter"; + public const string BlogModeratorGroupName = "Moderator"; + public const string FrontOfficeGroupName = "FrontOffice"; + public const string UserFilesPath = "/files"; + public const string AvatarsPath = "/avatars"; + public const string GitPath = "/sources"; + public const string DefaultAvatar = "/images/Users/icon_user.png"; + public const string AnonAvatar = "/images/Users/icon_anon_user.png"; + public const string YavscConnectionStringEnvName = "YAVSC_DB_CONNECTION"; + + // at the end, let 4*4 bytes in peace + public const int WebSocketsMaxBufLen = 4 * 1020; + + public static readonly long DefaultFSQ = 1024 * 1024 * 500; + + + public const string SshHeaderKey = "SSH"; + + public static readonly string NoneCode = "none"; + + public const int MaxUserNameLength = 26; + + public const string LivePath = "/live/cast"; + } +} diff --git a/src/Yavsc.Abstract/Makefile b/src/Yavsc.Abstract/Makefile index afd2bc7c..1b552c2c 100644 --- a/src/Yavsc.Abstract/Makefile +++ b/src/Yavsc.Abstract/Makefile @@ -2,7 +2,8 @@ SOURCE_DIR=$(HOME)/workspace/yavsc MAKEFILE_DIR=$(SOURCE_DIR)/scripts/build/make BASERESX=Resources/Yavsc.Attributes.Validation.Resources.resx \ Resources/Yavsc.Models.Messaging.Resources.resx \ - Resources/Yavsc.Models.IT.Fixing.Bug.resx + Resources/Yavsc.Models.IT.Fixing.Bug.resx\ + Resources/Yavsc.ChatHub.resx BASERESXGEN=$(BASERESX:.resx=.Designer.cs) include $(MAKEFILE_DIR)/versioning.mk include $(MAKEFILE_DIR)/dnx.mk diff --git a/src/Yavsc/Resources/Yavsc.ChatHub.Designer.cs b/src/Yavsc.Abstract/Resources/Yavsc.ChatHub.Designer.cs similarity index 95% rename from src/Yavsc/Resources/Yavsc.ChatHub.Designer.cs rename to src/Yavsc.Abstract/Resources/Yavsc.ChatHub.Designer.cs index 8ed93b2f..915867cd 100644 --- a/src/Yavsc/Resources/Yavsc.ChatHub.Designer.cs +++ b/src/Yavsc.Abstract/Resources/Yavsc.ChatHub.Designer.cs @@ -26,7 +26,7 @@ namespace Yavsc { public static System.Resources.ResourceManager ResourceManager { get { if (object.Equals(null, resourceMan)) { - System.Resources.ResourceManager temp = new System.Resources.ResourceManager(("Yavsc.Resources." + "Yavsc.ChatHub"), typeof(ChatHub).GetTypeInfo().Assembly); + System.Resources.ResourceManager temp = new System.Resources.ResourceManager(("Yavsc.Abstract.Resources." + "Yavsc.ChatHub"), typeof(ChatHub).GetTypeInfo().Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/Yavsc/Resources/Yavsc.ChatHub.en.resx b/src/Yavsc.Abstract/Resources/Yavsc.ChatHub.en.resx similarity index 100% rename from src/Yavsc/Resources/Yavsc.ChatHub.en.resx rename to src/Yavsc.Abstract/Resources/Yavsc.ChatHub.en.resx diff --git a/src/Yavsc/Resources/Yavsc.ChatHub.resx b/src/Yavsc.Abstract/Resources/Yavsc.ChatHub.resx similarity index 100% rename from src/Yavsc/Resources/Yavsc.ChatHub.resx rename to src/Yavsc.Abstract/Resources/Yavsc.ChatHub.resx diff --git a/src/Yavsc.Server/Constants.cs b/src/Yavsc.Server/Constants.cs index 154600bd..0e97bbed 100644 --- a/src/Yavsc.Server/Constants.cs +++ b/src/Yavsc.Server/Constants.cs @@ -1,69 +1,19 @@ -namespace Yavsc +namespace Yavsc.Server { using Microsoft.AspNet.Http; using Yavsc.Models.Auth; - public static class Constants + public static class ServerConstants { - public const string ApplicationName = "Yavsc", - CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company", - UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9._-]*$", - UserFileNamePatternRegExp = @"^([a-zA-Z0-9._-]*/)*[a-zA-Z0-9._-]+$", - AuthorizePath = "~/authorize", - TokenPath = "~/token", - LoginPath = "~/signin", - LogoutPath = "~/signout", UserInfoPath = "~/api/me", - SignalRPath = "/api/signalr", - LiveUserPath = "live", + public const string ApplicationName = "Yavsc"; + public const string CompanyInfoUrl = " https://societeinfo.com/app/rest/api/v1/company/json?registration_number={0}&key={1}"; - ApplicationAuthenticationSheme = "ServerCookie", - ExternalAuthenticationSheme= "ExternalCookie", - CompanyInfoUrl = " https://societeinfo.com/app/rest/api/v1/company/json?registration_number={0}&key={1}", - DefaultFactor = "Default", - MobileAppFactor = "Mobile Application", - EMailFactor = "Email", - SMSFactor = "SMS", - AdminGroupName = "Administrator", - PerformerGroupName = "Performer", - StarGroupName = "Star", - StarHunterGroupName = "StarHunter", - BlogModeratorGroupName = "Moderator", - FrontOfficeGroupName = "FrontOffice", - GCMNotificationUrl = "https://gcm-http.googleapis.com/gcm/send", - UserFilesPath = "/files", - AvatarsPath = "/avatars", - GitPath = "/sources", - DefaultAvatar = "/images/Users/icon_user.png", - AnonAvatar = "/images/Users/icon_anon_user.png", - YavscConnectionStringEnvName = "YAVSC_DB_CONNECTION"; - - // at the end, let 4*4 bytes in peace - public const int WebSocketsMaxBufLen = 4*1020; - - public static readonly long DefaultFSQ = 1024*1024*500; - - public static readonly Scope[] SiteScopes = {  - new Scope { Id = "profile", Description = "Your profile informations" },   - new Scope { Id = "book" , Description ="Your booking interface"},   - new Scope { Id = "blog" , Description ="Your blogging interface"},   - new Scope { Id = "estimate" , Description ="Your estimation interface"},   - new Scope { Id = "contract" , Description ="Your contract signature access"},  - new Scope { Id = "admin" , Description ="Your administration rights on this site"},  - new Scope { Id = "moderation" , Description ="Your moderator interface"},  - new Scope { Id = "frontoffice" , Description ="Your front office interface" } - }; - - public const string SshHeaderKey = "SSH"; private static readonly string[] GoogleScopes = { "openid", "profile", "email" }; public static readonly string[] GoogleCalendarScopes = { "openid", "profile", "email", "https://www.googleapis.com/auth/calendar" }; - public static readonly string NoneCode = "none"; - - public const int MaxUserNameLength = 26; - public const string LivePath = "/live/cast"; } } diff --git a/src/Yavsc.Server/Models/Access/CircleAuthorizationToFile.cs b/src/Yavsc.Server/Models/Access/CircleAuthorizationToFile.cs index 37e271fd..9884838d 100644 --- a/src/Yavsc.Server/Models/Access/CircleAuthorizationToFile.cs +++ b/src/Yavsc.Server/Models/Access/CircleAuthorizationToFile.cs @@ -1,6 +1,7 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using Newtonsoft.Json; +using Yavsc.Abstract; using Yavsc.Abstract.Identity.Security; using Yavsc.Attributes.Validation; using Yavsc.Models.Relationship; @@ -27,4 +28,4 @@ namespace Yavsc.Server.Models.Access [ForeignKey("CircleId"), JsonIgnore] public virtual Circle Circle { get; set; } } -} \ No newline at end of file +} diff --git a/src/Yavsc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs b/src/Yavsc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs index a7717f52..cbc1c45e 100644 --- a/src/Yavsc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs +++ b/src/Yavsc.Server/ViewModels/Account/ExternalLoginConfirmationViewModel.cs @@ -1,5 +1,6 @@ using System.ComponentModel.DataAnnotations; +using Yavsc.Abstract; using Yavsc.Attributes.Validation; namespace Yavsc.ViewModels.Account diff --git a/src/Yavsc/ApiControllers/accounting/AccountController.cs b/src/Yavsc/ApiControllers/accounting/AccountController.cs index 8f44d61c..2f089670 100644 --- a/src/Yavsc/ApiControllers/accounting/AccountController.cs +++ b/src/Yavsc/ApiControllers/accounting/AccountController.cs @@ -91,7 +91,7 @@ namespace Yavsc.WebApi.Controllers // POST api/Account/Register [AllowAnonymous] - public async Task Register(RegisterViewModel model) + public async Task Register(RegisterModel model) { if (!ModelState.IsValid) { diff --git a/src/Yavsc/AuthorizationServer/UserTokenProvider.cs b/src/Yavsc/AuthorizationServer/UserTokenProvider.cs index 3eb08763..cd20786b 100644 --- a/src/Yavsc/AuthorizationServer/UserTokenProvider.cs +++ b/src/Yavsc/AuthorizationServer/UserTokenProvider.cs @@ -4,6 +4,7 @@ using System.Threading.Tasks; using Microsoft.AspNet.DataProtection; using Microsoft.AspNet.Identity; using Yavsc.Models; +using Yavsc.Server; namespace Yavsc.Auth { @@ -22,14 +23,14 @@ namespace Yavsc.Auth { public Task GenerateAsync(string purpose, UserManager manager, ApplicationUser user) { if ( user==null ) throw new InvalidOperationException("no user"); - var por = new MonoDataProtector(Constants.ApplicationName,new string[] { purpose } ); + var por = new MonoDataProtector(ServerConstants.ApplicationName, new string[] { purpose } ); return Task.FromResult(por.Protect(UserStamp(user))); } public Task ValidateAsync(string purpose, string token, UserManager manager, ApplicationUser user) { - var por = new MonoDataProtector(Constants.ApplicationName,new string[] { purpose } ); + var por = new MonoDataProtector(ServerConstants.ApplicationName,new string[] { purpose } ); var userStamp = por.Unprotect(token); Console.WriteLine ("Unprotected: "+userStamp); string [] values = userStamp.Split(';'); @@ -40,4 +41,4 @@ namespace Yavsc.Auth { return $"{user.Id};{user.Email};{user.UserName}"; } } -} \ No newline at end of file +} diff --git a/src/Yavsc/Controllers/Accounting/AccountController.cs b/src/Yavsc/Controllers/Accounting/AccountController.cs index e90dbda7..332a36a8 100644 --- a/src/Yavsc/Controllers/Accounting/AccountController.cs +++ b/src/Yavsc/Controllers/Accounting/AccountController.cs @@ -244,7 +244,7 @@ namespace Yavsc.Controllers [HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task Register(RegisterViewModel model) + public async Task Register(RegisterModel model) { if (ModelState.IsValid) { @@ -315,7 +315,7 @@ namespace Yavsc.Controllers { var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Action("ConfirmEmail", "Account", - new { userId = user.Id, code = code }, protocol: "https", host: Startup.Authority); + new { userId = user.Id, code = code }, protocol: "https", host: Startup.Authority); var res = await _emailSender.SendEmailAsync(user.UserName, user.Email, this._localizer["ConfirmYourAccountTitle"], string.Format(this._localizer["ConfirmYourAccountBody"], @@ -525,6 +525,7 @@ namespace Yavsc.Controllers // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 // Send an email with this link + var code = await _userManager.GeneratePasswordResetTokenAsync(user); var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: "https", host: Startup.Authority); @@ -532,6 +533,8 @@ namespace Yavsc.Controllers await _emailSender.SendEmailAsync(user.UserName, user.Email, _localizer["Reset Password"], _localizer["Please reset your password by following this link:"] + " <" + callbackUrl + ">"); + + return View("ForgotPasswordConfirmation"); } @@ -611,6 +614,9 @@ namespace Yavsc.Controllers { return View("Error", new Exception("No Two factor authentication user")); } + + + var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user); @@ -635,16 +641,9 @@ namespace Yavsc.Controllers } // Generate the token and send it - var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider); - if (string.IsNullOrWhiteSpace(code)) - { - return View("Error", new Exception("Code is empty")); - } - - var message = "Your security code is: " + code; if (model.SelectedProvider == Constants.MobileAppFactor) { - return View("Error", new Exception("No SMS service was activated")); + return View("Error", new Exception("No mobile app service was activated")); } else // if (model.SelectedProvider == Constants.EMailFactor || model.SelectedProvider == "Default" ) if (model.SelectedProvider == Constants.SMSFactor) @@ -654,7 +653,7 @@ namespace Yavsc.Controllers } else // if (model.SelectedProvider == Constants.EMailFactor || model.SelectedProvider == "Default" ) { - await _emailSender.SendEmailAsync(user.UserName, await _userManager.GetEmailAsync(user), "Security Code", message); + var sent = await this.SendEMailForConfirmAsync(user); } return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe }); } @@ -690,6 +689,7 @@ namespace Yavsc.Controllers // If a user enters incorrect codes for a specified amount of time then the user account // will be locked out for a specified amount of time. _logger.LogWarning("Signin with code: {0} {1}", model.Provider, model.Code); + var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser); if (result.Succeeded) { diff --git a/src/Yavsc/Helpers/CompanyInfoHelpers.cs b/src/Yavsc/Helpers/CompanyInfoHelpers.cs index 148a7207..dcee9063 100644 --- a/src/Yavsc/Helpers/CompanyInfoHelpers.cs +++ b/src/Yavsc/Helpers/CompanyInfoHelpers.cs @@ -5,12 +5,14 @@ using Newtonsoft.Json.Linq; namespace Yavsc.Helpers { using Models.societe.com; + using Yavsc.Server; + public static class ComapnyInfoHelpers {  public static async Task CheckSiren(this HttpClient web, string siren, CompanyInfoSettings api) { using (var request = new HttpRequestMessage(HttpMethod.Get, - string.Format(Constants.CompanyInfoUrl,siren,api.ApiKey))) { + string.Format(ServerConstants.CompanyInfoUrl,siren,api.ApiKey))) { using (var response = await web.SendAsync(request)) { var payload = JObject.Parse(await response.Content.ReadAsStringAsync()); return payload.ToObject(); @@ -18,4 +20,4 @@ namespace Yavsc.Helpers } } } -} \ No newline at end of file +} diff --git a/src/Yavsc/Makefile b/src/Yavsc/Makefile index 050f255f..4eba5147 100644 --- a/src/Yavsc/Makefile +++ b/src/Yavsc/Makefile @@ -5,7 +5,6 @@ ASPNET_LOG_LEVEL=debug SOURCE_DIR=$(HOME)/workspace/yavsc MAKEFILE_DIR=$(SOURCE_DIR)/scripts/build/make BASERESX= Resources/Yavsc.Models.IT.Fixing.Resources.resx \ - Resources/Yavsc.ChatHub.resx \ Resources/Yavsc.ViewComponents.CommentViewComponent.resx \ Resources/Yavsc.ViewModels.FrontOffice.PerformerProfileViewModel.resx \ Resources/Yavsc.ViewModels.EnrolerViewModel.resx \ diff --git a/src/cli/Commands/Streamer.cs b/src/cli/Commands/Streamer.cs index ed642f6d..c8a4bc14 100644 --- a/src/cli/Commands/Streamer.cs +++ b/src/cli/Commands/Streamer.cs @@ -7,7 +7,7 @@ using cli.Model; using Microsoft.Extensions.CommandLineUtils; using Microsoft.Extensions.Logging; using Microsoft.Extensions.OptionsModel; -using Yavsc; +using Yavsc.Abstract; namespace cli { @@ -121,4 +121,4 @@ namespace cli { await _client.CloseAsync(WebSocketCloseStatus.NormalClosure, "EOF", _tokenSource.Token); } } -} \ No newline at end of file +} diff --git a/version.txt b/version.txt index 77fa9bb2..9085b446 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.6-rc09 +1.0.6-rc10