Skip to content

Localize strings in user-jwts tool #42061

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/Tools/dotnet-user-jwts/src/Commands/ClearCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ public static void Register(ProjectCommandLineApplication app)
{
app.Command("clear", cmd =>
{
cmd.Description = "Delete all issued JWTs for a project";
cmd.Description = Resources.ClearCommand_Description;

var forceOption = cmd.Option(
"--force",
"Don't prompt for confirmation before deleting JWTs",
Resources.ClearCommand_ForceOption_Description,
CommandOptionType.NoValue);

cmd.HelpOption("-h|--help");
Expand All @@ -39,16 +39,17 @@ private static int Execute(IReporter reporter, string projectPath, bool force)

if (count == 0)
{
reporter.Output($"There are no JWTs to delete from {project}.");
reporter.Output(Resources.FormatClearCommand_NoJwtsRemoved(project));
return 0;
}

if (!force)
{
reporter.Output($"Are you sure you want to delete {count} JWT(s) for {project}?{Environment.NewLine} [Y]es / [N]o");
reporter.Output(Resources.ClearCommand_Permission);
reporter.Output("[Y]es / [N]o");
if (Console.ReadLine().Trim().ToUpperInvariant() != "Y")
{
reporter.Output("Canceled, no JWTs were deleted.");
reporter.Output(Resources.ClearCommand_Canceled);
return 0;
}
}
Expand All @@ -62,7 +63,7 @@ private static int Execute(IReporter reporter, string projectPath, bool force)
jwtStore.Jwts.Clear();
jwtStore.Save();

reporter.Output($"Deleted {count} token(s) from {project} successfully.");
reporter.Output(Resources.FormatClearCommand_Confirmed(count, project));

return 0;
}
Expand Down
36 changes: 17 additions & 19 deletions src/Tools/dotnet-user-jwts/src/Commands/CreateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,59 +23,57 @@ public static void Register(ProjectCommandLineApplication app)
{
app.Command("create", cmd =>
{
cmd.Description = "Issue a new JSON Web Token";
cmd.Description = Resources.CreateCommand_Description;

var schemeNameOption = cmd.Option(
"--scheme",
"The scheme name to use for the generated token. Defaults to 'Bearer'",
Resources.CreateCommand_SchemeOption_Description,
CommandOptionType.SingleValue
);

var nameOption = cmd.Option(
"--name",
"The name of the user to create the JWT for. Defaults to the current environment user.",
Resources.CreateCommand_NameOption_Description,
CommandOptionType.SingleValue);

var audienceOption = cmd.Option(
"--audience",
"The audiences to create the JWT for. Defaults to the URLs configured in the project's launchSettings.json",
Resources.CreateCommand_AudienceOption_Description,
CommandOptionType.MultipleValue);

var issuerOption = cmd.Option(
"--issuer",
"The issuer of the JWT. Defaults to the dotnet-user-jwts",
Resources.CreateCommand_IssuerOption_Description,
CommandOptionType.SingleValue);

var scopesOption = cmd.Option(
"--scope",
"A scope claim to add to the JWT. Specify once for each scope.",
Resources.CreateCommand_ScopeOption_Description,
CommandOptionType.MultipleValue);

var rolesOption = cmd.Option(
"--role",
"A role claim to add to the JWT. Specify once for each role",
Resources.CreateCommand_RoleOption_Description,
CommandOptionType.MultipleValue);

var claimsOption = cmd.Option(
"--claim",
"Claims to add to the JWT. Specify once for each claim in the format \"name=value\"",
Resources.CreateCommand_ClaimOption_Description,
CommandOptionType.MultipleValue);

var notBeforeOption = cmd.Option(
"--not-before",
@"The UTC date & time the JWT should not be valid before in the format 'yyyy-MM-dd [[HH:mm[[:ss]]]]'. Defaults to the date & time the JWT is created",
Resources.CreateCommand_NotBeforeOption_Description,
CommandOptionType.SingleValue);

var expiresOnOption = cmd.Option(
"--expires-on",
@"The UTC date & time the JWT should expire in the format 'yyyy-MM-dd [[[[HH:mm]]:ss]]'. Defaults to 6 months after the --not-before date. " +
"Do not use this option in conjunction with the --valid-for option.",
Resources.CreateCommand_ExpiresOnOption_Description,
CommandOptionType.SingleValue);

var validForOption = cmd.Option(
"--valid-for",
"The period the JWT should expire after. Specify using a number followed by a period type like 'd' for days, 'h' for hours, " +
"'m' for minutes, and 's' for seconds, e.g. '365d'. Do not use this option in conjunction with the --expires-on option.",
Resources.CreateCommand_ValidForOption_Description,
CommandOptionType.SingleValue);

cmd.HelpOption("-h|--help");
Expand Down Expand Up @@ -117,7 +115,7 @@ private static (JwtCreatorOptions, bool) ValidateArguments(
var audience = audienceOption.HasValue() ? audienceOption.Values : DevJwtCliHelpers.GetAudienceCandidatesFromLaunchSettings(project).ToList();
if (audience is null)
{
reporter.Error("Could not determine the project's HTTPS URL. Please specify an audience for the JWT using the --audience option.");
reporter.Error(Resources.CreateCommand_NoAudience_Error);
isValid = false;
}
var issuer = issuerOption.HasValue() ? issuerOption.Value() : DevJwtsDefaults.Issuer;
Expand All @@ -127,7 +125,7 @@ private static (JwtCreatorOptions, bool) ValidateArguments(
{
if (!ParseDate(notBeforeOption.Value(), out notBefore))
{
reporter.Error(@"The date provided for --not-before could not be parsed. Dates must consist of a date and can include an optional timestamp.");
reporter.Error(Resources.FormatCreateCommand_InvalidDate_Error("--not-before"));
isValid = false;
}
}
Expand All @@ -137,7 +135,7 @@ private static (JwtCreatorOptions, bool) ValidateArguments(
{
if (!ParseDate(expiresOnOption.Value(), out expiresOn))
{
reporter.Error(@"The date provided for --expires-on could not be parsed. Dates must consist of a date and can include an optional timestamp.");
reporter.Error(Resources.FormatCreateCommand_InvalidDate_Error("--expires-on"));
isValid = false;
}
}
Expand All @@ -146,7 +144,7 @@ private static (JwtCreatorOptions, bool) ValidateArguments(
{
if (!TimeSpan.TryParseExact(validForOption.Value(), _timeSpanFormats, CultureInfo.InvariantCulture, out var validForValue))
{
reporter.Error("The period provided for --valid-for could not be parsed. Ensure you use a format like '10d', '22h', '45s' etc.");
reporter.Error(Resources.FormatCreateCommand_InvalidPeriod_Error("--valid-for"));
}
expiresOn = notBefore.Add(validForValue);
}
Expand All @@ -159,7 +157,7 @@ private static (JwtCreatorOptions, bool) ValidateArguments(
{
if (!DevJwtCliHelpers.TryParseClaims(claimsOption.Values, out claims))
{
reporter.Error("Malformed claims supplied. Ensure each claim is in the format \"name=value\".");
reporter.Error(Resources.CreateCommand_InvalidClaims_Error);
isValid = false;
}
}
Expand Down Expand Up @@ -197,7 +195,7 @@ private static int Execute(
var settingsToWrite = new JwtAuthenticationSchemeSettings(options.Scheme, options.Audiences, options.Issuer);
settingsToWrite.Save(appsettingsFilePath);

reporter.Output($"New JWT saved with ID '{jwtToken.Id}'.");
reporter.Output(Resources.FormatCreateCommand_Confirmed(jwtToken.Id));

return 0;
}
Expand Down
17 changes: 9 additions & 8 deletions src/Tools/dotnet-user-jwts/src/Commands/KeyCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ public static void Register(ProjectCommandLineApplication app)
{
app.Command("key", cmd =>
{
cmd.Description = "Display or reset the signing key used to issue JWTs";
cmd.Description = Resources.KeyCommand_Description;

var resetOption = cmd.Option(
"--reset",
"Reset the signing key. This will invalidate all previously issued JWTs for this project.",
Resources.KeyCommand_ResetOption_Description,
CommandOptionType.NoValue);

var forceOption = cmd.Option(
"--force",
"Don't prompt for confirmation before resetting the signing key.",
Resources.KeyCommand_ForceOption_Description,
CommandOptionType.NoValue);

cmd.HelpOption("-h|--help");
Expand All @@ -45,16 +45,17 @@ private static int Execute(IReporter reporter, string projectPath, bool reset, b
{
if (!force)
{
reporter.Output("Are you sure you want to reset the JWT signing key? This will invalidate all JWTs previously issued for this project.\n [Y]es / [N]o");
reporter.Output(Resources.KeyCommand_Permission);
reporter.Error("[Y]es / [N]o");
if (Console.ReadLine().Trim().ToUpperInvariant() != "Y")
{
reporter.Output("Key reset canceled.");
reporter.Output(Resources.KeyCommand_Canceled);
return 0;
}
}

var key = DevJwtCliHelpers.CreateSigningKeyMaterial(userSecretsId, reset: true);
reporter.Output($"New signing key created: {Convert.ToBase64String(key)}");
reporter.Output(Resources.FormatKeyCommand_KeyCreated(Convert.ToBase64String(key)));
return 0;
}

Expand All @@ -65,11 +66,11 @@ private static int Execute(IReporter reporter, string projectPath, bool reset, b

if (signingKeyMaterial is null)
{
reporter.Output("Signing key for JWTs was not found. One will be created automatically when the first JWT is created, or you can force creation of a key with the --reset option.");
reporter.Output(Resources.KeyCommand_KeyNotFound);
return 0;
}

reporter.Output($"Signing Key: {signingKeyMaterial}");
reporter.Output(Resources.FormatKeyCommand_Confirmed(signingKeyMaterial));
return 0;
}
}
10 changes: 5 additions & 5 deletions src/Tools/dotnet-user-jwts/src/Commands/ListCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ public static void Register(ProjectCommandLineApplication app)
{
app.Command("list", cmd =>
{
cmd.Description = "Lists the JWTs issued for the project";
cmd.Description = Resources.ListCommand_Description;

var showTokensOption = cmd.Option(
"--show-tokens",
"Indicates whether JWT base64 strings should be shown",
Resources.ListCommand_ShowTokenOption_Description,
CommandOptionType.NoValue);

cmd.HelpOption("-h|--help");
Expand All @@ -36,8 +36,8 @@ private static int Execute(IReporter reporter, string projectPath, bool showToke
}
var jwtStore = new JwtStore(userSecretsId);

reporter.Output($"Project: {project}");
reporter.Output($"User Secrets ID: {userSecretsId}");
reporter.Output(Resources.FormatListCommand_Project(project));
reporter.Output(Resources.FormatListCommand_UserSecretsId(userSecretsId));

if (jwtStore.Jwts is { Count: > 0 } jwts)
{
Expand Down Expand Up @@ -66,7 +66,7 @@ private static int Execute(IReporter reporter, string projectPath, bool showToke
}
else
{
reporter.Output("No JWTs created yet!");
reporter.Output(Resources.ListCommand_NoJwts);
}

return 0;
Expand Down
13 changes: 6 additions & 7 deletions src/Tools/dotnet-user-jwts/src/Commands/PrintCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ public static void Register(ProjectCommandLineApplication app)
{
app.Command("print", cmd =>
{
cmd.Description = "Print the details of a given JWT";
cmd.Description = Resources.PrintCommand_Description;

var idArgument = cmd.Argument("[id]", "The ID of the JWT to print");
var idArgument = cmd.Argument("[id]", Resources.PrintCommand_IdArgument_Description);

var showFullOption = cmd.Option(
"--show-full",
"Whether to show the full JWT contents in addition to the compact serialized format",
Resources.PrintCommand_ShowFullOption_Description,
CommandOptionType.NoValue);

cmd.HelpOption("-h|--help");
Expand All @@ -43,14 +43,13 @@ private static int Execute(IReporter reporter, string projectPath, string id, bo
}
var jwtStore = new JwtStore(userSecretsId);

if (!jwtStore.Jwts.ContainsKey(id))
if (!jwtStore.Jwts.TryGetValue(id, out var jwt))
{
reporter.Output($"No token with ID '{id}' found");
reporter.Output(Resources.FormatPrintCommand_NoJwtFound(id));
return 1;
}

reporter.Output($"Found JWT with ID '{id}'");
var jwt = jwtStore.Jwts[id];
reporter.Output(Resources.FormatPrintCommand_Confirmed(id));
JwtSecurityToken fullToken;

if (showFull)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public ProjectCommandLineApplication(IReporter reporter, bool throwOnUnexpectedA
{
ProjectOption = Option(
"-p|--project",
"The path of the project to operate on. Defaults to the project in the current directory",
Resources.ProjectOption_Description,
CommandOptionType.SingleValue);
Reporter = reporter;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

namespace Microsoft.AspNetCore.Authentication.JwtBearer.Tools;

internal sealed class DeleteCommand
internal sealed class RemoveCommand
{
public static void Register(ProjectCommandLineApplication app)
{
app.Command("delete", cmd =>
app.Command("remove", cmd =>
{
cmd.Description = "Delete a given JWT";
cmd.Description = Resources.RemoveCommand_Description;

var idArgument = cmd.Argument("[id]", "The ID of the JWT to delete");
var idArgument = cmd.Argument("[id]", Resources.RemoveCommand_IdArgument_Description);
cmd.HelpOption("-h|--help");

cmd.OnExecute(() =>
Expand All @@ -39,7 +39,7 @@ private static int Execute(IReporter reporter, string projectPath, string id)

if (!jwtStore.Jwts.ContainsKey(id))
{
reporter.Error($"[ERROR] No JWT with ID '{id}' found");
reporter.Error(Resources.FormatRemoveCommand_NoJwtFound(id));
return 1;
}

Expand All @@ -49,7 +49,7 @@ private static int Execute(IReporter reporter, string projectPath, string id)
jwtStore.Jwts.Remove(id);
jwtStore.Save();

reporter.Output($"Deleted JWT with ID '{id}'");
reporter.Output(Resources.FormatRemoveCommand_Confirmed(id));

return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Tools/dotnet-user-jwts/src/Helpers/DevJwtCliHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public static string[] GetAudienceCandidatesFromLaunchSettings(string project)
var value = applicationUrl.GetString();
if (value is { } applicationUrls)
{
return applicationUrls.Split(";");
return applicationUrls.Split(';');
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Tools/dotnet-user-jwts/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ public void Run(string[] args)
CreateCommand.Register(userJwts);
// dotnet user-jwts print ecd045
PrintCommand.Register(userJwts);
// dotnet user-jwts delete ecd045
DeleteCommand.Register(userJwts);
// dotnet user-jwts remove ecd045
RemoveCommand.Register(userJwts);
// dotnet user-jwts clear
ClearCommand.Register(userJwts);
// dotnet user-jwts key
Expand Down
Loading