Skip to content

Commit

Permalink
Adding auth scenario; needs cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
tylorhl-msft committed May 6, 2019
1 parent 5210b62 commit ee06bc4
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
using DataX.Utilities.Web;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authorization;
using DataX.ServiceHost.AspNetCore.Authorization.Roles;

namespace Flow.Management.Controllers
{
[Route("api")]
[Authorize(Roles = "DataXWriter,DataXReader")]
[DataXReader]
public partial class FlowManagementController : Controller
{
private readonly ILogger<FlowManagementController> _logger;
Expand All @@ -46,11 +47,12 @@ public FlowManagementController(ILogger<FlowManagementController> logger, FlowOp

[HttpPost]
[Route("flow/save")] // save flow config
[DataXWriter]
public async Task<ApiResult> SaveFlow([FromBody]JObject config)
{
try
{
RolesCheck.EnsureWriter(Request, _isLocal);
//RolesCheck.EnsureWriter(Request, _isLocal);
Ensure.NotNull(config, "config");

var inputJson = JsonConfig.From(config.ToString());
Expand All @@ -77,11 +79,12 @@ public async Task<ApiResult> SaveFlow([FromBody]JObject config)

[HttpPost]
[Route("flow/generateconfigs")] // generate flow configs
[DataXWriter]
public async Task<ApiResult> GenerateConfigs([FromBody] string flowName)
{
try
{
RolesCheck.EnsureWriter(Request, _isLocal);
//RolesCheck.EnsureWriter(Request, _isLocal);
Ensure.NotNull(flowName, "flowName");

var result = await this._runtimeConfigGenerator.GenerateRuntimeConfigs(flowName);
Expand Down Expand Up @@ -156,6 +159,7 @@ public async Task<ApiResult> GetAllFlowsMin()

[HttpPost]
[Route("flow/startjobs")]
[DataXWriter]
public async Task<ApiResult> StartJobsForFlow([FromBody] string flowName)
{
try
Expand All @@ -176,6 +180,7 @@ public async Task<ApiResult> StartJobsForFlow([FromBody] string flowName)

[HttpPost]
[Route("flow/restartjobs")]
[DataXWriter]
public async Task<ApiResult> RestartJobsForFlow([FromBody] string flowName)
{
try
Expand All @@ -196,6 +201,7 @@ public async Task<ApiResult> RestartJobsForFlow([FromBody] string flowName)

[HttpPost]
[Route("flow/stopjobs")]
[DataXWriter]
public async Task<ApiResult> StopJobsForFlow([FromBody] string flowName)
{
try
Expand All @@ -217,6 +223,7 @@ public async Task<ApiResult> StopJobsForFlow([FromBody] string flowName)

[HttpPost]
[Route("userqueries/schema")] // generator (sqlparser)
[DataXWriter]
public async Task<ApiResult> GetSchema([FromBody]JObject config)
{
try
Expand Down Expand Up @@ -244,6 +251,7 @@ public async Task<ApiResult> GetSchema([FromBody]JObject config)

[HttpPost]
[Route("userqueries/codegen")] // generator
[DataXWriter]
public async Task<ApiResult> GetCodeGen([FromBody]JObject config)
{
try
Expand Down Expand Up @@ -330,6 +338,7 @@ public async Task<ApiResult> GetJobsByNames([FromBody] string[] jobNames)

[HttpPost]
[Route("job/start")] // start the job
[DataXWriter]
public async Task<ApiResult> StartJob([FromBody] string jobName)
{
try
Expand All @@ -351,6 +360,7 @@ public async Task<ApiResult> StartJob([FromBody] string jobName)

[HttpPost]
[Route("job/stop")] // stop the job
[DataXWriter]
public async Task<ApiResult> StopJob([FromBody] string jobName)
{
try
Expand All @@ -371,6 +381,7 @@ public async Task<ApiResult> StopJob([FromBody] string jobName)

[HttpPost]
[Route("job/restart")]
[DataXWriter]
public async Task<ApiResult> RestartJob([FromBody] string jobName)
{
try
Expand All @@ -392,6 +403,7 @@ public async Task<ApiResult> RestartJob([FromBody] string jobName)

[HttpGet]
[Route("job/syncall")]
[DataXWriter]
public async Task<ApiResult> SyncAllJobs()
{
try
Expand Down
3 changes: 3 additions & 0 deletions Services/DataX.Flow/Flow.ManagementService/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using DataX.Config;
using DataX.Config.ConfigurationProviders;
using DataX.Config.PublicService;
using DataX.ServiceHost.AspNetCore.Authorization.Extensions;
using DataX.ServiceHost.ServiceFabric.Extensions.Configuration;
using DataX.Config.Storage;
using DataX.ServiceHost.ServiceFabric;
Expand Down Expand Up @@ -63,6 +64,8 @@ public void ConfigureServices(IServiceCollection services)
Configuration.GetSection("JwtBearerOptions").Bind(bearerOptions);

services
.AddSingleton(_dataXSettings)
.AddDataXAuthorization()
.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using DataX.Utilities.Web;
using System;
using System.Collections.Generic;
using System.Text;

namespace DataX.ServiceHost.AspNetCore.Authorization
{
public static class DataXAuthConstants
{
public const string PolicyPrefix = "DataXAuth_";

public static string WriterPolicyName { get; } = PolicyPrefix + RolesCheck.WriterRoleName;

public static string ReaderPolicyName { get; } = PolicyPrefix + RolesCheck.ReaderRoleName;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using DataX.ServiceHost.Settings;
using DataX.Utilities.Web;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization.Infrastructure;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace DataX.ServiceHost.AspNetCore.Authorization
{
/// <summary>
/// A for assertion requirements. We're extending this so that we can easily identify the DataX requirement instance
/// when adding in policy requirements. This lets us prevent duplication of requirements and handlers.
/// This is made internal as using it outside of this context may cause configuration issues if used improperly.
/// </summary>
internal abstract class DataXAuthRequirement : IAuthorizationHandler, IAuthorizationRequirement
{
public DataXSettings Settings { get; set; }

public DataXAuthRequirement() { }

public DataXAuthRequirement(DataXSettings settings)
{
Settings = settings;
}

public Task HandleAsync(AuthorizationHandlerContext context)
{
if(IsAuthorized(context, Settings))
{
context.Succeed(this);
}

return Task.CompletedTask;
}

protected abstract bool IsAuthorized(AuthorizationHandlerContext context, DataXSettings settings);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using DataX.Utilities.Web;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace DataX.ServiceHost.AspNetCore.Authorization
{
public abstract class DataXAuthorizeAttribute : AuthorizeAttribute
{
public DataXAuthorizeAttribute()
{
Policy = DataXAuthConstants.PolicyPrefix;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
namespace DataX.ServiceHost.AspNetCore.Authorization
{
using DataX.ServiceHost.Settings;
using Microsoft.AspNetCore.Authorization;
using System;
using System.Linq;

// This class is meant to simplify the syntax for adding requirements for policies
internal class DataXPolicyBuilder
{
private readonly AuthorizationOptions _options;
private readonly DataXSettings _settings;
private readonly Action<AuthorizationPolicyBuilder> _configurePolicy;

public DataXPolicyBuilder(
AuthorizationOptions options,
DataXSettings settings,
Action<AuthorizationPolicyBuilder> configurePolicy)
{
_options = options;
_settings = settings;
_configurePolicy = configurePolicy;
}

public DataXPolicyBuilder AddPolicy<TRequirement>(string name)
where TRequirement : DataXAuthRequirement, new()
{
_options.AddPolicy(name, DataXPolicy<TRequirement>);

return this;
}

private void DataXPolicy<TDataXRequirement>(AuthorizationPolicyBuilder policy)
where TDataXRequirement : DataXAuthRequirement, new()
{
AddDataXRequirements<TDataXRequirement>(policy);
}

/// <summary>
/// Adds the basic DataX auth policy to the builder
/// </summary>
private AuthorizationPolicyBuilder AddDataXRequirements<TDataXRequirement>(AuthorizationPolicyBuilder policy)
where TDataXRequirement : DataXAuthRequirement, new()
{
// We don't want to add the same requirement in again.
// If it does exist and the settings changed, then we want to make sure the new settings are used
RemoveDataXRequirements(policy);

var requirement = new TDataXRequirement()
{
Settings = _settings
};

policy.RequireAuthenticatedUser();
policy.AddRequirements(requirement);
_configurePolicy?.Invoke(policy);

return policy;
}

/// <summary>
/// Removes the DataXRequirements set in the policy builder if they exist.
/// </summary>
private static AuthorizationPolicyBuilder RemoveDataXRequirements(AuthorizationPolicyBuilder policy)
{
var requirements = policy.Requirements.Where(req => req is DataXAuthRequirement);

foreach (var req in requirements)
{
policy.Requirements.Remove(req);
}

return policy;
}
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using DataX.ServiceHost.Settings;
using DataX.Utilities.Web;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using DataX.ServiceHost.AspNetCore.Authorization.Requirements;

namespace DataX.ServiceHost.AspNetCore.Authorization.Extensions
{
public static class DataXAuthorizationExtensions
{
public static IServiceCollection AddDataXAuthorization(this IServiceCollection services)
{
return services.AddDataXAuthorization(null);
}

public static IServiceCollection AddDataXAuthorization(this IServiceCollection services, Action<AuthorizationPolicyBuilder> configurePolicy)
{
var settings = services.BuildServiceProvider().GetService<DataXSettings>();

// EnableOneBox scenario as it requires the least configuration and we can't assume cloud connection settings
if (settings == null)
{
settings = new DataXSettings()
{
EnableOneBox = true,
LocalRoot = "",
MetricsHttpEndpoint = "http://localhost:2020/",
SparkHome = "",
};
}

return services.AddAuthorization(options =>
{
new DataXPolicyBuilder(options, settings, configurePolicy)
.AddPolicy<DataXWriterRequirement>(DataXAuthConstants.WriterPolicyName)
.AddPolicy<DataXReaderRequirement>(DataXAuthConstants.ReaderPolicyName);
});
}
}
}

This file was deleted.

Loading

0 comments on commit ee06bc4

Please sign in to comment.