diff --git a/Ombi.Core/Users/UserHelper.cs b/Ombi.Core/Users/UserHelper.cs index ccb211a05..18c8bfc9f 100644 --- a/Ombi.Core/Users/UserHelper.cs +++ b/Ombi.Core/Users/UserHelper.cs @@ -63,7 +63,9 @@ namespace Ombi.Core.Users Username = localUsers.UserName, UserAlias = props.UserAlias, EmailAddress = props.EmailAddress, - Permissions = (Permissions) localUsers.Permissions + Permissions = (Permissions) localUsers.Permissions, + UserId = localUsers.UserGuid, + Features = (Features)localUsers.Features }; } @@ -76,7 +78,10 @@ namespace Ombi.Core.Users Username = plexUsers.Username, UserAlias = plexUsers.UserAlias, EmailAddress = plexUsers.EmailAddress, - Permissions = (Permissions)plexUsers.Permissions + Permissions = (Permissions)plexUsers.Permissions, + UserId = plexUsers.PlexUserId, + + Features = (Features)plexUsers.Features }; } @@ -89,7 +94,9 @@ namespace Ombi.Core.Users Username = embyUsers.Username, UserAlias = embyUsers.UserAlias, EmailAddress = embyUsers.EmailAddress, - Permissions = (Permissions)embyUsers.Permissions + Permissions = (Permissions)embyUsers.Permissions, + UserId = embyUsers.EmbyUserId, + Features = (Features)embyUsers.Features }; } return null; diff --git a/Ombi.Core/Users/UserHelperModel.cs b/Ombi.Core/Users/UserHelperModel.cs index ace42d4f9..3d7defb38 100644 --- a/Ombi.Core/Users/UserHelperModel.cs +++ b/Ombi.Core/Users/UserHelperModel.cs @@ -39,6 +39,7 @@ namespace Ombi.Core.Users public Features Features { get; set; } public string EmailAddress { get; set; } public UserType Type { get; set; } + public string UserId { get; set; } [JsonIgnore] public string UsernameOrAlias => string.IsNullOrEmpty(UserAlias) ? Username : UserAlias; diff --git a/Ombi.Services/Interfaces/INotificationService.cs b/Ombi.Services/Interfaces/INotificationService.cs index 6eb2d238c..2a40a722c 100644 --- a/Ombi.Services/Interfaces/INotificationService.cs +++ b/Ombi.Services/Interfaces/INotificationService.cs @@ -39,6 +39,7 @@ namespace Ombi.Services.Interfaces /// The model. /// Task Publish(NotificationModel model); + Task PublishTest(NotificationModel model, Settings settings, INotification type); /// /// Sends a notification to the user, this is usually for testing the settings. /// diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs index a5426e229..6ac7d76db 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs @@ -49,7 +49,7 @@ using PlexMediaType = Ombi.Store.Models.Plex.PlexMediaType; namespace Ombi.Services.Jobs.RecentlyAddedNewsletter { - public class + public class PlexRecentlyAddedNewsletter : HtmlTemplateGenerator, IPlexNewsletter { public PlexRecentlyAddedNewsletter(IPlexApi api, ISettingsService plexSettings, @@ -168,7 +168,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter recentlyAddedModel.Add(new PlexRecentlyAddedModel { Metadata = i, - EpisodeMetadata = new List() {episodeInfo}, + EpisodeMetadata = new List() { episodeInfo }, Content = relatedSeries }); } @@ -186,33 +186,12 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter continue; } - //var ep = filteredEp.Where(x => x.ShowTitle == t.Title); - if (filteredEp.Any()) + info.Add(new PlexRecentlyAddedModel { - var episodeList = new List(); - foreach (var ep in filteredEp) - { - var epInfo = Api.GetEpisodeMetaData(plexSettings.PlexAuthToken, plexSettings.FullUri, - ep.RatingKey); - episodeList.Add(epInfo); - } - - info.Add(new PlexRecentlyAddedModel - { - Metadata = i, - Content = t, - EpisodeMetadata = episodeList - }); - } - else - { - info.Add(new PlexRecentlyAddedModel - { - Metadata = i, - Content = t - }); - } + Metadata = i, + Content = t + }); } } GenerateTvHtml(info, sb); diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/RecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/RecentlyAddedNewsletter.cs index 6a15d00f4..20888df25 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/RecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/RecentlyAddedNewsletter.cs @@ -138,7 +138,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter if (embySettings.Enable) { var letter = EmbyNewsletter.GetNewsletter(testEmail) ?? new Newsletter(); - if (letter.Send) + if (letter.Send || testEmail) { SendNewsletter(newletterSettings, letter.Html, testEmail, "New Content On Emby!"); } @@ -153,7 +153,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter if (plexSettings.Enable) { var letter = PlexNewsletter.GetNewsletter(testEmail) ?? new Newsletter(); - if (letter.Send) + if (letter.Send || testEmail) { SendNewsletter(newletterSettings, letter.Html, testEmail); } diff --git a/Ombi.Services/Notification/EmailMessageNotification.cs b/Ombi.Services/Notification/EmailMessageNotification.cs index cd85913dc..1e99d834b 100644 --- a/Ombi.Services/Notification/EmailMessageNotification.cs +++ b/Ombi.Services/Notification/EmailMessageNotification.cs @@ -227,6 +227,7 @@ namespace Ombi.Services.Notification catch (Exception e) { Log.Error(e); + throw new InvalidOperationException(e.Message); } } diff --git a/Ombi.Services/Notification/NotificationService.cs b/Ombi.Services/Notification/NotificationService.cs index 1ff6a5fc0..4b19d3bb7 100644 --- a/Ombi.Services/Notification/NotificationService.cs +++ b/Ombi.Services/Notification/NotificationService.cs @@ -97,7 +97,13 @@ namespace Ombi.Services.Notification catch (Exception ex) { Log.Error(ex, $"Notification '{notification.NotificationName}' failed with exception"); + throw new InvalidOperationException(ex.Message); } } + + public async Task PublishTest(NotificationModel model, Settings settings, INotification type) + { + await type.NotifyAsync(model, settings); + } } } \ No newline at end of file diff --git a/Ombi.UI/Content/app/userManagement/Directives/table.html b/Ombi.UI/Content/app/userManagement/Directives/table.html index 8c7b381e5..c53d391a7 100644 --- a/Ombi.UI/Content/app/userManagement/Directives/table.html +++ b/Ombi.UI/Content/app/userManagement/Directives/table.html @@ -76,7 +76,7 @@ Local User - Plex User + Plex User Emby User diff --git a/Ombi.UI/Modules/Admin/AdminModule.cs b/Ombi.UI/Modules/Admin/AdminModule.cs index 03b8b7b82..72f60612e 100644 --- a/Ombi.UI/Modules/Admin/AdminModule.cs +++ b/Ombi.UI/Modules/Admin/AdminModule.cs @@ -126,7 +126,7 @@ namespace Ombi.UI.Modules.Admin ISlackApi slackApi, ISettingsService lp, ISettingsService scheduler, IJobRecord rec, IAnalytics analytics, ISettingsService notifyService, IRecentlyAdded recentlyAdded, IMassEmail massEmail, - ISettingsService watcherSettings , + ISettingsService watcherSettings, ISettingsService discord, IDiscordApi discordapi, ISettingsService settings, IRadarrApi radarrApi, ISettingsService embySettings, IEmbyApi emby @@ -168,9 +168,9 @@ namespace Ombi.UI.Modules.Admin RadarrApi = radarrApi; EmbyApi = emby; EmbySettings = embySettings; - + Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx); - + Get["/"] = _ => Admin(); Get["/authentication", true] = async (x, ct) => await Authentication(); @@ -226,7 +226,7 @@ namespace Ombi.UI.Modules.Admin Get["/newsletter", true] = async (x, ct) => await Newsletter(); Post["/newsletter", true] = async (x, ct) => await SaveNewsletter(); Post["/testnewsletteradminemail"] = x => TestNewsletterAdminEmail(); - + Get["/massemail"] = _ => MassEmailView(); Post["/testmassadminemail"] = x => TestMassAdminEmail(); Post["/sendmassemail"] = x => SendMassEmail(); @@ -453,16 +453,16 @@ namespace Ombi.UI.Modules.Admin { var plexSettings = this.Bind(); - if (plexSettings.Enable) - { - var valid = this.Validate(plexSettings); - if (!valid.IsValid) - { - return Response.AsJson(valid.SendJsonError()); - } - } + if (plexSettings.Enable) + { + var valid = this.Validate(plexSettings); + if (!valid.IsValid) + { + return Response.AsJson(valid.SendJsonError()); + } + } + - if (plexSettings.Enable) { var embySettings = await EmbySettings.GetSettingsAsync(); @@ -565,9 +565,9 @@ namespace Ombi.UI.Modules.Admin : new JsonResponseModel { Result = false, Message = "Could not update the settings, take a look at the logs." }); } - - + + private Negotiator Sickrage() { @@ -639,12 +639,14 @@ namespace Ombi.UI.Modules.Admin { NotificationService.Subscribe(new EmailMessageNotification(EmailService)); settings.Enabled = true; - await NotificationService.Publish(notificationModel, settings); + await NotificationService.PublishTest(notificationModel, settings, new EmailMessageNotification(EmailService)); Log.Info("Sent email notification test"); } - catch (Exception) + catch (Exception ex) { Log.Error("Failed to subscribe and publish test Email Notification"); + var msg = "Failed: " + ex.Message; + return Response.AsJson(new JsonResponseModel { Result = false, Message = msg }); } finally { @@ -653,7 +655,9 @@ namespace Ombi.UI.Modules.Admin NotificationService.UnSubscribe(new EmailMessageNotification(EmailService)); } } + return Response.AsJson(new JsonResponseModel { Result = true, Message = "Successfully sent a test Email Notification!" }); + } private Response SaveEmailNotifications() @@ -739,7 +743,7 @@ namespace Ombi.UI.Modules.Admin { NotificationService.Subscribe(new PushbulletNotification(PushbulletApi, PushbulletService)); settings.Enabled = true; - await NotificationService.Publish(notificationModel, settings); + await NotificationService.PublishTest(notificationModel, settings, new PushbulletNotification(PushbulletApi, PushbulletService)); Log.Info("Sent pushbullet notification test"); } catch (Exception) @@ -805,7 +809,7 @@ namespace Ombi.UI.Modules.Admin { NotificationService.Subscribe(new PushoverNotification(PushoverApi, PushoverService)); settings.Enabled = true; - await NotificationService.Publish(notificationModel, settings); + await NotificationService.PublishTest(notificationModel, settings, new PushoverNotification(PushoverApi, PushoverService)); Log.Info("Sent pushover notification test"); } catch (Exception) @@ -832,7 +836,7 @@ namespace Ombi.UI.Modules.Admin } if (!settings.Enabled) { - return Response.AsJson(new CouchPotatoProfiles{list = new List()}); + return Response.AsJson(new CouchPotatoProfiles { list = new List() }); } var profiles = CpApi.GetProfiles(settings.FullUri, settings.ApiKey); @@ -1000,7 +1004,7 @@ namespace Ombi.UI.Modules.Admin { NotificationService.Subscribe(new SlackNotification(SlackApi, SlackSettings)); settings.Enabled = true; - await NotificationService.Publish(notificationModel, settings); + await NotificationService.PublishTest(notificationModel, settings, new SlackNotification(SlackApi, SlackSettings)); Log.Info("Sent slack notification test"); } catch (Exception e) @@ -1071,7 +1075,7 @@ namespace Ombi.UI.Modules.Admin { NotificationService.Subscribe(new DiscordNotification(DiscordApi, DiscordSettings)); settings.Enabled = true; - await NotificationService.Publish(notificationModel, settings); + await NotificationService.PublishTest(notificationModel, settings, new DiscordNotification(DiscordApi, DiscordSettings)); Log.Info("Sent Discord notification test"); } catch (Exception e) @@ -1210,12 +1214,12 @@ namespace Ombi.UI.Modules.Admin PlexEpisodeCacher = s.PlexEpisodeCacher, PlexUserChecker = s.PlexUserChecker, UserRequestLimitResetter = s.UserRequestLimitResetter, - EmbyAvailabilityChecker = s.EmbyAvailabilityChecker, - EmbyContentCacher = s.EmbyContentCacher, - EmbyEpisodeCacher = s.EmbyEpisodeCacher, - EmbyUserChecker = s.EmbyUserChecker, - RadarrCacher = s.RadarrCacher, - WatcherCacher = s.WatcherCacher + EmbyAvailabilityChecker = s.EmbyAvailabilityChecker, + EmbyContentCacher = s.EmbyContentCacher, + EmbyEpisodeCacher = s.EmbyEpisodeCacher, + EmbyUserChecker = s.EmbyUserChecker, + RadarrCacher = s.RadarrCacher, + WatcherCacher = s.WatcherCacher }; return View["SchedulerSettings", model]; } @@ -1278,7 +1282,7 @@ namespace Ombi.UI.Modules.Admin var model = this.Bind(); return View["NotificationSettings", model]; } - + private Response TestNewsletterAdminEmail() { try @@ -1299,7 +1303,8 @@ namespace Ombi.UI.Modules.Admin { var settings = this.Bind(); Log.Debug("Clicked Admin Mass Email Test"); - if (settings.Subject == null) { + if (settings.Subject == null) + { return Response.AsJson(new JsonResponseModel { Result = false, Message = "Please Set a Subject" }); } if (settings.Body == null) diff --git a/Ombi.UI/Modules/Admin/CustomizationModule.cs b/Ombi.UI/Modules/Admin/CustomizationModule.cs index d34e41ee2..de42e82b4 100644 --- a/Ombi.UI/Modules/Admin/CustomizationModule.cs +++ b/Ombi.UI/Modules/Admin/CustomizationModule.cs @@ -122,8 +122,7 @@ namespace Ombi.UI.Modules.Admin } catch (Exception e) { - - throw; + throw e; } } } diff --git a/Ombi.UI/Modules/UserLoginModule.cs b/Ombi.UI/Modules/UserLoginModule.cs index 386c1ded2..58cd8255b 100644 --- a/Ombi.UI/Modules/UserLoginModule.cs +++ b/Ombi.UI/Modules/UserLoginModule.cs @@ -59,7 +59,8 @@ namespace Ombi.UI.Modules { public UserLoginModule(ISettingsService auth, IPlexApi api, ISettingsService plexSettings, ISettingsService pr, ISettingsService lp, IAnalytics a, IResourceLinker linker, IRepository userLogins, IExternalUserRepository plexUsers, ICustomUserMapper custom, - ISecurityExtensions security, ISettingsService userManagementSettings, IEmbyApi embyApi, ISettingsService emby, IExternalUserRepository embyU) + ISecurityExtensions security, ISettingsService userManagementSettings, IEmbyApi embyApi, ISettingsService emby, IExternalUserRepository embyU, + IUserHelper userHelper) : base("userlogin", pr, security) { AuthService = auth; @@ -75,6 +76,7 @@ namespace Ombi.UI.Modules EmbySettings = emby; EmbyApi = embyApi; EmbyUserRepository = embyU; + UserHelper = userHelper; Post["/", true] = async (x, ct) => await LoginUser(); Get["/logout"] = x => Logout(); @@ -135,6 +137,7 @@ namespace Ombi.UI.Modules private IExternalUserRepository EmbyUserRepository { get; } private ICustomUserMapper CustomUserMapper { get; } private ISettingsService UserManagementSettings { get; } + private IUserHelper UserHelper { get; } private static Logger Log = LogManager.GetCurrentClassLogger(); @@ -683,6 +686,14 @@ namespace Ombi.UI.Modules { type = UserType.EmbyUser;; } + if (string.IsNullOrEmpty(userId)) + { + // It's possible we have no auth enabled meaning the userId is empty + // Let's find that user! + + var user = UserHelper.GetUser(username); + userId = user.UserId; + } UserLogins.Insert(new UserLogins { UserId = userId, Type = type, LastLoggedIn = DateTime.UtcNow }); return m;