A lot of clean up and added a new Image api #865

pull/1488/head
Jamie.Rees 7 years ago
parent 69d75976c5
commit 1eb18b3187

@ -0,0 +1,35 @@
using System;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Ombi.Api.FanartTv.Models;
namespace Ombi.Api.FanartTv
{
public class FanartTvApi : IFanartTvApi
{
public FanartTvApi(IApi api)
{
Api = api;
}
private string Endpoint => "https://webservice.fanart.tv/v3";
private IApi Api { get; }
public async Task<TvResult> GetTvImages(int tvdbId, string token)
{
var request = new Request($"tv/{tvdbId}", Endpoint, HttpMethod.Get);
request.AddHeader("api-key", token);
return await Api.Request<TvResult>(request);
}
public async Task<MovieResult> GetMovieImages(int theMovieDbId, string token)
{
var request = new Request($"movies/{theMovieDbId}", Endpoint, HttpMethod.Get);
request.AddHeader("api-key", token);
return await Api.Request<MovieResult>(request);
}
}
}

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Ombi.Api.FanartTv.Models;
namespace Ombi.Api.FanartTv
{
public interface IFanartTvApi
{
Task<MovieResult> GetMovieImages(int theMovieDbId, string token);
Task<TvResult> GetTvImages(int tvdbId, string token);
}
}

@ -0,0 +1,17 @@
namespace Ombi.Api.FanartTv.Models
{
public class MovieResult
{
public string name { get; set; }
public string tmdb_id { get; set; }
public string imdb_id { get; set; }
public Content[] hdmovieclearart { get; set; }
public Content[] hdmovielogo { get; set; }
public Content[] moviebackground { get; set; }
public Content[] movieposter { get; set; }
public Content[] moviedisc { get; set; }
public Content[] moviebanner { get; set; }
public Content[] moviethumb { get; set; }
}
}

@ -0,0 +1,28 @@
namespace Ombi.Api.FanartTv.Models
{
public class TvResult
{
public string name { get; set; }
public string thetvdb_id { get; set; }
public Content[] hdtvlogo { get; set; }
public Content[] seasonposter { get; set; }
public Content[] seasonthumb { get; set; }
public Content[] characterart { get; set; }
public Content[] clearlogo { get; set; }
public Content[] hdclearart { get; set; }
public Content[] tvposter { get; set; }
public Content[] showbackground { get; set; }
public Content[] tvthumb { get; set; }
public Content[] clearart { get; set; }
public Content[] tvbanner { get; set; }
public Content[] seasonbanner { get; set; }
}
public class Content
{
public string id { get; set; }
public string url { get; set; }
public string lang { get; set; }
public string likes { get; set; }
}
}

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
</ItemGroup>
</Project>

@ -27,22 +27,19 @@ namespace Ombi.Core.Engine.Interfaces
protected string Username => UserPrinciple.Identity.Name; protected string Username => UserPrinciple.Identity.Name;
private OmbiUser _user; private OmbiUser _user;
protected async Task<OmbiUser> User() protected async Task<OmbiUser> GetUser()
{ {
if(_user == null) return _user ?? (_user = await UserManager.Users.FirstOrDefaultAsync(x => x.UserName == Username));
_user = await UserManager.Users.FirstOrDefaultAsync(x => x.UserName == Username);
return _user;
} }
protected async Task<string> UserAlias() protected async Task<string> UserAlias()
{ {
return (await User()).UserAlias; return (await GetUser()).UserAlias;
} }
protected async Task<bool> IsInRole(string roleName) protected async Task<bool> IsInRole(string roleName)
{ {
return await UserManager.IsInRoleAsync(await User(), roleName); return await UserManager.IsInRoleAsync(await GetUser(), roleName);
} }
public async Task<IEnumerable<RuleResult>> RunRequestRules(BaseRequest model) public async Task<IEnumerable<RuleResult>> RunRequestRules(BaseRequest model)

@ -57,7 +57,7 @@ namespace Ombi.Core.Engine
var fullMovieName = var fullMovieName =
$"{movieInfo.Title}{(!string.IsNullOrEmpty(movieInfo.ReleaseDate) ? $" ({DateTime.Parse(movieInfo.ReleaseDate).Year})" : string.Empty)}"; $"{movieInfo.Title}{(!string.IsNullOrEmpty(movieInfo.ReleaseDate) ? $" ({DateTime.Parse(movieInfo.ReleaseDate).Year})" : string.Empty)}";
var userDetails = await User(); var userDetails = await GetUser();
var requestModel = new MovieRequests var requestModel = new MovieRequests
{ {

@ -4,22 +4,19 @@ using Ombi.Core.Models.Requests;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Security.Claims;
using System.Security.Principal; using System.Security.Principal;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Ombi.Core.Engine.Interfaces; using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Helpers; using Ombi.Core.Helpers;
using Ombi.Core.IdentityResolver;
using Ombi.Core.Rule; using Ombi.Core.Rule;
using Ombi.Core.Rule.Interfaces; using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Entities.Requests; using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository.Requests; using Ombi.Store.Repository;
namespace Ombi.Core.Engine namespace Ombi.Core.Engine
{ {
@ -28,22 +25,24 @@ namespace Ombi.Core.Engine
public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user,
INotificationHelper helper, IMapper map, INotificationHelper helper, IMapper map,
IRuleEvaluator rule, UserManager<OmbiUser> manager, IRuleEvaluator rule, UserManager<OmbiUser> manager,
ITvSender sender) : base(user, requestService, rule, manager) ITvSender sender, IAuditRepository audit) : base(user, requestService, rule, manager)
{ {
TvApi = tvApi; TvApi = tvApi;
NotificationHelper = helper; NotificationHelper = helper;
Mapper = map; Mapper = map;
TvSender = sender; TvSender = sender;
Audit = audit;
} }
private INotificationHelper NotificationHelper { get; } private INotificationHelper NotificationHelper { get; }
private ITvMazeApi TvApi { get; } private ITvMazeApi TvApi { get; }
private IMapper Mapper { get; } private IMapper Mapper { get; }
private ITvSender TvSender {get;} private ITvSender TvSender {get;}
private IAuditRepository Audit { get; }
public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv) public async Task<RequestEngineResult> RequestTvShow(SearchTvShowViewModel tv)
{ {
var user = await User(); var user = await GetUser();
var tvBuilder = new TvShowRequestBuilder(TvApi); var tvBuilder = new TvShowRequestBuilder(TvApi);
(await tvBuilder (await tvBuilder
@ -63,6 +62,8 @@ namespace Ombi.Core.Engine
}; };
} }
await Audit.Record(AuditType.Added, AuditArea.TvRequest, $"Added Request {tv.Title}", Username);
var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.Id); var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.Id);
if (existingRequest != null) if (existingRequest != null)
{ {
@ -128,6 +129,7 @@ namespace Ombi.Core.Engine
public async Task<TvRequests> UpdateTvRequest(TvRequests request) public async Task<TvRequests> UpdateTvRequest(TvRequests request)
{ {
await Audit.Record(AuditType.Updated, AuditArea.TvRequest, $"Updated Request {request.Title}", Username);
var allRequests = TvRepository.Get(); var allRequests = TvRepository.Get();
var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id); var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id);
@ -138,6 +140,7 @@ namespace Ombi.Core.Engine
public async Task<ChildRequests> UpdateChildRequest(ChildRequests request) public async Task<ChildRequests> UpdateChildRequest(ChildRequests request)
{ {
await Audit.Record(AuditType.Updated, AuditArea.TvRequest, $"Updated Request {request.Title}", Username);
var allRequests = TvRepository.GetChild(); var allRequests = TvRepository.GetChild();
var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id); var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id);
@ -149,12 +152,14 @@ namespace Ombi.Core.Engine
public async Task RemoveTvChild(int requestId) public async Task RemoveTvChild(int requestId)
{ {
var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId); var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId);
await Audit.Record(AuditType.Deleted, AuditArea.TvRequest, $"Deleting Request {request.Title}", Username);
await TvRepository.DeleteChild(request); await TvRepository.DeleteChild(request);
} }
public async Task RemoveTvRequest(int requestId) public async Task RemoveTvRequest(int requestId)
{ {
var request = await TvRepository.Get().FirstOrDefaultAsync(x => x.Id == requestId); var request = await TvRepository.Get().FirstOrDefaultAsync(x => x.Id == requestId);
await Audit.Record(AuditType.Deleted, AuditArea.TvRequest, $"Deleting Request {request.Title}", Username);
await TvRepository.Delete(request); await TvRepository.Delete(request);
} }

@ -123,17 +123,20 @@ namespace Ombi.Core.Helpers
else if (tv.LatestSeason) else if (tv.LatestSeason)
{ {
var episodes = await TvApi.EpisodeLookup(ShowInfo.id); var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
var latest = episodes.OrderBy(x => x.season).FirstOrDefault(); var latest = episodes.OrderByDescending(x => x.season).FirstOrDefault();
var episodesRequests = new List<EpisodeRequests>(); var episodesRequests = new List<EpisodeRequests>();
foreach (var ep in episodes) foreach (var ep in episodes)
{ {
episodesRequests.Add(new EpisodeRequests if (ep.season == latest.season)
{ {
EpisodeNumber = ep.number, episodesRequests.Add(new EpisodeRequests
AirDate = DateTime.Parse(ep.airdate), {
Title = ep.name, EpisodeNumber = ep.number,
Url = ep.url AirDate = DateTime.Parse(ep.airdate),
}); Title = ep.name,
Url = ep.url
});
}
} }
ChildRequest.SeasonRequests.Add(new SeasonRequests ChildRequest.SeasonRequests.Add(new SeasonRequests
{ {
@ -144,7 +147,7 @@ namespace Ombi.Core.Helpers
else if (tv.FirstSeason) else if (tv.FirstSeason)
{ {
var episodes = await TvApi.EpisodeLookup(ShowInfo.id); var episodes = await TvApi.EpisodeLookup(ShowInfo.id);
var first = episodes.OrderByDescending(x => x.season).FirstOrDefault(); var first = episodes.OrderBy(x => x.season).FirstOrDefault();
var episodesRequests = new List<EpisodeRequests>(); var episodesRequests = new List<EpisodeRequests>();
foreach (var ep in episodes) foreach (var ep in episodes)
{ {

@ -7,63 +7,116 @@ using IdentityServer4.Models;
using IdentityServer4.Validation; using IdentityServer4.Validation;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Api.Emby;
using Ombi.Api.Emby.Models; using Ombi.Api.Emby.Models;
using Ombi.Api.Plex; using Ombi.Api.Plex;
using Ombi.Api.Plex.Models; using Ombi.Api.Plex.Models;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External; using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Settings.Settings.Models;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.IdentityResolver namespace Ombi.Core.IdentityResolver
{ {
public class OmbiOwnerPasswordValidator : IResourceOwnerPasswordValidator public class OmbiOwnerPasswordValidator : IResourceOwnerPasswordValidator
{ {
public OmbiOwnerPasswordValidator(UserManager<OmbiUser> um, IPlexApi api, public OmbiOwnerPasswordValidator(UserManager<OmbiUser> um, IPlexApi plexApi, IEmbyApi embyApi,
ISettingsService<PlexSettings> settings) ISettingsService<PlexSettings> settings, ISettingsService<OmbiSettings> ombiSettings,
ISettingsService<EmbySettings> embySettings, IAuditRepository log)
{ {
UserManager = um; UserManager = um;
Api = api; PlexApi = plexApi;
PlexSettings = settings; PlexSettings = settings;
OmbiSettings = ombiSettings;
EmbyApi = embyApi;
EmbySettings = embySettings;
Audit = log;
} }
private UserManager<OmbiUser> UserManager { get; } private UserManager<OmbiUser> UserManager { get; }
private IPlexApi Api { get; } private IPlexApi PlexApi { get; }
private IEmbyApi EmbyApi{ get; }
private ISettingsService<PlexSettings> PlexSettings { get; } private ISettingsService<PlexSettings> PlexSettings { get; }
private ISettingsService<EmbySettings> EmbySettings { get; }
private ISettingsService<OmbiSettings> OmbiSettings { get; }
private IAuditRepository Audit { get; }
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{ {
await Audit.Record(AuditType.None, AuditArea.Authentication, $"User {context.UserName} attempted to login", context.UserName);
var users = UserManager.Users; var users = UserManager.Users;
if (await LocalUser(context, users)) if (await LocalUser(context, users))
{ {
return; return;
} }
if (await PlexUser(context, users)) var ombi = await OmbiSettings.GetSettingsAsync();
if (ombi.AllowExternalUsersToAuthenticate)
{ {
return; if (await PlexUser(context, users))
} {
if (await EmbyUser(context, users)) return;
{ }
return; if (await EmbyUser(context, users))
{
return;
}
} }
await Audit.Record(AuditType.Fail, AuditArea.Authentication, $"User {context.UserName} failed to login", context.UserName);
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
} }
private async Task<bool> PlexUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users) private async Task<bool> PlexUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users)
{ {
var signInResult = await Api.SignIn(new UserRequest {login = context.UserName, password = context.Password}); var signInResult = await PlexApi.SignIn(new UserRequest {login = context.UserName, password = context.Password});
if (signInResult.user == null) if (signInResult?.user == null)
{ {
return false; return false;
} }
// Do we have a local user? // Do we have a local user?
var user = await users.FirstOrDefaultAsync(x => x.UserName == context.UserName && x.UserType == UserType.PlexUser); return await GetUserDetails(context, users, UserType.PlexUser);
}
private async Task<bool> EmbyUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users)
{
var embySettings = await EmbySettings.GetSettingsAsync();
var signInResult = await EmbyApi.LogIn(context.UserName, context.Password, embySettings.ApiKey,
embySettings.FullUri);
if (string.IsNullOrEmpty(signInResult?.Name))
{
return false;
}
throw new NotImplementedException(); // TODO finish return await GetUserDetails(context, users, UserType.EmbyUser);
} }
private Task<bool> EmbyUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users) private async Task<bool> GetUserDetails(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users, UserType userType)
{ {
throw new NotImplementedException(); var user = await users.FirstOrDefaultAsync(x => x.UserName == context.UserName && x.UserType == userType);
if (user != null)
{
var roles = await UserManager.GetRolesAsync(user);
var claims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName)
};
foreach (var role in roles)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
context.Result = new GrantValidationResult(user.UserName, "password", claims);
return true;
}
// Create the user?
return true;
} }
public async Task<bool> LocalUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users) public async Task<bool> LocalUser(ResourceOwnerPasswordValidationContext context, IQueryable<OmbiUser> users)
@ -72,13 +125,13 @@ namespace Ombi.Core.IdentityResolver
if (user == null) if (user == null)
{ {
//context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
return false; return false;
} }
var passwordValid = await UserManager.CheckPasswordAsync(user, context.Password); var passwordValid = await UserManager.CheckPasswordAsync(user, context.Password);
if (!passwordValid) if (!passwordValid)
{ {
await Audit.Record(AuditType.Fail, AuditArea.Authentication, $"User {context.UserName} failed to login", context.UserName);
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect"); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Username or password is incorrect");
return true; return true;
@ -96,6 +149,7 @@ namespace Ombi.Core.IdentityResolver
} }
context.Result = new GrantValidationResult(user.UserName, "password", claims); context.Result = new GrantValidationResult(user.UserName, "password", claims);
await Audit.Record(AuditType.Success, AuditArea.Authentication, $"User {context.UserName} has logged in", context.UserName);
return true; return true;
} }
} }

@ -1,16 +1,16 @@
using Microsoft.Extensions.Logging; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Ombi.Api.Sonarr; using Ombi.Api.Sonarr;
using Ombi.Api.Sonarr.Models; using Ombi.Api.Sonarr.Models;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External; using Ombi.Core.Settings.Models.External;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Store.Entities.Requests; using Ombi.Store.Entities.Requests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Ombi.Core namespace Ombi.Core.Senders
{ {
public class TvSender : ITvSender public class TvSender : ITvSender
{ {
@ -99,7 +99,7 @@ namespace Ombi.Core
// Ok, now let's sort out the episodes. // Ok, now let's sort out the episodes.
var sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri); var sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri);
while (sonarrEpisodes.Count() == 0) while (!sonarrEpisodes.Any())
{ {
// It could be that the series metadata is not ready yet. So wait // It could be that the series metadata is not ready yet. So wait
sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri); sonarrEpisodes = await SonarrApi.GetEpisodes(result.id, s.ApiKey, s.FullUri);

@ -28,8 +28,10 @@ using Ombi.Store.Repository;
using Ombi.Notifications.Agents; using Ombi.Notifications.Agents;
using Ombi.Schedule.Jobs.Radarr; using Ombi.Schedule.Jobs.Radarr;
using Ombi.Api; using Ombi.Api;
using Ombi.Api.FanartTv;
using Ombi.Api.Service; using Ombi.Api.Service;
using Ombi.Core.Rule.Interfaces; using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Senders;
using Ombi.Schedule.Ombi; using Ombi.Schedule.Ombi;
using Ombi.Store.Repository.Requests; using Ombi.Store.Repository.Requests;
@ -71,6 +73,7 @@ namespace Ombi.DependencyInjection
services.AddTransient<IRadarrApi, RadarrApi>(); services.AddTransient<IRadarrApi, RadarrApi>();
services.AddTransient<IDiscordApi, DiscordApi>(); services.AddTransient<IDiscordApi, DiscordApi>();
services.AddTransient<IOmbiService, OmbiService>(); services.AddTransient<IOmbiService, OmbiService>();
services.AddTransient<IFanartTvApi, FanartTvApi>();
} }
public static void RegisterStore(this IServiceCollection services) public static void RegisterStore(this IServiceCollection services)
@ -86,6 +89,8 @@ namespace Ombi.DependencyInjection
services.AddTransient<ITvRequestRepository, TvRequestRepository>(); services.AddTransient<ITvRequestRepository, TvRequestRepository>();
services.AddTransient<IMovieRequestRepository, MovieRequestRepository>(); services.AddTransient<IMovieRequestRepository, MovieRequestRepository>();
services.AddTransient<IAuditRepository, AuditRepository>();
services.AddTransient<IApplicationConfigRepository, ApplicationConfigRepository>();
//services.AddTransient<ITokenRepository, TokenRepository>(); //services.AddTransient<ITokenRepository, TokenRepository>();
services.AddTransient(typeof(ISettingsService<>), typeof(SettingsService<>)); services.AddTransient(typeof(ISettingsService<>), typeof(SettingsService<>));
} }

@ -13,6 +13,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" /> <ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" />
<ProjectReference Include="..\Ombi.Api.Emby\Ombi.Api.Emby.csproj" /> <ProjectReference Include="..\Ombi.Api.Emby\Ombi.Api.Emby.csproj" />
<ProjectReference Include="..\Ombi.Api.FanartTv\Ombi.Api.FanartTv.csproj" />
<ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" /> <ProjectReference Include="..\Ombi.Api.Plex\Ombi.Api.Plex.csproj" />
<ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" /> <ProjectReference Include="..\Ombi.Api.Radarr\Ombi.Api.Radarr.csproj" />
<ProjectReference Include="..\Ombi.Api.Service\Ombi.Api.Service.csproj" /> <ProjectReference Include="..\Ombi.Api.Service\Ombi.Api.Service.csproj" />

@ -4,6 +4,8 @@ namespace Ombi.Helpers
{ {
public class LoggingEvents public class LoggingEvents
{ {
public static EventId Authentication => new EventId(500);
public static EventId ApiException => new EventId(1000); public static EventId ApiException => new EventId(1000);
public static EventId RadarrApiException => new EventId(1001); public static EventId RadarrApiException => new EventId(1001);

@ -1,13 +1,12 @@
namespace Ombi.Core.Settings.Models namespace Ombi.Settings.Settings.Models
{ {
public class OmbiSettings : Ombi.Settings.Settings.Models.Settings public class OmbiSettings : Models.Settings
{ {
public int Port { get; set; }
//public string BaseUrl { get; set; } //public string BaseUrl { get; set; }
public bool CollectAnalyticData { get; set; } public bool CollectAnalyticData { get; set; }
public bool Wizard { get; set; } public bool Wizard { get; set; }
public string ExternalUrl { get; set; }
public string ApiKey { get; set; } public string ApiKey { get; set; }
public bool AllowExternalUsersToAuthenticate { get; set; }
} }
} }

@ -23,7 +23,7 @@ namespace Ombi.Store.Context
DbSet<NotificationTemplates> NotificationTemplates { get; set; } DbSet<NotificationTemplates> NotificationTemplates { get; set; }
DbSet<ApplicationConfiguration> ApplicationConfigurations { get; set; } DbSet<ApplicationConfiguration> ApplicationConfigurations { get; set; }
void Seed(); void Seed();
DbSet<Audit> Audit { get; set; }
DbSet<MovieRequests> MovieRequests { get; set; } DbSet<MovieRequests> MovieRequests { get; set; }
DbSet<TvRequests> TvRequests { get; set; } DbSet<TvRequests> TvRequests { get; set; }
DbSet<ChildRequests> ChildRequests { get; set; } DbSet<ChildRequests> ChildRequests { get; set; }

@ -34,6 +34,8 @@ namespace Ombi.Store.Context
public DbSet<MovieIssues> MovieIssues { get; set; } public DbSet<MovieIssues> MovieIssues { get; set; }
public DbSet<TvIssues> TvIssues { get; set; } public DbSet<TvIssues> TvIssues { get; set; }
public DbSet<Audit> Audit { get; set; }
public DbSet<ApplicationConfiguration> ApplicationConfigurations { get; set; } public DbSet<ApplicationConfiguration> ApplicationConfigurations { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
@ -44,6 +46,30 @@ namespace Ombi.Store.Context
public void Seed() public void Seed()
{ {
// Add the tokens
var fanArt = ApplicationConfigurations.FirstOrDefault(x => x.Type == ConfigurationTypes.FanartTv);
if (fanArt == null)
{
ApplicationConfigurations.Add(new ApplicationConfiguration
{
Type = ConfigurationTypes.FanartTv,
Value = "4b6d983efa54d8f45c68432521335f15"
});
SaveChanges();
}
var movieDb = ApplicationConfigurations.FirstOrDefault(x => x.Type == ConfigurationTypes.FanartTv);
if (movieDb == null)
{
ApplicationConfigurations.Add(new ApplicationConfiguration
{
Type = ConfigurationTypes.TheMovieDb,
Value = "b8eabaf5608b88d0298aa189dd90bf00"
});
SaveChanges();
}
// Check if templates exist // Check if templates exist
var templates = NotificationTemplates.ToList(); var templates = NotificationTemplates.ToList();
if (templates.Any()) if (templates.Any())

@ -13,5 +13,7 @@ namespace Ombi.Store.Entities
{ {
Url, Url,
Port, Port,
FanartTv,
TheMovieDb
} }
} }

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;
namespace Ombi.Store.Entities
{
[Table("Audit")]
public class Audit : Entity
{
public DateTime DateTime { get; set; }
public string Description { get; set; }
public AuditType AuditType { get; set; }
public AuditArea AuditArea { get; set; }
public string User { get; set; }
}
public enum AuditType
{
None,
Created,
Updated,
Deleted,
Approved,
Denied,
Success,
Fail,
Added
}
public enum AuditArea
{
Authentication,
User,
TvRequest,
MovieRequest,
}
}

@ -10,7 +10,7 @@ using Ombi.Helpers;
namespace Ombi.Store.Migrations namespace Ombi.Store.Migrations
{ {
[DbContext(typeof(OmbiContext))] [DbContext(typeof(OmbiContext))]
[Migration("20170728131851_Inital")] [Migration("20170801143617_Inital")]
partial class Inital partial class Inital
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -139,6 +139,26 @@ namespace Ombi.Store.Migrations
b.ToTable("ApplicationConfiguration"); b.ToTable("ApplicationConfiguration");
}); });
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AuditArea");
b.Property<int>("AuditType");
b.Property<DateTime>("DateTime");
b.Property<string>("Description");
b.Property<string>("User");
b.HasKey("Id");
b.ToTable("Audit");
});
modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")

@ -50,6 +50,23 @@ namespace Ombi.Store.Migrations
table.PrimaryKey("PK_ApplicationConfiguration", x => x.Id); table.PrimaryKey("PK_ApplicationConfiguration", x => x.Id);
}); });
migrationBuilder.CreateTable(
name: "Audit",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
AuditArea = table.Column<int>(nullable: false),
AuditType = table.Column<int>(nullable: false),
DateTime = table.Column<DateTime>(nullable: false),
Description = table.Column<string>(nullable: true),
User = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Audit", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "GlobalSettings", name: "GlobalSettings",
columns: table => new columns: table => new
@ -545,6 +562,9 @@ namespace Ombi.Store.Migrations
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "ApplicationConfiguration"); name: "ApplicationConfiguration");
migrationBuilder.DropTable(
name: "Audit");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "GlobalSettings"); name: "GlobalSettings");

@ -138,6 +138,26 @@ namespace Ombi.Store.Migrations
b.ToTable("ApplicationConfiguration"); b.ToTable("ApplicationConfiguration");
}); });
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AuditArea");
b.Property<int>("AuditType");
b.Property<DateTime>("DateTime");
b.Property<string>("Description");
b.Property<string>("User");
b.HasKey("Id");
b.ToTable("Audit");
});
modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b => modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
{ {
b.Property<int>("Id") b.Property<int>("Id")

@ -0,0 +1,23 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Store.Context;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public class ApplicationConfigRepository : IApplicationConfigRepository
{
public ApplicationConfigRepository(IOmbiContext ctx)
{
Ctx = ctx;
}
private IOmbiContext Ctx { get; }
public async Task<ApplicationConfiguration> Get(ConfigurationTypes type)
{
return await Ctx.ApplicationConfigurations.FirstOrDefaultAsync(x => x.Type == type);
}
}
}

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Ombi.Store.Context;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public class AuditRepository : IAuditRepository
{
public AuditRepository(IOmbiContext ctx)
{
Ctx = ctx;
}
private IOmbiContext Ctx { get; }
public async Task Record(AuditType type, AuditArea area, string description)
{
await Record(type, area, description, string.Empty);
}
public async Task Record(AuditType type, AuditArea area, string description, string user)
{
await Ctx.Audit.AddAsync(new Audit
{
User = user,
AuditArea = area,
AuditType = type,
DateTime = DateTime.UtcNow,
Description = description
});
await Ctx.SaveChangesAsync();
}
}
}

@ -0,0 +1,10 @@
using System.Threading.Tasks;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IApplicationConfigRepository
{
Task<ApplicationConfiguration> Get(ConfigurationTypes type);
}
}

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IAuditRepository
{
Task Record(AuditType type, AuditArea area, string description);
Task Record(AuditType type, AuditArea area, string description, string user);
}
}

@ -67,6 +67,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Notifications.Tests",
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Service", "Ombi.Api.Service\Ombi.Api.Service.csproj", "{A0892896-F5BD-47E2-823E-DFCE82514EEC}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Service", "Ombi.Api.Service\Ombi.Api.Service.csproj", "{A0892896-F5BD-47E2-823E-DFCE82514EEC}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.FanartTv", "Ombi.Api.FanartTv\Ombi.Api.FanartTv.csproj", "{FD947E63-A0D2-4878-8378-2005D5E9AB8A}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -165,6 +167,10 @@ Global
{A0892896-F5BD-47E2-823E-DFCE82514EEC}.Debug|Any CPU.Build.0 = Debug|Any CPU {A0892896-F5BD-47E2-823E-DFCE82514EEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0892896-F5BD-47E2-823E-DFCE82514EEC}.Release|Any CPU.ActiveCfg = Release|Any CPU {A0892896-F5BD-47E2-823E-DFCE82514EEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0892896-F5BD-47E2-823E-DFCE82514EEC}.Release|Any CPU.Build.0 = Release|Any CPU {A0892896-F5BD-47E2-823E-DFCE82514EEC}.Release|Any CPU.Build.0 = Release|Any CPU
{FD947E63-A0D2-4878-8378-2005D5E9AB8A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FD947E63-A0D2-4878-8378-2005D5E9AB8A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FD947E63-A0D2-4878-8378-2005D5E9AB8A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FD947E63-A0D2-4878-8378-2005D5E9AB8A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -187,5 +193,6 @@ Global
{6294A82D-4915-4FC3-B301-8F985716F34C} = {D11FE57E-1E57-491D-A1D4-01AEF4BE5CB6} {6294A82D-4915-4FC3-B301-8F985716F34C} = {D11FE57E-1E57-491D-A1D4-01AEF4BE5CB6}
{2C7836E7-B120-40A6-B641-DDAA02FBAE23} = {6F42AB98-9196-44C4-B888-D5E409F415A1} {2C7836E7-B120-40A6-B641-DDAA02FBAE23} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
{A0892896-F5BD-47E2-823E-DFCE82514EEC} = {9293CA11-360A-4C20-A674-B9E794431BF5} {A0892896-F5BD-47E2-823E-DFCE82514EEC} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{FD947E63-A0D2-4878-8378-2005D5E9AB8A} = {9293CA11-360A-4C20-A674-B9E794431BF5}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

@ -15,7 +15,8 @@ export interface IOmbiSettings extends ISettings {
collectAnalyticData: boolean, collectAnalyticData: boolean,
wizard: boolean, wizard: boolean,
apiKey: string, apiKey: string,
externalUrl:string, externalUrl: string,
allowExternalUsersToAuthenticate:boolean,
} }
export interface IEmbySettings extends IExternalSettings { export interface IEmbySettings extends IExternalSettings {

@ -20,8 +20,16 @@
<input type="text" class="form-control form-control-custom " id="externalUrl" name="externalUrl" placeholder="http://ombi.io/" formControlName="externalUrl" tooltipPosition="top" pTooltip="This will be the link that will be in any emails/notifications sent to the users."> <input type="text" class="form-control form-control-custom " id="externalUrl" name="externalUrl" placeholder="http://ombi.io/" formControlName="externalUrl" tooltipPosition="top" pTooltip="This will be the link that will be in any emails/notifications sent to the users.">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<div class="checkbox">
<input type="checkbox" id="allowExternalUsersToAuthenticate" allowExternalUsersToAuthenticate="allowExternalUsersToAuthenticate" formControlName="allowExternalUsersToAuthenticate"
pTooltip="This will allow Plex Friends and Emby users to log into Ombi.">
<label for="allowExternalUsersToAuthenticate">Allow media server users to authenticate</label>
</div>
</div>
<!--<div class="form-group">
<label for="ApiKey" class="control-label">Api Key</label> <label for="ApiKey" class="control-label">Api Key</label>
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control form-control-custom" id="ApiKey" name="ApiKey" formControlName="apiKey"> <input type="text" class="form-control form-control-custom" id="ApiKey" name="ApiKey" formControlName="apiKey">
@ -34,7 +42,7 @@
<div class="fa fa-clipboard"></div> <div class="fa fa-clipboard"></div>
</div> </div>
</div> </div>
</div> </div>-->
<div class="form-group"> <div class="form-group">
<div class="checkbox"> <div class="checkbox">

@ -22,13 +22,14 @@ export class OmbiComponent implements OnInit {
collectAnalyticData: [x.collectAnalyticData], collectAnalyticData: [x.collectAnalyticData],
apiKey: [{ value: x.apiKey, disabled: true }], apiKey: [{ value: x.apiKey, disabled: true }],
externalUrl: [x.externalUrl], externalUrl: [x.externalUrl],
}); allowExternalUsersToAuthenticate: [x.allowExternalUsersToAuthenticate]
});
}); });
} }
refreshApiKey() { refreshApiKey() {
} }
onSubmit(form: FormGroup) { onSubmit(form: FormGroup) {

@ -32,6 +32,7 @@ using Microsoft.AspNetCore.Mvc;
using Ombi.Core.Settings; using Ombi.Core.Settings;
using Ombi.Core.Settings.Models; using Ombi.Core.Settings.Models;
using Ombi.Core.Update; using Ombi.Core.Update;
using Ombi.Settings.Settings.Models;
namespace Ombi.Controllers namespace Ombi.Controllers
{ {

@ -178,8 +178,6 @@ namespace Ombi
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache) public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMemoryCache cache)
{ {
//loggerFactory.AddConsole(Configuration.GetSection("Logging"));
//loggerFactory.AddDebug();
var options = (IOptions<UserSettings>) app.ApplicationServices.GetService( var options = (IOptions<UserSettings>) app.ApplicationServices.GetService(
typeof(IOptions<UserSettings>)); typeof(IOptions<UserSettings>));

Loading…
Cancel
Save