generator-aspnet-oauth 6.0.0 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/generators/app/index.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
const fetch = require('cross-fetch');
|
|
3
|
+
const Generator = require('yeoman-generator');
|
|
4
|
+
const queryString = require('query-string');
|
|
5
|
+
const yosay = require('yosay');
|
|
5
6
|
|
|
6
|
-
module.exports =
|
|
7
|
-
initializing: function() {
|
|
8
|
-
this.templatedata = {};
|
|
7
|
+
module.exports = class extends Generator {
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
var done = this.async();
|
|
9
|
+
initializing() {
|
|
10
|
+
this.templateData = {};
|
|
11
|
+
this.log(yosay('Welcome to the classy ASP.NET OAuth Provider generator!'));
|
|
12
|
+
}
|
|
15
13
|
|
|
16
|
-
|
|
14
|
+
async prompting() {
|
|
15
|
+
const prompts = [{
|
|
17
16
|
type: 'input',
|
|
18
17
|
name: 'name',
|
|
19
18
|
message: 'What is the name of the provider you want to create?',
|
|
@@ -44,29 +43,76 @@ module.exports = yeoman.generators.Base.extend({
|
|
|
44
43
|
store: true
|
|
45
44
|
}];
|
|
46
45
|
|
|
47
|
-
this.prompt(prompts
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
writing
|
|
62
|
-
this.fs.copyTpl(this.templatePath('Project.csproj'), this.
|
|
63
|
-
this.fs.copyTpl(this.templatePath('AuthenticationDefaults.cs'), this.
|
|
64
|
-
this.fs.copyTpl(this.templatePath('AuthenticationExtensions.cs'), this.
|
|
65
|
-
this.fs.copyTpl(this.templatePath('AuthenticationHandler.cs'), this.
|
|
66
|
-
this.fs.copyTpl(this.templatePath('AuthenticationOptions.cs'), this.
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
46
|
+
const answers = await this.prompt(prompts);
|
|
47
|
+
|
|
48
|
+
this.templateData.name = answers.name;
|
|
49
|
+
this.templateData.authorname = answers.authorname;
|
|
50
|
+
this.templateData.authorizationendpoint = answers.authorizationendpoint;
|
|
51
|
+
this.templateData.tokenendpoint = answers.tokenendpoint;
|
|
52
|
+
this.templateData.userinformationendpoint = answers.userinformationendpoint;
|
|
53
|
+
|
|
54
|
+
this.templateData.currentVersion = await this.getCurrentVersion();
|
|
55
|
+
|
|
56
|
+
this.name = answers.name;
|
|
57
|
+
this.applicationName = 'AspNet.Security.OAuth.' + answers.name;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
writing() {
|
|
61
|
+
this.fs.copyTpl(this.templatePath('Project.csproj'), this.applicationName + '/' + this.applicationName + '.csproj', this.templateData)
|
|
62
|
+
this.fs.copyTpl(this.templatePath('AuthenticationDefaults.cs'), this.applicationName + '/' + this.name + 'AuthenticationDefaults.cs', this.templateData)
|
|
63
|
+
this.fs.copyTpl(this.templatePath('AuthenticationExtensions.cs'), this.applicationName + '/' + this.name + 'AuthenticationExtensions.cs', this.templateData)
|
|
64
|
+
this.fs.copyTpl(this.templatePath('AuthenticationHandler.cs'), this.applicationName + '/' + this.name + 'AuthenticationHandler.cs', this.templateData)
|
|
65
|
+
this.fs.copyTpl(this.templatePath('AuthenticationOptions.cs'), this.applicationName + '/' + this.name + 'AuthenticationOptions.cs', this.templateData)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async getCurrentVersion() {
|
|
69
|
+
|
|
70
|
+
let response = await fetch('https://api.nuget.org/v3/index.json');
|
|
71
|
+
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
throw new Error(`Failed to query NuGet service index. HTTP status code: ${response.status}.`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const serviceIndex = await response.json();
|
|
77
|
+
const baseAddress = serviceIndex.resources.find(resource => resource['@type'] === 'SearchQueryService/3.5.0')['@id'];
|
|
78
|
+
|
|
79
|
+
if (!baseAddress) {
|
|
80
|
+
throw new Error('Failed to determine the base address for the NuGet search query service.');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const query = queryString.stringify({
|
|
84
|
+
prerelease: false,
|
|
85
|
+
q: 'PackageId:AspNet.Security.OAuth.GitHub',
|
|
86
|
+
semVerLevel: '2.0.0',
|
|
87
|
+
take: 1
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const searchUrl = `${baseAddress}?${query}`;
|
|
91
|
+
response = await fetch(searchUrl);
|
|
92
|
+
|
|
93
|
+
if (!response.ok) {
|
|
94
|
+
throw new Error(`Failed to search for NuGet package from '${searchUrl}'. HTTP status code: ${response.status}.`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const searchResult = await response.json();
|
|
98
|
+
|
|
99
|
+
let latestVersion = null;
|
|
100
|
+
|
|
101
|
+
if (searchResult.data && searchResult.data.length > 0) {
|
|
102
|
+
latestVersion = searchResult.data[0].version;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!latestVersion) {
|
|
106
|
+
throw new Error('Failed to determine the latest version of the OAuth providers.');
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const dot = '.';
|
|
110
|
+
const versionParts = latestVersion.split(dot);
|
|
111
|
+
|
|
112
|
+
// Increment the build number by one for the release that
|
|
113
|
+
// would be the first one including this new provider.
|
|
114
|
+
versionParts[2] = parseInt(versionParts[2], 10) + 1;
|
|
115
|
+
|
|
116
|
+
return versionParts.join(dot);
|
|
71
117
|
}
|
|
72
|
-
}
|
|
118
|
+
};
|
|
@@ -18,7 +18,7 @@ namespace AspNet.Security.OAuth.<%= name %>;
|
|
|
18
18
|
/// <summary>
|
|
19
19
|
/// Defines a handler for authentication using <%= name %>.
|
|
20
20
|
/// </summary>
|
|
21
|
-
public class <%= name %>AuthenticationHandler : OAuthHandler<<%= name %>AuthenticationOptions>
|
|
21
|
+
public partial class <%= name %>AuthenticationHandler : OAuthHandler<<%= name %>AuthenticationOptions>
|
|
22
22
|
{
|
|
23
23
|
/// <summary>
|
|
24
24
|
/// Initializes a new instance of the <see cref="<%= name %>AuthenticationHandler"/> class.
|
|
@@ -45,23 +45,18 @@ public class <%= name %>AuthenticationHandler : OAuthHandler<<%= name %>Authenti
|
|
|
45
45
|
var endpoint = Options.UserInformationEndpoint;
|
|
46
46
|
|
|
47
47
|
// TODO Append any additional query string parameters required
|
|
48
|
-
|
|
48
|
+
////endpoint = QueryHelpers.AddQueryString(endpoint, "token", tokens.AccessToken);
|
|
49
49
|
|
|
50
50
|
using var request = new HttpRequestMessage(HttpMethod.Get, endpoint);
|
|
51
51
|
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
|
52
52
|
|
|
53
53
|
// TODO Add any HTTP request headers required
|
|
54
|
-
|
|
54
|
+
////request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
|
|
55
55
|
|
|
56
56
|
using var response = await Backchannel.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, Context.RequestAborted);
|
|
57
57
|
if (!response.IsSuccessStatusCode)
|
|
58
58
|
{
|
|
59
|
-
|
|
60
|
-
"returned a {Status} response with the following payload: {Headers} {Body}.",
|
|
61
|
-
/* Status: */ response.StatusCode,
|
|
62
|
-
/* Headers: */ response.Headers.ToString(),
|
|
63
|
-
/* Body: */ await response.Content.ReadAsStringAsync());
|
|
64
|
-
|
|
59
|
+
await Log.UserProfileErrorAsync(Logger, response, Context.RequestAborted);
|
|
65
60
|
throw new HttpRequestException("An error occurred while retrieving the user profile from <%= name %>.");
|
|
66
61
|
}
|
|
67
62
|
|
|
@@ -74,4 +69,23 @@ public class <%= name %>AuthenticationHandler : OAuthHandler<<%= name %>Authenti
|
|
|
74
69
|
await Events.CreatingTicket(context);
|
|
75
70
|
return new AuthenticationTicket(context.Principal!, context.Properties, Scheme.Name);
|
|
76
71
|
}
|
|
72
|
+
|
|
73
|
+
private static partial class Log
|
|
74
|
+
{
|
|
75
|
+
internal static async Task UserProfileErrorAsync(ILogger logger, HttpResponseMessage response, CancellationToken cancellationToken)
|
|
76
|
+
{
|
|
77
|
+
UserProfileError(
|
|
78
|
+
logger,
|
|
79
|
+
response.StatusCode,
|
|
80
|
+
response.Headers.ToString(),
|
|
81
|
+
await response.Content.ReadAsStringAsync(cancellationToken));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
[LoggerMessage(1, LogLevel.Error, "An error occurred while retrieving the user profile: the remote server returned a {Status} response with the following payload: {Headers} {Body}.")]
|
|
85
|
+
private static partial void UserProfileError(
|
|
86
|
+
ILogger logger,
|
|
87
|
+
System.Net.HttpStatusCode status,
|
|
88
|
+
string headers,
|
|
89
|
+
string body);
|
|
90
|
+
}
|
|
77
91
|
}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
<Project Sdk="Microsoft.NET.Sdk">
|
|
2
2
|
|
|
3
3
|
<PropertyGroup>
|
|
4
|
+
<PackageValidationBaselineVersion><%= currentVersion %></PackageValidationBaselineVersion>
|
|
4
5
|
<TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
|
|
5
6
|
</PropertyGroup>
|
|
6
7
|
|
|
8
|
+
<!-- This property group is required until the new provider is first published to NuGet.org -->
|
|
9
|
+
<PropertyGroup>
|
|
10
|
+
<DisablePackageBaselineValidation>true</DisablePackageBaselineValidation>
|
|
11
|
+
</PropertyGroup>
|
|
12
|
+
|
|
7
13
|
<PropertyGroup>
|
|
8
14
|
<Description>ASP.NET Core security provider enabling <%= name %> authentication.</Description>
|
|
9
15
|
<Authors><%= authorname %></Authors>
|
package/package.json
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "generator-aspnet-oauth",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "Yeoman generator for OAuth Providers for ASP.NET Core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "app/index.js",
|
|
7
7
|
"repository": "aspnet-contrib/generator-aspnet-oauth",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=14"
|
|
10
|
+
},
|
|
8
11
|
"author": {
|
|
9
12
|
"name": "Jerrie Pelser",
|
|
10
13
|
"email": "jerrie@jerriepelser.com",
|
|
@@ -23,11 +26,15 @@
|
|
|
23
26
|
"oauth"
|
|
24
27
|
],
|
|
25
28
|
"dependencies": {
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"yosay": "^
|
|
29
|
+
"cross-fetch": "^3.1.5",
|
|
30
|
+
"query-string": "^7.1.1",
|
|
31
|
+
"yosay": "^2.0.2",
|
|
32
|
+
"yeoman-generator": "^5.7.0"
|
|
29
33
|
},
|
|
30
34
|
"devDependencies": {
|
|
31
|
-
"
|
|
35
|
+
"glob": "^8.0.3",
|
|
36
|
+
"mocha": "^10.1.0",
|
|
37
|
+
"yeoman-assert": "^3.1.1",
|
|
38
|
+
"yeoman-test": "^6.3.0"
|
|
32
39
|
}
|
|
33
40
|
}
|