Skip to content

Commit 4160d44

Browse files
authored
Merge pull request #662 from immense/tech/admin-auth-policies
Use recommended policy-based authorization for Org Admin and Server Admin pages.
2 parents 5383343 + 2d73f74 commit 4160d44

19 files changed

+593
-492
lines changed

Server/App.razor

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<CascadingAuthenticationState>
22
<Router AppAssembly="@typeof(Program).Assembly" PreferExactMatches="@true">
33
<Found Context="routeData">
4-
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
4+
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
5+
<NotAuthorized>
6+
<div class="jumbotron">
7+
<h3>You are not authorized to access this resource.</h3>
8+
</div>
9+
</NotAuthorized>
10+
</AuthorizeRouteView>
511
</Found>
612
<NotFound>
713
<LayoutView Layout="@typeof(MainLayout)">
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
3+
namespace Remotely.Server.Auth;
4+
5+
public class OrganizationAdminRequirement : IAuthorizationRequirement
6+
{
7+
8+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
using Microsoft.AspNetCore.Identity;
3+
using Remotely.Shared.Models;
4+
using System.Threading.Tasks;
5+
6+
namespace Remotely.Server.Auth;
7+
8+
public class OrganizationAdminRequirementHandler : AuthorizationHandler<OrganizationAdminRequirement>
9+
{
10+
private readonly UserManager<RemotelyUser> _userManager;
11+
12+
public OrganizationAdminRequirementHandler(UserManager<RemotelyUser> userManager)
13+
{
14+
_userManager = userManager;
15+
}
16+
17+
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, OrganizationAdminRequirement requirement)
18+
{
19+
if (context.User.Identity?.IsAuthenticated != true)
20+
{
21+
context.Fail();
22+
return;
23+
}
24+
25+
var user = await _userManager.GetUserAsync(context.User);
26+
if (user?.IsAdministrator != true)
27+
{
28+
context.Fail();
29+
return;
30+
}
31+
32+
context.Succeed(requirement);
33+
}
34+
}

Server/Auth/PolicyNames.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Remotely.Server.Auth;
2+
3+
public static class PolicyNames
4+
{
5+
public const string TwoFactorRequired = nameof(TwoFactorRequired);
6+
public const string OrganizationAdminRequired = nameof(OrganizationAdminRequired);
7+
public const string ServerAdminRequired = nameof(ServerAdminRequired);
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using Microsoft.AspNetCore.Authorization;
2+
3+
namespace Remotely.Server.Auth;
4+
5+
public class ServerAdminRequirement : IAuthorizationRequirement
6+
{
7+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#nullable enable
2+
3+
using Microsoft.AspNetCore.Authorization;
4+
using Microsoft.AspNetCore.Identity;
5+
using Remotely.Shared.Models;
6+
using System.Threading.Tasks;
7+
8+
namespace Remotely.Server.Auth;
9+
10+
public class ServerAdminRequirementHandler : AuthorizationHandler<ServerAdminRequirement>
11+
{
12+
private readonly UserManager<RemotelyUser> _userManager;
13+
14+
public ServerAdminRequirementHandler(UserManager<RemotelyUser> userManager)
15+
{
16+
_userManager = userManager;
17+
}
18+
19+
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, ServerAdminRequirement requirement)
20+
{
21+
if (context.User.Identity?.IsAuthenticated != true)
22+
{
23+
context.Fail();
24+
return;
25+
}
26+
27+
var user = await _userManager.GetUserAsync(context.User);
28+
if (user?.IsServerAdmin != true)
29+
{
30+
context.Fail();
31+
return;
32+
}
33+
34+
context.Succeed(requirement);
35+
}
36+
}

Server/Auth/TwoFactorRequiredRequirement.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ namespace Remotely.Server.Auth
88
{
99
public class TwoFactorRequiredRequirement : IAuthorizationRequirement
1010
{
11-
public const string PolicyName = "TwoFactorRequired";
11+
1212
}
1313
}

Server/Components/LoaderHarness.razor

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,10 @@
1111
private bool _loaderShown;
1212
private string _statusMessage = string.Empty;
1313

14-
protected override Task OnAfterRenderAsync(bool firstRender)
14+
protected override Task OnInitializedAsync()
1515
{
16-
if (firstRender)
17-
{
18-
Messenger.Register<ShowLoaderMessage>(this, HandleShowLoaderMessage);
19-
}
20-
return base.OnAfterRenderAsync(firstRender);
16+
Messenger.Register<ShowLoaderMessage>(this, HandleShowLoaderMessage);
17+
return base.OnInitializedAsync();
2118
}
2219

2320
private async Task HandleShowLoaderMessage(ShowLoaderMessage message)

Server/Hubs/AgentHub.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public Task Chat(string message, bool disconnected, string browserConnectionId)
7272
}
7373

7474

75-
public async Task CheckForPendingSriptRuns()
75+
public async Task CheckForPendingScriptRuns()
7676
{
7777
var authToken = _expiringTokenService.GetToken(Time.Now.AddMinutes(AppConstants.ScriptRunExpirationMinutes));
7878
var scriptRuns = await _dataService.GetPendingScriptRuns(Device.ID);
@@ -166,7 +166,7 @@ public async Task DeviceHeartbeat(Device device)
166166

167167
var result = await _dataService.AddOrUpdateDevice(device);
168168

169-
if (result.IsSuccess)
169+
if (!result.IsSuccess)
170170
{
171171
return;
172172
}
@@ -189,7 +189,7 @@ public async Task DeviceHeartbeat(Device device)
189189
}
190190

191191

192-
await CheckForPendingSriptRuns();
192+
await CheckForPendingScriptRuns();
193193
}
194194

195195

Server/Pages/ApiKeys.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@page "/api-keys"
2-
@attribute [Authorize]
2+
@attribute [Authorize(Policy = PolicyNames.OrganizationAdminRequired)]
33
@inherits AuthComponentBase
44

55
@inject IDataService DataService

0 commit comments

Comments
 (0)