Skip to content

Commit

Permalink
Add a new provider for Imgur
Browse files Browse the repository at this point in the history
  • Loading branch information
kappa7194 authored and kevinchalet committed Sep 19, 2015
1 parent a402a45 commit 7fba20f
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 0 deletions.
7 changes: 7 additions & 0 deletions AspNet.Security.OAuth.Providers.sln
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AspNet.Security.OAuth.Spoti
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AspNet.Security.OAuth.Slack", "src\AspNet.Security.OAuth.Slack\AspNet.Security.OAuth.Slack.xproj", "{95266F79-613A-42C4-96E2-E1435AD9ED6E}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "AspNet.Security.OAuth.Imgur", "src\AspNet.Security.OAuth.Imgur\AspNet.Security.OAuth.Imgur.xproj", "{E323D375-7972-4892-AD38-CEB8F512F3D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -67,6 +69,10 @@ Global
{95266F79-613A-42C4-96E2-E1435AD9ED6E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95266F79-613A-42C4-96E2-E1435AD9ED6E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95266F79-613A-42C4-96E2-E1435AD9ED6E}.Release|Any CPU.Build.0 = Release|Any CPU
{E323D375-7972-4892-AD38-CEB8F512F3D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E323D375-7972-4892-AD38-CEB8F512F3D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E323D375-7972-4892-AD38-CEB8F512F3D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E323D375-7972-4892-AD38-CEB8F512F3D2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -81,5 +87,6 @@ Global
{9E09DCBC-20DB-4CD8-8A6D-5FA1958EEF14} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D}
{535CD0A4-2117-4576-8552-4188D7E8E3D4} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D}
{95266F79-613A-42C4-96E2-E1435AD9ED6E} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D}
{E323D375-7972-4892-AD38-CEB8F512F3D2} = {C1352FD3-AE8B-43EE-B45B-F6E0B3FBAC6D}
EndGlobalSection
EndGlobal
1 change: 1 addition & 0 deletions samples/Mvc.Client/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"dependencies": {
"AspNet.Security.OAuth.DeviantArt": "1.0.0-*",
"AspNet.Security.OAuth.GitHub": "1.0.0-*",
"AspNet.Security.OAuth.Imgur": "1.0.0-*",
"AspNet.Security.OAuth.LinkedIn": "1.0.0-*",
"AspNet.Security.OAuth.Slack": "1.0.0-*",
"AspNet.Security.OAuth.Spotify": "1.0.0-*",
Expand Down
18 changes: 18 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/AspNet.Security.OAuth.Imgur.xproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>e323d375-7972-4892-ad38-ceb8f512f3d2</ProjectGuid>
<RootNamespace>AspNet.Security.OAuth.Imgur</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
50 changes: 50 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/ImgurAuthenticationDefaults.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Authentication.OAuth;

namespace AspNet.Security.OAuth.Imgur {
/// <summary>
/// Default values used by the Imgur authentication middleware.
/// </summary>
public static class ImgurAuthenticationDefaults {
/// <summary>
/// Default value for <see cref="AuthenticationOptions.AuthenticationScheme"/>.
/// </summary>
public const string AuthenticationScheme = "Imgur";

/// <summary>
/// Default value for <see cref="OAuthOptions.Caption"/>.
/// </summary>
public const string Caption = "Imgur";

/// <summary>
/// Default value for <see cref="OAuthOptions.ClaimsIssuer"/>.
/// </summary>
public const string Issuer = "Imgur";

/// <summary>
/// Default value for <see cref="OAuthOptions.CallbackPath"/>.
/// </summary>
public const string CallbackPath = "/signin-imgur";

/// <summary>
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>.
/// </summary>
public const string AuthorizationEndpoint = "https://api.imgur.com/oauth2/authorize";

/// <summary>
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>.
/// </summary>
public const string TokenEndpoint = "https://api.imgur.com/oauth2/token";

/// <summary>
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/>.
/// </summary>
public const string UserInformationEndpoint = "https://api.imgur.com/3/account/me";
}
}
32 changes: 32 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/ImgurAuthenticationExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using System;
using AspNet.Security.OAuth.Imgur;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.OptionsModel;

namespace Microsoft.AspNet.Builder {
public static class ImgurAuthenticationExtensions {
public static IServiceCollection ConfigureImgurAuthentication(
[NotNull] this IServiceCollection services,
[NotNull] Action<ImgurAuthenticationOptions> configuration) {
return services.Configure(configuration);
}

public static IApplicationBuilder UseImgurAuthentication([NotNull] this IApplicationBuilder app) {
return app.UseMiddleware<ImgurAuthenticationMiddleware>();
}

public static IApplicationBuilder UseImgurAuthentication(
[NotNull] this IApplicationBuilder app,
[NotNull] Action<ImgurAuthenticationOptions> configuration) {
return app.UseMiddleware<ImgurAuthenticationMiddleware>(
new ConfigureOptions<ImgurAuthenticationOptions>(configuration));
}
}
}
55 changes: 55 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/ImgurAuthenticationHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using System.Net.Http;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Threading.Tasks;
using AspNet.Security.OAuth.Extensions;
using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.Http.Authentication;
using Microsoft.Framework.Internal;
using Newtonsoft.Json.Linq;

namespace AspNet.Security.OAuth.Imgur {
public class ImgurAuthenticationHandler : OAuthHandler<ImgurAuthenticationOptions> {
public ImgurAuthenticationHandler([NotNull] HttpClient client)
: base(client) {
}

protected override async Task<AuthenticationTicket> CreateTicketAsync([NotNull] ClaimsIdentity identity,
[NotNull] AuthenticationProperties properties, [NotNull] OAuthTokenResponse tokens) {
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);

var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
response.EnsureSuccessStatusCode();

var payload = JObject.Parse(await response.Content.ReadAsStringAsync());

identity.AddOptionalClaim(ClaimTypes.NameIdentifier, ImgurAuthenticationHelper.GetId(payload), Options.ClaimsIssuer)
.AddOptionalClaim(ClaimTypes.Name, ImgurAuthenticationHelper.GetUrl(payload), Options.ClaimsIssuer)
.AddOptionalClaim("urn:imgur:reputation", ImgurAuthenticationHelper.GetReputation(payload), Options.ClaimsIssuer)
.AddOptionalClaim("urn:imgur:created", ImgurAuthenticationHelper.GetCreated(payload), Options.ClaimsIssuer)
.AddOptionalClaim("urn:imgur:proexpiration", ImgurAuthenticationHelper.GetProExpiration(payload), Options.ClaimsIssuer);

var context = new OAuthAuthenticatedContext(Context, Options, Backchannel, tokens, payload) {
Principal = new ClaimsPrincipal(identity),
Properties = properties
};

await Options.Events.Authenticated(context);

if (context.Principal?.Identity == null) {
return null;
}

return new AuthenticationTicket(context.Principal, context.Properties, context.Options.AuthenticationScheme);
}
}
}
52 changes: 52 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/ImgurAuthenticationHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using Microsoft.Framework.Internal;
using Newtonsoft.Json.Linq;

namespace AspNet.Security.OAuth.Imgur {
/// <summary>
/// Contains static methods that allow to extract user's information from a <see cref="JObject"/>
/// instance retrieved from Imgur after a successful authentication process.
/// </summary>
public static class ImgurAuthenticationHelper {
/// <summary>
/// Gets the id of the authenticated user.
/// </summary>
public static string GetId([NotNull] JObject user) => user.Value<JObject>("data")
?.Value<string>("id");

/// <summary>
/// Gets the url (name) of the authenticated user.
/// </summary>
public static string GetUrl([NotNull] JObject user) => user.Value<JObject>("data")
?.Value<string>("url");

/// <summary>
/// Gets the bio of the authenticated user.
/// </summary>
public static string GetBio([NotNull] JObject user) => user.Value<JObject>("data")
?.Value<string>("bio");

/// <summary>
/// Gets the reputation of the authenticated user.
/// </summary>
public static string GetReputation([NotNull] JObject user) => user.Value<JObject>("data")
?.Value<string>("reputation");

/// <summary>
/// Gets the epoch time of account creation of the authenticated user.
/// </summary>
public static string GetCreated([NotNull] JObject user) => user.Value<JObject>("data")
?.Value<string>("created");

/// <summary>
/// Gets the epoch time of the expiration of the pro account of the authenticated user.
/// </summary>
public static string GetProExpiration([NotNull] JObject user) => user.Value<JObject>("data")
?.Value<string>("pro_expiration");
}
}
34 changes: 34 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/ImgurAuthenticationMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using Microsoft.AspNet.Authentication;
using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.DataProtection;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Logging;
using Microsoft.Framework.OptionsModel;
using Microsoft.Framework.WebEncoders;

namespace AspNet.Security.OAuth.Imgur {
public class ImgurAuthenticationMiddleware : OAuthMiddleware<ImgurAuthenticationOptions> {
public ImgurAuthenticationMiddleware(
[NotNull] RequestDelegate next,
[NotNull] IDataProtectionProvider dataProtectionProvider,
[NotNull] ILoggerFactory loggerFactory,
[NotNull] IUrlEncoder encoder,
[NotNull] IOptions<SharedAuthenticationOptions> externalOptions,
[NotNull] IOptions<ImgurAuthenticationOptions> options,
ConfigureOptions<ImgurAuthenticationOptions> configureOptions = null)
: base(next, dataProtectionProvider, loggerFactory,
encoder, externalOptions, options, configureOptions) {
}

protected override AuthenticationHandler<ImgurAuthenticationOptions> CreateHandler() {
return new ImgurAuthenticationHandler(Backchannel);
}
}
}
29 changes: 29 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/ImgurAuthenticationOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
* for more information concerning the license and the contributors participating to this project.
*/

using Microsoft.AspNet.Authentication.OAuth;
using Microsoft.AspNet.Http;

namespace AspNet.Security.OAuth.Imgur {
/// <summary>
/// Defines a set of options used by <see cref="ImgurAuthenticationHandler"/>.
/// </summary>
public class ImgurAuthenticationOptions : OAuthOptions {
public ImgurAuthenticationOptions() {
AuthenticationScheme = ImgurAuthenticationDefaults.AuthenticationScheme;
Caption = ImgurAuthenticationDefaults.Caption;
ClaimsIssuer = ImgurAuthenticationDefaults.Issuer;

CallbackPath = new PathString(ImgurAuthenticationDefaults.CallbackPath);

AuthorizationEndpoint = ImgurAuthenticationDefaults.AuthorizationEndpoint;
TokenEndpoint = ImgurAuthenticationDefaults.TokenEndpoint;
UserInformationEndpoint = ImgurAuthenticationDefaults.UserInformationEndpoint;

SaveTokensAsClaims = false;
}
}
}
33 changes: 33 additions & 0 deletions src/AspNet.Security.OAuth.Imgur/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"version": "1.0.0-*",
"description": "ASP.NET 5 security middleware enabling Imgur authentication.",
"authors": [ "Albireo" ],
"owners": [ "Kévin Chalet", "Jerrie Pelser" ],

"projectUrl": "https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html",

"dependencies": {
"AspNet.Security.OAuth.Extensions": {
"type": "build",
"version": "1.0.0-*"
},

"Microsoft.AspNet.Authentication.OAuth": "1.0.0-*",

"Microsoft.Framework.NotNullAttribute.Internal": {
"type": "build",
"version": "1.0.0-*"
}
},

"frameworks": {
"dnx451": { },

"dnxcore50": {
"dependencies": {
"System.Security.Claims": "4.0.1-*"
}
}
}
}

0 comments on commit 7fba20f

Please sign in to comment.