public static UserEntity UpdateTicket(string device, ref string ticket) { using (AuthLogic.Disable()) using (var tr = new Transaction()) { var pair = UserTicketEntity.ParseTicket(ticket); UserEntity user = Database.Retrieve <UserEntity>(pair.userId); CleanExpiredTickets(user); UserTicketEntity?userTicket = user.UserTickets().SingleOrDefaultEx(t => t.Ticket == pair.ticket); if (userTicket == null) { throw new UnauthorizedAccessException("User attempted to log-in with an invalid ticket"); } UserTicketEntity result = new UserTicketEntity { User = user.ToLite(), Device = device, ConnectionDate = TimeZoneManager.Now, Ticket = Guid.NewGuid().ToString(), }.Save(); ticket = result.StringTicket(); return(tr.Commit(user)); } }
public PropertyAllowed Merge(PropertyRoute key, Lite <RoleEntity> role, IEnumerable <KeyValuePair <Lite <RoleEntity>, PropertyAllowed> > baseValues) { PropertyAllowed best = AuthLogic.GetMergeStrategy(role) == MergeStrategy.Union ? Max(baseValues.Select(a => a.Value)) : Min(baseValues.Select(a => a.Value)); if (!BasicPermission.AutomaticUpgradeOfProperties.IsAuthorized(role)) { return(best); } var maxUp = PropertyAuthLogic.MaxAutomaticUpgrade.TryGetS(key); if (maxUp.HasValue && maxUp <= best) { return(best); } if (baseValues.Where(a => a.Value.Equals(best)).All(a => GetDefault(key, a.Key).Equals(a.Value))) { var def = GetDefault(key, role); return(maxUp.HasValue && maxUp <= def ? maxUp.Value : def); } return(best); }
public static ResetPasswordRequestEntity SendResetPasswordRequestEmail(string email) { UserEntity?user; using (AuthLogic.Disable()) { user = Database .Query <UserEntity>() .SingleOrDefault(u => u.Email == email && u.State != UserState.Disabled); if (user == null) { throw new ApplicationException(AuthEmailMessage.EmailNotFound.NiceToString()); } } try { var request = ResetPasswordRequest(user); string url = EmailLogic.Configuration.UrlLeft + @"/auth/ResetPassword?code={0}".FormatWith(request.Code); using (AuthLogic.Disable()) new ResetPasswordRequestEmail(request, url).SendMail(); return(request); } catch (Exception ex) { ex.LogException(); throw new ApplicationException(LoginAuthMessage.AnErrorOccurredRequestNotProcessed.NiceToString()); } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { AuthLogic.AssertStarted(sb); OperationLogic.AssertStarted(sb); OperationLogic.AllowOperation += OperationLogic_AllowOperation; cache = new AuthCache <RuleOperationEntity, OperationAllowedRule, OperationSymbol, OperationSymbol, OperationAllowed>(sb, s => s, s => s, merger: new OperationMerger(), invalidateWithTypes: true, coercer: OperationCoercer.Instance); AuthLogic.ExportToXml += exportAll => cache.ExportXml("Operations", "Operation", s => s.Key, b => b.ToString(), exportAll ? OperationLogic.RegisteredOperations.ToList() : null); AuthLogic.ImportFromXml += (x, roles, replacements) => { string replacementKey = "AuthRules:" + typeof(OperationSymbol).Name; replacements.AskForReplacements( x.Element("Operations").Elements("Role").SelectMany(r => r.Elements("Operation")).Select(p => p.Attribute("Resource").Value).ToHashSet(), SymbolLogic <OperationSymbol> .AllUniqueKeys(), replacementKey); return(cache.ImportXml(x, "Operations", "Operation", roles, s => SymbolLogic <OperationSymbol> .TryToSymbol(replacements.Apply(replacementKey, s)), EnumExtensions.ToEnum <OperationAllowed>)); }; } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { TypeLogic.AssertStarted(sb); AuthLogic.AssertStarted(sb); TypeConditionLogic.Start(sb); sb.Schema.EntityEventsGlobal.Saving += Schema_Saving; //because we need Modifications propagated sb.Schema.EntityEventsGlobal.Retrieved += EntityEventsGlobal_Retrieved; sb.Schema.IsAllowedCallback += Schema_IsAllowedCallback; sb.Schema.SchemaCompleted += () => { foreach (var type in TypeConditionLogic.Types) { miRegister.GetInvoker(type)(Schema.Current); } }; sb.Schema.Synchronizing += Schema_Synchronizing; sb.Schema.EntityEventsGlobal.PreUnsafeDelete += query => { return(TypeAuthLogic.OnIsDelete(query.ElementType)); }; cache = new TypeAuthCache(sb, merger: TypeAllowedMerger.Instance); AuthLogic.ExportToXml += exportAll => cache.ExportXml(exportAll ? TypeLogic.TypeToEntity.Keys.ToList() : null); AuthLogic.ImportFromXml += (x, roles, replacements) => cache.ImportXml(x, roles, replacements); } }
static void UserTicketLogic_Saving(UserEntity user) { if (!user.IsNew && user.IsGraphModified && !user.InDB(u => u.PasswordHash).SequenceEqual(user.PasswordHash)) { using (AuthLogic.Disable()) user.UserTickets().UnsafeDelete(); } }
public static void ChangePassword(Lite <UserEntity> user, byte[] passwordHash, byte[] newPasswordHash) { var userEntity = user.RetrieveAndForget(); userEntity.PasswordHash = newPasswordHash; using (AuthLogic.Disable()) userEntity.Execute(UserOperation.Save); }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { sb.Include <ResetPasswordRequestEntity>() .WithQuery(() => e => new { Entity = e, e.Id, e.RequestDate, e.Code, e.User, e.User.Email }); EmailLogic.AssertStarted(sb); EmailModelLogic.RegisterEmailModel <ResetPasswordRequestEmail>(() => new EmailTemplateEntity { DisableAuthorization = true, Messages = CultureInfoLogic.ForEachCulture(culture => new EmailTemplateMessageEmbedded(culture) { Text = "<p>{0}</p>".FormatWith(AuthEmailMessage.YouRecentlyRequestedANewPassword.NiceToString()) + "<p>{0} @[User.UserName]</p>".FormatWith(AuthEmailMessage.YourUsernameIs.NiceToString()) + "<p>{0}</p>".FormatWith(AuthEmailMessage.YouCanResetYourPasswordByFollowingTheLinkBelow.NiceToString()) + "<p><a href=\"@[m:Url]\">@[m:Url]</a></p>", Subject = AuthEmailMessage.ResetPasswordRequestSubject.NiceToString() }).ToMList() }); new Graph <ResetPasswordRequestEntity> .Execute(ResetPasswordRequestOperation.Execute) { CanBeNew = false, CanBeModified = false, CanExecute = (e) => e.Lapsed == false ? null : AuthEmailMessage.YourResetPasswordRequestHasExpired.NiceToString(), Execute = (e, args) => { string password = args.GetArg <string>(); e.Lapsed = true; var user = e.User; var error = UserEntity.OnValidatePassword(password); if (error != null) { throw new ApplicationException(error); } user.PasswordHash = Security.EncodePassword(password); using (AuthLogic.Disable()) user.Execute(UserOperation.Save); } } .Register(); } }
public static string OnLoginMessage() { if (AuthLogic.LoginMessage != null) { return(AuthLogic.LoginMessage()); } return(null); }
public static UserEntity ChangePasswordLogin(string username, byte[] passwordHash, byte[] newPasswordHash) { var userEntity = RetrieveUser(username, passwordHash); userEntity.PasswordHash = newPasswordHash; using (AuthLogic.Disable()) userEntity.Execute(UserOperation.Save); return(Login(username, newPasswordHash)); }
public bool Merge(PermissionSymbol key, Lite <RoleEntity> role, IEnumerable <KeyValuePair <Lite <RoleEntity>, bool> > baseValues) { if (AuthLogic.GetMergeStrategy(role) == MergeStrategy.Union) { return(baseValues.Any(a => a.Value)); } else { return(baseValues.All(a => a.Value)); } }
public static UserEntity Login(string username, byte[] passwordHash) { using (AuthLogic.Disable()) { UserEntity user = RetrieveUser(username, passwordHash); OnUserLogingIn(user); return(user); } }
public Func <PropertyRoute, PropertyAllowed> MergeDefault(Lite <RoleEntity> role) { return(pr => { if (!BasicPermission.AutomaticUpgradeOfProperties.IsAuthorized(role) || PropertyAuthLogic.AvoidAutomaticUpgradeCollection.Contains(pr)) { return AuthLogic.GetDefaultAllowed(role) ? PropertyAllowed.Modify : PropertyAllowed.None; } return GetDefault(pr, role); }); }
public Func <OperationSymbol, OperationAllowed> MergeDefault(Lite <RoleEntity> role) { return(key => { if (!BasicPermission.AutomaticUpgradeOfOperations.IsAuthorized(role) || OperationAuthLogic.AvoidAutomaticUpgradeCollection.Contains(key)) { return AuthLogic.GetDefaultAllowed(role) ? OperationAllowed.Allow : OperationAllowed.None; } return GetDefault(key, role); }); }
public static UserEntity RetrieveUser(string username, byte[] passwordHash) { using (AuthLogic.Disable()) { UserEntity?user = RetrieveUser(username); if (user == null) { throw new IncorrectUsernameException(LoginAuthMessage.Username0IsNotValid.NiceToString().FormatWith(username)); } if (user.PasswordHash == null || !user.PasswordHash.SequenceEqual(passwordHash)) { using (UserHolder.UserSession(SystemUser !)) { user.LoginFailedCounter++; user.Execute(UserOperation.Save); if (MaxFailedLoginAttempts.HasValue && user.LoginFailedCounter == MaxFailedLoginAttempts && user.State == UserState.Active) { var config = EmailLogic.Configuration; var request = ResetPasswordRequestLogic.ResetPasswordRequest(user); var url = $"{config.UrlLeft}/auth/resetPassword?code={request.Code}"; var mail = new UserLockedMail(user, url); mail.SendMailAsync(); user.Execute(UserOperation.Deactivate); throw new UserLockedException(LoginAuthMessage.User0IsDisabled.NiceToString() .FormatWith(user.UserName)); } throw new IncorrectPasswordException(LoginAuthMessage.IncorrectPassword.NiceToString()); } } if (user.LoginFailedCounter > 0) { using (UserHolder.UserSession(SystemUser !)) { user.LoginFailedCounter = 0; user.Execute(UserOperation.Save); } } return(user); } }
public static UserEntity Login(string username, byte[] passwordHash, out string authenticationType) { using (AuthLogic.Disable()) { UserEntity user = RetrieveUser(username, passwordHash); OnUserLogingIn(user); authenticationType = "database"; return(user); } }
public static void Start(SchemaBuilder sb, DynamicQueryManager dqm) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { AuthLogic.AssertStarted(sb); QueryLogic.Start(sb, dqm); dqm.AllowQuery += new Func <object, bool, bool>(dqm_AllowQuery); cache = new AuthCache <RuleQueryEntity, QueryAllowedRule, QueryEntity, object, QueryAllowed>(sb, qn => QueryLogic.ToQueryName(qn.Key), QueryLogic.GetQueryEntity, merger: new QueryMerger(), invalidateWithTypes: true, coercer: QueryCoercer.Instance); AuthLogic.ExportToXml += exportAll => cache.ExportXml("Queries", "Query", QueryUtils.GetKey, b => b.ToString(), exportAll ? QueryLogic.QueryNames.Values.ToList(): null); AuthLogic.ImportFromXml += (x, roles, replacements) => { string replacementKey = "AuthRules:" + typeof(QueryEntity).Name; replacements.AskForReplacements( x.Element("Queries").Elements("Role").SelectMany(r => r.Elements("Query")).Select(p => p.Attribute("Resource").Value).ToHashSet(), QueryLogic.QueryNames.Keys.ToHashSet(), replacementKey); return(cache.ImportXml(x, "Queries", "Query", roles, s => { var qn = QueryLogic.TryToQueryName(replacements.Apply(replacementKey, s)); if (qn == null) { return null; } return QueryLogic.GetQueryEntity(qn); }, str => { if (Enum.TryParse <QueryAllowed>(str, out var result)) { return result; } var bResult = bool.Parse(str); //For backwards compatibilityS return bResult ? QueryAllowed.Allow : QueryAllowed.None; })); }; } }
public static void Start(SchemaBuilder sb) { if (sb.NotDefined(MethodInfo.GetCurrentMethod())) { AuthLogic.AssertStarted(sb); sb.Include <PermissionSymbol>(); SymbolLogic <PermissionSymbol> .Start(sb, () => RegisteredPermission.ToHashSet()); sb.Include <RulePermissionEntity>() .WithUniqueIndex(rt => new { rt.Resource, rt.Role }); cache = new AuthCache <RulePermissionEntity, PermissionAllowedRule, PermissionSymbol, PermissionSymbol, bool>(sb, toKey: p => p, toEntity: p => p, isEquals: (p1, p2) => p1 == p2, merger: new PermissionMerger(), invalidateWithTypes: false); sb.Schema.EntityEvents <RoleEntity>().PreUnsafeDelete += query => { Database.Query <RulePermissionEntity>().Where(r => query.Contains(r.Role.Entity)).UnsafeDelete(); return(null); }; RegisterPermissions(BasicPermission.AdminRules, BasicPermission.AutomaticUpgradeOfProperties, BasicPermission.AutomaticUpgradeOfOperations, BasicPermission.AutomaticUpgradeOfQueries); AuthLogic.ExportToXml += exportAll => cache.ExportXml("Permissions", "Permission", a => a.Key, b => b.ToString(), exportAll ? PermissionAuthLogic.RegisteredPermission.ToList() : null); AuthLogic.ImportFromXml += (x, roles, replacements) => { string replacementKey = "AuthRules:" + typeof(PermissionSymbol).Name; replacements.AskForReplacements( x.Element("Permissions").Elements("Role").SelectMany(r => r.Elements("Permission")).Select(p => p.Attribute("Resource").Value).ToHashSet(), SymbolLogic <PermissionSymbol> .Symbols.Select(s => s.Key).ToHashSet(), replacementKey); return(cache.ImportXml(x, "Permissions", "Permission", roles, s => SymbolLogic <PermissionSymbol> .TryToSymbol(replacements.Apply(replacementKey, s)), bool.Parse)); }; sb.Schema.Table <PermissionSymbol>().PreDeleteSqlSync += new Func <Entity, SqlPreCommand>(AuthCache_PreDeleteSqlSync); } }
public static ResetPasswordRequestEntity ResetPasswordRequestExecute(string code, string password) { using (AuthLogic.Disable()) { var rpr = Database.Query <ResetPasswordRequestEntity>() .Where(r => r.Code == code && r.IsValid) .SingleEx(); using (UserHolder.UserSession(rpr.User)) { rpr.Execute(ResetPasswordRequestOperation.Execute, password); } return(rpr); } }
public static IDisposable UnsafeUserSession(string username) { UserEntity?user; using (AuthLogic.Disable()) { user = RetrieveUser(username); if (user == null) { throw new ApplicationException(AuthMessage.Username0IsNotValid.NiceToString().FormatWith(username)); } } return(UserHolder.UserSession(user)); }
public Func <PropertyRoute, PropertyAllowed> MergeDefault(Lite <RoleEntity> role) { return(pr => { if (!BasicPermission.AutomaticUpgradeOfProperties.IsAuthorized(role)) { return AuthLogic.GetDefaultAllowed(role) ? PropertyAllowed.Write : PropertyAllowed.None; } var maxUp = PropertyAuthLogic.MaxAutomaticUpgrade.TryGetS(pr); var def = GetDefault(pr, role); return maxUp.HasValue && maxUp <= def ? maxUp.Value : def; }); }
public Func <object, QueryAllowed> MergeDefault(Lite <RoleEntity> role) { return(key => { if (!BasicPermission.AutomaticUpgradeOfQueries.IsAuthorized(role)) { return AuthLogic.GetDefaultAllowed(role) ? QueryAllowed.Allow: QueryAllowed.None; } var maxUp = QueryAuthLogic.MaxAutomaticUpgrade.TryGetS(key); var def = GetDefault(key, role); return maxUp.HasValue && maxUp <= def ? maxUp.Value : def; }); }
public static ResetPasswordRequestEntity ResetPasswordRequestExecute(string code, string password) { using (AuthLogic.Disable()) { //Remove old previous requests var rpr = Database.Query <ResetPasswordRequestEntity>() .Where(r => r.Code == code && !r.Lapsed) .SingleOrDefault(); using (UserHolder.UserSession(rpr.User)) { rpr.Execute(ResetPasswordRequestOperation.Execute, password); } return(rpr); } }
public static void SessionStart(string userHostAddress, string userAgent) { var user = UserEntity.Current; if (SessionLogLogic.RoleTracked(user.Role)) { using (AuthLogic.Disable()) { new SessionLogEntity { User = user.ToLite(), SessionStart = TimeZoneManager.Now.TrimToSeconds(), UserHostAddress = userHostAddress, UserAgent = userAgent }.Save(); } } }
public PropertyAllowed Merge(PropertyRoute key, Lite <RoleEntity> role, IEnumerable <KeyValuePair <Lite <RoleEntity>, PropertyAllowed> > baseValues) { PropertyAllowed best = AuthLogic.GetMergeStrategy(role) == MergeStrategy.Union ? Max(baseValues.Select(a => a.Value)) : Min(baseValues.Select(a => a.Value)); if (!BasicPermission.AutomaticUpgradeOfProperties.IsAuthorized(role) || PropertyAuthLogic.AvoidAutomaticUpgradeCollection.Contains(key)) { return(best); } if (baseValues.Where(a => a.Value.Equals(best)).All(a => GetDefault(key, a.Key).Equals(a.Value))) { return(GetDefault(key, role)); } return(best); }
public static UserEntity?TryRetrieveUser(string username, byte[] passwordHash) { using (AuthLogic.Disable()) { UserEntity?user = RetrieveUser(username); if (user == null) { return(null); } if (!user.PasswordHash.SequenceEqual(passwordHash)) { return(null); } return(user); } }
public static UserEntity RetrieveUser(string username, byte[] passwordHash) { using (AuthLogic.Disable()) { UserEntity?user = RetrieveUser(username); if (user == null) { throw new IncorrectUsernameException(AuthMessage.Username0IsNotValid.NiceToString().FormatWith(username)); } if (!user.PasswordHash.SequenceEqual(passwordHash)) { throw new IncorrectPasswordException(AuthMessage.IncorrectPassword.NiceToString()); } return(user); } }
public static ResetPasswordRequestEntity ResetPasswordRequest(UserEntity user) { using (AuthLogic.Disable()) { //Remove old previous requests Database.Query <ResetPasswordRequestEntity>() .Where(r => r.User.Is(user) && r.RequestDate < TimeZoneManager.Now.AddMonths(1)) .UnsafeUpdate() .Set(e => e.Lapsed, e => true) .Execute(); return(new ResetPasswordRequestEntity() { Code = MyRandom.Current.NextString(5), User = user, RequestDate = TimeZoneManager.Now, }.Save()); } }
public static UserEntity CreateUserFromAD(ActiveDirectoryUser adUser) { ClientCredentialProvider authProvider = GetClientCredentialProvider(); GraphServiceClient graphClient = new GraphServiceClient(authProvider); var msGraphUser = graphClient.Users[adUser.ObjectID.ToString()].Request().GetAsync().Result; using (ExecutionMode.Global()) { var user = Database.Query <UserEntity>().SingleOrDefaultEx(a => a.Mixin <UserOIDMixin>().OID == Guid.Parse(msGraphUser.Id)); if (user != null) { return(user); } var config = ((ActiveDirectoryAuthorizer)AuthLogic.Authorizer !).GetConfig(); user = Database.Query <UserEntity>().SingleOrDefault(a => a.UserName == msGraphUser.UserPrincipalName) ?? (msGraphUser.UserPrincipalName.Contains("@") && config.AllowMatchUsersBySimpleUserName ? Database.Query <UserEntity>().SingleOrDefault(a => a.Email == msGraphUser.UserPrincipalName || a.UserName == msGraphUser.UserPrincipalName.Before("@")) : null); if (user != null) { using (AuthLogic.Disable()) using (OperationLogic.AllowSave <UserEntity>()) { user.Mixin <UserOIDMixin>().OID = Guid.Parse(msGraphUser.Id); user.UserName = msGraphUser.UserPrincipalName; user.Email = msGraphUser.UserPrincipalName; if (!UserOIDMixin.AllowUsersWithPassswordAndOID) { user.PasswordHash = null; } user.Save(); } return(user); } } var result = ((ActiveDirectoryAuthorizer)AuthLogic.Authorizer !).OnAutoCreateUser(new MicrosoftGraphCreateUserContext(msGraphUser)); return(result ?? throw new InvalidOperationException(ReflectionTools.GetPropertyInfo((ActiveDirectoryConfigurationEmbedded e) => e.AutoCreateUsers).NiceName() + " is not activated")); }
public static string NewTicket(string device) { using (AuthLogic.Disable()) using (var tr = new Transaction()) { CleanExpiredTickets(UserEntity.Current); UserTicketEntity result = new UserTicketEntity { User = UserEntity.Current.ToLite(), Device = device, ConnectionDate = TimeZoneManager.Now, Ticket = Guid.NewGuid().ToString(), }; result.Save(); return(tr.Commit(result.StringTicket())); } }