mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-21 05:43:19 -07:00
Allow users to login without a password
This commit is contained in:
parent
a957b37995
commit
d5787e6625
8 changed files with 130 additions and 10 deletions
|
@ -37,6 +37,7 @@ 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.Helpers;
|
||||||
|
using Ombi.Settings.Settings.Models;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
namespace Ombi.Core.Authentication
|
namespace Ombi.Core.Authentication
|
||||||
|
@ -47,20 +48,36 @@ namespace Ombi.Core.Authentication
|
||||||
IPasswordHasher<OmbiUser> passwordHasher, IEnumerable<IUserValidator<OmbiUser>> userValidators,
|
IPasswordHasher<OmbiUser> passwordHasher, IEnumerable<IUserValidator<OmbiUser>> userValidators,
|
||||||
IEnumerable<IPasswordValidator<OmbiUser>> passwordValidators, ILookupNormalizer keyNormalizer,
|
IEnumerable<IPasswordValidator<OmbiUser>> passwordValidators, ILookupNormalizer keyNormalizer,
|
||||||
IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<OmbiUser>> logger, IPlexApi plexApi,
|
IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<OmbiUser>> logger, IPlexApi plexApi,
|
||||||
IEmbyApi embyApi, ISettingsService<EmbySettings> embySettings)
|
IEmbyApi embyApi, ISettingsService<EmbySettings> embySettings, ISettingsService<AuthenticationSettings> auth)
|
||||||
: base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
|
: base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
|
||||||
{
|
{
|
||||||
_plexApi = plexApi;
|
_plexApi = plexApi;
|
||||||
_embyApi = embyApi;
|
_embyApi = embyApi;
|
||||||
_embySettings = embySettings;
|
_embySettings = embySettings;
|
||||||
|
_authSettings = auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IPlexApi _plexApi;
|
private readonly IPlexApi _plexApi;
|
||||||
private readonly IEmbyApi _embyApi;
|
private readonly IEmbyApi _embyApi;
|
||||||
private readonly ISettingsService<EmbySettings> _embySettings;
|
private readonly ISettingsService<EmbySettings> _embySettings;
|
||||||
|
private readonly ISettingsService<AuthenticationSettings> _authSettings;
|
||||||
|
|
||||||
public override async Task<bool> CheckPasswordAsync(OmbiUser user, string password)
|
public override async Task<bool> CheckPasswordAsync(OmbiUser user, string password)
|
||||||
{
|
{
|
||||||
|
var authSettings = await _authSettings.GetSettingsAsync();
|
||||||
|
if (authSettings.AllowNoPassword)
|
||||||
|
{
|
||||||
|
// Check their roles
|
||||||
|
var roles = await GetRolesAsync(user);
|
||||||
|
if (roles.Contains(OmbiRoles.Admin) || roles.Contains(OmbiRoles.PowerUser))
|
||||||
|
{
|
||||||
|
// Do nothing, let it continue to check the password
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (user.UserType == UserType.LocalUser)
|
if (user.UserType == UserType.LocalUser)
|
||||||
{
|
{
|
||||||
return await base.CheckPasswordAsync(user, password);
|
return await base.CheckPasswordAsync(user, password);
|
||||||
|
|
|
@ -4,13 +4,7 @@ namespace Ombi.Settings.Settings.Models
|
||||||
{
|
{
|
||||||
public class AuthenticationSettings
|
public class AuthenticationSettings
|
||||||
{
|
{
|
||||||
/// <summary>
|
public bool AllowNoPassword { get; set; }
|
||||||
/// This determins if Plex and/or Emby users can log into Ombi
|
|
||||||
/// </summary>
|
|
||||||
/// <value>
|
|
||||||
/// <c>true</c> if [allow external users to authenticate]; otherwise, <c>false</c>.
|
|
||||||
/// </value>
|
|
||||||
public bool AllowExternalUsersToAuthenticate { get; set; }
|
|
||||||
|
|
||||||
// Password Options
|
// Password Options
|
||||||
public bool RequireDigit { get; set; }
|
public bool RequireDigit { get; set; }
|
||||||
|
|
|
@ -122,7 +122,7 @@ export interface IJobSettings {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAuthenticationSettings extends ISettings {
|
export interface IAuthenticationSettings extends ISettings {
|
||||||
allowExternalUsersToAuthenticate: boolean;
|
allowNoPassword: boolean;
|
||||||
// Password
|
// Password
|
||||||
|
|
||||||
requiredDigit: boolean;
|
requiredDigit: boolean;
|
||||||
|
|
|
@ -45,7 +45,7 @@ export class LoginComponent implements OnInit {
|
||||||
|
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
username: ["", [Validators.required]],
|
username: ["", [Validators.required]],
|
||||||
password: ["", [Validators.required]],
|
password: [""],
|
||||||
rememberMe: [false],
|
rememberMe: [false],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
<settings-menu></settings-menu>
|
||||||
|
|
||||||
|
<wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Authentication-Settings'"></wiki>
|
||||||
|
<fieldset *ngIf="form">
|
||||||
|
<legend>Authentication</legend>
|
||||||
|
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="allowNoPassword" name="allowNoPassword" formControlName="allowNoPassword">
|
||||||
|
<label for="allowNoPassword" tooltipPosition="top" pTooltip="Allow users to login with out a password">Allow users to login without a password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- <hr/>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="requiredDigit" name="requiredDigit" formControlName="requiredDigit">
|
||||||
|
<label for="requiredDigit">Require a digit in the password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="requiredLength" class="control-label">Required password length</label>
|
||||||
|
<div>
|
||||||
|
<input type="text" class="form-control form-control-custom " id="requiredLength" name="requiredLength" formControlName="requiredLength">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="requiredLowercase" name="requiredLowercase" formControlName="requiredLowercase">
|
||||||
|
<label for="requiredLowercase">Require a lowercase character in the password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="requireNonAlphanumeric" name="requireNonAlphanumeric" formControlName="requireNonAlphanumeric">
|
||||||
|
<label for="requireNonAlphanumeric">Require a NonAlphanumeric character in the password</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="requireUppercase" name="requireUppercase" formControlName="requireUppercase">
|
||||||
|
<label for="requireUppercase">Require a uppercase character in the password</label>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</fieldset>
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { FormBuilder, FormGroup } from "@angular/forms";
|
||||||
|
|
||||||
|
import { NotificationService } from "../../services";
|
||||||
|
import { SettingsService } from "../../services";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: "./authentication.component.html",
|
||||||
|
})
|
||||||
|
export class AuthenticationComponent implements OnInit {
|
||||||
|
|
||||||
|
public form: FormGroup;
|
||||||
|
|
||||||
|
constructor(private settingsService: SettingsService,
|
||||||
|
private notificationService: NotificationService,
|
||||||
|
private fb: FormBuilder) { }
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.settingsService.getAuthentication().subscribe(x => {
|
||||||
|
this.form = this.fb.group({
|
||||||
|
allowNoPassword: [x.allowNoPassword],
|
||||||
|
requiredDigit: [x.requiredDigit],
|
||||||
|
requiredLength: [x.requiredLength],
|
||||||
|
requiredLowercase: [x.requiredLowercase],
|
||||||
|
requireNonAlphanumeric: [x.requireNonAlphanumeric],
|
||||||
|
requireUppercase: [x.requireUppercase],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onSubmit(form: FormGroup) {
|
||||||
|
if (form.invalid) {
|
||||||
|
this.notificationService.error("Please check your entered values");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.settingsService.saveAuthentication(form.value).subscribe(x => {
|
||||||
|
if (x) {
|
||||||
|
this.notificationService.success("Successfully saved Authentication settings");
|
||||||
|
} else {
|
||||||
|
this.notificationService.success("There was an error when saving the Authentication settings");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import { CouchPotatoService, JobService, RadarrService, SonarrService, TesterSer
|
||||||
|
|
||||||
import { PipeModule } from "../pipes/pipe.module";
|
import { PipeModule } from "../pipes/pipe.module";
|
||||||
import { AboutComponent } from "./about/about.component";
|
import { AboutComponent } from "./about/about.component";
|
||||||
|
import { AuthenticationComponent } from "./authentication/authentication.component";
|
||||||
import { CouchPotatoComponent } from "./couchpotato/couchpotato.component";
|
import { CouchPotatoComponent } from "./couchpotato/couchpotato.component";
|
||||||
import { CustomizationComponent } from "./customization/customization.component";
|
import { CustomizationComponent } from "./customization/customization.component";
|
||||||
import { DogNzbComponent } from "./dognzb/dognzb.component";
|
import { DogNzbComponent } from "./dognzb/dognzb.component";
|
||||||
|
@ -60,6 +61,7 @@ const routes: Routes = [
|
||||||
{ path: "Settings/Telegram", component: TelegramComponent, canActivate: [AuthGuard] },
|
{ path: "Settings/Telegram", component: TelegramComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "Settings/Jobs", component: JobsComponent, canActivate: [AuthGuard] },
|
{ path: "Settings/Jobs", component: JobsComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "Settings/SickRage", component: SickRageComponent, canActivate: [AuthGuard] },
|
{ path: "Settings/SickRage", component: SickRageComponent, canActivate: [AuthGuard] },
|
||||||
|
{ path: "Settings/Authentication", component: AuthenticationComponent, canActivate: [AuthGuard] },
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -105,6 +107,7 @@ const routes: Routes = [
|
||||||
DogNzbComponent,
|
DogNzbComponent,
|
||||||
SickRageComponent,
|
SickRageComponent,
|
||||||
TelegramComponent,
|
TelegramComponent,
|
||||||
|
AuthenticationComponent,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
RouterModule,
|
RouterModule,
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Customization']">Customization</a></li>
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Customization']">Customization</a></li>
|
||||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/LandingPage']">Landing Page</a></li>
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/LandingPage']">Landing Page</a></li>
|
||||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/UserManagement']">User Importer</a></li>
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/UserManagement']">User Importer</a></li>
|
||||||
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Authentication']">Authentication</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue