mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
Added User Management support for Emby #435
This commit is contained in:
parent
4feb3cd462
commit
4193cb88fd
23 changed files with 354 additions and 118 deletions
|
@ -51,5 +51,6 @@ namespace Ombi.Core.SettingModels
|
||||||
public int EmbyEpisodeCacher { get; set; }
|
public int EmbyEpisodeCacher { get; set; }
|
||||||
public int EmbyContentCacher { get; set; }
|
public int EmbyContentCacher { get; set; }
|
||||||
public int EmbyAvailabilityChecker { get; set; }
|
public int EmbyAvailabilityChecker { get; set; }
|
||||||
|
public int EmbyUserChecker { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
138
Ombi.Services/Jobs/EmbyUserChecker.cs
Normal file
138
Ombi.Services/Jobs/EmbyUserChecker.cs
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
#region Copyright
|
||||||
|
|
||||||
|
// /************************************************************************
|
||||||
|
// Copyright (c) 2016 Jamie Rees
|
||||||
|
// File: StoreCleanup.cs
|
||||||
|
// Created By: Jamie Rees
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
// a copy of this software and associated documentation files (the
|
||||||
|
// "Software"), to deal in the Software without restriction, including
|
||||||
|
// without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
// permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
// the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be
|
||||||
|
// included in all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
// ************************************************************************/
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using NLog;
|
||||||
|
using Ombi.Api.Interfaces;
|
||||||
|
using Ombi.Core;
|
||||||
|
using Ombi.Core.SettingModels;
|
||||||
|
using Ombi.Core.Users;
|
||||||
|
using Ombi.Helpers.Permissions;
|
||||||
|
using Ombi.Services.Interfaces;
|
||||||
|
using Ombi.Store.Models.Emby;
|
||||||
|
using Ombi.Store.Repository;
|
||||||
|
using Quartz;
|
||||||
|
|
||||||
|
namespace Ombi.Services.Jobs
|
||||||
|
{
|
||||||
|
public class EmbyUserChecker : IJob, IEmbyUserChecker
|
||||||
|
{
|
||||||
|
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public EmbyUserChecker(IExternalUserRepository<EmbyUsers> plexUsers, IEmbyApi embyApi, IJobRecord rec, ISettingsService<EmbySettings> embyS, ISettingsService<PlexRequestSettings> prSettings, ISettingsService<UserManagementSettings> umSettings,
|
||||||
|
IRequestService requestService, IUserRepository localUser)
|
||||||
|
{
|
||||||
|
Repo = plexUsers;
|
||||||
|
JobRecord = rec;
|
||||||
|
EmbyApi = embyApi;
|
||||||
|
EmbySettings = embyS;
|
||||||
|
PlexRequestSettings = prSettings;
|
||||||
|
UserManagementSettings = umSettings;
|
||||||
|
RequestService = requestService;
|
||||||
|
LocalUserRepository = localUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IJobRecord JobRecord { get; }
|
||||||
|
private IEmbyApi EmbyApi { get; }
|
||||||
|
private IExternalUserRepository<EmbyUsers> Repo { get; }
|
||||||
|
private ISettingsService<EmbySettings> EmbySettings { get; }
|
||||||
|
private ISettingsService<PlexRequestSettings> PlexRequestSettings { get; }
|
||||||
|
private ISettingsService<UserManagementSettings> UserManagementSettings { get; }
|
||||||
|
private IRequestService RequestService { get; }
|
||||||
|
private IUserRepository LocalUserRepository { get; }
|
||||||
|
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
JobRecord.SetRunning(true, JobNames.EmbyUserChecker);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = EmbySettings.GetSettings();
|
||||||
|
if (string.IsNullOrEmpty(settings.ApiKey) || !settings.Enable)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var embyUsers = EmbyApi.GetUsers(settings.FullUri, settings.ApiKey);
|
||||||
|
var userManagementSettings = UserManagementSettings.GetSettings();
|
||||||
|
var requests = RequestService.GetAll().ToList();
|
||||||
|
|
||||||
|
var dbUsers = Repo.GetAll().ToList();
|
||||||
|
var localUsers = LocalUserRepository.GetAll().ToList();
|
||||||
|
|
||||||
|
// Regular users
|
||||||
|
foreach (var user in embyUsers)
|
||||||
|
{
|
||||||
|
var dbUser = dbUsers.FirstOrDefault(x => x.EmbyUserId == user.Id);
|
||||||
|
if (dbUser != null)
|
||||||
|
{
|
||||||
|
// we already have a user
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Looks like it's a new user!
|
||||||
|
var m = new EmbyUsers
|
||||||
|
{
|
||||||
|
EmbyUserId = user.Id,
|
||||||
|
Permissions = UserManagementHelper.GetPermissions(userManagementSettings),
|
||||||
|
Features = UserManagementHelper.GetFeatures(userManagementSettings),
|
||||||
|
UserAlias = string.Empty,
|
||||||
|
Username = user.Name,
|
||||||
|
LoginId = Guid.NewGuid().ToString()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// If it's the admin, give them the admin permission
|
||||||
|
if (user.Policy.IsAdministrator)
|
||||||
|
{
|
||||||
|
if (!((Permissions) m.Permissions).HasFlag(Permissions.Administrator))
|
||||||
|
{
|
||||||
|
m.Permissions += (int)Permissions.Administrator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Repo.Insert(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.Error(e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
JobRecord.SetRunning(false, JobNames.EmbyUserChecker);
|
||||||
|
JobRecord.Record(JobNames.EmbyUserChecker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Execute(IJobExecutionContext context)
|
||||||
|
{
|
||||||
|
Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
10
Ombi.Services/Jobs/IEmbyUserChecker.cs
Normal file
10
Ombi.Services/Jobs/IEmbyUserChecker.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
using Quartz;
|
||||||
|
|
||||||
|
namespace Ombi.Services.Jobs
|
||||||
|
{
|
||||||
|
public interface IEmbyUserChecker
|
||||||
|
{
|
||||||
|
void Execute(IJobExecutionContext context);
|
||||||
|
void Start();
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,6 +45,7 @@ namespace Ombi.Services.Jobs
|
||||||
public const string RecentlyAddedEmail = "Recently Added Email Notification";
|
public const string RecentlyAddedEmail = "Recently Added Email Notification";
|
||||||
public const string FaultQueueHandler = "Request Fault Queue Handler";
|
public const string FaultQueueHandler = "Request Fault Queue Handler";
|
||||||
public const string PlexUserChecker = "Plex User Checker";
|
public const string PlexUserChecker = "Plex User Checker";
|
||||||
|
public const string EmbyUserChecker = "Emby User Checker";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -95,6 +95,7 @@
|
||||||
<Compile Include="Interfaces\IStoreBackup.cs" />
|
<Compile Include="Interfaces\IStoreBackup.cs" />
|
||||||
<Compile Include="Interfaces\IStoreCleanup.cs" />
|
<Compile Include="Interfaces\IStoreCleanup.cs" />
|
||||||
<Compile Include="Interfaces\IUserRequestLimitResetter.cs" />
|
<Compile Include="Interfaces\IUserRequestLimitResetter.cs" />
|
||||||
|
<Compile Include="Jobs\IEmbyUserChecker.cs" />
|
||||||
<Compile Include="Jobs\Interfaces\IEmbyEpisodeCacher.cs" />
|
<Compile Include="Jobs\Interfaces\IEmbyEpisodeCacher.cs" />
|
||||||
<Compile Include="Jobs\Interfaces\IEmbyContentCacher.cs" />
|
<Compile Include="Jobs\Interfaces\IEmbyContentCacher.cs" />
|
||||||
<Compile Include="Jobs\Interfaces\IEmbyAvailabilityChecker.cs" />
|
<Compile Include="Jobs\Interfaces\IEmbyAvailabilityChecker.cs" />
|
||||||
|
@ -104,6 +105,7 @@
|
||||||
<Compile Include="Jobs\EmbyAvailabilityChecker.cs" />
|
<Compile Include="Jobs\EmbyAvailabilityChecker.cs" />
|
||||||
<Compile Include="Jobs\EmbyContentCacher.cs" />
|
<Compile Include="Jobs\EmbyContentCacher.cs" />
|
||||||
<Compile Include="Jobs\EmbyEpisodeCacher.cs" />
|
<Compile Include="Jobs\EmbyEpisodeCacher.cs" />
|
||||||
|
<Compile Include="Jobs\EmbyUserChecker.cs" />
|
||||||
<Compile Include="Jobs\RadarrCacher.cs" />
|
<Compile Include="Jobs\RadarrCacher.cs" />
|
||||||
<Compile Include="Jobs\WatcherCacher.cs" />
|
<Compile Include="Jobs\WatcherCacher.cs" />
|
||||||
<Compile Include="Jobs\HtmlTemplateGenerator.cs" />
|
<Compile Include="Jobs\HtmlTemplateGenerator.cs" />
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace Ombi.Store.Models.Emby
|
||||||
[Table(nameof(EmbyUsers))]
|
[Table(nameof(EmbyUsers))]
|
||||||
public class EmbyUsers : Entity
|
public class EmbyUsers : Entity
|
||||||
{
|
{
|
||||||
public string PlexUserId { get; set; }
|
public string EmbyUserId { get; set; }
|
||||||
public string UserAlias { get; set; }
|
public string UserAlias { get; set; }
|
||||||
public int Permissions { get; set; }
|
public int Permissions { get; set; }
|
||||||
public int Features { get; set; }
|
public int Features { get; set; }
|
||||||
|
|
|
@ -33,7 +33,7 @@ using Ombi.Helpers;
|
||||||
|
|
||||||
namespace Ombi.Store.Repository
|
namespace Ombi.Store.Repository
|
||||||
{
|
{
|
||||||
public class BaseExternalUserRepository<T> : BaseGenericRepository<T>, IExternalUserRepository<T> where T : class
|
public class BaseExternalUserRepository<T> : BaseGenericRepository<T>, IExternalUserRepository<T> where T : Entity
|
||||||
{
|
{
|
||||||
public BaseExternalUserRepository(ISqliteConfiguration config, ICacheProvider cache) : base(config,cache)
|
public BaseExternalUserRepository(ISqliteConfiguration config, ICacheProvider cache) : base(config,cache)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Ombi.Store.Repository
|
namespace Ombi.Store.Repository
|
||||||
{
|
{
|
||||||
public interface IExternalUserRepository<T> where T : class
|
public interface IExternalUserRepository<T> where T : Entity
|
||||||
{
|
{
|
||||||
T Get(string id);
|
T Get(string id);
|
||||||
T Get(int id);
|
T Get(int id);
|
||||||
|
|
|
@ -128,7 +128,7 @@ CREATE UNIQUE INDEX IF NOT EXISTS PlexUsers_Id ON PlexUsers (Id);
|
||||||
CREATE TABLE IF NOT EXISTS EmbyUsers
|
CREATE TABLE IF NOT EXISTS EmbyUsers
|
||||||
(
|
(
|
||||||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
PlexUserId varchar(100) NOT NULL,
|
EmbyUserId varchar(100) NOT NULL,
|
||||||
UserAlias varchar(100) NOT NULL,
|
UserAlias varchar(100) NOT NULL,
|
||||||
Permissions INTEGER,
|
Permissions INTEGER,
|
||||||
Features INTEGER,
|
Features INTEGER,
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
<strong>Email Address: </strong><span ng-bind="selectedUser.emailAddress"></span>
|
<strong>Email Address: </strong><span ng-bind="selectedUser.emailAddress"></span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>User Type: </strong><span ng-bind="selectedUser.type === 1 ? 'Local User' : 'Plex User'"></span>
|
<strong>User Type: </strong>
|
||||||
|
<span ng-if="selectedUser.type === 1">Local User</span>
|
||||||
|
<span ng-if="selectedUser.type === 2">Emby User</span>
|
||||||
|
<span ng-if="selectedUser.type === 3">Plex User</span>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -75,7 +75,9 @@
|
||||||
{{u.permissionsFormattedString}}
|
{{u.permissionsFormattedString}}
|
||||||
</td>
|
</td>
|
||||||
<td ng-hide="hideColumns">
|
<td ng-hide="hideColumns">
|
||||||
{{u.type === 1 ? 'Local User' : 'Plex User'}}
|
<span ng-if="u.type === 1">Local User</span>
|
||||||
|
<span ng-if="u.type === 3">Plex User</span>
|
||||||
|
<span ng-if="u.type === 2">Emby User</span>
|
||||||
</td>
|
</td>
|
||||||
<td ng-hide="hideColumns" ng-bind="u.lastLoggedIn === minDate ? 'Never' : formatDate(u.lastLoggedIn)"></td>
|
<td ng-hide="hideColumns" ng-bind="u.lastLoggedIn === minDate ? 'Never' : formatDate(u.lastLoggedIn)"></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -25,12 +25,15 @@
|
||||||
|
|
||||||
$('#contentBody').on('click', '#embyApiKeySave', function (e) {
|
$('#contentBody').on('click', '#embyApiKeySave', function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
$('#spinner').attr("class", "fa fa-spinner fa-spin");
|
||||||
|
|
||||||
var $form = $("#embyAuthForm");
|
var $form = $("#embyAuthForm");
|
||||||
$.post($form.prop("action"), $form.serialize(), function (response) {
|
$.post($form.prop("action"), $form.serialize(), function (response) {
|
||||||
if (response.result === true) {
|
if (response.result === true) {
|
||||||
loadArea("authArea");
|
loadArea("authArea");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
$('#spinner').attr("class", "fa fa-times");
|
||||||
generateNotify(response.message, "warning");
|
generateNotify(response.message, "warning");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -78,6 +78,7 @@ namespace Ombi.UI.Jobs
|
||||||
JobBuilder.Create<EmbyEpisodeCacher>().WithIdentity("EmbyEpisodeCacher", "Emby").Build(),
|
JobBuilder.Create<EmbyEpisodeCacher>().WithIdentity("EmbyEpisodeCacher", "Emby").Build(),
|
||||||
JobBuilder.Create<EmbyAvailabilityChecker>().WithIdentity("EmbyAvailabilityChecker", "Emby").Build(),
|
JobBuilder.Create<EmbyAvailabilityChecker>().WithIdentity("EmbyAvailabilityChecker", "Emby").Build(),
|
||||||
JobBuilder.Create<EmbyContentCacher>().WithIdentity("EmbyContentCacher", "Emby").Build(),
|
JobBuilder.Create<EmbyContentCacher>().WithIdentity("EmbyContentCacher", "Emby").Build(),
|
||||||
|
JobBuilder.Create<EmbyUserChecker>().WithIdentity("EmbyUserChecker", "Emby").Build(),
|
||||||
};
|
};
|
||||||
|
|
||||||
jobs.AddRange(jobList);
|
jobs.AddRange(jobList);
|
||||||
|
@ -189,6 +190,10 @@ namespace Ombi.UI.Jobs
|
||||||
{
|
{
|
||||||
s.EmbyEpisodeCacher = 11;
|
s.EmbyEpisodeCacher = 11;
|
||||||
}
|
}
|
||||||
|
if (s.EmbyUserChecker == 0)
|
||||||
|
{
|
||||||
|
s.EmbyUserChecker = 24;
|
||||||
|
}
|
||||||
|
|
||||||
var triggers = new List<ITrigger>();
|
var triggers = new List<ITrigger>();
|
||||||
|
|
||||||
|
@ -318,6 +323,14 @@ namespace Ombi.UI.Jobs
|
||||||
.WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyAvailabilityChecker).RepeatForever())
|
.WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyAvailabilityChecker).RepeatForever())
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
var embyUserChecker =
|
||||||
|
TriggerBuilder.Create()
|
||||||
|
.WithIdentity("EmbyUserChecker", "Emby")
|
||||||
|
.StartNow()
|
||||||
|
//.StartAt(DateBuilder.FutureDate(1, IntervalUnit.Minute))
|
||||||
|
.WithSimpleSchedule(x => x.WithIntervalInHours(s.EmbyUserChecker).RepeatForever())
|
||||||
|
.Build();
|
||||||
|
|
||||||
triggers.Add(rencentlyAdded);
|
triggers.Add(rencentlyAdded);
|
||||||
triggers.Add(plexAvailabilityChecker);
|
triggers.Add(plexAvailabilityChecker);
|
||||||
triggers.Add(srCacher);
|
triggers.Add(srCacher);
|
||||||
|
@ -335,6 +348,7 @@ namespace Ombi.UI.Jobs
|
||||||
triggers.Add(embyEpisode);
|
triggers.Add(embyEpisode);
|
||||||
triggers.Add(embyAvailabilityChecker);
|
triggers.Add(embyAvailabilityChecker);
|
||||||
triggers.Add(embyContentCacher);
|
triggers.Add(embyContentCacher);
|
||||||
|
triggers.Add(embyUserChecker);
|
||||||
|
|
||||||
return triggers;
|
return triggers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,8 @@ namespace Ombi.UI.Models
|
||||||
{
|
{
|
||||||
public class ScheduledJobsViewModel : ScheduledJobsSettings
|
public class ScheduledJobsViewModel : ScheduledJobsSettings
|
||||||
{
|
{
|
||||||
|
public bool Emby { get; set; }
|
||||||
|
public bool Plex { get; set; }
|
||||||
public Dictionary<string,DateTime> JobRecorder { get; set; }
|
public Dictionary<string,DateTime> JobRecorder { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1130,6 +1130,8 @@ namespace Ombi.UI.Modules.Admin
|
||||||
{
|
{
|
||||||
var s = await ScheduledJobSettings.GetSettingsAsync();
|
var s = await ScheduledJobSettings.GetSettingsAsync();
|
||||||
var allJobs = await JobRecorder.GetJobsAsync();
|
var allJobs = await JobRecorder.GetJobsAsync();
|
||||||
|
var emby = await EmbySettings.GetSettingsAsync();
|
||||||
|
var plex = await PlexService.GetSettingsAsync();
|
||||||
|
|
||||||
var dict = new Dictionary<string, DateTime>();
|
var dict = new Dictionary<string, DateTime>();
|
||||||
|
|
||||||
|
@ -1150,6 +1152,8 @@ namespace Ombi.UI.Modules.Admin
|
||||||
|
|
||||||
var model = new ScheduledJobsViewModel
|
var model = new ScheduledJobsViewModel
|
||||||
{
|
{
|
||||||
|
Emby = emby.Enable,
|
||||||
|
Plex = plex.Enable,
|
||||||
CouchPotatoCacher = s.CouchPotatoCacher,
|
CouchPotatoCacher = s.CouchPotatoCacher,
|
||||||
PlexAvailabilityChecker = s.PlexAvailabilityChecker,
|
PlexAvailabilityChecker = s.PlexAvailabilityChecker,
|
||||||
SickRageCacher = s.SickRageCacher,
|
SickRageCacher = s.SickRageCacher,
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
IRadarrCacher radarrCacher, ICouchPotatoCacher cpCacher, IStoreBackup store, ISickRageCacher srCacher, IAvailabilityChecker plexChceker,
|
IRadarrCacher radarrCacher, ICouchPotatoCacher cpCacher, IStoreBackup store, ISickRageCacher srCacher, IAvailabilityChecker plexChceker,
|
||||||
IStoreCleanup cleanup, IUserRequestLimitResetter requestLimit, IPlexEpisodeCacher episodeCacher, IRecentlyAdded recentlyAdded,
|
IStoreCleanup cleanup, IUserRequestLimitResetter requestLimit, IPlexEpisodeCacher episodeCacher, IRecentlyAdded recentlyAdded,
|
||||||
IFaultQueueHandler faultQueueHandler, IPlexUserChecker plexUserChecker, IEmbyAvailabilityChecker embyAvailabilityChecker, IEmbyEpisodeCacher embyEpisode,
|
IFaultQueueHandler faultQueueHandler, IPlexUserChecker plexUserChecker, IEmbyAvailabilityChecker embyAvailabilityChecker, IEmbyEpisodeCacher embyEpisode,
|
||||||
IEmbyContentCacher embyContentCacher) : base("admin", settingsService, security)
|
IEmbyContentCacher embyContentCacher, IEmbyUserChecker embyUser) : base("admin", settingsService, security)
|
||||||
{
|
{
|
||||||
Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx);
|
Before += (ctx) => Security.AdminLoginRedirect(Permissions.Administrator, ctx);
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
EmbyAvailabilityChecker = embyAvailabilityChecker;
|
EmbyAvailabilityChecker = embyAvailabilityChecker;
|
||||||
EmbyContentCacher = embyContentCacher;
|
EmbyContentCacher = embyContentCacher;
|
||||||
EmbyEpisodeCacher = embyEpisode;
|
EmbyEpisodeCacher = embyEpisode;
|
||||||
|
EmbyUserChecker = embyUser;
|
||||||
|
|
||||||
Post["/schedulerun", true] = async (x, ct) => await ScheduleRun((string)Request.Form.key);
|
Post["/schedulerun", true] = async (x, ct) => await ScheduleRun((string)Request.Form.key);
|
||||||
}
|
}
|
||||||
|
@ -88,6 +89,7 @@ namespace Ombi.UI.Modules.Admin
|
||||||
private IEmbyAvailabilityChecker EmbyAvailabilityChecker { get; }
|
private IEmbyAvailabilityChecker EmbyAvailabilityChecker { get; }
|
||||||
private IEmbyContentCacher EmbyContentCacher { get; }
|
private IEmbyContentCacher EmbyContentCacher { get; }
|
||||||
private IEmbyEpisodeCacher EmbyEpisodeCacher { get; }
|
private IEmbyEpisodeCacher EmbyEpisodeCacher { get; }
|
||||||
|
private IEmbyUserChecker EmbyUserChecker { get; }
|
||||||
|
|
||||||
|
|
||||||
private async Task<Response> ScheduleRun(string key)
|
private async Task<Response> ScheduleRun(string key)
|
||||||
|
@ -162,6 +164,10 @@ namespace Ombi.UI.Modules.Admin
|
||||||
{
|
{
|
||||||
EmbyAvailabilityChecker.CheckAndUpdateAll();
|
EmbyAvailabilityChecker.CheckAndUpdateAll();
|
||||||
}
|
}
|
||||||
|
if (key.Equals(JobNames.EmbyUserChecker, StringComparison.CurrentCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
EmbyUserChecker.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel { Result = true });
|
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||||
|
|
|
@ -197,6 +197,8 @@ namespace Ombi.UI.Modules
|
||||||
}
|
}
|
||||||
|
|
||||||
var plexSettings = await PlexSettings.GetSettingsAsync();
|
var plexSettings = await PlexSettings.GetSettingsAsync();
|
||||||
|
if (plexSettings.Enable)
|
||||||
|
{
|
||||||
var plexDbUsers = await PlexUsersRepository.GetAllAsync();
|
var plexDbUsers = await PlexUsersRepository.GetAllAsync();
|
||||||
var plexUsers = PlexApi.GetUsers(plexSettings.PlexAuthToken);
|
var plexUsers = PlexApi.GetUsers(plexSettings.PlexAuthToken);
|
||||||
var plexDbUser = plexDbUsers.FirstOrDefault(x => x.PlexUserId == model.Id);
|
var plexDbUser = plexDbUsers.FirstOrDefault(x => x.PlexUserId == model.Id);
|
||||||
|
@ -256,6 +258,35 @@ namespace Ombi.UI.Modules
|
||||||
var retUser = MapPlexUser(plexUser, user, userLogin?.LastLoggedIn ?? DateTime.MinValue);
|
var retUser = MapPlexUser(plexUser, user, userLogin?.LastLoggedIn ?? DateTime.MinValue);
|
||||||
return Response.AsJson(retUser);
|
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.
|
return null; // We should never end up here.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,7 +566,7 @@ namespace Ombi.UI.Modules
|
||||||
{
|
{
|
||||||
//Get Plex Users
|
//Get Plex Users
|
||||||
var plexUsers = PlexApi.GetUsers(plexSettings.PlexAuthToken);
|
var plexUsers = PlexApi.GetUsers(plexSettings.PlexAuthToken);
|
||||||
if (plexUsers != null && plexUsers.User != null)
|
if (plexUsers?.User != null)
|
||||||
{
|
{
|
||||||
foreach (var u in plexUsers.User)
|
foreach (var u in plexUsers.User)
|
||||||
{
|
{
|
||||||
|
@ -585,12 +616,12 @@ namespace Ombi.UI.Modules
|
||||||
if (!string.IsNullOrEmpty(embySettings.ApiKey))
|
if (!string.IsNullOrEmpty(embySettings.ApiKey))
|
||||||
{
|
{
|
||||||
//Get Plex Users
|
//Get Plex Users
|
||||||
var plexUsers = EmbyApi.GetUsers(embySettings.FullUri, embySettings.ApiKey);
|
var embyUsers = EmbyApi.GetUsers(embySettings.FullUri, embySettings.ApiKey);
|
||||||
if (plexUsers != null)
|
if (embyUsers != null)
|
||||||
{
|
{
|
||||||
foreach (var u in plexUsers)
|
foreach (var u in embyUsers)
|
||||||
{
|
{
|
||||||
var dbUser = embyDbUsers.FirstOrDefault(x => x.PlexUserId == u.Id);
|
var dbUser = embyDbUsers.FirstOrDefault(x => x.EmbyUserId == u.Id);
|
||||||
var userDb = userLogins.FirstOrDefault(x => x.UserId == u.Id);
|
var userDb = userLogins.FirstOrDefault(x => x.UserId == u.Id);
|
||||||
|
|
||||||
// We don't have the user in the database yet
|
// We don't have the user in the database yet
|
||||||
|
@ -599,15 +630,6 @@ namespace Ombi.UI.Modules
|
||||||
: MapEmbyUser(u, dbUser, userDb?.LastLoggedIn ?? DateTime.MinValue));
|
: MapEmbyUser(u, dbUser, userDb?.LastLoggedIn ?? DateTime.MinValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also get the server admin
|
|
||||||
var account = PlexApi.GetAccount(embySettings.PlexAuthToken);
|
|
||||||
if (account != null)
|
|
||||||
{
|
|
||||||
var dbUser = embyDbUsers.FirstOrDefault(x => x.PlexUserId == account.Id);
|
|
||||||
var userDb = userLogins.FirstOrDefault(x => x.UserId == account.Id);
|
|
||||||
model.Add(MapPlexAdmin(account, dbUser, userDb?.LastLoggedIn ?? DateTime.MinValue));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Response.AsJson(model);
|
return Response.AsJson(model);
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,7 +121,7 @@ namespace Ombi.UI.Modules
|
||||||
if (model?.user == null)
|
if (model?.user == null)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
Response.AsJson(new JsonResponseModel {Result = false, Message = "Incorrect username or password!"});
|
Response.AsJson(new JsonResponseModel { Result = false, Message = "Incorrect username or password!" });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the auth token in the session so we can use it in the next form
|
// Set the auth token in the session so we can use it in the next form
|
||||||
|
@ -132,7 +132,7 @@ namespace Ombi.UI.Modules
|
||||||
|
|
||||||
return
|
return
|
||||||
Response.AsJson(
|
Response.AsJson(
|
||||||
new {Result = true, firstServer?.Port, Ip = firstServer?.LocalAddresses, firstServer?.Scheme});
|
new { Result = true, firstServer?.Port, Ip = firstServer?.LocalAddresses, firstServer?.Scheme });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Response> Plex()
|
private async Task<Response> Plex()
|
||||||
|
@ -163,7 +163,7 @@ namespace Ombi.UI.Modules
|
||||||
var result = await PlexSettings.SaveSettingsAsync(form);
|
var result = await PlexSettings.SaveSettingsAsync(form);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel {Result = true});
|
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
Response.AsJson(new JsonResponseModel
|
Response.AsJson(new JsonResponseModel
|
||||||
|
@ -189,7 +189,7 @@ namespace Ombi.UI.Modules
|
||||||
var result = await PlexRequestSettings.SaveSettingsAsync(currentSettings);
|
var result = await PlexRequestSettings.SaveSettingsAsync(currentSettings);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new {Result = true});
|
return Response.AsJson(new { Result = true });
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -207,7 +207,7 @@ namespace Ombi.UI.Modules
|
||||||
var result = await Auth.SaveSettingsAsync(form);
|
var result = await Auth.SaveSettingsAsync(form);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
return Response.AsJson(new JsonResponseModel {Result = true});
|
return Response.AsJson(new JsonResponseModel { Result = true });
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
Response.AsJson(new JsonResponseModel
|
Response.AsJson(new JsonResponseModel
|
||||||
|
@ -219,9 +219,9 @@ namespace Ombi.UI.Modules
|
||||||
|
|
||||||
private async Task<Response> CreateUser()
|
private async Task<Response> CreateUser()
|
||||||
{
|
{
|
||||||
var username = (string) Request.Form.Username;
|
var username = (string)Request.Form.Username;
|
||||||
var userId = Mapper.CreateUser(username, Request.Form.Password,
|
var userId = Mapper.CreateUser(username, Request.Form.Password,
|
||||||
EnumHelper<Permissions>.All() - (int) Permissions.ReadOnlyUser, 0);
|
EnumHelper<Permissions>.All() - (int)Permissions.ReadOnlyUser, 0);
|
||||||
Analytics.TrackEventAsync(Category.Wizard, Action.Finish, "Finished the wizard", username,
|
Analytics.TrackEventAsync(Category.Wizard, Action.Finish, "Finished the wizard", username,
|
||||||
CookieHelper.GetAnalyticClientId(Cookies));
|
CookieHelper.GetAnalyticClientId(Cookies));
|
||||||
Session[SessionKeys.UsernameKey] = username;
|
Session[SessionKeys.UsernameKey] = username;
|
||||||
|
@ -236,15 +236,15 @@ namespace Ombi.UI.Modules
|
||||||
|
|
||||||
var baseUrl = string.IsNullOrEmpty(settings.BaseUrl) ? string.Empty : $"/{settings.BaseUrl}";
|
var baseUrl = string.IsNullOrEmpty(settings.BaseUrl) ? string.Empty : $"/{settings.BaseUrl}";
|
||||||
|
|
||||||
return CustomModuleExtensions.LoginAndRedirect(this, (Guid) userId, fallbackRedirectUrl: $"{baseUrl}/search");
|
return CustomModuleExtensions.LoginAndRedirect(this, (Guid)userId, fallbackRedirectUrl: $"{baseUrl}/search");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Response> EmbyAuth()
|
private async Task<Response> EmbyAuth()
|
||||||
{
|
{
|
||||||
var ip = (string) Request.Form.Ip;
|
var ip = (string)Request.Form.Ip;
|
||||||
var port = (int) Request.Form.Port;
|
var port = (int)Request.Form.Port;
|
||||||
var apiKey = (string) Request.Form.ApiKey;
|
var apiKey = (string)Request.Form.ApiKey;
|
||||||
var ssl = (bool) Request.Form.Ssl;
|
var ssl = (bool)Request.Form.Ssl;
|
||||||
|
|
||||||
var settings = new EmbySettings
|
var settings = new EmbySettings
|
||||||
{
|
{
|
||||||
|
@ -262,7 +262,7 @@ namespace Ombi.UI.Modules
|
||||||
|
|
||||||
if (result != null && result.Any())
|
if (result != null && result.Any())
|
||||||
{
|
{
|
||||||
|
settings.AdministratorId = result.FirstOrDefault(x => x.Policy.IsAdministrator)?.Id ?? string.Empty;
|
||||||
await EmbySettings.SaveSettingsAsync(settings);
|
await EmbySettings.SaveSettingsAsync(settings);
|
||||||
|
|
||||||
return Response.AsJson(new JsonResponseModel
|
return Response.AsJson(new JsonResponseModel
|
||||||
|
|
|
@ -63,6 +63,7 @@ namespace Ombi.UI.NinjectModules
|
||||||
Bind<IEmbyAvailabilityChecker>().To<EmbyAvailabilityChecker>();
|
Bind<IEmbyAvailabilityChecker>().To<EmbyAvailabilityChecker>();
|
||||||
Bind<IEmbyContentCacher>().To<EmbyContentCacher>();
|
Bind<IEmbyContentCacher>().To<EmbyContentCacher>();
|
||||||
Bind<IEmbyEpisodeCacher>().To<EmbyEpisodeCacher>();
|
Bind<IEmbyEpisodeCacher>().To<EmbyEpisodeCacher>();
|
||||||
|
Bind<IEmbyUserChecker>().To<EmbyUserChecker>();
|
||||||
|
|
||||||
|
|
||||||
Bind<IAnalytics>().To<Analytics>();
|
Bind<IAnalytics>().To<Analytics>();
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
<legend>Scheduler Settings</legend>
|
<legend>Scheduler Settings</legend>
|
||||||
<small>Please note, you will need to restart for these settings to take effect</small>
|
<small>Please note, you will need to restart for these settings to take effect</small>
|
||||||
|
|
||||||
|
|
||||||
|
@if (Model.Plex)
|
||||||
|
{
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="PlexAvailabilityChecker" class="control-label">Plex Availability Checker (min)</label>
|
<label for="PlexAvailabilityChecker" class="control-label">Plex Availability Checker (min)</label>
|
||||||
<input type="text" class="form-control form-control-custom " id="PlexAvailabilityChecker" name="PlexAvailabilityChecker" value="@Model.PlexAvailabilityChecker">
|
<input type="text" class="form-control form-control-custom " id="PlexAvailabilityChecker" name="PlexAvailabilityChecker" value="@Model.PlexAvailabilityChecker">
|
||||||
|
@ -51,6 +54,34 @@
|
||||||
<input type="text" class="form-control form-control-custom " id="PlexUserChecker" name="PlexUserChecker" value="@Model.PlexUserChecker">
|
<input type="text" class="form-control form-control-custom " id="PlexUserChecker" name="PlexUserChecker" value="@Model.PlexUserChecker">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<small>Please note, the minimum time for this to run is 11 hours, if set below 11 then we will ignore that value. This is a very resource intensive job, the less we run it the better.</small>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="PlexEpisodeCacher" class="control-label">Plex Episode Cacher (hours)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="PlexEpisodeCacher" name="PlexEpisodeCacher" value="@Model.PlexEpisodeCacher">
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (Model.Emby)
|
||||||
|
{
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="EmbyAvailabilityChecker" class="control-label">Emby Availability Checker (min)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="EmbyAvailabilityChecker" name="EmbyAvailabilityChecker" value="@Model.EmbyAvailabilityChecker">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="EmbyContentCacher" class="control-label">Emby Content Cacher (min)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="EmbyContentCacher" name="EmbyContentCacher" value="@Model.EmbyContentCacher">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="EmbyUserChecker" class="control-label">Emby User Checker (hours)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="EmbyUserChecker" name="EmbyUserChecker" value="@Model.EmbyUserChecker">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="EmbyEpisodeCacher" class="control-label">Emby Episode Cacher (hours)</label>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="EmbyEpisodeCacher" name="EmbyEpisodeCacher" value="@Model.EmbyEpisodeCacher">
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="CouchPotatoCacher" class="control-label">Couch Potato Cacher (min)</label>
|
<label for="CouchPotatoCacher" class="control-label">Couch Potato Cacher (min)</label>
|
||||||
<input type="text" class="form-control form-control-custom " id="CouchPotatoCacher" name="CouchPotatoCacher" value="@Model.CouchPotatoCacher">
|
<input type="text" class="form-control form-control-custom " id="CouchPotatoCacher" name="CouchPotatoCacher" value="@Model.CouchPotatoCacher">
|
||||||
|
@ -64,11 +95,7 @@
|
||||||
<input type="text" class="form-control form-control-custom " id="RadarrCacher" name="RadarrCacher" value="@Model.RadarrCacher">
|
<input type="text" class="form-control form-control-custom " id="RadarrCacher" name="RadarrCacher" value="@Model.RadarrCacher">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<small>Please note, the minimum time for this to run is 11 hours, if set below 11 then we will ignore that value. This is a very resource intensive job, the less we run it the better.</small>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="PlexEpisodeCacher" class="control-label">Plex Episode Cacher (hours)</label>
|
|
||||||
<input type="text" class="form-control form-control-custom " id="PlexEpisodeCacher" name="PlexEpisodeCacher" value="@Model.PlexEpisodeCacher">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="SonarrCacher" class="control-label">Sonarr Cacher (min)</label>
|
<label for="SonarrCacher" class="control-label">Sonarr Cacher (min)</label>
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
<input id="dateTimeOffset" name="DateTimeOffset" hidden="hidden" />
|
<input id="dateTimeOffset" name="DateTimeOffset" hidden="hidden" />
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
<label>@UI.UserLogin_Username</label>
|
<label>Username</label>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<input id="username" class="form-control form-control-custom" type="text" name="Username" placeholder="@UI.UserLogin_Username_Placeholder" />
|
<input id="username" class="form-control form-control-custom" type="text" name="Username" placeholder="Username" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<label for="portNumber" class="control-label">Port</label>
|
<label for="portNumber" class="control-label">Port</label>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input type="text" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="8069">
|
<input type="text" class="form-control form-control-custom " id="portNumber" name="Port" placeholder="8096">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: center; margin-top: 20px">
|
<div style="text-align: center; margin-top: 20px">
|
||||||
<a href="#" id="embyApiKeySave" class="btn btn-primary-outline">Next</a>
|
<a href="#" id="embyApiKeySave" class="btn btn-primary-outline">Next <div id="spinner"></div></a>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue