Finsihed adding preset themes.

Added query string support for api key #1689
Added swedish lang #1691
pull/1654/head
Jamie 7 years ago
parent 9252bbf110
commit aad5a71c98

@ -19,7 +19,7 @@ namespace Ombi.Api.Github
public async Task<List<CakeThemes>> GetCakeThemes()
{
var request = new Request("repos/leram84/layer.Cake/contents/ombi/themes", BaseUrl, HttpMethod.Get);
var request = new Request("repos/tidusjar/layer.Cake/contents/ombi/themes", BaseUrl, HttpMethod.Get);
request.AddHeader("Accept", "application/vnd.github.v3+json");
request.AddHeader("User-Agent", "Ombi");
return await _api.Request<List<CakeThemes>>(request);

@ -16,7 +16,7 @@ namespace Ombi.Settings.Settings.Models
public string PresetThemeContent { get; set; }
[NotMapped]
public string PresetThemeVersionVersion
public string PresetThemeVersion
{
get
{

@ -26,13 +26,13 @@ export class AppComponent implements OnInit {
private readonly settingsService: SettingsService,
private readonly jobService: JobService,
public readonly translate: TranslateService) {
this.translate.addLangs(["en", "de", "fr","da","es","it","nl"]);
this.translate.addLangs(["en", "de", "fr","da","es","it","nl","sv"]);
// this language will be used as a fallback when a translation isn't found in the current language
this.translate.setDefaultLang("en");
// See if we can match the supported langs with the current browser lang
const browserLang: string = translate.getBrowserLang();
this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl/) ? browserLang : "en");
this.translate.use(browserLang.match(/en|fr|da|de|es|it|nl|sv/) ? browserLang : "en");
}
public ngOnInit() {

@ -3,7 +3,7 @@
<fieldset *ngIf="settings">
<legend>Customization</legend>
<div class="col-md-6">
<div class="col-md-5">
<div class="form-group">
<label for="applicationName" class="control-label">Application Name</label>
<div>
@ -27,6 +27,12 @@
tooltipPosition="top" pTooltip="Use a URL e.g. www.google.com/logo.png">
</div>
</div>
<div *ngIf="settings.logo" class="form-group">
<label for="logo" class="control-label">Logo Preview:</label>
<div>
<img [src]="settings.logo" style="width: 300px" />
</div>
</div>
<div class="form-group">
@ -46,7 +52,7 @@
</div>
</div>
<!-- <div class="col-md-6">
<div class="col-md-7">
<div *ngIf="themes">
<div class="form-group">
<label for="presetTheme" class="control-label">Preset Themes</label>
@ -56,19 +62,14 @@
</select>
</div>
</div>
<div class="form-group">
<textarea rows="4" type="text" class="form-control-custom form-control " id="themeContent" name="themeContent" [(ngModel)]="settings.presetThemeContent"> {{settings.presetThemeContent}} </textarea>
<div class="form-group" *ngIf="settings.presetThemeContent">
<textarea rows="25" type="text" class="form-control-custom form-control " id="themeContent" name="themeContent" [(ngModel)]="settings.presetThemeContent"> {{settings.presetThemeContent}} </textarea>
</div>
</div>
</div> -->
</div>
<div *ngIf="settings.logo" class="form-group">
<label for="logo" class="control-label">Logo Preview:</label>
<div>
<img [src]="settings.logo" style="width: 300px" />
</div>
</div>
</fieldset>

@ -19,6 +19,18 @@ export class CustomizationComponent implements OnInit {
this.settings = x;
this.settingsService.getThemes().subscribe(t => {
this.themes = t;
const existingTheme = this.themes.filter((item) => {
return item.fullName === this.settings.presetThemeName;
})[0];
if(existingTheme) {
const index = this.themes.indexOf(existingTheme, 0);
if (index > -1) {
this.themes.splice(index, 1);
}
}
if(x.hasPresetTheme) {
this.themes.unshift({displayName: x.presetThemeDisplayName, fullName: x.presetThemeName, url: "", version: x.presetThemeVersion});
} else {
@ -45,9 +57,9 @@ export class CustomizationComponent implements OnInit {
return val.fullName === selectedThemeFullName;
});
// if(selectedTheme[0].fullName === this.settings.presetThemeName) {
// return;
// }
if(selectedTheme[0].fullName === this.settings.presetThemeName) {
return;
}
this.settings.presetThemeName = selectedThemeFullName;
this.settingsService.getThemeContent(selectedTheme[0].url).subscribe(x => {

@ -259,6 +259,7 @@ namespace Ombi.Controllers
/// <param name="url"></param>
/// <returns></returns>
[HttpGet("themecontent")]
[AllowAnonymous]
public async Task<string> GetThemeContent([FromQuery]string url)
{
var content = await _githubApi.GetThemesRawContent(url);

@ -194,7 +194,7 @@ namespace Ombi
app.UseAuthentication();
ApiKeyMiddlewear(app, serviceProvider);
app.ApiKeyMiddlewear(serviceProvider);
app.UseSwagger();
app.UseSwaggerUI(c =>
{
@ -213,46 +213,6 @@ namespace Ombi
defaults: new { controller = "Home", action = "Index" });
});
}
private static void ApiKeyMiddlewear(IApplicationBuilder app, IServiceProvider serviceProvider)
{
app.Use(async (context, next) =>
{
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
{
// Let's check if this is an API Call
if (context.Request.Headers["ApiKey"].Any())
{
// validate the supplied API key
// Validate it
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
var settingsProvider = serviceProvider.GetService<ISettingsService<OmbiSettings>>();
var ombiSettings = settingsProvider.GetSettings();
var valid = ombiSettings.ApiKey.Equals(headerKey, StringComparison.CurrentCultureIgnoreCase);
if (!valid)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("Invalid API Key");
}
else
{
var identity = new GenericIdentity("API");
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
context.User = principal;
await next();
}
}
else
{
await next();
}
}
else
{
await next();
}
});
}
}
public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter

@ -1,14 +1,23 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Principal;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.PlatformAbstractions;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using Ombi.Config;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Models.Identity;
using Ombi.Settings.Settings.Models;
using Swashbuckle.AspNetCore.Swagger;
namespace Ombi
@ -103,5 +112,58 @@ namespace Ombi
x.TokenValidationParameters = tokenValidationParameters;
});
}
public static void ApiKeyMiddlewear(this IApplicationBuilder app, IServiceProvider serviceProvider)
{
app.Use(async (context, next) =>
{
if (context.Request.Path.StartsWithSegments(new PathString("/api")))
{
// Let's check if this is an API Call
if (context.Request.Headers["ApiKey"].Any())
{
// validate the supplied API key
// Validate it
var headerKey = context.Request.Headers["ApiKey"].FirstOrDefault();
await ValidateApiKey(serviceProvider, context, next, headerKey);
}
else if (context.Request.Query.ContainsKey("apikey"))
{
if (context.Request.Query.TryGetValue("apikey", out var queryKey))
{
await ValidateApiKey(serviceProvider, context, next, queryKey);
}
}
else
{
await next();
}
}
else
{
await next();
}
});
}
private static async Task ValidateApiKey(IServiceProvider serviceProvider, HttpContext context, Func<Task> next, string key)
{
var settingsProvider = serviceProvider.GetService<ISettingsService<OmbiSettings>>();
var ombiSettings = settingsProvider.GetSettings();
var valid = ombiSettings.ApiKey.Equals(key, StringComparison.CurrentCultureIgnoreCase);
if (!valid)
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
await context.Response.WriteAsync("Invalid API Key");
}
else
{
var identity = new GenericIdentity("API");
var principal = new GenericPrincipal(identity, new[] { "Admin", "ApiUser" });
context.User = principal;
await next();
}
}
}
}

@ -56,6 +56,13 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
@{
if (customization.HasPresetTheme)
{
<style>
@Html.Raw(customization.PresetThemeContent)
</style>
}
if (!string.IsNullOrEmpty(customization.CustomCssLink))
{
<link rel="stylesheet" href="@customization.CustomCssLink" asp-append-version="true"/>

@ -1,54 +0,0 @@
{
"Login": {
"SignInButton": "crwdns37:0crwdne37:0",
"UsernamePlaceholder": "crwdns38:0crwdne38:0",
"PasswordPlaceholder": "crwdns39:0crwdne39:0",
"RememberMe": "crwdns40:0crwdne40:0",
"ForgottenPassword": "crwdns41:0crwdne41:0",
"Errors": {
"IncorrectCredentials": "crwdns71:0crwdne71:0"
}
},
"Common": {
"ContinueButton": "crwdns42:0crwdne42:0",
"Errors": {
"Validation": "crwdns72:0crwdne72:0"
}
},
"PasswordReset": {
"EmailAddressPlaceholder": "crwdns43:0crwdne43:0",
"ResetPasswordButton": "crwdns44:0crwdne44:0"
},
"LandingPage": {
"OnlineHeading": "crwdns45:0crwdne45:0",
"OnlineParagraph": "crwdns46:0crwdne46:0",
"PartiallyOnlineHeading": "crwdns47:0crwdne47:0",
"PartiallyOnlineParagraph": "crwdns48:0crwdne48:0",
"MultipleServersUnavailable": "crwdns49:0{{serversUnavailable}}crwdnd49:0{{totalServers}}crwdne49:0",
"SingleServerUnavailable": "crwdns50:0{{serversUnavailable}}crwdnd50:0{{totalServers}}crwdne50:0",
"OfflineHeading": "crwdns51:0crwdne51:0",
"OfflineParagraph": "crwdns52:0crwdne52:0",
"CheckPageForUpdates": "crwdns73:0crwdne73:0"
},
"NavigationBar": {
"Search": "crwdns54:0crwdne54:0",
"Requests": "crwdns55:0crwdne55:0",
"UserManagement": "crwdns56:0crwdne56:0",
"Donate": "crwdns57:0crwdne57:0",
"DonateTooltip": "crwdns58:0crwdne58:0",
"UpdateAvailableTooltip": "crwdns59:0crwdne59:0",
"Settings": "crwdns60:0crwdne60:0",
"Welcome": "crwdns61:0{{username}}crwdne61:0",
"UpdateDetails": "crwdns62:0crwdne62:0",
"Logout": "crwdns63:0crwdne63:0",
"Language": {
"English": "crwdns64:0crwdne64:0",
"French": "crwdns65:0crwdne65:0",
"Spanish": "crwdns66:0crwdne66:0",
"German": "crwdns67:0crwdne67:0",
"Italian": "crwdns68:0crwdne68:0",
"Danish": "crwdns69:0crwdne69:0",
"Dutch": "crwdns70:0crwdne70:0"
}
}
}
Loading…
Cancel
Save