diff --git a/src/SignClient/Program.cs b/src/SignClient/Program.cs index 72fa3b54..4a733007 100644 --- a/src/SignClient/Program.cs +++ b/src/SignClient/Program.cs @@ -24,11 +24,12 @@ public static int Main(string[] args) var description = cfg.Option("-d | --description", "Description", CommandOptionType.SingleValue); var descUrl = cfg.Option("-u | --descriptionUrl", "Description Url", CommandOptionType.SingleValue); var maxConcurrency = cfg.Option("-m | --maxConcurrency", "Maximum concurrency (default is 4)", CommandOptionType.SingleValue); + var loggingLevel = cfg.Option("-l | --logLevel", "Logging level (default is warn)", CommandOptionType.SingleValue); cfg.OnExecute(() => { var sign = new SignCommand(application); - return sign.Sign(configFile, inputFile, baseDirectory, outputFile, fileList, secret, user, name, description, descUrl, maxConcurrency); + return sign.Sign(configFile, inputFile, baseDirectory, outputFile, fileList, secret, user, name, description, descUrl, maxConcurrency, loggingLevel); }); }); diff --git a/src/SignClient/SignCommand.cs b/src/SignClient/SignCommand.cs index 196d54bc..d64d1d59 100644 --- a/src/SignClient/SignCommand.cs +++ b/src/SignClient/SignCommand.cs @@ -45,7 +45,8 @@ public int Sign CommandOption name, CommandOption description, CommandOption descriptionUrl, - CommandOption maxConcurrency + CommandOption maxConcurrency, + CommandOption loggingLevel ) { try @@ -89,6 +90,28 @@ CommandOption maxConcurrency baseDirectory.Values.Add(Environment.CurrentDirectory); } + var logLevel = LogLevel.Warning; + + if (loggingLevel.HasValue()) + { + if (!Enum.TryParse(typeof(LogLevel), loggingLevel.Value(), ignoreCase: true, out var logLevelObj)) + { + signCommandLineApplication.Error.WriteLine("--logLevel parameter invalid. Valid options are: error, warning, info, verbose"); + return EXIT_CODES.INVALID_OPTIONS; + } + + logLevel = (LogLevel)logLevelObj; + } + + void Log(string facility, LogLevel level, string message) + { + if (level <= logLevel) + { + var writer = level == LogLevel.Error ? signCommandLineApplication.Error : signCommandLineApplication.Out; + writer.WriteLine($"[{facility}][{level}] {message}"); + } + } + List inputFiles; // If we're going to glob, we can't be fully rooted currently (fix me later) @@ -130,11 +153,14 @@ CommandOption maxConcurrency var clientId = configuration["SignClient:AzureAd:ClientId"]; var resourceId = configuration["SignClient:Service:ResourceId"]; + var logMsal = new LogCallback((LogLevel level, string message, bool containsPii) => Log("MSAL", level, message)); + // See if we have a Username option if (username.HasValue()) { // ROPC flow var pca = PublicClientApplicationBuilder.Create(clientId) + .WithLogging(logMsal, logLevel, enablePiiLogging: false, enableDefaultPlatformLogging: true) .WithAuthority(authority) .Build(); @@ -142,23 +168,32 @@ CommandOption maxConcurrency getAccessToken = async () => { + Log("RESTCLIENT", LogLevel.Info, "Obtaining access token for PublicClientApplication."); + var tokenResult = await pca.AcquireTokenByUsernamePassword(new[] { $"{resourceId}/user_impersonation" }, username.Value(), secret).ExecuteAsync(); + Log("RESTCLIENT", LogLevel.Info, $"Obtained access token for PublicClientApplication. Correlation ID = {tokenResult.CorrelationId}; Expires on = {tokenResult.ExpiresOn}."); + return tokenResult.AccessToken; }; } else { var context = ConfidentialClientApplicationBuilder.Create(clientId) + .WithLogging(logMsal, logLevel, enablePiiLogging: false, enableDefaultPlatformLogging: true) .WithAuthority(authority) .WithClientSecret(clientSecret.Value()) .Build(); getAccessToken = async () => { - // Client credential flow - var res = await context.AcquireTokenForClient(new[] { $"{resourceId}/.default" }).ExecuteAsync(); - return res.AccessToken; + Log("RESTCLIENT", LogLevel.Info, "Obtaining access token for ConfidentialClientApplication."); + + var tokenResult = await context.AcquireTokenForClient(new[] { $"{resourceId}/.default" }).ExecuteAsync(); + + Log("RESTCLIENT", LogLevel.Info, $"Obtained access token for PublicClientApplication. Correlation ID = {tokenResult.CorrelationId}; Expires on = {tokenResult.ExpiresOn}."); + + return tokenResult.AccessToken; }; } @@ -284,7 +319,5 @@ string ExpandFilePath(string file) return file; } } - - } }