Skip to content

confirm plugin command implemented incorrectly #6

Description

@davidmatson

Three related issues with the confirm command implementation, per docs:

  1. The confirm command takes Base64 (unpadded) encoded values for the yes and no strings. The current implementation does not base64-decode them.
  2. The ok response must have either a "yes" or "no" value in the command argument. The current implementation uses an empty argument array.
  3. The user likely should not be required to type or copy/paste in the full displayed text and instead should just give a simple simple yes/no indication. (Upstream age, for example, uses just 1 and 2, IIRC).

Here's corrected code (.NET Standard 2.0) for the first two issues:

        private void HandleConfirm(PluginConnection conn, string[] args, byte[] body)
        {
            var message = EncodingExtended.UTF8.GetString(body);
            var yes = args.Length > 0 ? EncodingExtended.UTF8.GetString(Base64Unpadded.Decode(args[0].AsSpan())) : "yes";
            var no = args.Length > 1 ? EncodingExtended.UTF8.GetString(Base64Unpadded.Decode(args[1].AsSpan())) : null;
            var confirmed = _callbacks.Confirm(message, yes, no);
            conn.WriteStanza("ok", new[] { confirmed ? "yes" : "no" }, Array.Empty<byte>());
        }

Here's suggested code (.NET Standard 2.0) for the third issue:

            public bool Confirm(string message, string yes, string no)
            {
                var options = $"[y: {yes}/n: {no ?? "no"}] (y/N): ";
                Console.Error.Write($"{message} {options}");
                string response;
                bool result;
                bool first = true;

                do
                {
                    if (!first)
                    {
                        Console.Error.Write("Please enter y (yes) or n (no) (y/N): ");
                    }

                    response = Console.ReadLine()?.Trim() ?? "";
                    first = false;
                } while (!TryParseConfirmResponse(response, out result));

                return result;
            }

            private static bool TryParseConfirmResponse(string response, out bool parsed)
            {
                if (response.Equals("y", StringComparison.OrdinalIgnoreCase) ||
                    response.Equals("yes", StringComparison.OrdinalIgnoreCase))
                {
                    parsed = true;
                    return true;
                }
                else if (response.Length == 0 ||
                    response.Equals("n", StringComparison.OrdinalIgnoreCase) ||
                    response.Equals("no", StringComparison.OrdinalIgnoreCase))
                {
                    parsed = false;
                    return true;
                }
                else
                {
                    parsed = default;
                    return false;
                }
            }
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions