Added the option to import the plex admin.

Fixed #1701
pull/1741/head
tidusjar 7 years ago
parent 1813b45fb3
commit 560072eba4

@ -18,5 +18,6 @@ namespace Ombi.Api.Plex
Task<PlexMetadata> GetSeasons(string authToken, string plexFullHost, int ratingKey);
Task<PlexContainer> GetAllEpisodes(string authToken, string host, string section, int start, int retCount);
Task<PlexFriends> GetUsers(string authToken);
Task<PlexAccount> GetAccount(string authToken);
}
}

@ -2,13 +2,21 @@
namespace Ombi.Api.Plex.Models
{
public class PlexAccount
{
public User user { get; set; }
}
public class User
{
public string id { get; set; }
public string email { get; set; }
public string uuid { get; set; }
public string joined_at { get; set; }
public string username { get; set; }
public string title { get; set; }
public string thumb { get; set; }
public string hasPassword { get; set; }
public string authentication_token { get; set; }
public Subscription subscription { get; set; }
public Roles roles { get; set; }

@ -18,7 +18,7 @@ namespace Ombi.Api.Plex
private const string SignInUri = "https://plex.tv/users/sign_in.json";
private const string FriendsUri = "https://plex.tv/pms/friends/all";
private const string GetAccountUri = "https://plex.tv/users/account";
private const string GetAccountUri = "https://plex.tv/users/account.json";
private const string ServerUri = "https://plex.tv/pms/servers.xml";
/// <summary>
@ -52,6 +52,13 @@ namespace Ombi.Api.Plex
return await Api.Request<PlexStatus>(request);
}
public async Task<PlexAccount> GetAccount(string authToken)
{
var request = new Request(GetAccountUri, string.Empty, HttpMethod.Get);
AddHeaders(request, authToken);
return await Api.Request<PlexAccount>(request);
}
public async Task<PlexServer> GetServer(string authToken)
{
var request = new Request(ServerUri, string.Empty, HttpMethod.Get, ContentType.Xml);

@ -1,10 +1,10 @@
using System.Security.Principal;
using System.Threading.Tasks;
using Moq;
using Ombi.Core.Claims;
using Ombi.Core.Rule.Rules.Request;
using Ombi.Store.Entities.Requests;
using NUnit.Framework;
using Ombi.Helpers;
namespace Ombi.Core.Tests.Rule.Request
{

@ -2,8 +2,8 @@ using System.Security.Principal;
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
using Ombi.Core.Claims;
using Ombi.Core.Rule.Rules;
using Ombi.Helpers;
using Ombi.Store.Entities.Requests;
namespace Ombi.Core.Tests.Rule.Request

@ -1,8 +1,8 @@
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Claims;
using Ombi.Core.Models.Requests;
using Ombi.Core.Rule.Interfaces;
using Ombi.Helpers;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;

@ -1,8 +1,8 @@
using Ombi.Core.Claims;
using Ombi.Store.Entities;
using Ombi.Store.Entities;
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Rule.Interfaces;
using Ombi.Helpers;
using Ombi.Store.Entities.Requests;
namespace Ombi.Core.Rule.Rules

@ -1,7 +1,7 @@
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Claims;
using Ombi.Core.Rule.Interfaces;
using Ombi.Helpers;
using Ombi.Store.Entities.Requests;
namespace Ombi.Core.Rule.Rules.Specific

@ -108,7 +108,7 @@ namespace Ombi.Core.Senders
// Get the root path from the rootfolder selected.
// For some reason, if we haven't got one use the first root folder in Sonarr
// TODO make this overrideable via the UI
var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? 0, s);
var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s);
try
{
// Does the series actually exist?

@ -1,4 +1,4 @@
namespace Ombi.Core.Claims
namespace Ombi.Helpers
{
public static class OmbiRoles
{

@ -39,7 +39,7 @@ namespace Ombi.Notifications.Interfaces
public async Task NotifyAsync(NotificationOptions model)
{
var configuration = GetConfiguration();
var configuration = await GetConfiguration();
await NotifyAsync(model, configuration);
}
@ -100,6 +100,12 @@ namespace Ombi.Notifications.Interfaces
}
}
/// <summary>
/// Loads the TV or Movie Request
/// </summary>
/// <param name="requestId"></param>
/// <param name="type"></param>
/// <returns></returns>
protected virtual async Task LoadRequest(int requestId, RequestType type)
{
if (type == RequestType.Movie)
@ -112,12 +118,19 @@ namespace Ombi.Notifications.Interfaces
}
}
private T GetConfiguration()
private async Task<T> GetConfiguration()
{
var settings = Settings.GetSettings();
var settings = await Settings.GetSettingsAsync();
return settings;
}
/// <summary>
/// Loads the correct template from the DB
/// </summary>
/// <param name="agent"></param>
/// <param name="type"></param>
/// <param name="model"></param>
/// <returns></returns>
protected virtual async Task<NotificationMessageContent> LoadTemplate(NotificationAgent agent, NotificationType type, NotificationOptions model)
{
var template = await TemplateRepository.GetTemplate(agent, type);

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
@ -44,6 +45,8 @@ namespace Ombi.Schedule.Jobs.Plex
{
return;
}
var allUsers = await _userManager.Users.Where(x => x.UserType == UserType.PlexUser).ToListAsync();
foreach (var server in settings.Servers)
{
@ -52,6 +55,8 @@ namespace Ombi.Schedule.Jobs.Plex
continue;
}
await ImportAdmin(userManagementSettings, server, allUsers);
var users = await _api.GetUsers(server.PlexAuthToken);
foreach (var plexUser in users.User)
@ -80,12 +85,8 @@ namespace Ombi.Schedule.Jobs.Plex
};
_log.LogInformation("Creating Plex user {0}", newUser.UserName);
var result = await _userManager.CreateAsync(newUser);
if (!result.Succeeded)
if (!LogResult(result))
{
foreach (var identityError in result.Errors)
{
_log.LogError(LoggingEvents.PlexUserImporter, identityError.Description);
}
continue;
}
if (userManagementSettings.DefaultRoles.Any())
@ -107,5 +108,59 @@ namespace Ombi.Schedule.Jobs.Plex
}
}
}
private async Task ImportAdmin(UserManagementSettings settings, PlexServers server, List<OmbiUser> allUsers)
{
if (!settings.ImportPlexAdmin)
{
return;
}
var plexAdmin = (await _api.GetAccount(server.PlexAuthToken)).user;
// Check if the admin is already in the DB
var adminUserFromDb = allUsers.FirstOrDefault(x =>
x.ProviderUserId.Equals(plexAdmin.id, StringComparison.CurrentCultureIgnoreCase));
if (adminUserFromDb != null)
{
// Let's update the user
adminUserFromDb.Email = plexAdmin.email;
adminUserFromDb.UserName = plexAdmin.username;
adminUserFromDb.ProviderUserId = plexAdmin.id;
await _userManager.UpdateAsync(adminUserFromDb);
return;
}
var newUser = new OmbiUser
{
UserType = UserType.PlexUser,
UserName = plexAdmin.username ?? plexAdmin.id,
ProviderUserId = plexAdmin.id,
Email = plexAdmin.email ?? string.Empty,
Alias = string.Empty
};
var result = await _userManager.CreateAsync(newUser);
if (!LogResult(result))
{
return;
}
var roleResult = await _userManager.AddToRoleAsync(newUser, OmbiRoles.Admin);
LogResult(roleResult);
}
private bool LogResult(IdentityResult result)
{
if (!result.Succeeded)
{
foreach (var identityError in result.Errors)
{
_log.LogError(LoggingEvents.PlexUserImporter, identityError.Description);
}
}
return result.Succeeded;
}
}
}

@ -13,8 +13,6 @@ namespace Ombi.Core.Settings.Models.External
public class PlexServers : ExternalSettings
{
public string Name { get; set; }
public bool EnableEpisodeSearching { get; set; }
public string PlexAuthToken { get; set; }
public string MachineIdentifier { get; set; }

@ -4,6 +4,7 @@ namespace Ombi.Settings.Settings.Models
{
public class UserManagementSettings : Settings
{
public bool ImportPlexAdmin { get; set; }
public bool ImportPlexUsers { get; set; }
public bool ImportEmbyUsers { get; set; }
public List<string> DefaultRoles { get; set; } = new List<string>();

@ -1,5 +1,5 @@
using Microsoft.AspNetCore.Authorization;
using Ombi.Core.Claims;
using Ombi.Helpers;
namespace Ombi.Attributes
{

@ -1,5 +1,7 @@
<p-growl [value]="notificationService.messages" [life]="3000"></p-growl>
<div *ngIf="user.name">
<div *ngIf="hasRole('Admin') || hasRole('PowerUser')" class="adminUser"></div>
</div>
<nav *ngIf="showNav" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">

@ -121,7 +121,8 @@ export interface IAuthenticationSettings extends ISettings {
}
export interface IUserManagementSettings extends ISettings {
importPlexUsers: boolean;
importPlexUsers: boolean;
importPlexAdmin: boolean;
importEmbyUsers: boolean;
defaultRoles: string[];
bannedPlexUserIds: string[];

@ -14,6 +14,12 @@ export interface IUser {
checked: boolean;
}
export interface ICreateWizardUser {
username: string;
password: string;
usePlexAdminAccount: boolean;
}
export enum UserType {
LocalUser = 1,
PlexUser = 2,

@ -28,7 +28,7 @@ export class MovieSearchComponent implements OnInit {
private readonly translate: TranslateService, private sanitizer: DomSanitizer) {
this.searchChanged
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
.debounceTime(600) // Wait Xms after the last event before emitting last event
.distinctUntilChanged() // only emit if value is different from previous value
.subscribe(x => {
this.searchText = x as string;
@ -40,9 +40,9 @@ export class MovieSearchComponent implements OnInit {
.subscribe(x => {
this.movieResults = x;
this.searchApplied = true;
// Now let's load some exta info including IMDBId
// Now let's load some extra info including IMDB Id
// This way the search is fast at displaying results.
this.getExtaInfo();
this.getExtraInfo();
});
});
}
@ -103,7 +103,7 @@ export class MovieSearchComponent implements OnInit {
this.searchService.popularMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
this.getExtraInfo();
});
}
public nowPlayingMovies() {
@ -111,7 +111,7 @@ export class MovieSearchComponent implements OnInit {
this.searchService.nowPlayingMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
this.getExtraInfo();
});
}
public topRatedMovies() {
@ -119,19 +119,19 @@ export class MovieSearchComponent implements OnInit {
this.searchService.topRatedMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
this.getExtraInfo();
});
}
public upcomingMovies() {
this.clearResults();
this.searchService.upcomignMovies()
this.searchService.upcomingMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
this.getExtraInfo();
});
}
private getExtaInfo() {
private getExtraInfo() {
this.movieResults.forEach((val, index) => {

@ -122,7 +122,7 @@ export class MovieSearchGridComponent implements OnInit {
}
public upcomingMovies() {
this.clearResults();
this.searchService.upcomignMovies()
this.searchService.upcomingMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
@ -130,7 +130,7 @@ export class MovieSearchGridComponent implements OnInit {
}
private getExtaInfo() {
this.movieResults.forEach((val, index) => {
this.movieResults.forEach((val) => {
this.searchService.getMovieInformation(val.id)
.subscribe(m => this.updateItem(val, m));
});

@ -4,7 +4,7 @@ import { Http } from "@angular/http";
import { AuthHttp } from "angular2-jwt";
import { Observable } from "rxjs/Rx";
import { ICheckbox, IIdentityResult, IResetPasswordToken, IUpdateLocalUser, IUser } from "../interfaces";
import { ICheckbox, ICreateWizardUser, IIdentityResult, IResetPasswordToken, IUpdateLocalUser, IUser } from "../interfaces";
import { ServiceAuthHelpers } from "./service.helpers";
@Injectable()
@ -12,8 +12,8 @@ export class IdentityService extends ServiceAuthHelpers {
constructor(http: AuthHttp, private regularHttp: Http, public platformLocation: PlatformLocation) {
super(http, "/api/v1/Identity/", platformLocation);
}
public createWizardUser(username: string, password: string): Observable<boolean> {
return this.regularHttp.post(`${this.url}Wizard/`, JSON.stringify({ username, password }), { headers: this.headers }).map(this.extractData);
public createWizardUser(user: ICreateWizardUser): Observable<boolean> {
return this.regularHttp.post(`${this.url}Wizard/`, JSON.stringify(user), { headers: this.headers }).map(this.extractData);
}
public getUser(): Observable<IUser> {

@ -22,7 +22,7 @@ export class SearchService extends ServiceAuthHelpers {
public popularMovies(): Observable<ISearchMovieResult[]> {
return this.http.get(`${this.url}/Movie/Popular`).map(this.extractData);
}
public upcomignMovies(): Observable<ISearchMovieResult[]> {
public upcomingMovies(): Observable<ISearchMovieResult[]> {
return this.http.get(`${this.url}/Movie/upcoming`).map(this.extractData);
}
public nowPlayingMovies(): Observable<ISearchMovieResult[]> {

@ -13,6 +13,13 @@
<label for="importPlex">Import Plex Users</label>
</div>
</div>
<div class="form-group">
<div class="checkbox">
<input type="checkbox" id="importAdmin" [(ngModel)]="settings.importPlexAdmin">
<label for="importAdmin">Import Plex Admin</label>
</div>
</div>
<div *ngIf="plexUsers">
<p>Plex Users exclude from Import</p>

@ -1,21 +1,6 @@
<h1>User Management</h1>
<!--Search-->
<div class="row">
<div class="form-group">
<div class="input-group">
<div class="input-group-addon left-radius">
<i class="fa fa-search"></i>
</div>
<input type="text" class="form-control" id="search" placeholder="Search" [(ngModel)]="searchTerm">
</div>
</div>
</div>
<button type="button" class="btn btn-success-outline" [routerLink]="['/usermanagement/add']">Add User</button>
<!-- Table -->

@ -18,7 +18,7 @@ export class CreateAdminComponent {
private router: Router, private auth: AuthService, private settings: SettingsService) { }
public createUser() {
this.identityService.createWizardUser(this.username, this.password).subscribe(x => {
this.identityService.createWizardUser({username: this.username, password: this.password, usePlexAdminAccount: false}).subscribe(x => {
if (x) {
// Log me in.
this.auth.login({ username: this.username, password: this.password, rememberMe:false }).subscribe(c => {

@ -22,4 +22,6 @@
</div>
</div>
</div>
</div>
</div>
<p-confirmDialog></p-confirmDialog>

@ -1,8 +1,11 @@
import { Component } from "@angular/core";
import { Router } from "@angular/router";
import { ConfirmationService } from "primeng/primeng";
import { PlexService } from "../../services";
import { NotificationService } from "../../services";
import { IdentityService, NotificationService, SettingsService } from "../../services";
import { AuthService } from "./../../auth/auth.service";
@Component({
templateUrl: "./plex.component.html",
@ -12,7 +15,12 @@ export class PlexComponent {
public login: string;
public password: string;
constructor(private plexService: PlexService, private router: Router, private notificationService: NotificationService) { }
constructor(private plexService: PlexService, private router: Router,
private notificationService: NotificationService,
private confirmationService: ConfirmationService,
private identityService: IdentityService,
private settings: SettingsService,
private auth: AuthService) { }
public requestAuthToken() {
this.plexService.logIn(this.login, this.password).subscribe(x => {
@ -20,7 +28,46 @@ export class PlexComponent {
this.notificationService.error("Username or password was incorrect. Could not authenticate with Plex.");
return;
}
this.router.navigate(["Wizard/CreateAdmin"]);
this.confirmationService.confirm({
message: "Do you want your Plex user to be the main admin account on Ombi?",
header: "Use Plex Account",
icon: "fa fa-check",
accept: () => {
this.identityService.createWizardUser({
username: "",
password: "",
usePlexAdminAccount: true,
}).subscribe(x => {
if (x) {
this.auth.login({ username: this.login, password: this.password, rememberMe:false }).subscribe(c => {
localStorage.setItem("id_token", c.access_token);
// Mark that we have done the settings now
this.settings.getOmbi().subscribe(ombi => {
ombi.wizard = true;
this.settings.saveOmbi(ombi).subscribe(x => {
this.settings.getUserManagementSettings().subscribe(usr => {
usr.importPlexAdmin = true;
this.settings.saveUserManagementSettings(usr).subscribe(saved => {
this.router.navigate(["login"]);
});
});
});
});
});
} else {
this.notificationService.error("Could not get the Plex Admin Information");
return;
}
});
},
reject: () => {
this.router.navigate(["Wizard/CreateAdmin"]);
},
});
});
}
}

@ -3,6 +3,8 @@ import { NgModule } from "@angular/core";
import { FormsModule } from "@angular/forms";
import { RouterModule, Routes } from "@angular/router";
import {ConfirmationService, ConfirmDialogModule } from "primeng/primeng";
import { CreateAdminComponent } from "./createadmin/createadmin.component";
import { EmbyComponent } from "./emby/emby.component";
import { MediaServerComponent } from "./mediaserver/mediaserver.component";
@ -25,6 +27,7 @@ const routes: Routes = [
imports: [
CommonModule,
FormsModule,
ConfirmDialogModule,
RouterModule.forChild(routes),
],
declarations: [
@ -41,6 +44,7 @@ const routes: Routes = [
PlexService,
IdentityService,
EmbyService,
ConfirmationService,
],
})

@ -43,32 +43,30 @@ namespace Ombi.Controllers.External
{
try
{
// Do we already have settings?
_log.LogDebug("OK, signing into Plex");
var settings = await PlexSettings.GetSettingsAsync();
if (!settings.Servers?.Any() ?? false) return null;
// Do we already have settings?
_log.LogDebug("OK, signing into Plex");
var settings = await PlexSettings.GetSettingsAsync();
if (!settings.Servers?.Any() ?? false) return null;
_log.LogDebug("This is our first time, good to go!");
_log.LogDebug("This is our first time, good to go!");
var result = await PlexApi.SignIn(request);
var result = await PlexApi.SignIn(request);
_log.LogDebug("Attempting to sign in to Plex.Tv");
if (!string.IsNullOrEmpty(result.user?.authentication_token))
{
_log.LogDebug("Sign in successful");
_log.LogDebug("Getting servers");
var server = await PlexApi.GetServer(result.user.authentication_token);
var servers = server.Server.FirstOrDefault();
if (servers == null)
_log.LogDebug("Attempting to sign in to Plex.Tv");
if (!string.IsNullOrEmpty(result.user?.authentication_token))
{
_log.LogWarning("Looks like we can't find any Plex Servers");
}
_log.LogDebug("Adding first server");
_log.LogDebug("Sign in successful");
_log.LogDebug("Getting servers");
var server = await PlexApi.GetServer(result.user.authentication_token);
var servers = server.Server.FirstOrDefault();
if (servers == null)
{
_log.LogWarning("Looks like we can't find any Plex Servers");
}
_log.LogDebug("Adding first server");
settings.Enable = true;
settings.Servers = new List<PlexServers> {
settings.Enable = true;
settings.Servers = new List<PlexServers> {
new PlexServers
{
PlexAuthToken = result.user.authentication_token,
@ -81,11 +79,11 @@ namespace Ombi.Controllers.External
}
};
await PlexSettings.SaveSettingsAsync(settings);
}
await PlexSettings.SaveSettingsAsync(settings);
}
_log.LogDebug("Finished");
return result;
_log.LogDebug("Finished");
return result;
}
catch (Exception e)
{

@ -12,14 +12,15 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Ombi.Api.Plex;
using Ombi.Attributes;
using Ombi.Config;
using Ombi.Core.Authentication;
using Ombi.Core.Claims;
using Ombi.Core.Helpers;
using Ombi.Core.Models.UI;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Models;
using Ombi.Models.Identity;
using Ombi.Notifications;
@ -35,6 +36,7 @@ using OmbiIdentityResult = Ombi.Models.Identity.IdentityResult;
namespace Ombi.Controllers
{
/// <inheritdoc />
/// <summary>
/// The Identity Controller, the API for everything Identity/User related
/// </summary>
@ -48,7 +50,9 @@ namespace Ombi.Controllers
IWelcomeEmail welcome,
IMovieRequestRepository m,
ITvRequestRepository t,
ILogger<IdentityController> l)
ILogger<IdentityController> l,
IPlexApi plexApi,
ISettingsService<PlexSettings> settings)
{
UserManager = user;
Mapper = mapper;
@ -60,6 +64,8 @@ namespace Ombi.Controllers
MovieRepo = m;
TvRepo = t;
_log = l;
_plexApi = plexApi;
_plexSettings = settings;
}
private OmbiUserManager UserManager { get; }
@ -71,7 +77,9 @@ namespace Ombi.Controllers
private IWelcomeEmail WelcomeEmail { get; }
private IMovieRequestRepository MovieRepo { get; }
private ITvRequestRepository TvRepo { get; }
private ILogger<IdentityController> _log;
private readonly ILogger<IdentityController> _log;
private readonly IPlexApi _plexApi;
private readonly ISettingsService<PlexSettings> _plexSettings;
/// <summary>
/// This is what the Wizard will call when creating the user for the very first time.
@ -85,7 +93,7 @@ namespace Ombi.Controllers
[HttpPost("Wizard")]
[ApiExplorerSettings(IgnoreApi = true)]
[AllowAnonymous]
public async Task<bool> CreateWizardUser([FromBody] UserAuthModel user)
public async Task<bool> CreateWizardUser([FromBody] CreateUserWizardModel user)
{
var users = UserManager.Users;
if (users.Any())
@ -94,13 +102,48 @@ namespace Ombi.Controllers
return false;
}
if (user.UsePlexAdminAccount)
{
var settings = await _plexSettings.GetSettingsAsync();
var authToken = settings.Servers.FirstOrDefault()?.PlexAuthToken ?? string.Empty;
if (authToken.IsNullOrEmpty())
{
_log.LogWarning("Could not find an auth token to create the plex user with");
return false;
}
var plexUser = await _plexApi.GetAccount(authToken);
var adminUser = new OmbiUser
{
UserName = plexUser.user.username,
UserType = UserType.PlexUser,
Email = plexUser.user.email,
ProviderUserId = plexUser.user.id
};
return await SaveWizardUser(user, adminUser);
}
var userToCreate = new OmbiUser
{
UserName = user.Username,
UserType = UserType.LocalUser
};
var result = await UserManager.CreateAsync(userToCreate, user.Password);
return await SaveWizardUser(user, userToCreate);
}
private async Task<bool> SaveWizardUser(CreateUserWizardModel user, OmbiUser userToCreate)
{
IdentityResult result;
// When creating the admin as the plex user, we do not pass in the password.
if (user.Password.HasValue())
{
result = await UserManager.CreateAsync(userToCreate, user.Password);
}
else
{
result = await UserManager.CreateAsync(userToCreate);
}
if (result.Succeeded)
{
_log.LogInformation("Created User {0}", userToCreate.UserName);
@ -319,7 +362,7 @@ namespace Ombi.Controllers
{
return Error("You need to provide your current password to make any changes");
}
var changingPass = !string.IsNullOrEmpty(ui.Password) || !string.IsNullOrEmpty(ui.ConfirmNewPassword);
if (changingPass)
@ -457,7 +500,7 @@ namespace Ombi.Controllers
{
return Error("You do not have the correct permissions to delete this user");
}
// We need to delete all the requests first
var moviesUserRequested = MovieRepo.GetAll().Where(x => x.RequestedUserId == userId);
var tvUserRequested = TvRepo.GetChild().Where(x => x.RequestedUserId == userId);

@ -10,7 +10,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Ombi.Core.Authentication;
using Ombi.Core.Claims;
using Ombi.Helpers;
using Ombi.Models;
using Ombi.Models.Identity;
using Ombi.Store.Entities;

@ -0,0 +1,9 @@
namespace Ombi.Models
{
public class CreateUserWizardModel
{
public string Username { get; set; }
public string Password { get; set; }
public bool UsePlexAdminAccount { get; set; }
}
}

@ -5,5 +5,6 @@
public string Username { get; set; }
public string Password { get; set; }
public bool RememberMe { get; set; }
public bool UsePlexAdminAccount { get; set; }
}
}
Loading…
Cancel
Save