/// <summary> /// Updates an existing organizational unit to the given values. /// </summary> /// <param name="updatedUnit">The updated unit.</param> /// <returns>MethodResult indicating success.</returns> public MethodResult UpdateOrganizationalUnit(OrganizationalUnit updatedUnit) { var adapter = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>(); if (updatedUnit.IsPrincipalUnit) { var current = adapter.GetOrganizationalUnitById(updatedUnit.Id); if (current.AdminMailAddress != updatedUnit.AdminMailAddress) { var user = adapter.GetUserByMailAddress(current.AdminMailAddress); var tempResult = new UserController().ChangeMailAddress(user, updatedUnit.AdminMailAddress); if (!tempResult.IsSucceeded()) { return(tempResult); } tempResult = new UserController().ResetPassword(updatedUnit.AdminMailAddress); if (!tempResult.IsSucceeded()) { return(tempResult); } } if (current.Name == updatedUnit.Name) { return(new MethodResult()); } } return(adapter.RenameOrganizationalUnit(updatedUnit.Id, updatedUnit.Name)); }
/// <summary> /// Changes the users mail address. /// </summary> /// <param name="user">The user.</param> /// <param name="newUserMail">The new mail address.</param> /// <returns>MethodResult indicating success.</returns> public MethodResult ChangeMailAddress(User user, string newUserMail) { if (string.IsNullOrWhiteSpace(newUserMail) || (newUserMail.Contains("@") == false)) { throw new InvalidDataException("Invalid mail address."); } var oldMail = user.MailAddress; var result = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().ChangeMailAddress(user, newUserMail); if (result.IsSucceeded()) { string newPasswordAppender = null; if (user.MustChangePassword) { var innerResult = InnerResetPassword(newUserMail); if (innerResult.IsSucceeded()) { newPasswordAppender = string.Format(ClipperTexts.NewlyGeneratedPasswordOnMailReset, innerResult.Result); } } QuerySendMailAsync(user, ClipperTexts.MailChangedMailSubject, ClipperTexts.MailChangedMailBody + newPasswordAppender); QuerySendMailAsync(new Notifiable(oldMail, user.UserName), ClipperTexts.MailChangedMailSubject, ClipperTexts.MailChangedMailBody); } return(result); }
/// <summary> /// Resets a given users password /// </summary> /// <param name="userMail">The mail of the of which the pw should be reset.</param> /// <returns>MethodResult containing generated password.</returns> private static MethodResult <string> InnerResetPassword(string userMail) { var newPassword = PasswordGenerator.GeneratePw(); var result = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().ResetPassword(userMail, newPassword); return(result.IsSucceeded() ? new MethodResult <string>(newPassword) : new MethodResult <string>(result == null ? SuccessState.UnknownError : result.Status, result?.UserMessage, null)); }
/// <summary> /// Gets the feed data. /// </summary> /// <param name="userId">The user id.</param> /// <param name="feedId">The feed id.</param> /// <param name="page">The requested page.</param> /// <param name="showArchived">A value indicating whether the archived articles should be shown or not.</param> /// <returns>List of <see cref="ShortArticle"/>s within the feed.</returns> public IReadOnlyCollection <ShortArticle> GetFeed(Guid userId, Guid feedId, int page, bool showArchived) { var adapter = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>(); var data = adapter.GetFeedRequestData(userId, feedId); var since = showArchived ? DateTime.MinValue : data.Item2; var inheritedUnit = adapter.GetUnitInheritedBlackList(userId); return(DatabaseAdapterFactory.GetControllerInstance <IIndexerService>().GetFeedAsync(data.Item1, since, data.Item3, page, inheritedUnit).Result); }
public void GetControllerTest() { var firstController = DatabaseAdapterFactory.GetControllerInstance <IIndexerService>(); Assert.IsNotNull(firstController); var secondController = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>(); Assert.IsNotNull(secondController); }
/// <summary> /// Attempts to change the password. /// </summary> /// <param name="user">The users mail address</param> /// <param name="newPassword">The new user password.</param> /// <returns>MethodResult indicating success.</returns> public MethodResult ChangePassword(User user, string newPassword) { if (string.IsNullOrWhiteSpace(newPassword)) { throw new InvalidDataException("Invalid password"); } var result = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().ChangePassword(user, newPassword); if (result.IsSucceeded()) { QuerySendMailAsync(user, ClipperTexts.PasswordChangedMailSubject, ClipperTexts.PasswordChangedMailBody); } return(result); }
public void InvalidControllerInterface() { Exception t = null; try { // ReSharper disable once UnusedVariable var tmp = DatabaseAdapterFactory.GetControllerInstance <IClipperUserAPI>(); } catch (Exception e) { t = e; } Assert.IsTrue(t is ArgumentOutOfRangeException); }
/// <summary> /// Notifies the Observer that (probably) new web page content has been detected by a crawler. /// Note: Must be thread safe /// </summary> /// <param name="title">The title.</param> /// <param name="description">The image description</param> /// <param name="link">The link.</param> /// <param name="imageLink">The link of the image.</param> /// <param name="published">The published date.</param> /// <param name="source">The source.</param> /// <returns>If indexing is required: a task with the corresponding indexing job. /// <para>Otherwise: a completed Task</para></returns> public Task NotifyNewImageContentFoundThreadSafe(string title, string description, string imageLink, string link, DateTime published, Source source) { if (DoesNotViolateBlackList(source, title) && DoesNotViolateBlackList(source, description)) { var article = new Article(Guid.NewGuid(), title, link, imageLink, description, published, DateTime.UtcNow, source.Id); var job = DatabaseAdapterFactory.GetControllerInstance <IIndexerService>().IndexArticleThreadSafeAsync(article); return(job ?? Task.CompletedTask); } return(Task.CompletedTask); }
public void IndexArticleTest() { var elasticController = DatabaseAdapterFactory.GetControllerInstance <IIndexerService>(); var milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var guid = Guid.NewGuid(); var indexedguid = Guid.NewGuid(); var articleOne = new Article(guid, "abgef" + milliseconds, "http://" + milliseconds + ".de", "http://" + milliseconds + ".de", "abgefssmt", DateTime.Today, DateTime.Today, indexedguid); try { elasticController.IndexArticleThreadSafeAsync(articleOne); Assert.IsTrue(true); } catch (Exception) { Assert.Fail(); } }
/// <summary> /// Administratively adds a user. /// </summary> /// <param name="toAdd">The user to add.</param> /// <param name="userUnits">The users units.</param> /// <returns>MethodResult indicating success.</returns> public MethodResult AdministrativelyAddUser(User toAdd, IReadOnlyList <Guid> userUnits) { var password = PasswordGenerator.GeneratePw(); var result = Factory.GetControllerInstance <IClipperDatabase>().AddUser(toAdd.MailAddress, toAdd.UserName, password, toAdd.Role, toAdd.PrincipalUnitId, userUnits[0], true, true); MethodResult innerResult = result; if (result.IsSucceeded()) { if (userUnits.Count > 1) { innerResult = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>() .SetUserOrganizationalUnits(result.Result, userUnits.Skip(1)); } QuerySendMailAsync(toAdd, ClipperTexts.AccountCreatedMailSubject, string.Format(ClipperTexts.AccountCreatedMailBody, toAdd.UserName, password)); } return(innerResult); }
/// <summary> /// Notifies the Observer that a (probably) new Rss feed item has been detected by a crawler. /// Note: Must be thread safe /// </summary> /// <param name="item">The item to index</param> /// <param name="rssKey">The belonging rss key.</param> /// <param name="source">The source.</param> /// <returns>If indexing is required: a task with the corresponding indexing job. /// <para>Otherwise: a completed Task</para></returns> public Task NotifyNewRssFeedFoundThreadSave(SyndicationItem item, RssKey rssKey, Source source) { var plainText = item.Summary?.Text?.GetTextFromHtml() ?? string.Empty; var plainTitle = item.Title?.Text.GetTextFromHtml() ?? source.Name; if (DoesNotViolateBlackList(source, plainText) && DoesNotViolateBlackList(source, plainTitle)) { var article = new Article(Guid.NewGuid(), plainTitle, rssKey.Link, null, plainText, new DateTime(rssKey.Updated), DateTime.UtcNow, source.Id); var job = DatabaseAdapterFactory.GetControllerInstance <IIndexerService>() .IndexRssFeedItemThreadSafeAsync(article, rssKey); return(job ?? Task.CompletedTask); } return(Task.CompletedTask); }
/// <summary> /// Modifies the user. /// </summary> /// <param name="toModify">The user to modify.</param> /// <param name="userUnits">The users units.</param> /// <returns>MethodResult indicating success.</returns> public MethodResult ModifyUser(User toModify, IReadOnlyList <Guid> userUnits) { var adapter = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>(); var currentUser = GetUserInfo(toModify.Id); if (toModify.UserMailAddress != currentUser.MailAddress) { var result = ChangeMailAddress(toModify, toModify.UserMailAddress); if (!result.IsSucceeded()) { return(result); } } if (toModify.UserName != currentUser.UserName || toModify.Role != currentUser.Role || toModify.IsValid != currentUser.IsValid || !userUnits.ToHashSet().SetEquals(currentUser.OrganizationalUnits.Select(x => x.Id))) { return(adapter.ModifyUser(toModify.Id, toModify.UserName, toModify.Role, toModify.IsValid, userUnits)); } return(new MethodResult()); }
public static T GetControllerInstance <T>() { if (typeof(T) == typeof(IClipperUserAPI) || typeof(IClipperSystemAdministratorAPI) == typeof(T) || typeof(IClipperStaffChiefAPI) == typeof(T)) { return((T)(object)new UserController()); } if (typeof(T) == typeof(IClipperDatabase)) { return((T)DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>()); } if (typeof(T) == typeof(IClipperService)) { return((T)(object)new StatusController()); } if (typeof(T) == typeof(IClipperOrganizationalUnitAPI)) { return((T)(object)new OrganizationalUnitController()); } if (typeof(T) == typeof(ICrawlerController)) { return((T)(object)CrawlerController.GetCrawlerController()); } if (typeof(T) == typeof(INotificationController)) { return((T)(object)new NotificationControllerWrapper()); } throw new ArgumentOutOfRangeException(nameof(T)); }
/// <summary> /// Gets all information on a user /// </summary> /// <param name="requested">The id of the user whose information is requested</param> /// <returns>All the information on a user like the <see cref="OrganizationalUnit"/>s he belongs to</returns> public ExtendedUser GetUserInfo(Guid requested) { return(DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().GetUserInfo(requested)); }
/// <summary> /// Gets the minimal information of the users a staffchief can manage /// </summary> /// <param name="userId">The id of the staffchief</param> /// <returns>A list of <see cref="BasicUserInformation"/> if the given id actually belonged to a staffchief</returns> public IReadOnlyList <BasicUserInformation> GetManageableUsers(Guid userId) { return(DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().GetManageableUsers(userId)); }
/// <summary> /// Checks if new feeds available and if notification and what kind of notification is wanted. /// </summary> /// <param name="timerState">The timer state.</param> private static void CheckForNotifications(object timerState) { using (new PerfTracer(nameof(CheckForNotifications))) { try { Scheduler.Change(Timeout.Infinite, Timeout.Infinite); var notifiableUserSettings = Factory.GetControllerInstance <IClipperDatabase>().GetNotifiableUserSettings(); var parallelOpts = new ParallelOptions { MaxDegreeOfParallelism = AppConfiguration.MaxNotificationJobDegreeOfParallelism }; Parallel.ForEach(notifiableUserSettings, parallelOpts, (notifiable) => { if (notifiable != null && notifiable.Settings != null && notifiable.Settings.NotificationSettings != NotificationSetting.None && notifiable.Settings.Feeds.Any()) { var lastFetched = LastCheckTime.TryGetOrAddIfNotPresentOrNull(notifiable.UserId); if (lastFetched < notifiable.LastLoginTime) { lastFetched = notifiable.LastLoginTime; } if (lastFetched.AddMinutes(notifiable.Settings.NotificationCheckIntervalInMinutes) <= DateTime.UtcNow) { LastCheckTime[notifiable.UserId] = DateTime.UtcNow; var indexer = DatabaseAdapterFactory.GetControllerInstance <IIndexerService>(); var feeds = indexer.GetCompleteFeedAsync(notifiable.Settings, lastFetched).GetAwaiter().GetResult(); if (feeds.Any()) { // We need to loop though all (-> blacklists) // Anyways one query to determine if at least something COULD be relevant is way better than x querys // which determine nothing is relevant at all. var blackList = DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>() .GetUnitInheritedBlackList(notifiable.UserId); //These can run in parallel aswell, as the main amount of time is waiting for elastic feeds = notifiable.Settings.Feeds .AsParallel() .WithDegreeOfParallelism(AppConfiguration.MaxNotificationJobDegreeOfParallelism) .Select(f => indexer.GetFeedAsync(f, lastFetched, 100000, 0, blackList).Result) .SelectMany(s => s) .Distinct(ArticleComparer.ShortArticleComparer).ToList(); if (feeds.Any()) { var defText = "Visit " + AppConfiguration.MailConfigurationFELoginLink + notifiable.PrincipalUnitName; if (notifiable.Settings.NotificationSettings == NotificationSetting.PdfPerMail) { var pdf = PdfGenerator.GeneratePdf(feeds, notifiable.UserName); MailController.QuerySendMailAsync(notifiable, ClipperTexts.DefaultMailSubject, defText, pdf, "Clipper.pdf"); } else { MailController.QuerySendMailAsync(notifiable, ClipperTexts.DefaultMailSubject, defText); } } } } } }); } catch (Exception error) { Console.WriteLine(error); } finally { Scheduler.Change(60 * 1000, Timeout.Infinite); } } }
/// <summary> /// Gets the children of a principal unit. /// </summary> /// <param name="principalUnitId">The principal unit identifier.</param> /// <returns>List of children of given principal unit.</returns> public IReadOnlyList <Tuple <string, Guid> > GetPrincipalUnitChildren(Guid principalUnitId) { return(DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().GetPrincipalUnitChildren(principalUnitId)); }
/// <summary> /// Gets a specific article. /// </summary> /// <param name="articleId">The article id.</param> /// <returns>The (full) <see cref="Article"/>.</returns> public Article GetArticle(Guid articleId) { return(DatabaseAdapterFactory.GetControllerInstance <IIndexerService>().GetArticleAsync(articleId).Result); }
/// <summary> /// Clears all indexes (use with care, this is a permanent operation). /// </summary> public void ClearAllIndexes() { DatabaseAdapterFactory.GetControllerInstance <IIndexerService>().ClearIndex(); }
/// <summary> /// Gets the user settings. /// </summary> /// <param name="userId">The user id.</param> /// <returns>The settings of the given user.</returns> public UserSettings GetUserSettings(Guid userId) { return(DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().GetUserSettingsByUserId(userId)); }
/// <summary> /// Gets the principal units. /// </summary> /// <returns>List of principal units.</returns> public IReadOnlyList <Tuple <string, Guid> > GetPrincipalUnitBasicInformation() { return(DatabaseAdapterFactory.GetControllerInstance <IClipperDatabase>().GetPrincipalUnitBasicInformation()); }