예제 #1
0
        private async Task <IEnumerable <UserManagementUsersViewModel> > LoadEmbyUsers()
        {
            var embyDbUsers = await EmbyRepository.GetAllAsync();

            var model = new List <UserManagementUsersViewModel>();

            var userLogins = UserLoginsRepo.GetAll().ToList();

            var embySettings = await EmbySettings.GetSettingsAsync();

            if (!string.IsNullOrEmpty(embySettings.ApiKey))
            {
                //Get Plex Users
                var embyUsers = EmbyApi.GetUsers(embySettings.FullUri, embySettings.ApiKey);
                if (embyUsers != null)
                {
                    foreach (var u in embyUsers)
                    {
                        var dbUser = embyDbUsers.FirstOrDefault(x => x.EmbyUserId == u.Id);
                        var userDb = userLogins.FirstOrDefault(x => x.UserId == u.Id);

                        // We don't have the user in the database yet
                        model.Add(dbUser == null
                            ? MapEmbyUser(u, null, userDb?.LastLoggedIn ?? DateTime.MinValue)
                            : MapEmbyUser(u, dbUser, userDb?.LastLoggedIn ?? DateTime.MinValue));
                    }
                }
            }
            return(model);
        }
예제 #2
0
        private async Task <Response> LoadUsers()
        {
            var plexSettings = await PlexSettings.GetSettingsAsync();

            var embySettings = await EmbySettings.GetSettingsAsync();

            if (plexSettings.Enable)
            {
                return(await LoadPlexUsers());
            }
            if (embySettings.Enable)
            {
                return(await LoadEmbyUsers());
            }

            return(null);
        }
예제 #3
0
        private async Task <Response> ChangeRequestAvailability(int requestId, bool available)
        {
            if (!Security.HasAnyPermissions(User, Permissions.Administrator, Permissions.ManageRequests))
            {
                return(Response.AsJson(new JsonResponseModel {
                    Result = false, Message = "Sorry, you do not have the correct permissions to change a request."
                }));
            }

            Analytics.TrackEventAsync(Category.Requests, Action.Update, available ? "Make request available" : "Make request unavailable", Username, CookieHelper.GetAnalyticClientId(Cookies));
            var originalRequest = await Service.GetAsync(requestId);

            if (originalRequest == null)
            {
                return(Response.AsJson(new JsonResponseModel {
                    Result = false, Message = "Request does not exist to change the availability!"
                }));
            }

            originalRequest.Available = available;

            var result = await Service.UpdateRequestAsync(originalRequest);

            var plexSettings = await PlexSettings.GetSettingsAsync();

            if (plexSettings.Enable)
            {
                await
                PlexNotificationEngine.NotifyUsers(originalRequest,
                                                   available?NotificationType.RequestAvailable : NotificationType.RequestDeclined);
            }

            var embySettings = await EmbySettings.GetSettingsAsync();

            if (embySettings.Enable)
            {
                await EmbyNotificationEngine.NotifyUsers(originalRequest,
                                                         available?NotificationType.RequestAvailable : NotificationType.RequestDeclined);
            }
            return(Response.AsJson(result
                                       ? new { Result = true, Available = available, Message = string.Empty }
                                       : new { Result = false, Available = false, Message = "Could not update the availability, please try again or check the logs" }));
        }
예제 #4
0
        private async Task <Response> LoadUsers()
        {
            var model        = new List <UserManagementUsersViewModel>();
            var plexSettings = await PlexSettings.GetSettingsAsync();

            var embySettings = await EmbySettings.GetSettingsAsync();

            if (plexSettings.Enable)
            {
                model.AddRange(await LoadPlexUsers());
            }
            if (embySettings.Enable)
            {
                model.AddRange(await LoadEmbyUsers());
            }

            model.AddRange(await LoadLocalUsers());

            return(Response.AsJson(model));
        }
예제 #5
0
        private async Task <Response> CheckStatus()
        {
            var plexSettings = await PlexSettings.GetSettingsAsync();

            if (plexSettings.Enable)
            {
                if (string.IsNullOrEmpty(plexSettings.PlexAuthToken) || string.IsNullOrEmpty(plexSettings.Ip))
                {
                    return(Response.AsJson(false));
                }
                try
                {
                    var status = PlexApi.GetStatus(plexSettings.PlexAuthToken, plexSettings.FullUri);
                    return(Response.AsJson(status != null));
                }
                catch (Exception)
                {
                    return(Response.AsJson(false));
                }
            }

            var emby = await EmbySettings.GetSettingsAsync();

            if (emby.Enable)
            {
                if (string.IsNullOrEmpty(emby.AdministratorId) || string.IsNullOrEmpty(emby.Ip))
                {
                    return(Response.AsJson(false));
                }
                try
                {
                    var status = EmbyApi.GetSystemInformation(emby.ApiKey, emby.FullUri);
                    return(Response.AsJson(status?.Version != null));
                }
                catch (Exception)
                {
                    return(Response.AsJson(false));
                }
            }
            return(Response.AsJson(false));
        }
예제 #6
0
        private async Task <Response> UpdateUser()
        {
            Analytics.TrackEventAsync(Category.UserManagement, Action.Update, "Updated User", Username, CookieHelper.GetAnalyticClientId(Cookies));
            var body = Request.Body.AsString();

            if (string.IsNullOrEmpty(body))
            {
                return(Response.AsJson(new JsonResponseModel {
                    Result = false, Message = "Could not save user, invalid JSON body"
                }));
            }

            var model = JsonConvert.DeserializeObject <UserManagementUpdateModel>(body);

            if (string.IsNullOrWhiteSpace(model.Id))
            {
                return(Response.AsJson(new JsonResponseModel
                {
                    Result = true,
                    Message = "Couldn't find the user"
                }));
            }

            var permissionsValue = model.Permissions.Where(c => c.Selected).Sum(c => c.Value);
            var featuresValue    = model.Features.Where(c => c.Selected).Sum(c => c.Value);

            Guid outId;

            Guid.TryParse(model.Id, out outId);
            var localUser = UserMapper.GetUser(outId);

            // Update Local User
            if (localUser != null)
            {
                localUser.Permissions = permissionsValue;
                localUser.Features    = featuresValue;

                var currentProps = ByteConverterHelper.ReturnObject <UserProperties>(localUser.UserProperties);

                // Let's check if the alias has changed, if so we need to change all the requests associated with this
                await UpdateRequests(localUser.UserName, currentProps.UserAlias, model.Alias);

                currentProps.UserAlias    = model.Alias;
                currentProps.EmailAddress = model.EmailAddress;

                localUser.UserProperties = ByteConverterHelper.ReturnBytes(currentProps);

                var user    = UserMapper.EditUser(localUser);
                var dbUser  = UserLoginsRepo.GetAll().FirstOrDefault(x => x.UserId == user.UserGuid);
                var retUser = MapLocalUser(user, dbUser?.LastLoggedIn ?? DateTime.MinValue);
                return(Response.AsJson(retUser));
            }

            var plexSettings = await PlexSettings.GetSettingsAsync();

            if (plexSettings.Enable)
            {
                var plexDbUsers = await PlexUsersRepository.GetAllAsync();

                var plexUsers  = PlexApi.GetUsers(plexSettings.PlexAuthToken);
                var plexDbUser = plexDbUsers.FirstOrDefault(x => x.PlexUserId == model.Id);
                var plexUser   = plexUsers.User.FirstOrDefault(x => x.Id == model.Id);
                var userLogin  = UserLoginsRepo.GetAll().FirstOrDefault(x => x.UserId == model.Id);
                if (plexDbUser != null && plexUser != null)
                {
                    // We have a user in the DB for this Plex Account
                    plexDbUser.Permissions = permissionsValue;
                    plexDbUser.Features    = featuresValue;

                    await UpdateRequests(plexDbUser.Username, plexDbUser.UserAlias, model.Alias);

                    plexDbUser.UserAlias    = model.Alias;
                    plexDbUser.EmailAddress = model.EmailAddress;

                    await PlexUsersRepository.UpdateAsync(plexDbUser);

                    var retUser = MapPlexUser(plexUser, plexDbUser, userLogin?.LastLoggedIn ?? DateTime.MinValue);
                    return(Response.AsJson(retUser));
                }

                // So it could actually be the admin
                var account = PlexApi.GetAccount(plexSettings.PlexAuthToken);
                if (plexDbUser != null && account != null)
                {
                    // We have a user in the DB for this Plex Account
                    plexDbUser.Permissions = permissionsValue;
                    plexDbUser.Features    = featuresValue;

                    await UpdateRequests(plexDbUser.Username, plexDbUser.UserAlias, model.Alias);

                    plexDbUser.UserAlias = model.Alias;

                    await PlexUsersRepository.UpdateAsync(plexDbUser);

                    var retUser = MapPlexAdmin(account, plexDbUser, userLogin?.LastLoggedIn ?? DateTime.MinValue);
                    return(Response.AsJson(retUser));
                }

                // We have a Plex Account but he's not in the DB
                if (plexUser != null)
                {
                    var user = new PlexUsers
                    {
                        Permissions  = permissionsValue,
                        Features     = featuresValue,
                        UserAlias    = model.Alias,
                        PlexUserId   = plexUser.Id,
                        EmailAddress = plexUser.Email,
                        Username     = plexUser.Title,
                        LoginId      = Guid.NewGuid().ToString()
                    };

                    await PlexUsersRepository.InsertAsync(user);

                    var retUser = MapPlexUser(plexUser, user, userLogin?.LastLoggedIn ?? DateTime.MinValue);
                    return(Response.AsJson(retUser));
                }
            }

            var embySettings = await EmbySettings.GetSettingsAsync();

            if (embySettings.Enable)
            {
                var embyDbUsers = await EmbyRepository.GetAllAsync();

                var embyUsers      = EmbyApi.GetUsers(embySettings.FullUri, embySettings.ApiKey);
                var selectedDbUser = embyDbUsers.FirstOrDefault(x => x.EmbyUserId == model.Id);
                var embyUser       = embyUsers.FirstOrDefault(x => x.Id == model.Id);

                var userLogin = UserLoginsRepo.GetAll().FirstOrDefault(x => x.UserId == model.Id);
                if (selectedDbUser != null && embyUser != null)
                {
                    // We have a user in the DB for this Plex Account
                    selectedDbUser.Permissions = permissionsValue;
                    selectedDbUser.Features    = featuresValue;

                    await UpdateRequests(selectedDbUser.Username, selectedDbUser.UserAlias, model.Alias);

                    selectedDbUser.UserAlias    = model.Alias;
                    selectedDbUser.EmailAddress = model.EmailAddress;

                    await EmbyRepository.UpdateAsync(selectedDbUser);

                    var retUser = MapEmbyUser(embyUser, selectedDbUser, userLogin?.LastLoggedIn ?? DateTime.MinValue);
                    return(Response.AsJson(retUser));
                }
            }
            return(null); // We should never end up here.
        }
예제 #7
0
        private async Task <Response> PasswordLogin()
        {
            var password = Request.Form.password.Value;

            if (string.IsNullOrEmpty(password))
            {
                return(Response.AsJson(new { result = false, message = Resources.UI.UserLogin_IncorrectUserPass }));
            }

            var dateTimeOffset = Request.Form.DateTimeOffset;
            var loginGuid      = Guid.Empty;
            var settings       = await AuthService.GetSettingsAsync();

            var username      = Session[SessionKeys.UserLoginName].ToString();
            var authenticated = false;
            var isOwner       = false;
            var userId        = string.Empty;

            var plexSettings = await PlexSettings.GetSettingsAsync();

            var embySettings = await EmbySettings.GetSettingsAsync();

            // attempt local login first as it has the least amount of overhead
            userId = CustomUserMapper.ValidateUser(username, password)?.ToString();
            if (userId != null)
            {
                authenticated = true;
            }
            else if (userId == null && plexSettings.Enable)
            {
                if (settings.UserAuthentication) // Authenticate with Plex
                {
                    Log.Debug("Need to auth and also provide pass");
                    var signedIn = (PlexAuthentication)PlexApi.SignIn(username, password);
                    if (signedIn.user?.authentication_token != null)
                    {
                        Log.Debug("Correct credentials, checking if the user is account owner or in the friends list");
                        if (CheckIfUserIsOwner(plexSettings.PlexAuthToken, signedIn.user?.username))
                        {
                            Log.Debug("User is the account owner");
                            authenticated = true;
                            isOwner       = true;
                        }
                        else
                        {
                            authenticated = CheckIfUserIsInPlexFriends(username, plexSettings.PlexAuthToken);
                            Log.Debug("Friends list result = {0}", authenticated);
                        }
                        userId = signedIn.user.uuid;
                    }
                }
            }
            else if (userId == null && embySettings.Enable)
            {
                if (settings.UserAuthentication) // Authenticate with Emby
                {
                    Log.Debug("Need to auth and also provide pass");
                    EmbyUser signedIn = null;
                    try
                    {
                        signedIn = (EmbyUser)EmbyApi.LogIn(username, password, embySettings.ApiKey, embySettings.FullUri);
                    }
                    catch (Exception e)
                    {
                        Log.Error(e);
                    }
                    if (signedIn != null)
                    {
                        Log.Debug("Correct credentials, checking if the user is account owner or in the friends list");
                        if (signedIn?.Policy?.IsAdministrator ?? false)
                        {
                            Log.Debug("User is the account owner");
                            authenticated = true;
                            isOwner       = true;
                        }
                        else
                        {
                            authenticated = CheckIfEmbyUser(username, embySettings);
                            Log.Debug("Friends list result = {0}", authenticated);
                        }
                        userId = signedIn?.Id;
                    }
                }
            }

            if (!authenticated)
            {
                return(Response.AsJson(new { result = false, message = Resources.UI.UserLogin_IncorrectUserPass }));
            }

            var m = await AuthenticationSetup(userId, username, dateTimeOffset, loginGuid, isOwner, plexSettings.Enable, embySettings.Enable);

            var landingSettings = await LandingPageSettings.GetSettingsAsync();

            if (landingSettings.Enabled)
            {
                if (!landingSettings.BeforeLogin) // After Login
                {
                    var uri = Linker.BuildRelativeUri(Context, "LandingPageIndex");
                    if (m.LoginGuid != Guid.Empty)
                    {
                        return(CustomModuleExtensions.LoginAndRedirect(this, m.LoginGuid, null, uri.ToString()));
                    }
                    return(Response.AsRedirect(uri.ToString()));
                }
            }

            var retVal = Linker.BuildRelativeUri(Context, "SearchIndex");

            if (m.LoginGuid != Guid.Empty)
            {
                return(CustomModuleExtensions.LoginAndRedirect(this, m.LoginGuid, null, retVal.ToString()));
            }
            return(Response.AsJson(new { result = true, url = retVal.ToString() }));
        }
예제 #8
0
        private async Task <Response> UsernameLogin()
        {
            var username       = Request.Form.username.Value;
            var dateTimeOffset = Request.Form.DateTimeOffset;
            var loginGuid      = Guid.Empty;
            var settings       = await AuthService.GetSettingsAsync();

            if (string.IsNullOrWhiteSpace(username) || IsUserInDeniedList(username, settings))
            {
                return(Response.AsJson(new { result = false, message = Resources.UI.UserLogin_IncorrectUserPass }));
            }

            var plexSettings = await PlexSettings.GetSettingsAsync();

            var embySettings = await EmbySettings.GetSettingsAsync();

            var      authenticated = false;
            var      isOwner       = false;
            var      userId        = string.Empty;
            EmbyUser embyUser      = null;

            if (plexSettings.Enable)
            {
                if (settings.UserAuthentication) // Check against the users in Plex
                {
                    try
                    {
                        Log.Debug("Need to auth");
                        authenticated = CheckIfUserIsInPlexFriends(username, plexSettings.PlexAuthToken);
                        if (authenticated)
                        {
                            userId = GetUserIdIsInPlexFriends(username, plexSettings.PlexAuthToken);
                        }
                        if (CheckIfUserIsOwner(plexSettings.PlexAuthToken, username))
                        {
                            Log.Debug("User is the account owner");
                            authenticated = true;
                            isOwner       = true;
                            userId        = GetOwnerId(plexSettings.PlexAuthToken, username);
                        }
                        Log.Debug("Friends list result = {0}", authenticated);
                    }
                    catch (Exception)
                    {
                        return(Response.AsJson(new { result = false, message = Resources.UI.UserLogin_IncorrectUserPass }));
                    }
                }
                else if (!settings.UserAuthentication) // No auth, let them pass!
                {
                    authenticated = true;
                }
            }
            if (embySettings.Enable)
            {
                if (settings.UserAuthentication) // Check against the users in Plex
                {
                    Log.Debug("Need to auth");
                    authenticated = CheckIfEmbyUser(username, embySettings);
                    if (authenticated)
                    {
                        embyUser = GetEmbyUser(username, embySettings);
                        userId   = embyUser?.Id;
                    }
                    if (embyUser?.Policy?.IsAdministrator ?? false)
                    {
                        Log.Debug("User is the account owner");
                        authenticated = true;
                        isOwner       = true;
                    }
                    Log.Debug("Friends list result = {0}", authenticated);
                }
                else if (!settings.UserAuthentication) // No auth, let them pass!
                {
                    authenticated = true;
                }
            }

            UsersModel dbUser = await IsDbuser(username);

            if (dbUser != null) // in the db?
            {
                var perms = (Permissions)dbUser.Permissions;
                authenticated = true;
                isOwner       = perms.HasFlag(Permissions.Administrator);
                userId        = dbUser.UserGuid;
            }

            if (settings.UsePassword || isOwner || Security.HasPermissions(username, Permissions.Administrator))
            {
                Session[SessionKeys.UserLoginName] = username;

                var path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Views", "UserLogin");
                var file = System.IO.Directory.GetFiles(path).FirstOrDefault(x => x.Contains("Password.cshtml"));
                var html = File.ReadAllText(file);

                return(Response.AsJson(new { result = true, usePassword = true, html }));
            }

            if (!authenticated)
            {
                return(Response.AsJson(new { result = false, message = Resources.UI.UserLogin_IncorrectUserPass }));
            }
            var result = await AuthenticationSetup(userId, username, dateTimeOffset, loginGuid, isOwner, plexSettings.Enable, embySettings.Enable);


            var landingSettings = await LandingPageSettings.GetSettingsAsync();

            if (landingSettings.Enabled)
            {
                if (!landingSettings.BeforeLogin) // After Login
                {
                    var uri = Linker.BuildRelativeUri(Context, "LandingPageIndex");
                    if (loginGuid != Guid.Empty)
                    {
                        return(CustomModuleExtensions.LoginAndRedirect(this, result.LoginGuid, null, uri.ToString()));
                    }
                    return(Response.AsRedirect(uri.ToString()));
                }
            }


            var retVal = Linker.BuildRelativeUri(Context, "SearchIndex");

            if (result.LoginGuid != Guid.Empty)
            {
                return(CustomModuleExtensions.LoginAndRedirect(this, result.LoginGuid, null, retVal.ToString()));
            }
            return(Response.AsJson(new { result = true, url = retVal.ToString() }));
        }
예제 #9
0
        public async Task NotifyUsers(IEnumerable <RequestedModel> modelChanged, NotificationType type)
        {
            try
            {
                var embySettings = await EmbySettings.GetSettingsAsync();

                var embyUsers   = EmbyApi.GetUsers(embySettings.FullUri, embySettings.ApiKey);
                var userAccount = embyUsers.FirstOrDefault(x => x.Policy.IsAdministrator);

                var adminUsername = userAccount?.Name ?? string.Empty;

                var users = UserHelper.GetUsersWithFeature(Features.RequestAddedNotification).ToList();
                Log.Debug("Notifying Users Count {0}", users.Count);
                foreach (var model in modelChanged)
                {
                    var selectedUsers = new List <string>();

                    foreach (var u in users)
                    {
                        var requestUser = model.RequestedUsers.FirstOrDefault(
                            x => x.Equals(u.Username, StringComparison.CurrentCultureIgnoreCase) || x.Equals(u.UserAlias, StringComparison.CurrentCultureIgnoreCase));
                        if (string.IsNullOrEmpty(requestUser))
                        {
                            continue;
                        }

                        // Make sure we do not already have the user
                        if (!selectedUsers.Contains(requestUser))
                        {
                            selectedUsers.Add(requestUser);
                        }
                    }

                    foreach (var user in selectedUsers)
                    {
                        var localUser =
                            users.FirstOrDefault(x =>
                                                 x.Username.Equals(user, StringComparison.CurrentCultureIgnoreCase) ||
                                                 x.UserAlias.Equals(user, StringComparison.CurrentCultureIgnoreCase));
                        Log.Info("Notifying user {0}", user);
                        if (user.Equals(adminUsername, StringComparison.CurrentCultureIgnoreCase))
                        {
                            Log.Info("This user is the Plex server owner");
                            await PublishUserNotification(userAccount?.Name, localUser?.EmailAddress, model.Title, model.PosterPath, type, model.Type);

                            return;
                        }



                        // So if the request was from an alias, then we need to use the local user (since that contains the alias).
                        // If we do not have a local user, then we should be using the Emby user if that user exists.
                        // This will execute most of the time since Emby and Local users will most always be in the database.
                        if (localUser != null)
                        {
                            if (string.IsNullOrEmpty(localUser?.EmailAddress))
                            {
                                Log.Info("There is no email address for this Local user ({0}), cannot send notification", localUser.Username);
                                continue;
                            }

                            Log.Info("Sending notification to: {0} at: {1}, for : {2}", localUser, localUser.EmailAddress, model.Title);
                            await PublishUserNotification(localUser.Username, localUser.EmailAddress, model.Title, model.PosterPath, type, model.Type);
                        }
                        else
                        {
                            var embyUser = EmbyUserRepo.GetUserByUsername(user);
                            var email    = embyUsers.FirstOrDefault(x => x.Name.Equals(user, StringComparison.CurrentCultureIgnoreCase));
                            if (string.IsNullOrEmpty(embyUser?.EmailAddress)) // TODO this needs to be the email
                            {
                                Log.Info("There is no email address for this Emby user ({0}), cannot send notification", email?.Name);
                                // We do not have a plex user that requested this!
                                continue;
                            }

                            Log.Info("Sending notification to: {0} at: {1}, for : {2}", embyUser?.Username, embyUser?.EmailAddress, model.Title);
                            await PublishUserNotification(email?.Name, embyUser?.EmailAddress, model.Title, model.PosterPath, type, model.Type);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }
예제 #10
0
        public async Task NotifyUsers(RequestedModel model, NotificationType type)
        {
            try
            {
                var embySettings = await EmbySettings.GetSettingsAsync();

                var embyUsers   = EmbyApi.GetUsers(embySettings.FullUri, embySettings.ApiKey);
                var userAccount = embyUsers.FirstOrDefault(x => x.Policy.IsAdministrator);
                var localUsers  = UserHelper.GetUsers().ToList();

                var adminUsername = userAccount.Name ?? string.Empty;

                var users = UserHelper.GetUsersWithFeature(Features.RequestAddedNotification).ToList();
                Log.Debug("Notifying Users Count {0}", users.Count);

                // Get the usernames or alias depending if they have an alias
                var userNamesWithFeature = users.Select(x => x.UsernameOrAlias).ToList();
                Log.Debug("Users with the feature count {0}", userNamesWithFeature.Count);
                Log.Debug("Usernames: ");
                foreach (var u in userNamesWithFeature)
                {
                    Log.Debug(u);
                }

                Log.Debug("Users in the requested model count: {0}", model.AllUsers.Count);
                Log.Debug("usernames from model: ");
                foreach (var modelAllUser in model.AllUsers)
                {
                    Log.Debug(modelAllUser);
                }

                if (model.AllUsers == null || !model.AllUsers.Any())
                {
                    Log.Debug("There are no users in the model.AllUsers, no users to notify");
                    return;
                }
                var usersToNotify = userNamesWithFeature.Intersect(model.AllUsers, StringComparer.CurrentCultureIgnoreCase).ToList();

                if (!usersToNotify.Any())
                {
                    Log.Debug("Could not find any users after the .Intersect()");
                }

                Log.Debug("Users being notified for this request count {0}", users.Count);
                foreach (var user in usersToNotify)
                {
                    var embyUser = EmbyUserRepo.GetUserByUsername(user);
                    Log.Info("Notifying user {0}", user);
                    if (user.Equals(adminUsername, StringComparison.CurrentCultureIgnoreCase))
                    {
                        Log.Info("This user is the Emby server owner");
                        await PublishUserNotification(userAccount.Name, embyUser.EmailAddress, model.Title, model.PosterPath, type, model.Type);

                        return;
                    }

                    var email = embyUsers.FirstOrDefault(x => x.Name.Equals(user, StringComparison.CurrentCultureIgnoreCase));
                    if (email == null)
                    {
                        // Local User?
                        var local = localUsers.FirstOrDefault(x => x.UsernameOrAlias.Equals(user));
                        if (local != null)
                        {
                            Log.Info("Sending notification to: {0} at: {1}, for title: {2}", local.UsernameOrAlias, local.EmailAddress, model.Title);
                            await PublishUserNotification(local.UsernameOrAlias, local.EmailAddress, model.Title, model.PosterPath, type, model.Type);

                            continue;
                        }
                    }

                    Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Name, embyUser.EmailAddress, model.Title);
                    await PublishUserNotification(email.Name, embyUser.EmailAddress, model.Title, model.PosterPath, type, model.Type);
                }
            }
            catch (Exception e)
            {
                Log.Error(e);
            }
        }