mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 21:03:17 -07:00
Fixed #1583 you can now delete users.
Fixed the issue where the requested by was not showing. Finally fixed the broken poster paths
This commit is contained in:
parent
c3b2ef2f31
commit
1dc8eac035
27 changed files with 157 additions and 155 deletions
|
@ -13,5 +13,6 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
RequestCountModel RequestCount();
|
RequestCountModel RequestCount();
|
||||||
Task<IEnumerable<T>> GetRequests(int count, int position);
|
Task<IEnumerable<T>> GetRequests(int count, int position);
|
||||||
Task<IEnumerable<T>> GetRequests();
|
Task<IEnumerable<T>> GetRequests();
|
||||||
|
Task<bool> UserHasRequest(string userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -120,7 +120,10 @@ namespace Ombi.Core.Engine
|
||||||
public async Task<IEnumerable<MovieRequests>> GetRequests(int count, int position)
|
public async Task<IEnumerable<MovieRequests>> GetRequests(int count, int position)
|
||||||
{
|
{
|
||||||
var allRequests = await MovieRepository.GetWithUser().Skip(position).Take(count).ToListAsync();
|
var allRequests = await MovieRepository.GetWithUser().Skip(position).Take(count).ToListAsync();
|
||||||
allRequests.ForEach(x => PosterPathHelper.FixPosterPath(x.PosterPath));
|
allRequests.ForEach(x =>
|
||||||
|
{
|
||||||
|
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
|
||||||
|
});
|
||||||
return allRequests;
|
return allRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +261,11 @@ namespace Ombi.Core.Engine
|
||||||
await MovieRepository.Delete(request);
|
await MovieRepository.Delete(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UserHasRequest(string userId)
|
||||||
|
{
|
||||||
|
return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName)
|
private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName)
|
||||||
{
|
{
|
||||||
await MovieRepository.Add(model);
|
await MovieRepository.Add(model);
|
||||||
|
|
|
@ -242,6 +242,11 @@ namespace Ombi.Core.Engine
|
||||||
await TvRepository.Delete(request);
|
await TvRepository.Delete(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UserHasRequest(string userId)
|
||||||
|
{
|
||||||
|
return await TvRepository.GetChild().AnyAsync(x => x.RequestedUserId == userId);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<RequestEngineResult> AddExistingRequest(ChildRequests newRequest, TvRequests existingRequest)
|
private async Task<RequestEngineResult> AddExistingRequest(ChildRequests newRequest, TvRequests existingRequest)
|
||||||
{
|
{
|
||||||
// Add the child
|
// Add the child
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace Ombi.Core.Models.UI
|
||||||
public class UserViewModel
|
public class UserViewModel
|
||||||
{
|
{
|
||||||
public string Id { get; set; }
|
public string Id { get; set; }
|
||||||
public string Username { get; set; }
|
public string UserName { get; set; }
|
||||||
public string Alias { get; set; }
|
public string Alias { get; set; }
|
||||||
public List<ClaimCheckboxes> Claims { get; set; }
|
public List<ClaimCheckboxes> Claims { get; set; }
|
||||||
public string EmailAddress { get; set; }
|
public string EmailAddress { get; set; }
|
||||||
|
|
|
@ -4,6 +4,7 @@ using Ombi.Core.Rule.Interfaces;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
|
using Ombi.Store.Repository.Requests;
|
||||||
|
|
||||||
namespace Ombi.Core.Rule.Rules.Request
|
namespace Ombi.Core.Rule.Rules.Request
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,8 @@ namespace Ombi.Store.Repository
|
||||||
IQueryable<T> GetAll();
|
IQueryable<T> GetAll();
|
||||||
Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate);
|
Task<T> FirstOrDefaultAsync(Expression<Func<T, bool>> predicate);
|
||||||
Task AddRange(IEnumerable<T> content);
|
Task AddRange(IEnumerable<T> content);
|
||||||
|
Task DeleteRange(IEnumerable<T> req);
|
||||||
|
Task Delete(T request);
|
||||||
|
|
||||||
IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
|
IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
|
||||||
IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath)
|
IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath)
|
||||||
|
|
|
@ -48,6 +48,18 @@ namespace Ombi.Store.Repository
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task Delete(T request)
|
||||||
|
{
|
||||||
|
_db.Remove(request);
|
||||||
|
await _ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task DeleteRange(IEnumerable<T> req)
|
||||||
|
{
|
||||||
|
_db.RemoveRange(req);
|
||||||
|
await _ctx.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
|
public IIncludableQueryable<TEntity, TProperty> Include<TEntity, TProperty>(
|
||||||
IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath)
|
IQueryable<TEntity> source, Expression<Func<TEntity, TProperty>> navigationPropertyPath)
|
||||||
where TEntity : class
|
where TEntity : class
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
|
|
||||||
namespace Ombi.Store.Repository
|
namespace Ombi.Store.Repository.Requests
|
||||||
{
|
{
|
||||||
public interface IMovieRequestRepository : IRepository<MovieRequests>
|
public interface IMovieRequestRepository : IRepository<MovieRequests>
|
||||||
{
|
{
|
||||||
Task<MovieRequests> Add(MovieRequests request);
|
Task<MovieRequests> Add(MovieRequests request);
|
||||||
Task Delete(MovieRequests request);
|
|
||||||
Task<MovieRequests> GetRequestAsync(int theMovieDbId);
|
Task<MovieRequests> GetRequestAsync(int theMovieDbId);
|
||||||
MovieRequests GetRequest(int theMovieDbId);
|
MovieRequests GetRequest(int theMovieDbId);
|
||||||
Task Update(MovieRequests request);
|
Task Update(MovieRequests request);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
using Ombi.Store.Entities.Requests;
|
using Ombi.Store.Entities.Requests;
|
||||||
|
@ -19,5 +20,6 @@ namespace Ombi.Store.Repository.Requests
|
||||||
Task UpdateChild(ChildRequests request);
|
Task UpdateChild(ChildRequests request);
|
||||||
IQueryable<ChildRequests> GetChild();
|
IQueryable<ChildRequests> GetChild();
|
||||||
Task Save();
|
Task Save();
|
||||||
|
Task DeleteChildRange(IEnumerable<ChildRequests> request);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
@ -46,12 +47,6 @@ namespace Ombi.Store.Repository.Requests
|
||||||
.AsQueryable();
|
.AsQueryable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Delete(MovieRequests request)
|
|
||||||
{
|
|
||||||
Db.MovieRequests.Remove(request);
|
|
||||||
await Db.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Update(MovieRequests request)
|
public async Task Update(MovieRequests request)
|
||||||
{
|
{
|
||||||
if (Db.Entry(request).State == EntityState.Detached)
|
if (Db.Entry(request).State == EntityState.Detached)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
|
@ -89,6 +90,12 @@ namespace Ombi.Store.Repository.Requests
|
||||||
await Db.SaveChangesAsync();
|
await Db.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task DeleteChildRange(IEnumerable<ChildRequests> request)
|
||||||
|
{
|
||||||
|
Db.ChildRequests.RemoveRange(request);
|
||||||
|
await Db.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Update(TvRequests request)
|
public async Task Update(TvRequests request)
|
||||||
{
|
{
|
||||||
Db.Update(request);
|
Db.Update(request);
|
||||||
|
|
5
src/Ombi/.vscode/settings.json
vendored
Normal file
5
src/Ombi/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"usermanagement"
|
||||||
|
]
|
||||||
|
}
|
|
@ -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, TooltipModule } from "primeng/primeng";
|
import { ButtonModule, CaptchaModule,ConfirmationService, ConfirmDialogModule, DataTableModule,DialogModule, SharedModule, TooltipModule } from "primeng/primeng";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import { AppComponent } from "./app.component";
|
import { AppComponent } from "./app.component";
|
||||||
|
@ -80,6 +80,7 @@ const routes: Routes = [
|
||||||
RequestsModule,
|
RequestsModule,
|
||||||
CaptchaModule,
|
CaptchaModule,
|
||||||
TooltipModule,
|
TooltipModule,
|
||||||
|
ConfirmDialogModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
@ -98,6 +99,7 @@ const routes: Routes = [
|
||||||
IdentityService,
|
IdentityService,
|
||||||
StatusService,
|
StatusService,
|
||||||
LandingPageService,
|
LandingPageService,
|
||||||
|
ConfirmationService,
|
||||||
ImageService,
|
ImageService,
|
||||||
//DragulaService
|
//DragulaService
|
||||||
],
|
],
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
export interface IUser {
|
export interface IUser {
|
||||||
id: string;
|
id: string;
|
||||||
username: string;
|
userName: string;
|
||||||
alias: string;
|
alias: string;
|
||||||
claims: ICheckbox[];
|
claims: ICheckbox[];
|
||||||
emailAddress: string;
|
emailAddress: string;
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
<br />
|
<br />
|
||||||
<div>
|
<div>
|
||||||
<span>Requested By: </span>
|
<span>Requested By: </span>
|
||||||
<span *ngIf="!isAdmin">{{request.requestedUser.username}}</span>
|
<span *ngIf="!isAdmin">{{request.requestedUser.userName}}</span>
|
||||||
<span *ngIf="isAdmin && request.requestedUser.alias">{{request.requestedUser.alias}}</span>
|
<span *ngIf="isAdmin && request.requestedUser.alias">{{request.requestedUser.alias}}</span>
|
||||||
<span *ngIf="isAdmin && !request.requestedUser.alias">{{request.requestedUser.username}}</span>
|
<span *ngIf="isAdmin && !request.requestedUser.alias">{{request.requestedUser.userName}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span>Status: </span>
|
<span>Status: </span>
|
||||||
|
|
|
@ -47,6 +47,10 @@ export class IdentityService extends ServiceAuthHelpers {
|
||||||
return this.http.delete(`${this.url}${user.id}`, { headers: this.headers }).map(this.extractData);
|
return this.http.delete(`${this.url}${user.id}`, { headers: this.headers }).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public hasUserRequested(userId: string): Observable<boolean> {
|
||||||
|
return this.http.get(`${this.url}userhasrequest/${userId}`).map(this.extractData);
|
||||||
|
}
|
||||||
|
|
||||||
public submitResetPassword(email: string): Observable<IIdentityResult> {
|
public submitResetPassword(email: string): Observable<IIdentityResult> {
|
||||||
return this.regularHttp.post(this.url + "reset", JSON.stringify({email}), { headers: this.headers }).map(this.extractData);
|
return this.regularHttp.post(this.url + "reset", JSON.stringify({email}), { headers: this.headers }).map(this.extractData);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export class UpdateDetailsComponent implements OnInit {
|
||||||
const localUser = x as IUpdateLocalUser;
|
const localUser = x as IUpdateLocalUser;
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
id:[localUser.id],
|
id:[localUser.id],
|
||||||
username: [localUser.username],
|
username: [localUser.userName],
|
||||||
emailAddress: [localUser.emailAddress, [Validators.email]],
|
emailAddress: [localUser.emailAddress, [Validators.email]],
|
||||||
confirmNewPassword: [localUser.confirmNewPassword],
|
confirmNewPassword: [localUser.confirmNewPassword],
|
||||||
currentPassword: [localUser.currentPassword, [Validators.required]],
|
currentPassword: [localUser.currentPassword, [Validators.required]],
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username" class="control-label">Username</label>
|
<label for="username" class="control-label">Username</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" [(ngModel)]="user.username" class="form-control form-control-custom " id="username" name="username" value="{{user?.username}}">
|
<input type="text" [(ngModel)]="user.userName" class="form-control form-control-custom " id="username" name="username" value="{{user?.userName}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -24,7 +24,7 @@ export class UserManagementAddComponent implements OnInit {
|
||||||
emailAddress: "",
|
emailAddress: "",
|
||||||
id: "",
|
id: "",
|
||||||
password: "",
|
password: "",
|
||||||
username: "",
|
userName: "",
|
||||||
userType: UserType.LocalUser,
|
userType: UserType.LocalUser,
|
||||||
checked:false,
|
checked:false,
|
||||||
hasLoggedIn: false,
|
hasLoggedIn: false,
|
||||||
|
@ -54,7 +54,7 @@ export class UserManagementAddComponent implements OnInit {
|
||||||
|
|
||||||
this.identityService.createUser(this.user).subscribe(x => {
|
this.identityService.createUser(this.user).subscribe(x => {
|
||||||
if (x.successful) {
|
if (x.successful) {
|
||||||
this.notificationSerivce.success("Updated", `The user ${this.user.username} has been created successfully`);
|
this.notificationSerivce.success("Updated", `The user ${this.user.userName} has been created successfully`);
|
||||||
this.router.navigate(["usermanagement"]);
|
this.router.navigate(["usermanagement"]);
|
||||||
} else {
|
} else {
|
||||||
x.errors.forEach((val) => {
|
x.errors.forEach((val) => {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
<div *ngIf="user">
|
<div *ngIf="user">
|
||||||
<h3>User: {{user.username}}</h3>
|
<h3>User: {{user.userName}}</h3>
|
||||||
<button type="button" class="btn btn-primary-outline" style="float:right;" [routerLink]="['/usermanagement/']">Back</button>
|
<button type="button" class="btn btn-primary-outline" style="float:right;" [routerLink]="['/usermanagement/']">Back</button>
|
||||||
|
|
||||||
|
|
||||||
|
<p-confirmDialog></p-confirmDialog>
|
||||||
|
|
||||||
<div class="modal-body" style="margin-top: 45px;">
|
<div class="modal-body" style="margin-top: 45px;">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<h4>User Details</h4>
|
<h4>User Details</h4>
|
||||||
|
@ -14,7 +16,7 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="username" class="control-label">Username</label>
|
<label for="username" class="control-label">Username</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" [(ngModel)]="user.username" [readonly]="true" class="form-control form-control-custom " id="username" name="username" value="{{user?.username}}">
|
<input type="text" [(ngModel)]="user.userName" [readonly]="true" class="form-control form-control-custom " id="username" name="username" value="{{user?.userName}}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { Router } from "@angular/router";
|
import { Router } from "@angular/router";
|
||||||
|
import { ConfirmationService } from "primeng/primeng";
|
||||||
|
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute } from "@angular/router";
|
||||||
import { IUser } from "../interfaces";
|
import { IUser } from "../interfaces";
|
||||||
|
@ -15,8 +16,9 @@ export class UserManagementEditComponent {
|
||||||
|
|
||||||
constructor(private identityService: IdentityService,
|
constructor(private identityService: IdentityService,
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private notificationSerivce: NotificationService,
|
private notificationService: NotificationService,
|
||||||
private router: Router) {
|
private router: Router,
|
||||||
|
private confirmationService: ConfirmationService) {
|
||||||
this.route.params
|
this.route.params
|
||||||
.subscribe((params: any) => {
|
.subscribe((params: any) => {
|
||||||
this.userId = params.id;
|
this.userId = params.id;
|
||||||
|
@ -28,27 +30,38 @@ export class UserManagementEditComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public delete() {
|
public delete() {
|
||||||
|
|
||||||
|
this.confirmationService.confirm({
|
||||||
|
message: "Are you sure that you want to delete this user? If this user has any requests they will also be deleted.",
|
||||||
|
header: "Are you sure?",
|
||||||
|
icon: "fa fa-trash",
|
||||||
|
accept: () => {
|
||||||
this.identityService.deleteUser(this.user).subscribe(x => {
|
this.identityService.deleteUser(this.user).subscribe(x => {
|
||||||
if (x.successful) {
|
if (x.successful) {
|
||||||
this.notificationSerivce.success("Deleted", `The user ${this.user.username} was deleted`);
|
this.notificationService.success("Deleted", `The user ${this.user.userName} was deleted`);
|
||||||
this.router.navigate(["usermanagement"]);
|
this.router.navigate(["usermanagement"]);
|
||||||
} else {
|
} else {
|
||||||
x.errors.forEach((val) => {
|
x.errors.forEach((val) => {
|
||||||
this.notificationSerivce.error("Error", val);
|
this.notificationService.error("Error", val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
reject: () => {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public resetPassword() {
|
public resetPassword() {
|
||||||
this.identityService.submitResetPassword(this.user.emailAddress).subscribe(x => {
|
this.identityService.submitResetPassword(this.user.emailAddress).subscribe(x => {
|
||||||
if (x.successful) {
|
if (x.successful) {
|
||||||
this.notificationSerivce.success("Reset", `Sent reset password email to ${this.user.emailAddress}`);
|
this.notificationService.success("Reset", `Sent reset password email to ${this.user.emailAddress}`);
|
||||||
this.router.navigate(["usermanagement"]);
|
this.router.navigate(["usermanagement"]);
|
||||||
} else {
|
} else {
|
||||||
x.errors.forEach((val) => {
|
x.errors.forEach((val) => {
|
||||||
this.notificationSerivce.error("Error", val);
|
this.notificationService.error("Error", val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,17 +76,17 @@ export class UserManagementEditComponent {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!hasClaims) {
|
if (!hasClaims) {
|
||||||
this.notificationSerivce.error("Error", "Please assign a role");
|
this.notificationService.error("Error", "Please assign a role");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.identityService.updateUser(this.user).subscribe(x => {
|
this.identityService.updateUser(this.user).subscribe(x => {
|
||||||
if (x.successful) {
|
if (x.successful) {
|
||||||
this.notificationSerivce.success("Updated", `The user ${this.user.username} has been updated successfully`);
|
this.notificationService.success("Updated", `The user ${this.user.userName} has been updated successfully`);
|
||||||
this.router.navigate(["usermanagement"]);
|
this.router.navigate(["usermanagement"]);
|
||||||
} else {
|
} else {
|
||||||
x.errors.forEach((val) => {
|
x.errors.forEach((val) => {
|
||||||
this.notificationSerivce.error("Error", val);
|
this.notificationService.error("Error", val);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
<input type="checkbox" [(ngModel)]="u.checked">
|
<input type="checkbox" [(ngModel)]="u.checked">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{u.username}}
|
{{u.userName}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{u.alias}}
|
{{u.alias}}
|
||||||
|
@ -97,108 +97,4 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="modal fade in" *ngIf="showEditDialog" style="display: block;">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" (click)="showEditDialog=false">×</button>
|
|
||||||
<h4 class="modal-title">Editing User {{selectedUser?.username}}</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="username" class="control-label">Username</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" [(ngModel)]="selectedUser.username" [readonly]="true" class="form-control form-control-custom " id="username" name="username" value="{{selectedUser?.username}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="alias" class="control-label">Alias</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" [(ngModel)]="selectedUser.alias" class="form-control form-control-custom " id="alias" name="alias" value="{{selectedUser?.alias}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="alias" class="control-label">Email Address</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" [(ngModel)]="selectedUser.emailAddress" class="form-control form-control-custom " id="emailAddress" name="emailAddress" value="{{selectedUser?.emailAddress}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngFor="let c of selectedUser.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>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-danger-outline" (click)="showEditDialog=false">Close</button>
|
|
||||||
<button type="button" class="btn btn-primary-outline" (click)="updateUser()">Save changes</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="modal fade in " *ngIf="showCreateDialogue" style="display: block;">
|
|
||||||
<div class="modal-dialog">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<button type="button" class="close" (click)="showCreateDialogue=false">×</button>
|
|
||||||
<h4 class="modal-title">Create User</h4>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="username" class="control-label">Username</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" [(ngModel)]="createdUser.username" class="form-control form-control-custom " id="username" name="username" value="{{createdUser?.username}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="alias" class="control-label">Alias</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" [(ngModel)]="createdUser.alias" class="form-control form-control-custom " id="alias" name="alias" value="{{createdUser?.alias}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="emailAddress" class="control-label">Email Address</label>
|
|
||||||
<div>
|
|
||||||
<input type="text" [(ngModel)]="createdUser.emailAddress" class="form-control form-control-custom " id="emailAddress" name="emailAddress" value="{{createdUser?.emailAddress}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="password" class="control-label">Password</label>
|
|
||||||
<div>
|
|
||||||
<input type="password" [(ngModel)]="createdUser.password" class="form-control form-control-custom " id="password" name="password" value="{{createdUser?.password}}">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div *ngFor="let c of availableClaims">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-danger-outline" (click)="showCreateDialogue=false">Close</button>
|
|
||||||
<button type="button" class="btn btn-primary-outline" (click)="create()">Add User</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -2,7 +2,7 @@
|
||||||
import { NgModule } from "@angular/core";
|
import { NgModule } from "@angular/core";
|
||||||
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
|
||||||
import { RouterModule, Routes } from "@angular/router";
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
import { MultiSelectModule, TooltipModule } from "primeng/primeng";
|
import { ConfirmationService, ConfirmDialogModule, MultiSelectModule, TooltipModule } from "primeng/primeng";
|
||||||
|
|
||||||
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ const routes: Routes = [
|
||||||
NgbModule.forRoot(),
|
NgbModule.forRoot(),
|
||||||
MultiSelectModule,
|
MultiSelectModule,
|
||||||
PipeModule,
|
PipeModule,
|
||||||
|
ConfirmDialogModule,
|
||||||
TooltipModule,
|
TooltipModule,
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
|
@ -46,6 +46,7 @@ const routes: Routes = [
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
IdentityService,
|
IdentityService,
|
||||||
|
ConfirmationService,
|
||||||
],
|
],
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -301,3 +301,13 @@ button.list-group-item:focus {
|
||||||
.ui-state-default {
|
.ui-state-default {
|
||||||
border: 2px solid $bg-colour-disabled;
|
border: 2px solid $bg-colour-disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ui-button {
|
||||||
|
background: $primary-colour $i;
|
||||||
|
border: 1px solid $primary-colour-outline $i;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-dialog-titlebar{
|
||||||
|
background:$bg-colour-disabled;
|
||||||
|
color:white;
|
||||||
|
}
|
|
@ -27,6 +27,8 @@ using Ombi.Schedule.Jobs.Ombi;
|
||||||
using Ombi.Settings.Settings.Models;
|
using Ombi.Settings.Settings.Models;
|
||||||
using Ombi.Settings.Settings.Models.Notifications;
|
using Ombi.Settings.Settings.Models.Notifications;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
|
using Ombi.Store.Repository;
|
||||||
|
using Ombi.Store.Repository.Requests;
|
||||||
using OmbiIdentityResult = Ombi.Models.Identity.IdentityResult;
|
using OmbiIdentityResult = Ombi.Models.Identity.IdentityResult;
|
||||||
|
|
||||||
namespace Ombi.Controllers
|
namespace Ombi.Controllers
|
||||||
|
@ -41,7 +43,9 @@ namespace Ombi.Controllers
|
||||||
public IdentityController(OmbiUserManager user, IMapper mapper, RoleManager<IdentityRole> rm, IEmailProvider prov,
|
public IdentityController(OmbiUserManager user, IMapper mapper, RoleManager<IdentityRole> rm, IEmailProvider prov,
|
||||||
ISettingsService<EmailNotificationSettings> s,
|
ISettingsService<EmailNotificationSettings> s,
|
||||||
ISettingsService<CustomizationSettings> c,
|
ISettingsService<CustomizationSettings> c,
|
||||||
IWelcomeEmail welcome)
|
IWelcomeEmail welcome,
|
||||||
|
IMovieRequestRepository m,
|
||||||
|
ITvRequestRepository t)
|
||||||
{
|
{
|
||||||
UserManager = user;
|
UserManager = user;
|
||||||
Mapper = mapper;
|
Mapper = mapper;
|
||||||
|
@ -50,6 +54,8 @@ namespace Ombi.Controllers
|
||||||
EmailSettings = s;
|
EmailSettings = s;
|
||||||
CustomizationSettings = c;
|
CustomizationSettings = c;
|
||||||
WelcomeEmail = welcome;
|
WelcomeEmail = welcome;
|
||||||
|
MovieRepo = m;
|
||||||
|
TvRepo = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OmbiUserManager UserManager { get; }
|
private OmbiUserManager UserManager { get; }
|
||||||
|
@ -59,6 +65,8 @@ namespace Ombi.Controllers
|
||||||
private ISettingsService<EmailNotificationSettings> EmailSettings { get; }
|
private ISettingsService<EmailNotificationSettings> EmailSettings { get; }
|
||||||
private ISettingsService<CustomizationSettings> CustomizationSettings { get; }
|
private ISettingsService<CustomizationSettings> CustomizationSettings { get; }
|
||||||
private IWelcomeEmail WelcomeEmail { get; }
|
private IWelcomeEmail WelcomeEmail { get; }
|
||||||
|
private IMovieRequestRepository MovieRepo { get; }
|
||||||
|
private ITvRequestRepository TvRepo { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is what the Wizard will call when creating the user for the very first time.
|
/// This is what the Wizard will call when creating the user for the very first time.
|
||||||
|
@ -134,7 +142,7 @@ namespace Ombi.Controllers
|
||||||
model.Add(await GetUserWithRoles(user));
|
model.Add(await GetUserWithRoles(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
return model.OrderBy(x => x.Username);
|
return model.OrderBy(x => x.UserName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -169,7 +177,7 @@ namespace Ombi.Controllers
|
||||||
var vm = new UserViewModel
|
var vm = new UserViewModel
|
||||||
{
|
{
|
||||||
Alias = user.Alias,
|
Alias = user.Alias,
|
||||||
Username = user.UserName,
|
UserName = user.UserName,
|
||||||
Id = user.Id,
|
Id = user.Id,
|
||||||
EmailAddress = user.Email,
|
EmailAddress = user.Email,
|
||||||
UserType = (Core.Models.UserType)(int)user.UserType,
|
UserType = (Core.Models.UserType)(int)user.UserType,
|
||||||
|
@ -223,7 +231,7 @@ namespace Ombi.Controllers
|
||||||
{
|
{
|
||||||
Alias = user.Alias,
|
Alias = user.Alias,
|
||||||
Email = user.EmailAddress,
|
Email = user.EmailAddress,
|
||||||
UserName = user.Username,
|
UserName = user.UserName,
|
||||||
UserType = UserType.LocalUser,
|
UserType = UserType.LocalUser,
|
||||||
};
|
};
|
||||||
var userResult = await UserManager.CreateAsync(ombiUser, user.Password);
|
var userResult = await UserManager.CreateAsync(ombiUser, user.Password);
|
||||||
|
@ -423,6 +431,20 @@ namespace Ombi.Controllers
|
||||||
{
|
{
|
||||||
return Error("You do not have the correct permissions to delete this user");
|
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);
|
||||||
|
|
||||||
|
if (moviesUserRequested.Any())
|
||||||
|
{
|
||||||
|
await MovieRepo.DeleteRange(moviesUserRequested);
|
||||||
|
}
|
||||||
|
if (tvUserRequested.Any())
|
||||||
|
{
|
||||||
|
await TvRepo.DeleteChildRange(tvUserRequested);
|
||||||
|
}
|
||||||
|
|
||||||
var result = await UserManager.DeleteAsync(userToDelete);
|
var result = await UserManager.DeleteAsync(userToDelete);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
|
@ -559,7 +581,7 @@ namespace Ombi.Controllers
|
||||||
var ombiUser = new OmbiUser
|
var ombiUser = new OmbiUser
|
||||||
{
|
{
|
||||||
Email = user.EmailAddress,
|
Email = user.EmailAddress,
|
||||||
UserName = user.Username
|
UserName = user.UserName
|
||||||
};
|
};
|
||||||
BackgroundJob.Enqueue(() => WelcomeEmail.SendEmail(ombiUser));
|
BackgroundJob.Enqueue(() => WelcomeEmail.SendEmail(ombiUser));
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,21 @@ namespace Ombi.Controllers
|
||||||
return TvRequestEngine.RequestCount();
|
return TvRequestEngine.RequestCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the passed in user has a request
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("userhasrequest")]
|
||||||
|
public async Task<bool> UserHasRequest(string userId)
|
||||||
|
{
|
||||||
|
var movies = await MovieRequestEngine.UserHasRequest(userId);
|
||||||
|
var tv = await TvRequestEngine.UserHasRequest(userId);
|
||||||
|
|
||||||
|
return movies || tv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///// <summary>
|
///// <summary>
|
||||||
///// Gets the specific grid model for the requests (for modelling the UI).
|
///// Gets the specific grid model for the requests (for modelling the UI).
|
||||||
///// </summary>
|
///// </summary>
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace Ombi.Controllers
|
||||||
public async Task<IActionResult> GetToken([FromBody] UserAuthModel model)
|
public async Task<IActionResult> GetToken([FromBody] UserAuthModel model)
|
||||||
{
|
{
|
||||||
await _audit.Record(AuditType.None, AuditArea.Authentication,
|
await _audit.Record(AuditType.None, AuditArea.Authentication,
|
||||||
$"Username {model.Username} attempting to authenticate");
|
$"UserName {model.Username} attempting to authenticate");
|
||||||
|
|
||||||
var user = await _userManager.FindByNameAsync(model.Username);
|
var user = await _userManager.FindByNameAsync(model.Username);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue