mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-11 15:56:05 -07:00
Added the ability to enable Plex User importing. We also allow you to exclude users #1456
This commit is contained in:
parent
edd15e54b6
commit
97d63f13d3
15 changed files with 171 additions and 45 deletions
|
@ -55,6 +55,13 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
|
|
||||||
foreach (var plexUsers in users.User)
|
foreach (var plexUsers in users.User)
|
||||||
{
|
{
|
||||||
|
// Check if we should import this user
|
||||||
|
if (userManagementSettings.BannedPlexUserIds.Contains(plexUsers.Id))
|
||||||
|
{
|
||||||
|
// Do not import these, they are not allowed into the country.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if this Plex User already exists
|
// Check if this Plex User already exists
|
||||||
// We are using the Plex USERNAME and Not the TITLE, the Title is for HOME USERS
|
// We are using the Plex USERNAME and Not the TITLE, the Title is for HOME USERS
|
||||||
var existingPlexUser = allUsers.FirstOrDefault(x => x.ProviderUserId == plexUsers.Id);
|
var existingPlexUser = allUsers.FirstOrDefault(x => x.ProviderUserId == plexUsers.Id);
|
||||||
|
@ -79,7 +86,6 @@ namespace Ombi.Schedule.Jobs.Plex
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// TODO Set default permissions/roles
|
|
||||||
if (userManagementSettings.DefaultRoles.Any())
|
if (userManagementSettings.DefaultRoles.Any())
|
||||||
{
|
{
|
||||||
foreach (var defaultRole in userManagementSettings.DefaultRoles)
|
foreach (var defaultRole in userManagementSettings.DefaultRoles)
|
||||||
|
|
|
@ -6,6 +6,8 @@ namespace Ombi.Settings.Settings.Models
|
||||||
{
|
{
|
||||||
public bool ImportPlexUsers { get; set; }
|
public bool ImportPlexUsers { get; set; }
|
||||||
public bool ImportEmbyUsers { get; set; }
|
public bool ImportEmbyUsers { get; set; }
|
||||||
public List<string> DefaultRoles { get; set; }
|
public List<string> DefaultRoles { get; set; } = new List<string>();
|
||||||
|
public List<string> BannedPlexUserIds { get; set; } = new List<string>();
|
||||||
|
public List<string> BannedEmbyUserIds { get; set; } = new List<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@
|
||||||
<li id="UserManagement" [routerLinkActive]="['active']"><a [routerLink]="['/usermanagement']"><i class="fa fa-user"></i> User Management</a></li>
|
<li id="UserManagement" [routerLinkActive]="['active']"><a [routerLink]="['/usermanagement']"><i class="fa fa-user"></i> User Management</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul *ngIf="hasRole('Admin') || hasRole('PowerUser')" class="nav navbar-nav">
|
<ul *ngIf="hasRole('Admin') || hasRole('PowerUser')" class="nav navbar-nav">
|
||||||
<li><a href="https://www.paypal.me/PlexRequestsNet" target="_blank"><i class="fa fa-heart" style="color:red"></i> Donate!</a></li>
|
<li><a href="https://www.paypal.me/PlexRequestsNet" target="_blank" pTooltip="This is how I convince my wife to let me spend my spare time on Ombi ;)"><i class="fa fa-heart" style="color:red"></i> Donate!</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import { RouterModule, Routes } from "@angular/router";
|
||||||
//import { DragulaModule, DragulaService } from 'ng2-dragula/ng2-dragula';
|
//import { DragulaModule, DragulaService } from 'ng2-dragula/ng2-dragula';
|
||||||
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
||||||
import { GrowlModule } from "primeng/components/growl/growl";
|
import { GrowlModule } from "primeng/components/growl/growl";
|
||||||
import { ButtonModule, CaptchaModule, DataTableModule,DialogModule, SharedModule } from "primeng/primeng";
|
import { ButtonModule, CaptchaModule, DataTableModule,DialogModule, SharedModule, TooltipModule } from "primeng/primeng";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { AppComponent } from "./app.component";
|
import { AppComponent } from "./app.component";
|
||||||
|
@ -79,6 +79,7 @@ const routes: Routes = [
|
||||||
UserManagementModule,
|
UserManagementModule,
|
||||||
RequestsModule,
|
RequestsModule,
|
||||||
CaptchaModule,
|
CaptchaModule,
|
||||||
|
TooltipModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
|
|
@ -20,6 +20,11 @@ export interface IPlexLibResponse {
|
||||||
data: IPlexLibraries;
|
data: IPlexLibraries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IPlexFriends {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IMediaContainer {
|
export interface IMediaContainer {
|
||||||
directory: IDirectory[];
|
directory: IDirectory[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { ISettings } from "./ICommon";
|
import { ISettings } from "./ICommon";
|
||||||
import { ICheckbox } from "./index";
|
|
||||||
|
|
||||||
export interface IExternalSettings extends ISettings {
|
export interface IExternalSettings extends ISettings {
|
||||||
ssl: boolean;
|
ssl: boolean;
|
||||||
|
@ -106,7 +105,9 @@ export interface IAuthenticationSettings extends ISettings {
|
||||||
export interface IUserManagementSettings extends ISettings {
|
export interface IUserManagementSettings extends ISettings {
|
||||||
importPlexUsers: boolean;
|
importPlexUsers: boolean;
|
||||||
importEmbyUsers: boolean;
|
importEmbyUsers: boolean;
|
||||||
defaultClaims: ICheckbox[];
|
defaultRoles: string[];
|
||||||
|
bannedPlexUserIds: string[];
|
||||||
|
bannedEmbyUserIds: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IAbout {
|
export interface IAbout {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<h1 id="searchTitle">Search</h1>
|
<h1 id="searchTitle">Search</h1>
|
||||||
<h4>Want to watch something that is not currently available?! No problem! Just search for it below and request it!</h4>
|
<h4>Want to watch something that is not currently available? No problem, just search for it below and request it!</h4>
|
||||||
<br />
|
<br />
|
||||||
<!-- Nav tabs -->
|
<!-- Nav tabs -->
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,7 @@ import { Observable } from "rxjs/Rx";
|
||||||
|
|
||||||
import { ServiceAuthHelpers } from "../service.helpers";
|
import { ServiceAuthHelpers } from "../service.helpers";
|
||||||
|
|
||||||
import { IPlexAuthentication, IPlexLibResponse, IPlexServerViewModel } from "../../interfaces";
|
import { IPlexAuthentication, IPlexFriends, IPlexLibResponse, IPlexServer, IPlexServerViewModel } from "../../interfaces";
|
||||||
import { IPlexServer } from "../../interfaces";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PlexService extends ServiceAuthHelpers {
|
export class PlexService extends ServiceAuthHelpers {
|
||||||
|
@ -27,4 +26,7 @@ export class PlexService extends ServiceAuthHelpers {
|
||||||
return this.http.post(`${this.url}Libraries`, JSON.stringify(plexSettings), { headers: this.headers }).map(this.extractData).catch(this.handleError);
|
return this.http.post(`${this.url}Libraries`, JSON.stringify(plexSettings), { headers: this.headers }).map(this.extractData).catch(this.handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getFriends(): Observable<IPlexFriends[]> {
|
||||||
|
return this.http.get(`${this.url}Friends`, { headers: this.headers }).map(this.extractData).catch(this.handleError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,42 +2,50 @@
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>User Management Settings</legend>
|
<legend>User Management Settings</legend>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div *ngIf="plexEnabled">
|
<div *ngIf="plexEnabled">
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="checkbox">
|
|
||||||
<input type="checkbox" id="importPlex" formControlName="importPlexUsers">
|
|
||||||
<label for="importPlexUsers">Import Plex Users</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="importPlex" [(ngModel)]="importPlexUsers">
|
||||||
|
<label for="importPlexUsers">Import Plex Users</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div *ngIf="plexUsers">
|
||||||
<div *ngIf="embyEnabled">
|
<p>Plex Users exclude from Import</p>
|
||||||
|
|
||||||
|
<p-autoComplete [(ngModel)]="bannedPlexUsers" [suggestions]="filteredPlexUsers" [multiple]="true" field="username" (completeMethod)="filterCountryMultiple($event)"></p-autoComplete>
|
||||||
<div class="form-group">
|
|
||||||
<div class="checkbox">
|
|
||||||
<input type="checkbox" id="importEmbyUsers" formControlName="importEmbyUsers">
|
|
||||||
<label for="importEmbyUsers">Import Emby Users</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6" >
|
|
||||||
<h4>Default Roles</h4>
|
|
||||||
|
|
||||||
<div *ngFor="let c of claims">
|
|
||||||
<div class="form-group">
|
|
||||||
<div class="checkbox">
|
|
||||||
<input type="checkbox" [(ngModel)]="c.enabled" [value]="c.value" id="create{{c.value}}" [attr.name]="'create' + c.value" ng-checked="c.enabled">
|
|
||||||
<label for="create{{c.value}}">{{c.value}}</label>
|
|
||||||
|
|
||||||
</div>
|
<div *ngIf="embyEnabled">
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="importEmbyUsers" [(ngModel)]="importEmbyUsers">
|
||||||
|
<label for="importEmbyUsers">Import Emby Users</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>Default Roles</h4>
|
||||||
|
|
||||||
|
<div *ngFor="let c of claims">
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" [(ngModel)]="c.enabled" [value]="c.value" id="create{{c.value}}" [attr.name]="'create' + c.value" ng-checked="c.enabled">
|
||||||
|
<label for="create{{c.value}}">{{c.value | humanize}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit" id="save" (click)="submit()" class="btn btn-primary-outline">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
|
@ -1,7 +1,8 @@
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
|
||||||
import { ICheckbox, IUserManagementSettings } from "../../interfaces";
|
import { ICheckbox, IUserManagementSettings } from "../../interfaces";
|
||||||
import { IdentityService, SettingsService } from "../../services";
|
import { IPlexFriends } from "../../interfaces/IPlex";
|
||||||
|
import { IdentityService, NotificationService, PlexService, SettingsService } from "../../services";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./usermanagement.component.html",
|
templateUrl: "./usermanagement.component.html",
|
||||||
|
@ -13,22 +14,40 @@ export class UserManagementComponent implements OnInit {
|
||||||
public settings: IUserManagementSettings;
|
public settings: IUserManagementSettings;
|
||||||
public claims: ICheckbox[];
|
public claims: ICheckbox[];
|
||||||
|
|
||||||
|
public plexUsers: IPlexFriends[];
|
||||||
|
public filteredPlexUsers: IPlexFriends[];
|
||||||
|
public bannedPlexUsers: IPlexFriends[] = [];
|
||||||
|
|
||||||
constructor(private settingsService: SettingsService,
|
constructor(private settingsService: SettingsService,
|
||||||
//private notificationService: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private identityService: IdentityService) {
|
private identityService: IdentityService,
|
||||||
|
private plexService: PlexService) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.settingsService.getUserManagementSettings().subscribe(x => {
|
this.settingsService.getUserManagementSettings().subscribe(x => {
|
||||||
this.settings = x;
|
this.settings = x;
|
||||||
|
|
||||||
|
this.plexService.getFriends().subscribe(f => {
|
||||||
|
this.plexUsers = f;
|
||||||
|
this.plexUsers.forEach((plex) => {
|
||||||
|
const isExcluded = this.settings.bannedPlexUserIds.some((val) => {
|
||||||
|
return plex.id === val;
|
||||||
|
});
|
||||||
|
if (isExcluded) {
|
||||||
|
this.bannedPlexUsers.push(plex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.identityService.getAllAvailableClaims().subscribe(c => {
|
this.identityService.getAllAvailableClaims().subscribe(c => {
|
||||||
|
|
||||||
this.claims = c;
|
this.claims = c;
|
||||||
this.claims.forEach((claim) => {
|
this.claims.forEach((claim) => {
|
||||||
if (this.settings.defaultClaims) {
|
if (this.settings.defaultRoles) {
|
||||||
const hasClaim = this.settings.defaultClaims.some((item) => {
|
const hasClaim = this.settings.defaultRoles.some((item) => {
|
||||||
return item.value === claim.value && item.enabled;
|
return item === claim.value;
|
||||||
});
|
});
|
||||||
claim.enabled = hasClaim;
|
claim.enabled = hasClaim;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +56,30 @@ export class UserManagementComponent implements OnInit {
|
||||||
});
|
});
|
||||||
this.settingsService.getPlex().subscribe(x => this.plexEnabled = x.enable);
|
this.settingsService.getPlex().subscribe(x => this.plexEnabled = x.enable);
|
||||||
this.settingsService.getEmby().subscribe(x => this.embyEnabled = x.enable);
|
this.settingsService.getEmby().subscribe(x => this.embyEnabled = x.enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public submit(): void {
|
||||||
|
const enabledClaims = this.claims.filter((claim) => {
|
||||||
|
return claim.enabled;
|
||||||
|
});
|
||||||
|
this.settings.defaultRoles = enabledClaims.map((claim) => claim.value);
|
||||||
|
this.settings.bannedPlexUserIds = this.bannedPlexUsers.map((u) => u.id);
|
||||||
|
this.settingsService.saveUserManagementSettings(this.settings).subscribe(x => {
|
||||||
|
if (x === true) {
|
||||||
|
this.notificationService.success("Saved", "Successfully saved the User Management Settings");
|
||||||
|
} else {
|
||||||
|
this.notificationService.success("Settings Saved", "There was an error when saving the Ombi settings");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public filterCountryMultiple(event: any) {
|
||||||
|
this.filteredPlexUsers = this.filter(event.query, this.plexUsers);
|
||||||
|
}
|
||||||
|
|
||||||
|
private filter(query: string, users: IPlexFriends[]): IPlexFriends[] {
|
||||||
|
return users.filter((val) => {
|
||||||
|
return val.username.toLowerCase().indexOf(query.toLowerCase()) === 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,4 +278,17 @@ button.list-group-item:focus {
|
||||||
}
|
}
|
||||||
.ui-widget-content {
|
.ui-widget-content {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.ui-inputtext {
|
||||||
|
background: $bg-colour;
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
.ui-autocomplete-input-token input{
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-state-default {
|
||||||
|
border: 2px solid $bg-colour-disabled;
|
||||||
}
|
}
|
|
@ -782,4 +782,16 @@ textarea {
|
||||||
.ui-treetable-toggler.fa.fa-fw.ui-clickable.fa-caret-right,
|
.ui-treetable-toggler.fa.fa-fw.ui-clickable.fa-caret-right,
|
||||||
.ui-treetable-toggler.fa.fa-fw.ui-clickable.fa-caret-down {
|
.ui-treetable-toggler.fa.fa-fw.ui-clickable.fa-caret-down {
|
||||||
display: none;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-state-highlight {
|
||||||
|
background: $primary-colour;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-inputtext {
|
||||||
|
background: $form-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-state-default {
|
||||||
|
border: 1px solid $form-color-lighter;
|
||||||
}
|
}
|
29
src/Ombi/Controllers/External/PlexController.cs
vendored
29
src/Ombi/Controllers/External/PlexController.cs
vendored
|
@ -10,6 +10,7 @@ using Ombi.Api.Plex.Models;
|
||||||
using Ombi.Attributes;
|
using Ombi.Attributes;
|
||||||
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.Models.External;
|
using Ombi.Models.External;
|
||||||
|
|
||||||
namespace Ombi.Controllers.External
|
namespace Ombi.Controllers.External
|
||||||
|
@ -104,9 +105,9 @@ namespace Ombi.Controllers.External
|
||||||
Data = libs
|
Data = libs
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_log.LogWarning(e,"Error thrown when attempting to obtain the plex libs");
|
_log.LogWarning(e, "Error thrown when attempting to obtain the plex libs");
|
||||||
|
|
||||||
var message = e.InnerException != null ? $"{e.Message} - {e.InnerException.Message}" : e.Message;
|
var message = e.InnerException != null ? $"{e.Message} - {e.InnerException.Message}" : e.Message;
|
||||||
return new PlexLibrariesResponse
|
return new PlexLibrariesResponse
|
||||||
|
@ -142,6 +143,30 @@ namespace Ombi.Controllers.External
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the plex friends.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("friends")]
|
||||||
|
public async Task<IEnumerable<PlexUsersViewModel>> GetFriends()
|
||||||
|
{
|
||||||
|
var vm = new List<PlexUsersViewModel>();
|
||||||
|
var s = await PlexSettings.GetSettingsAsync();
|
||||||
|
foreach (var server in s.Servers)
|
||||||
|
{
|
||||||
|
var users = await PlexApi.GetUsers(server.PlexAuthToken);
|
||||||
|
if (users?.User != null && users.User.Any())
|
||||||
|
{
|
||||||
|
vm.AddRange(users.User.Select(u => new PlexUsersViewModel
|
||||||
|
{
|
||||||
|
Username = u.Username,
|
||||||
|
Id = u.Id
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out any dupes
|
||||||
|
return vm.DistinctBy(x => x.Id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
8
src/Ombi/Models/External/PlexUsersViewModel.cs
vendored
Normal file
8
src/Ombi/Models/External/PlexUsersViewModel.cs
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Ombi.Models.External
|
||||||
|
{
|
||||||
|
public class PlexUsersViewModel
|
||||||
|
{
|
||||||
|
public string Username { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue