Fixed signlar

pull/2947/head^2
Jamie Rees 6 years ago
parent f16b33c437
commit 15d34e0aaf

@ -0,0 +1,39 @@
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using System.Linq;
using System.Security.Claims;
using System.Xml;
namespace Ombi.Hubs
{
public class NotificationHub : Hub
{
public static ConcurrentDictionary<string, string> UsersOnline = new ConcurrentDictionary<string, string>();
public override Task OnConnectedAsync()
{
var identity = (ClaimsIdentity) Context.User.Identity;
var userIdClaim = identity.Claims.FirstOrDefault(x => x.Type.Equals("Id", StringComparison.InvariantCultureIgnoreCase));
if (userIdClaim == null)
{
return base.OnConnectedAsync();
}
UsersOnline.TryAdd(Context.ConnectionId, userIdClaim.Value);
return base.OnConnectedAsync();
}
public override Task OnDisconnectedAsync(Exception exception)
{
UsersOnline.TryRemove(Context.ConnectionId, out _);
return base.OnDisconnectedAsync(exception);
}
public Task Notification(string data)
{
return Clients.All.SendAsync("Notification", data);
}
}
}

@ -1,14 +0,0 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
namespace Ombi.Hubs
{
public class ScheduledJobsHub : Hub
{
public Task Send(string data)
{
return Clients.All.SendAsync("Send", data);
}
}
}

@ -14,7 +14,7 @@ import { StorageService } from './shared/storage/storage-service';
import { HubConnection } from '@aspnet/signalr'; import { HubConnection } from '@aspnet/signalr';
import * as signalR from '@aspnet/signalr'; import * as signalR from '@aspnet/signalr';
@Component({ @Component({
selector: "app-ombi", selector: "app-ombi",
@ -37,11 +37,12 @@ export class AppComponent implements OnInit {
public username: string; public username: string;
private checkedForUpdate: boolean; private checkedForUpdate: boolean;
private hubConnected: boolean;
@HostBinding('class') public componentCssClass; @HostBinding('class') public componentCssClass;
private scheduleHubConnection: HubConnection | undefined; private notificationHubConnection: HubConnection | undefined;
constructor(public notificationService: NotificationService, constructor(public notificationService: NotificationService,
public authService: AuthService, public authService: AuthService,
@ -117,26 +118,27 @@ export class AppComponent implements OnInit {
}, },
err => this.checkedForUpdate = true); err => this.checkedForUpdate = true);
} }
}
});
this.scheduleHubConnection = new signalR.HubConnectionBuilder().withUrl("/hubs/schedules", { if (this.authService.loggedIn() && !this.hubConnected) {
accessTokenFactory: () => { this.notificationHubConnection = new signalR.HubConnectionBuilder().withUrl("/hubs/notification", {
return this.authService.getToken(); accessTokenFactory: () => {
} return this.authService.getToken();
}) }
.configureLogging(signalR.LogLevel.Information).build(); }).configureLogging(signalR.LogLevel.Information).build();
this.scheduleHubConnection this.notificationHubConnection
.start() .start()
.then(() => console.info('Connection started!')) .then(() => this.hubConnected = true)
.catch(err => console.error(err)); .catch(err => console.error(err));
this.scheduleHubConnection.on("Send", (data: any) => { this.notificationHubConnection.on("Notification", (data: any) => {
this.snackBar.open(data,"OK", { this.snackBar.open(data, "OK", {
duration: 3000 duration: 3000
}); });
}); });
}
}
});
} }
public openMobileApp(event: any) { public openMobileApp(event: any) {

@ -11,7 +11,7 @@ import { InputSwitchModule, SidebarModule } from "primeng/primeng";
import { import {
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule, MatSelectModule, MatTableModule, MatPaginatorModule, MatSortModule, MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule, MatSelectModule, MatTableModule, MatPaginatorModule, MatSortModule,
MatTreeModule, MatStepperModule} from '@angular/material'; MatTreeModule, MatStepperModule, MatSnackBarModule} from '@angular/material';
import { MatCardModule, MatInputModule, MatTabsModule, MatAutocompleteModule, MatCheckboxModule, MatExpansionModule, MatDialogModule, MatProgressSpinnerModule, import { MatCardModule, MatInputModule, MatTabsModule, MatAutocompleteModule, MatCheckboxModule, MatExpansionModule, MatDialogModule, MatProgressSpinnerModule,
MatChipsModule } from "@angular/material"; MatChipsModule } from "@angular/material";
import { EpisodeRequestComponent } from "./episode-request/episode-request.component"; import { EpisodeRequestComponent } from "./episode-request/episode-request.component";

@ -126,7 +126,8 @@ namespace Ombi.Controllers.V1
new Claim(JwtRegisteredClaimNames.Sub, user.UserName), new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(ClaimTypes.NameIdentifier, user.Id), new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Name, user.UserName), new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim("Id", user.Id)
}; };
claims.AddRange(roles.Select(role => new Claim("role", role))); claims.AddRange(roles.Select(role => new Claim("role", role)));

@ -20,12 +20,12 @@ namespace Ombi.Controllers.V2
[ApiController] [ApiController]
public class HubController : ControllerBase public class HubController : ControllerBase
{ {
public HubController(IHubContext<ScheduledJobsHub> hub) public HubController(IHubContext<NotificationHub> hub)
{ {
_hub = hub; _hub = hub;
} }
private readonly IHubContext<ScheduledJobsHub> _hub; private readonly IHubContext<NotificationHub> _hub;
/// <summary> /// <summary>
/// Returns search results for both TV and Movies /// Returns search results for both TV and Movies
@ -34,7 +34,7 @@ namespace Ombi.Controllers.V2
[HttpGet("{searchTerm}")] [HttpGet("{searchTerm}")]
public async Task MultiSearch(string searchTerm) public async Task MultiSearch(string searchTerm)
{ {
await _hub.Clients.All.SendAsync("Send", searchTerm); await _hub.Clients.All.SendAsync("Notification", searchTerm);
} }
} }
} }

@ -221,7 +221,7 @@ namespace Ombi
c.SwaggerEndpoint("/swagger/v2/swagger.json", "API V2"); c.SwaggerEndpoint("/swagger/v2/swagger.json", "API V2");
}); });
app.UseSignalR(routes => { routes.MapHub<ScheduledJobsHub>("/hubs/schedules"); }); app.UseSignalR(routes => { routes.MapHub<NotificationHub>("/hubs/notification"); });
app.UseMvcWithDefaultRoute(); app.UseMvcWithDefaultRoute();

@ -6,6 +6,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
@ -144,12 +145,12 @@ namespace Ombi
{ {
OnMessageReceived = context => OnMessageReceived = context =>
{ {
var accessToken = context.Request.Headers["id_token"]; var accessToken = context.Request.Query["access_token"];
// If the request is for our hub... // If the request is for our hub...
var path = context.HttpContext.Request.Path; var path = context.HttpContext.Request.Path;
if (!string.IsNullOrEmpty(accessToken) && if (!string.IsNullOrEmpty(accessToken) &&
(path.StartsWithSegments("/hubs/"))) (path.StartsWithSegments("/hubs")))
{ {
// Read the token out of the query string // Read the token out of the query string
context.Token = accessToken; context.Token = accessToken;
@ -158,6 +159,7 @@ namespace Ombi
} }
}; };
}); });
} }
} }
} }
Loading…
Cancel
Save