mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-19 21:03:17 -07:00
stuff #865 need to work on the claims correctly
This commit is contained in:
parent
224b942190
commit
b4789363e8
14 changed files with 169 additions and 87 deletions
|
@ -88,6 +88,7 @@ namespace Ombi.Core.IdentityResolver
|
|||
|
||||
public async Task<UserDto> UpdateUser(UserDto userDto)
|
||||
{
|
||||
userDto.Claims.RemoveAll(x => x.Type == ClaimTypes.Country); // This is a hack around the Mapping Profile
|
||||
var user = Mapper.Map<User>(userDto);
|
||||
return Mapper.Map<UserDto>(await UserRepository.UpdateUser(user));
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace Ombi.Store.Context
|
|||
DbSet<PlexContent> PlexContent { get; set; }
|
||||
DbSet<User> Users { get; set; }
|
||||
EntityEntry<GlobalSettings> Entry(GlobalSettings settings);
|
||||
EntityEntry<User> Entry(User settings);
|
||||
EntityEntry<TEntity> Attach<TEntity>(TEntity entity) where TEntity : class;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Resources;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
|
@ -38,7 +39,12 @@ namespace Ombi.Store.Context
|
|||
|
||||
public EntityEntry<GlobalSettings> Entry(GlobalSettings settings)
|
||||
{
|
||||
return Entry(settings);
|
||||
return base.Entry(settings);
|
||||
}
|
||||
|
||||
public EntityEntry<User> Entry(User settings)
|
||||
{
|
||||
return base.Entry(settings);
|
||||
}
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
|
|
|
@ -67,7 +67,9 @@ namespace Ombi.Store.Repository
|
|||
|
||||
public async Task<User> UpdateUser(User user)
|
||||
{
|
||||
Db.Users.Update(user);
|
||||
Db.Entry(user).State = EntityState.Modified;
|
||||
Db.Entry(user).Property(x => x.Salt).IsModified = false;
|
||||
Db.Entry(user).Property(x => x.Password).IsModified = false;
|
||||
await Db.SaveChangesAsync();
|
||||
return user;
|
||||
}
|
||||
|
|
10
src/Ombi/wwwroot/app/app.component.css
Normal file
10
src/Ombi/wwwroot/app/app.component.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
@media (max-width: 978px) {
|
||||
.top-spacing {
|
||||
padding-top: 10%
|
||||
}
|
||||
}
|
||||
@media (min-width: 979px) {
|
||||
.top-spacing {
|
||||
padding-top: 5%
|
||||
}
|
||||
}
|
|
@ -24,15 +24,15 @@
|
|||
<ul class="nav navbar-nav">
|
||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/requests']"><i class="fa fa-plus"></i> Requests</a></li>
|
||||
</ul>
|
||||
<ul *ngIf="isAdmin || isPowerUser" class="nav navbar-nav">
|
||||
<ul *ngIf="hasRole('Admin') || hasRole('PowerUser')" class="nav navbar-nav">
|
||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/usermanagement']"><i class="fa fa-user"></i> User Management</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li *ngIf="isAdmin" [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Ombi']"><i class="fa fa-cog"></i> Settings</a></li>
|
||||
<li *ngIf="hasRole('Admin') " [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Ombi']"><i class="fa fa-cog"></i> Settings</a></li>
|
||||
<li [routerLinkActive]="['active']" class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-user"></i> Welcome {{username}} <span class="caret"></span></a>
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><i class="fa fa-user"></i> Welcome {{user.name}} <span class="caret"></span></a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/user/changepassword']"><i class="fa fa-key"></i> Change Password</a></li>
|
||||
<li [routerLinkActive]="['active']"><a (click)="logOut()"><i class="fa fa-sign-out"></i> Logout</a></li>
|
||||
|
@ -44,7 +44,7 @@
|
|||
</nav>
|
||||
|
||||
|
||||
<div class="container" style="padding-top: 5%">
|
||||
<div class="container top-spacing">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,45 +3,50 @@ import { Router } from '@angular/router';
|
|||
import { NotificationService } from './services/notification.service';
|
||||
import { SettingsService } from './services/settings.service';
|
||||
import { AuthService } from './auth/auth.service';
|
||||
import { IdentityService } from './services/identity.service';
|
||||
import { ILocalUser } from './auth/IUserLogin';
|
||||
|
||||
import { ICustomizationSettings } from './interfaces/ISettings';
|
||||
|
||||
import style from './app.component.css';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'ombi',
|
||||
moduleId: module.id,
|
||||
templateUrl: './app.component.html'
|
||||
templateUrl: './app.component.html',
|
||||
styles: [style]
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
constructor(public notificationService: NotificationService, public authService: AuthService, private router: Router, private settingsService: SettingsService
|
||||
, private identityService: IdentityService) {
|
||||
) {
|
||||
}
|
||||
|
||||
customizationSettings: ICustomizationSettings;
|
||||
user: ILocalUser;
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
this.user = this.authService.claims();
|
||||
|
||||
|
||||
|
||||
this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x);
|
||||
|
||||
this.router.events.subscribe(() => {
|
||||
this.username = localStorage.getItem('currentUser');
|
||||
this.showNav = this.authService.loggedIn();
|
||||
});
|
||||
|
||||
this.isAdmin = this.identityService.hasRole("Admin");
|
||||
this.isPowerUser = this.identityService.hasRole("PowerUser");
|
||||
}
|
||||
|
||||
hasRole(role: string): boolean {
|
||||
return this.user.roles.some(r => r === role)
|
||||
}
|
||||
|
||||
logOut() {
|
||||
this.authService.logout();
|
||||
this.router.navigate(["login"]);
|
||||
}
|
||||
|
||||
username:string;
|
||||
showNav: boolean;
|
||||
isAdmin: boolean;
|
||||
isPowerUser:boolean;
|
||||
}
|
|
@ -2,3 +2,8 @@
|
|||
username: string,
|
||||
password:string
|
||||
}
|
||||
|
||||
export interface ILocalUser {
|
||||
roles: string[],
|
||||
name: string
|
||||
}
|
|
@ -4,9 +4,9 @@ import { Observable } from 'rxjs/Rx';
|
|||
|
||||
import { ServiceHelpers } from '../services/service.helpers';
|
||||
|
||||
import { IUserLogin } from './IUserLogin';
|
||||
import { IUserLogin, ILocalUser } from './IUserLogin';
|
||||
|
||||
import { tokenNotExpired } from 'angular2-jwt';
|
||||
import { tokenNotExpired, JwtHelper } from 'angular2-jwt';
|
||||
|
||||
import { Http } from '@angular/http';
|
||||
|
||||
|
@ -16,6 +16,8 @@ export class AuthService extends ServiceHelpers {
|
|||
super(http, '/api/v1/token');
|
||||
}
|
||||
|
||||
jwtHelper: JwtHelper = new JwtHelper();
|
||||
|
||||
login(login:IUserLogin) : Observable<any> {
|
||||
return this.http.post(`${this.url}/`, JSON.stringify(login), { headers: this.headers })
|
||||
.map(this.extractData);
|
||||
|
@ -26,6 +28,29 @@ export class AuthService extends ServiceHelpers {
|
|||
return tokenNotExpired('id_token');
|
||||
}
|
||||
|
||||
claims(): ILocalUser {
|
||||
if (this.loggedIn()) {
|
||||
var token = localStorage.getItem('id_token');
|
||||
|
||||
var json = this.jwtHelper.decodeToken(token);
|
||||
var roles = json["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"]
|
||||
var name = json["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"];
|
||||
|
||||
|
||||
var u = { name: name, roles: [] as string[] };
|
||||
if (roles instanceof Array) {
|
||||
|
||||
u.roles.concat(roles);
|
||||
} else {
|
||||
u.roles.push(roles);
|
||||
}
|
||||
|
||||
return <ILocalUser>u;
|
||||
|
||||
}
|
||||
return <ILocalUser>{};
|
||||
}
|
||||
|
||||
logout() {
|
||||
localStorage.removeItem('id_token');
|
||||
localStorage.removeItem('currentUser');
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
claims: ICheckbox[],
|
||||
emailAddress: string,
|
||||
password: string,
|
||||
userType : UserType,
|
||||
userType: UserType,
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,5 +18,6 @@ export enum UserType {
|
|||
|
||||
export interface ICheckbox {
|
||||
value: string,
|
||||
enabled:boolean,
|
||||
enabled: boolean,
|
||||
}
|
||||
|
||||
|
|
13
src/Ombi/wwwroot/app/search/seriesinformation.component.css
Normal file
13
src/Ombi/wwwroot/app/search/seriesinformation.component.css
Normal file
|
@ -0,0 +1,13 @@
|
|||
#requestFloatingBtn {
|
||||
position: fixed; /* Fixed/sticky position */
|
||||
bottom: 20px; /* Place the button at the bottom of the page */
|
||||
right: 30px; /* Place the button 30px from the right */
|
||||
z-index: 99; /* Make sure it does not overlap */
|
||||
cursor: pointer; /* Add a mouse pointer on hover */
|
||||
padding: 15px; /* Some padding */
|
||||
border-radius: 10px; /* Rounded corners */
|
||||
}
|
||||
|
||||
#requestFloatingBtn:hover {
|
||||
background-color: #555; /* Add a dark-grey background on hover */
|
||||
}
|
|
@ -1,8 +1,10 @@
|
|||
<div *ngIf="series">
|
||||
|
||||
<ngb-tabset>
|
||||
|
||||
|
||||
<div *ngFor="let season of series.seasonRequests;">
|
||||
<div *ngFor="let season of series.seasonRequests">
|
||||
<ngb-tab [id]="season.seasonNumber" [title]="season.seasonNumber">
|
||||
<ng-template ngbTabContent>
|
||||
<h2>Season: {{season.seasonNumber}}</h2>
|
||||
|
||||
<table class="table table-striped table-hover table-responsive table-condensed">
|
||||
|
@ -56,11 +58,18 @@
|
|||
|
||||
<td>
|
||||
|
||||
<button (click)="addRequest(ep)" [disabled]="ep.available || ep.requested || ep.approved" class="btn btn-sm btn-info-outline">Request</button>
|
||||
<button (click)="addRequest(ep)" [disabled]="ep.available || ep.requested || ep.approved" class="btn btn-sm btn-primary-outline">Request</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ng-template>
|
||||
</ngb-tab>
|
||||
</div>
|
||||
</ngb-tabset>
|
||||
|
||||
|
||||
|
||||
|
||||
<button id="requestFloatingBtn" class="btn btn-sm btn-success" title="Go to top">Request</button>
|
||||
</div>
|
||||
|
|
|
@ -10,11 +10,13 @@ import { NotificationService } from '../services/notification.service';
|
|||
|
||||
import { ISearchTvResult } from '../interfaces/ISearchTvResult';
|
||||
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
|
||||
import { IEpisodesRequested } from"../interfaces/IRequestModel";
|
||||
import { IEpisodesRequested } from "../interfaces/IRequestModel";
|
||||
|
||||
@Component({
|
||||
selector: 'ombi',
|
||||
moduleId: module.id,
|
||||
templateUrl: './seriesinformation.component.html'
|
||||
templateUrl: './seriesinformation.component.html',
|
||||
styleUrls: ['./seriesinformation.component.css']
|
||||
})
|
||||
export class SeriesInformationComponent implements OnInit, OnDestroy {
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ export class UserManagementComponent implements OnInit {
|
|||
|
||||
updateUser() {
|
||||
this.showEditDialog = false;
|
||||
this.identityService.updateUser(this.selectedUser).subscribe(x => this.selectedUser = x);
|
||||
}
|
||||
|
||||
create() {
|
||||
|
@ -64,7 +65,8 @@ export class UserManagementComponent implements OnInit {
|
|||
emailAddress: "",
|
||||
password: "",
|
||||
userType: 1,
|
||||
username: ""
|
||||
username: "",
|
||||
|
||||
}
|
||||
this.resetClaims();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue