Skip to content

Commit 44bd9a9

Browse files
committed
Reusable Proxy factory for 0auth requests.
1 parent df4987e commit 44bd9a9

File tree

14 files changed

+326
-24
lines changed

14 files changed

+326
-24
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Umbraco.Cms.Integrations.Authorization.Core.Interfaces;
3+
4+
namespace Umbraco.Cms.Integrations.Authorization.Core
5+
{
6+
public static class Dependencies
7+
{
8+
public static void AddAuthorizationModule(this IServiceCollection services)
9+
{
10+
services.AddHttpClient();
11+
}
12+
}
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.Net.Http;
2+
using System.Threading.Tasks;
3+
4+
using Microsoft.AspNetCore.Http;
5+
6+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Dtos;
7+
8+
namespace Umbraco.Cms.Integrations.Authorization.Core.Interfaces
9+
{
10+
public interface IAuthorizationService
11+
{
12+
Task<ResponseDto> ProcessAsync(HttpContent content);
13+
14+
HttpContent GetContent(IFormCollection form);
15+
}
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+

2+
namespace Umbraco.Cms.Integrations.Authorization.Core.Models.Dtos
3+
{
4+
public class ResponseDto
5+
{
6+
public int StatusCode { get; set; }
7+
8+
public string ContentType { get; set; }
9+
10+
public long? ContentLength { get; set; }
11+
12+
public string Content { get; set; }
13+
}
14+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+

2+
namespace Umbraco.Cms.Integrations.Authorization.Core.Models.Enums
3+
{
4+
public class ServiceType
5+
{
6+
public enum ServiceTypeEnum
7+
{
8+
Hubspot,
9+
Semrush,
10+
Shopify
11+
}
12+
}
13+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net5.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
9+
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="6.0.0" />
10+
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<Reference Include="Microsoft.AspNetCore.Http.Features">
15+
<HintPath>..\..\..\..\..\Program Files\dotnet\shared\Microsoft.AspNetCore.App\5.0.12\Microsoft.AspNetCore.Http.Features.dll</HintPath>
16+
</Reference>
17+
<Reference Include="Microsoft.Extensions.Primitives">
18+
<HintPath>..\..\..\..\..\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\5.0.0\ref\net5.0\Microsoft.Extensions.Primitives.dll</HintPath>
19+
</Reference>
20+
</ItemGroup>
21+
22+
</Project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+

2+
namespace Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Configuration
3+
{
4+
public class Settings
5+
{
6+
public string BaseUrl { get; set; }
7+
8+
public string AuthEndpoint { get; set; }
9+
10+
public string ClientId { get; set; }
11+
12+
public string ClientSecret { get; set; }
13+
14+
public string RedirectUri { get; set; }
15+
}
16+
}
Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
using Microsoft.AspNetCore.Http;
1+
using System;
2+
using Microsoft.AspNetCore.Http;
23
using Microsoft.AspNetCore.Mvc;
34
using Microsoft.Extensions.Options;
45
using System.IO;
56
using System.Linq;
67
using System.Net.Http;
78
using System.Threading.Tasks;
9+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Enums;
10+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Dtos;
811
using Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Configuration;
12+
using Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Factories;
913

1014
namespace Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Controllers
1115
{
@@ -15,34 +19,55 @@ public class OAuthProxyController : Controller
1519
private readonly IHttpClientFactory _httpClientFactory;
1620
private readonly AppSettings _appSettings;
1721

18-
public OAuthProxyController(IHttpClientFactory httpClientFactory, IOptions<AppSettings> appSettings)
22+
private readonly AuthorizationServiceFactory _authorizationServiceFactory;
23+
24+
public OAuthProxyController(IHttpClientFactory httpClientFactory, IOptions<AppSettings> appSettings,
25+
AuthorizationServiceFactory authorizationServiceFactory)
1926
{
2027
_httpClientFactory = httpClientFactory;
2128
_appSettings = appSettings.Value;
29+
30+
_authorizationServiceFactory = authorizationServiceFactory;
2231
}
2332

2433
[HttpPost]
2534
[Route("/oauth/v1/token")]
2635
public async Task ProxyTokenRequest()
2736
{
28-
var httpClient = _httpClientFactory.CreateClient("HubspotToken");
37+
if (Request.Headers.TryGetValue("service_type", out var serviceType))
38+
{
39+
try
40+
{
41+
var serviceTypeParsed =
42+
(ServiceType.ServiceTypeEnum) Enum.Parse(typeof(ServiceType.ServiceTypeEnum), serviceType);
2943

30-
var response = await httpClient.PostAsync("oauth/v1/token", GetContent(Request.Form));
31-
var content = await response.Content.ReadAsStringAsync();
44+
var service = _authorizationServiceFactory.Create(serviceTypeParsed);
3245

33-
Response.StatusCode = (int)response.StatusCode;
46+
var content = service.GetContent(Request.Form);
3447

35-
Response.ContentType = response.Content.Headers.ContentType?.ToString();
36-
Response.ContentLength = response.Content.Headers.ContentLength;
48+
var response = await service.ProcessAsync(content);
3749

38-
await Response.WriteAsync(content);
39-
}
50+
await Response.WriteAsync(response.Content);
51+
}
52+
catch (ArgumentException ex)
53+
{
54+
Response.StatusCode = StatusCodes.Status500InternalServerError;
4055

41-
private HttpContent GetContent(IFormCollection form)
42-
{
43-
var dictionary = form.ToDictionary(x => x.Key, x => x.Value.ToString());
44-
dictionary.Add("client_secret", _appSettings.ClientSecret);
45-
return new FormUrlEncodedContent(dictionary);
56+
await Response.WriteAsync(ex.Message);
57+
}
58+
catch (NotImplementedException ex)
59+
{
60+
Response.StatusCode = StatusCodes.Status500InternalServerError;
61+
62+
await Response.WriteAsync(ex.Message);
63+
}
64+
}
65+
else
66+
{
67+
Response.StatusCode = StatusCodes.Status500InternalServerError;
68+
69+
await Response.WriteAsync("Service Type header is missing.");
70+
}
4671
}
4772
}
4873
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Net.Http;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.Extensions.Configuration;
5+
using Microsoft.Extensions.Options;
6+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Enums;
7+
using Umbraco.Cms.Integrations.Authorization.Core.Interfaces;
8+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Dtos;
9+
using Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Configuration;
10+
using Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Services;
11+
12+
namespace Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Factories
13+
{
14+
public class AuthorizationServiceFactory
15+
{
16+
private readonly IHttpClientFactory _httpClientFactory;
17+
18+
private readonly IConfiguration _configuration;
19+
20+
public AuthorizationServiceFactory(IHttpClientFactory httpClientFactory, IConfiguration configuration)
21+
{
22+
_httpClientFactory = httpClientFactory;
23+
24+
_configuration = configuration;
25+
}
26+
27+
public IAuthorizationService Create(ServiceType.ServiceTypeEnum serviceType)
28+
{
29+
switch (serviceType)
30+
{
31+
case ServiceType.ServiceTypeEnum.Hubspot:
32+
return new HubspotService(_httpClientFactory, _configuration);
33+
case ServiceType.ServiceTypeEnum.Semrush:
34+
return new SemrushService(_httpClientFactory, _configuration);
35+
default: throw new NotImplementedException("Service Type not implemented.");
36+
}
37+
}
38+
}
39+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System;
2+
using System.Linq;
3+
using System.Net.Http;
4+
using System.Threading.Tasks;
5+
6+
using Microsoft.AspNetCore.Http;
7+
using Microsoft.Extensions.Configuration;
8+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Dtos;
9+
using Umbraco.Cms.Integrations.Authorization.Core.Interfaces;
10+
using Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Configuration;
11+
12+
namespace Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Services
13+
{
14+
public class HubspotService: IAuthorizationService
15+
{
16+
private readonly IHttpClientFactory _httpClientFactory;
17+
18+
private readonly IConfiguration _configuration;
19+
20+
private readonly Settings _settings;
21+
22+
public HubspotService(IHttpClientFactory httpClientFactory, IConfiguration configuration)
23+
{
24+
_httpClientFactory = httpClientFactory;
25+
26+
_configuration = configuration;
27+
28+
_settings = new Settings();
29+
_configuration.GetSection("HubspotSettings").Bind(_settings);
30+
}
31+
32+
public async Task<ResponseDto> ProcessAsync(HttpContent content)
33+
{
34+
var client = _httpClientFactory.CreateClient();
35+
client.BaseAddress = new Uri(_settings.BaseUrl);
36+
37+
var response = await client.PostAsync(_settings.AuthEndpoint, content);
38+
39+
var responseContent = await response.Content.ReadAsStringAsync();
40+
41+
return new ResponseDto
42+
{
43+
StatusCode = (int)response.StatusCode,
44+
ContentType = response.Content.Headers.ContentType?.ToString(),
45+
ContentLength = response.Content.Headers.ContentLength,
46+
Content = responseContent
47+
};
48+
}
49+
50+
public HttpContent GetContent(IFormCollection form)
51+
{
52+
var dictionary = form.ToDictionary(x => x.Key, x => x.Value.ToString());
53+
54+
dictionary.Add("client_secret", _settings.ClientSecret);
55+
56+
return new FormUrlEncodedContent(dictionary);
57+
}
58+
}
59+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using System;
2+
using System.Linq;
3+
using System.Net.Http;
4+
using System.Threading.Tasks;
5+
6+
using Microsoft.AspNetCore.Http;
7+
using Microsoft.Extensions.Configuration;
8+
using Microsoft.Extensions.Options;
9+
10+
using Umbraco.Cms.Integrations.Authorization.Core.Models.Dtos;
11+
using Umbraco.Cms.Integrations.Authorization.Core.Interfaces;
12+
using Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Configuration;
13+
14+
namespace Umbraco.Forms.Integrations.Crm.Hubspot.OAuthProxy.Services
15+
{
16+
public class SemrushService: IAuthorizationService
17+
{
18+
private readonly IHttpClientFactory _httpClientFactory;
19+
20+
private readonly IConfiguration _configuration;
21+
22+
private readonly Settings _settings;
23+
24+
public SemrushService(IHttpClientFactory httpClientFactory, IConfiguration configuration)
25+
{
26+
_httpClientFactory = httpClientFactory;
27+
28+
_configuration = configuration;
29+
30+
_settings = new Settings();
31+
_configuration.GetSection("SemrushSettings").Bind(_settings);
32+
}
33+
34+
public async Task<ResponseDto> ProcessAsync(HttpContent content)
35+
{
36+
var client = _httpClientFactory.CreateClient();
37+
client.BaseAddress = new Uri(_settings.BaseUrl);
38+
39+
var response = await client.PostAsync(_settings.AuthEndpoint, content);
40+
41+
var responseContent = await response.Content.ReadAsStringAsync();
42+
43+
return new ResponseDto
44+
{
45+
StatusCode = (int) response.StatusCode,
46+
ContentType = response.Content.Headers.ContentType?.ToString(),
47+
ContentLength = response.Content.Headers.ContentLength,
48+
Content = responseContent
49+
};
50+
}
51+
52+
public HttpContent GetContent(IFormCollection form)
53+
{
54+
var dictionary = form.ToDictionary(x => x.Key, x => x.Value.ToString());
55+
56+
dictionary.Add("client_id", _settings.ClientId);
57+
dictionary.Add("client_secret", _settings.ClientSecret);
58+
dictionary.Add("grant_type", "authorization_code");
59+
dictionary.Add("redirect_uri", _settings.RedirectUri);
60+
61+
return new FormUrlEncodedContent(dictionary);
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)