Added the ability to enable Plex User importing. We also allow you to exclude users #1456

pull/1520/head
tidusjar 7 years ago
parent edd15e54b6
commit 97d63f13d3

@ -55,6 +55,13 @@ namespace Ombi.Schedule.Jobs.Plex
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
// 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);
@ -79,7 +86,6 @@ namespace Ombi.Schedule.Jobs.Plex
}
continue;
}
// TODO Set default permissions/roles
if (userManagementSettings.DefaultRoles.Any())
{
foreach (var defaultRole in userManagementSettings.DefaultRoles)

@ -6,6 +6,8 @@ namespace Ombi.Settings.Settings.Models
{
public bool ImportPlexUsers { 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>
</ul>
<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>

@ -10,7 +10,7 @@ import { RouterModule, Routes } from "@angular/router";
//import { DragulaModule, DragulaService } from 'ng2-dragula/ng2-dragula';
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
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
import { AppComponent } from "./app.component";
@ -79,6 +79,7 @@ const routes: Routes = [
UserManagementModule,
RequestsModule,
CaptchaModule,
TooltipModule,
],
declarations: [
AppComponent,

@ -20,6 +20,11 @@ export interface IPlexLibResponse {
data: IPlexLibraries;
}
export interface IPlexFriends {
id: string;
username: string;
}
export interface IMediaContainer {
directory: IDirectory[];
}

@ -1,5 +1,4 @@
import { ISettings } from "./ICommon";
import { ICheckbox } from "./index";
export interface IExternalSettings extends ISettings {
ssl: boolean;
@ -106,7 +105,9 @@ export interface IAuthenticationSettings extends ISettings {
export interface IUserManagementSettings extends ISettings {
importPlexUsers: boolean;
importEmbyUsers: boolean;
defaultClaims: ICheckbox[];
defaultRoles: string[];
bannedPlexUserIds: string[];
bannedEmbyUserIds: string[];
}
export interface IAbout {

@ -1,5 +1,5 @@
<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 />
<!-- Nav tabs -->

@ -6,8 +6,7 @@ import { Observable } from "rxjs/Rx";
import { ServiceAuthHelpers } from "../service.helpers";
import { IPlexAuthentication, IPlexLibResponse, IPlexServerViewModel } from "../../interfaces";
import { IPlexServer } from "../../interfaces";
import { IPlexAuthentication, IPlexFriends, IPlexLibResponse, IPlexServer, IPlexServerViewModel } from "../../interfaces";
@Injectable()
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);
}
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>
<legend>User Management Settings</legend>
<div class="col-md-6">
<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="col-md-6">
<div *ngIf="plexEnabled">
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="importPlex" [(ngModel)]="importPlexUsers">
<label for="importPlexUsers">Import Plex Users</label>
</div>
</div>
<div *ngIf="embyEnabled">
<div *ngIf="plexUsers">
<p>Plex Users exclude from Import</p>
<p-autoComplete [(ngModel)]="bannedPlexUsers" [suggestions]="filteredPlexUsers" [multiple]="true" field="username" (completeMethod)="filterCountryMultiple($event)"></p-autoComplete>
</div>
</div>
<div *ngIf="embyEnabled">
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="importEmbyUsers" formControlName="importEmbyUsers">
<label for="importEmbyUsers">Import Emby Users</label>
</div>
</div>
<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 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>
<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>

@ -1,7 +1,8 @@
import { Component, OnInit } from "@angular/core";
import { ICheckbox, IUserManagementSettings } from "../../interfaces";
import { IdentityService, SettingsService } from "../../services";
import { IPlexFriends } from "../../interfaces/IPlex";
import { IdentityService, NotificationService, PlexService, SettingsService } from "../../services";
@Component({
templateUrl: "./usermanagement.component.html",
@ -13,22 +14,40 @@ export class UserManagementComponent implements OnInit {
public settings: IUserManagementSettings;
public claims: ICheckbox[];
public plexUsers: IPlexFriends[];
public filteredPlexUsers: IPlexFriends[];
public bannedPlexUsers: IPlexFriends[] = [];
constructor(private settingsService: SettingsService,
//private notificationService: NotificationService,
private identityService: IdentityService) {
private notificationService: NotificationService,
private identityService: IdentityService,
private plexService: PlexService) {
}
public ngOnInit(): void {
this.settingsService.getUserManagementSettings().subscribe(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.claims = c;
this.claims.forEach((claim) => {
if (this.settings.defaultClaims) {
const hasClaim = this.settings.defaultClaims.some((item) => {
return item.value === claim.value && item.enabled;
if (this.settings.defaultRoles) {
const hasClaim = this.settings.defaultRoles.some((item) => {
return item === claim.value;
});
claim.enabled = hasClaim;
}
@ -37,6 +56,30 @@ export class UserManagementComponent implements OnInit {
});
this.settingsService.getPlex().subscribe(x => this.plexEnabled = 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 {
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-down {
display: none;
}
.ui-state-highlight {
background: $primary-colour;
}
.ui-inputtext {
background: $form-color;
}
.ui-state-default {
border: 1px solid $form-color-lighter;
}

@ -10,6 +10,7 @@ using Ombi.Api.Plex.Models;
using Ombi.Attributes;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Models.External;
namespace Ombi.Controllers.External
@ -104,9 +105,9 @@ namespace Ombi.Controllers.External
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;
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);
}
}
}

@ -0,0 +1,8 @@
namespace Ombi.Models.External
{
public class PlexUsersViewModel
{
public string Username { get; set; }
public string Id { get; set; }
}
}
Loading…
Cancel
Save