diff --git a/Ombi.UI/Views/UserWizard/Index.cshtml b/Ombi.UI/Views/UserWizard/Index.cshtml index 8ecf52d29..734a9e4a5 100644 --- a/Ombi.UI/Views/UserWizard/Index.cshtml +++ b/Ombi.UI/Views/UserWizard/Index.cshtml @@ -10,7 +10,7 @@ } @Html.LoadWizardAssets() - +
diff --git a/Ombi/Ombi.Api/Api.cs b/Ombi/Ombi.Api/Api.cs index 931598b50..824e8af9e 100644 --- a/Ombi/Ombi.Api/Api.cs +++ b/Ombi/Ombi.Api/Api.cs @@ -1,8 +1,5 @@ using System; -using System.IO; using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; using System.Threading.Tasks; using Newtonsoft.Json; @@ -10,7 +7,7 @@ namespace Ombi.Api { public class Api { - public static JsonSerializerSettings Settings = new JsonSerializerSettings + private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; @@ -27,5 +24,39 @@ namespace Ombi.Api var receiveString = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(receiveString, Settings); } + + public async Task Request(Request request) + { + using (var httpClient = new HttpClient()) + { + using (var httpRequestMessage = new HttpRequestMessage(request.HttpMethod, request.FullUri)) + { + // Add the Json Body + if (request.JsonBody != null) + { + httpRequestMessage.Content = new JsonContent(request.JsonBody); + } + + // Add headers + foreach (var header in request.Headers) + { + httpRequestMessage.Headers.Add(header.Key, header.Value); + } + using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) + { + if (!httpResponseMessage.IsSuccessStatusCode) + { + // Logging + } + // do something with the response + var data = httpResponseMessage.Content; + + + var receivedString = await data.ReadAsStringAsync(); + return JsonConvert.DeserializeObject(receivedString, Settings); + } + } + } + } } } diff --git a/Ombi/Ombi.Api/ApiHelper.cs b/Ombi/Ombi.Api/ApiHelper.cs index 61050909e..fa9d3e7ab 100644 --- a/Ombi/Ombi.Api/ApiHelper.cs +++ b/Ombi/Ombi.Api/ApiHelper.cs @@ -71,8 +71,5 @@ namespace Ombi.Api : $"{startingTag}{parameter}={value}"; return builder.Uri; } - - - } } \ No newline at end of file diff --git a/Ombi/Ombi.Api/JsonContent.cs b/Ombi/Ombi.Api/JsonContent.cs new file mode 100644 index 000000000..58a2f2363 --- /dev/null +++ b/Ombi/Ombi.Api/JsonContent.cs @@ -0,0 +1,13 @@ +using System.Net.Http; +using System.Text; +using Newtonsoft.Json; + +namespace Ombi.Api +{ + internal class JsonContent : StringContent + { + public JsonContent(object obj) : + base(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json") + { } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Api/Ombi.Api.csproj b/Ombi/Ombi.Api/Ombi.Api.csproj index 80457725a..b3d86c156 100644 --- a/Ombi/Ombi.Api/Ombi.Api.csproj +++ b/Ombi/Ombi.Api/Ombi.Api.csproj @@ -1,7 +1,7 @@  - netstandard1.4 + netstandard1.6 diff --git a/Ombi/Ombi.Api/Request.cs b/Ombi/Ombi.Api/Request.cs new file mode 100644 index 000000000..a7a00501f --- /dev/null +++ b/Ombi/Ombi.Api/Request.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Bson; + +namespace Ombi.Api +{ + public class Request + { + public Request(string endpoint, string baseUrl, HttpMethod http) + { + Endpoint = endpoint; + BaseUrl = baseUrl; + HttpMethod = http; + } + + public string Endpoint { get; } + public string BaseUrl { get; } + public HttpMethod HttpMethod { get; } + + private string FullUrl + { + get + { + var sb = new StringBuilder(); + sb.Append(!BaseUrl.EndsWith("/") ? string.Format("{0}/", BaseUrl) : BaseUrl); + sb.Append(Endpoint.StartsWith("/") ? Endpoint.Remove(0, 1) : Endpoint); + return sb.ToString(); + } + } + + private Uri _modified; + + public Uri FullUri + { + get => _modified != null ? _modified : new Uri(FullUrl); + set => _modified = value; + } + + public List> Headers { get; } = new List>(); + + public object JsonBody { get; set; } + + public bool IsValidUrl + { + get + { + try + { + // ReSharper disable once ObjectCreationAsStatement + new Uri(FullUrl); + return true; + } + catch (Exception) + { + return false; + } + } + } + + public void AddHeader(string key, string value) + { + Headers.Add(new KeyValuePair(key, value)); + } + + public void AddJsonBody(object obj) + { + JsonBody = obj; + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Core/Ombi.Core.csproj b/Ombi/Ombi.Core/Ombi.Core.csproj index d6bb44f88..7bac40bb5 100644 --- a/Ombi/Ombi.Core/Ombi.Core.csproj +++ b/Ombi/Ombi.Core/Ombi.Core.csproj @@ -1,7 +1,7 @@  - netstandard1.4 + netstandard1.6 diff --git a/Ombi/Ombi.Core/Settings/Models/External/EmbySettings.cs b/Ombi/Ombi.Core/Settings/Models/External/EmbySettings.cs new file mode 100644 index 000000000..b68cbe9d8 --- /dev/null +++ b/Ombi/Ombi.Core/Settings/Models/External/EmbySettings.cs @@ -0,0 +1,10 @@ +namespace Ombi.Core.Settings.Models.External +{ + public sealed class EmbySettings : ExternalSettings + { + public bool Enable { get; set; } + public string ApiKey { get; set; } + public string AdministratorId { get; set; } + public bool EnableEpisodeSearching { get; set; } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Core/Settings/Models/External/ExternalSettings.cs b/Ombi/Ombi.Core/Settings/Models/External/ExternalSettings.cs new file mode 100644 index 000000000..cdaf3158c --- /dev/null +++ b/Ombi/Ombi.Core/Settings/Models/External/ExternalSettings.cs @@ -0,0 +1,29 @@ +using System; +using Newtonsoft.Json; +using Ombi.Helpers; + +namespace Ombi.Core.Settings.Models.External +{ + public abstract class ExternalSettings : Settings + { + public bool Ssl { get; set; } + public string SubDir { get; set; } + public string Ip { get; set; } + public int Port { get; set; } + + [JsonIgnore] + public virtual Uri FullUri + { + get + { + if (!string.IsNullOrEmpty(SubDir)) + { + var formattedSubDir = Ip.ReturnUriWithSubDir(Port, Ssl, SubDir); + return formattedSubDir; + } + var formatted = Ip.ReturnUri(Port, Ssl); + return formatted; + } + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Core/Settings/Models/External/PlexSettings.cs b/Ombi/Ombi.Core/Settings/Models/External/PlexSettings.cs new file mode 100644 index 000000000..80c57af3b --- /dev/null +++ b/Ombi/Ombi.Core/Settings/Models/External/PlexSettings.cs @@ -0,0 +1,12 @@ +namespace Ombi.Core.Settings.Models.External +{ + public sealed class PlexSettings : ExternalSettings + { + + public bool Enable { get; set; } + public bool EnableEpisodeSearching { get; set; } + + public string PlexAuthToken { get; set; } + public string MachineIdentifier { get; set; } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Core/Settings/SettingsResolver.cs b/Ombi/Ombi.Core/Settings/SettingsResolver.cs index 33c7cf2c2..d0bff8d36 100644 --- a/Ombi/Ombi.Core/Settings/SettingsResolver.cs +++ b/Ombi/Ombi.Core/Settings/SettingsResolver.cs @@ -1,4 +1,6 @@ using System; +using System.Linq; +using System.Reflection; using Microsoft.Extensions.DependencyInjection; namespace Ombi.Core.Settings diff --git a/Ombi/Ombi.Core/Settings/SettingsService.cs b/Ombi/Ombi.Core/Settings/SettingsService.cs index c796710fa..552325e24 100644 --- a/Ombi/Ombi.Core/Settings/SettingsService.cs +++ b/Ombi/Ombi.Core/Settings/SettingsService.cs @@ -118,12 +118,12 @@ namespace Ombi.Core.Settings private string EncryptSettings(GlobalSettings settings) { - return StringCipher.Encrypt(settings.Content, settings.SettingsName); + return StringCipher.EncryptString(settings.Content, $"Ombiv3SettingsEncryptionPassword"); } private string DecryptSettings(GlobalSettings settings) { - return StringCipher.Decrypt(settings.Content, settings.SettingsName); + return StringCipher.DecryptString(settings.Content, $"Ombiv3SettingsEncryptionPassword"); } } } \ No newline at end of file diff --git a/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj index 1e12ffd1a..d776f14ed 100644 --- a/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj +++ b/Ombi/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -1,7 +1,7 @@  - netstandard1.4 + netstandard1.6 diff --git a/Ombi/Ombi.Helpers/Ombi.Helpers.csproj b/Ombi/Ombi.Helpers/Ombi.Helpers.csproj index 00920ab0c..7cf7de058 100644 --- a/Ombi/Ombi.Helpers/Ombi.Helpers.csproj +++ b/Ombi/Ombi.Helpers/Ombi.Helpers.csproj @@ -1,10 +1,11 @@  - netstandard1.4 + netstandard1.6 + diff --git a/Ombi/Ombi.Helpers/StringCipher.cs b/Ombi/Ombi.Helpers/StringCipher.cs index df10fcb6a..f55238ca3 100644 --- a/Ombi/Ombi.Helpers/StringCipher.cs +++ b/Ombi/Ombi.Helpers/StringCipher.cs @@ -1,3 +1,4 @@ +using EasyCrypto; using System; using System.IO; using System.Security.Cryptography; @@ -81,5 +82,18 @@ namespace Ombi.Helpers } } } + + + public static string EncryptString(string text, string keyString) + { + var result = AesEncryption.EncryptWithPassword(text, keyString); + return result; + } + + public static string DecryptString(string cipherText, string keyString) + { + var result = AesEncryption.DecryptWithPassword(cipherText, keyString); + return result; + } } } diff --git a/Ombi/Ombi.Helpers/UriHelper.cs b/Ombi/Ombi.Helpers/UriHelper.cs new file mode 100644 index 000000000..83cd27e9d --- /dev/null +++ b/Ombi/Ombi.Helpers/UriHelper.cs @@ -0,0 +1,123 @@ +using System; + +namespace Ombi.Helpers +{ + public static class UriHelper + { + private const string Https = "Https"; + private const string Http = "Http"; + + public static Uri ReturnUri(this string val) + { + if (val == null) + { + throw new ApplicationSettingsException("The URI is null, please check your settings to make sure you have configured the applications correctly."); + } + try + { + var uri = new UriBuilder(); + + if (val.StartsWith("http://", StringComparison.Ordinal)) + { + uri = new UriBuilder(val); + } + else if (val.StartsWith("https://", StringComparison.Ordinal)) + { + uri = new UriBuilder(val); + } + else if (val.Contains(":")) + { + var split = val.Split(':', '/'); + int port; + int.TryParse(split[1], out port); + + uri = split.Length == 3 + ? new UriBuilder(Http, split[0], port, "/" + split[2]) + : new UriBuilder(Http, split[0], port); + } + else + { + uri = new UriBuilder(Http, val); + } + + return uri.Uri; + } + catch (Exception exception) + { + throw new Exception(exception.Message, exception); + } + } + + /// + /// Returns the URI. + /// + /// The value. + /// The port. + /// if set to true [SSL]. + /// The subdir. + /// + /// The URI is null, please check your settings to make sure you have configured the applications correctly. + /// + public static Uri ReturnUri(this string val, int port, bool ssl = default(bool)) + { + if (val == null) + { + throw new ApplicationSettingsException("The URI is null, please check your settings to make sure you have configured the applications correctly."); + } + try + { + var uri = new UriBuilder(); + + if (val.StartsWith("http://", StringComparison.Ordinal)) + { + var split = val.Split('/'); + uri = split.Length >= 4 ? new UriBuilder(Http, split[2], port, "/" + split[3]) : new UriBuilder(new Uri($"{val}:{port}")); + } + else if (val.StartsWith("https://", StringComparison.Ordinal)) + { + var split = val.Split('/'); + uri = split.Length >= 4 + ? new UriBuilder(Https, split[2], port, "/" + split[3]) + : new UriBuilder(Https, split[2], port); + } + else if (ssl) + { + uri = new UriBuilder(Https, val, port); + } + else + { + uri = new UriBuilder(Http, val, port); + } + + return uri.Uri; + } + catch (Exception exception) + { + throw new Exception(exception.Message, exception); + } + } + + public static Uri ReturnUriWithSubDir(this string val, int port, bool ssl, string subDir) + { + var uriBuilder = new UriBuilder(val); + if (ssl) + { + uriBuilder.Scheme = Https; + } + if (!string.IsNullOrEmpty(subDir)) + { + uriBuilder.Path = subDir; + } + uriBuilder.Port = port; + + return uriBuilder.Uri; + } + } + + public class ApplicationSettingsException : Exception + { + public ApplicationSettingsException(string s) : base(s) + { + } + } +} \ No newline at end of file diff --git a/Ombi/Ombi.Store/Ombi.Store.csproj b/Ombi/Ombi.Store/Ombi.Store.csproj index 6a83ce47c..ffc1d529a 100644 --- a/Ombi/Ombi.Store/Ombi.Store.csproj +++ b/Ombi/Ombi.Store/Ombi.Store.csproj @@ -1,7 +1,7 @@  - netstandard1.4 + netstandard1.6 diff --git a/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs b/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs index 987276a55..e5e0da498 100644 --- a/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs +++ b/Ombi/Ombi.Store/Repository/SettingsJsonRepository.cs @@ -65,7 +65,6 @@ namespace Ombi.Store.Repository public async Task UpdateAsync(GlobalSettings entity) { - Db.Settings.Update(entity); await Db.SaveChangesAsync(); } @@ -77,7 +76,6 @@ namespace Ombi.Store.Repository public void Update(GlobalSettings entity) { - Db.Settings.Update(entity); Db.SaveChanges(); } } diff --git a/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj b/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj index 16516740e..07b575cc8 100644 --- a/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj +++ b/Ombi/Ombi.TheMovieDbApi/Ombi.TheMovieDbApi.csproj @@ -1,7 +1,7 @@  - netstandard1.4 + netstandard1.6 diff --git a/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs index 33787f911..76342d915 100644 --- a/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/Ombi/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Net.Http; using System.Threading.Tasks; using Ombi.Api; using Ombi.TheMovieDbApi.Models; @@ -13,63 +12,62 @@ namespace Ombi.TheMovieDbApi Api = new Api.Api(); } private const string ApiToken = "b8eabaf5608b88d0298aa189dd90bf00"; - private static readonly Uri BaseUri = new Uri("http://api.themoviedb.org/3/"); - public Api.Api Api { get; } + private static readonly string BaseUri ="http://api.themoviedb.org/3/"; + private Api.Api Api { get; } public async Task GetMovieInformation(int movieId) { - var url = BaseUri.ChangePath("movie/{0}", movieId.ToString()); - url = AddHeaders(url); - return await Api.Get(url); + var request = new Request($"movie/{movieId}", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + + return await Api.Request(request); } public async Task GetMovieInformationWithVideo(int movieId) { - var url = BaseUri.ChangePath("movie/{0}", movieId.ToString()); - url = AddHeaders(url); - url = url.AddQueryParameter("append_to_response", "videos"); - return await Api.Get(url); + var request = new Request($"movie/{movieId}", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + request.FullUri = request.FullUri.AddQueryParameter("append_to_response", "videos"); + return await Api.Request(request); } public async Task> SearchMovie(string searchTerm) { - var url = BaseUri.ChangePath("search/movie/"); - url = AddHeaders(url); - url = url.AddQueryParameter("query", searchTerm); - return await Api.Get>(url); + var request = new Request($"search/movie", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + request.FullUri = request.FullUri.AddQueryParameter("query", searchTerm); + + return await Api.Request>(request); } public async Task> PopularMovies() { - var url = BaseUri.ChangePath("movie/popular"); - url = AddHeaders(url); - return await Api.Get>(url); + var request = new Request($"movie/popular", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + + return await Api.Request>(request); } public async Task> TopRated() { - var url = BaseUri.ChangePath("movie/top_rated"); - url = AddHeaders(url); - return await Api.Get>(url); + var request = new Request($"movie/top_rated", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + return await Api.Request>(request); } public async Task> Upcoming() { - var url = BaseUri.ChangePath("movie/upcoming"); - url = AddHeaders(url); - return await Api.Get>(url); + var request = new Request($"movie/upcoming", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + return await Api.Request>(request); } public async Task> NowPlaying() { - var url = BaseUri.ChangePath("movie/now_playing"); - url = AddHeaders(url); - return await Api.Get>(url); + var request = new Request($"movie/now_playing", BaseUri, HttpMethod.Get); + request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); + return await Api.Request>(request); } - private Uri AddHeaders(Uri url) - { - return url.AddQueryParameter("api_key", ApiToken); - } } } diff --git a/Ombi/Ombi/.gitignore b/Ombi/Ombi/.gitignore index ef724f488..6c6136a36 100644 --- a/Ombi/Ombi/.gitignore +++ b/Ombi/Ombi/.gitignore @@ -1,6 +1,5 @@ /wwwroot/css/** /wwwroot/fonts/** -/wwwroot/images/** /wwwroot/lib/** /wwwroot/maps/** /wwwroot/app/**/*.js diff --git a/Ombi/Ombi/Controllers/SettingsController.cs b/Ombi/Ombi/Controllers/SettingsController.cs index db83c15b6..fdd5f4d31 100644 --- a/Ombi/Ombi/Controllers/SettingsController.cs +++ b/Ombi/Ombi/Controllers/SettingsController.cs @@ -1,8 +1,10 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Ombi.Core.Settings; using Ombi.Core.Settings.Models; +using Ombi.Core.Settings.Models.External; namespace Ombi.Controllers { @@ -19,19 +21,51 @@ namespace Ombi.Controllers [HttpGet("ombi")] public async Task OmbiSettings() { - var settings = SettingsResolver.Resolve(); - - return await settings.GetSettingsAsync(); + return await Get(); } [HttpPost("ombi")] public async Task OmbiSettings([FromBody]OmbiSettings ombi) { - var settings = SettingsResolver.Resolve(); + return await Save(ombi); + + } + + [HttpGet("plex")] + public async Task PlexSettings() + { + return await Get(); + } - return await settings.SaveSettingsAsync(ombi); + [HttpPost("plex")] + public async Task PlexSettings([FromBody]PlexSettings plex) + { + return await Save(plex); } + [HttpGet("emby")] + public async Task EmbySettings() + { + return await Get(); + } + [HttpPost("emby")] + public async Task EmbySettings([FromBody]EmbySettings emby) + { + return await Save(emby); + } + + + private async Task Get() + { + var settings = SettingsResolver.Resolve(); + return await settings.GetSettingsAsync(); + } + + private async Task Save(T settingsModel) + { + var settings = SettingsResolver.Resolve(); + return await settings.SaveSettingsAsync(settingsModel); + } } } diff --git a/Ombi/Ombi/Ombi.csproj b/Ombi/Ombi/Ombi.csproj index 784ae0f46..da1c749d6 100644 --- a/Ombi/Ombi/Ombi.csproj +++ b/Ombi/Ombi/Ombi.csproj @@ -16,19 +16,82 @@ - - - - PreserveNewest - + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + PreserveNewest + + + + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + + + + + + + + diff --git a/Ombi/Ombi/wwwroot/app/app.component.html b/Ombi/Ombi/wwwroot/app/app.component.html index a75b30406..1d28e3abe 100644 --- a/Ombi/Ombi/wwwroot/app/app.component.html +++ b/Ombi/Ombi/wwwroot/app/app.component.html @@ -1,4 +1,4 @@ - +