annotate src/conv.rs @ 73:ac6881304c78

Do conversations, along with way too much stuff. This implements conversations, along with all the memory management brouhaha that goes along with it. The conversation now lives directly on the handle rather than being a thing you have to get from it and then call manually. It Turns Out this makes things a lot easier! I guess we reorganized things again. For the last time. For real. I promise. This all passes ASAN, so it seems Pretty Good!
author Paul Fisher <paul@pfish.zone>
date Thu, 05 Jun 2025 03:41:38 -0400
parents 47eb242a4f88
children c7c596e6388f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
1 //! The PAM conversation and associated Stuff.
60
05cc2c27334f The Big Refactor: clean up docs and exports.
Paul Fisher <paul@pfish.zone>
parents: 59
diff changeset
2
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
3 // Temporarily allowed until we get the actual conversation functions hooked up.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
4 #![allow(dead_code)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
5
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
6 use crate::constants::Result;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
7 use crate::ErrorCode;
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
8 use secure_string::SecureString;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
9 // TODO: In most cases, we should be passing around references to strings
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
10 // or binary data. Right now we don't because that turns type inference and
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
11 // trait definitions/implementations into a HUGE MESS.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
12 //
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
13 // Ideally, we would be using some kind of `TD: TextData` and `BD: BinaryData`
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
14 // associated types in the various Conversation traits to avoid copying
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
15 // when unnecessary.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
16
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
17 /// The types of message and request that can be sent to a user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
18 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
19 /// The data within each enum value is the prompt (or other information)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
20 /// that will be presented to the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
21 #[derive(Clone, Copy, Debug)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
22 pub enum Message<'a> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
23 /// Requests information from the user; will be masked when typing.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
24 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
25 /// Response: [`MaskedText`](Response::MaskedText)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
26 MaskedPrompt(&'a str),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
27 /// Requests information from the user; will not be masked.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
28 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
29 /// Response: [`Text`](Response::Text)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
30 Prompt(&'a str),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
31 /// "Yes/No/Maybe conditionals" (a Linux-PAM extension).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
32 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
33 /// Response: [`Text`](Response::Text)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
34 /// (Linux-PAM documentation doesn't define its contents.)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
35 RadioPrompt(&'a str),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
36 /// Raises an error message to the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
37 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
38 /// Response: [`NoResponse`](Response::NoResponse)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
39 Error(&'a str),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
40 /// Sends an informational message to the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
41 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
42 /// Response: [`NoResponse`](Response::NoResponse)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
43 Info(&'a str),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
44 /// Requests binary data from the client (a Linux-PAM extension).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
45 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
46 /// This is used for non-human or non-keyboard prompts (security key?).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
47 /// NOT part of the X/Open PAM specification.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
48 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
49 /// Response: [`Binary`](Response::Binary)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
50 BinaryPrompt {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
51 /// Some binary data.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
52 data: &'a [u8],
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
53 /// A "type" that you can use for signalling. Has no strict definition in PAM.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
54 data_type: u8,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
55 },
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
56 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
57
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
58 /// The responses that PAM will return from a request.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
59 #[derive(Debug, PartialEq, derive_more::From)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
60 pub enum Response {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
61 /// Used to fill in list entries where there is no response expected.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
62 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
63 /// Used in response to:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
64 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
65 /// - [`Error`](Message::Error)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
66 /// - [`Info`](Message::Info)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
67 NoResponse,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
68 /// A response with text data from the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
69 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
70 /// Used in response to:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
71 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
72 /// - [`Prompt`](Message::Prompt)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
73 /// - [`RadioPrompt`](Message::RadioPrompt) (a Linux-PAM extension)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
74 Text(String),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
75 /// A response to a masked request with text data from the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
76 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
77 /// Used in response to:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
78 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
79 /// - [`MaskedPrompt`](Message::MaskedPrompt)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
80 MaskedText(SecureString),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
81 /// A response to a binary request (a Linux-PAM extension).
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
82 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
83 /// Used in response to:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
84 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
85 /// - [`BinaryPrompt`](Message::BinaryPrompt)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
86 Binary(BinaryData),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
87 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
88
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
89 /// The function type for a conversation.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
90 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
91 /// A macro to save typing `FnMut(&[Message]) -> Result<Vec<Response>>`.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
92 #[macro_export]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
93 macro_rules! conv_type {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
94 () => {FnMut(&[Message]) -> Result<Vec<Response>>};
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
95 (impl) => { impl FnMut(&[Message]) -> Result<Vec<Response>> }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
96 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
97
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
98 /// A channel for PAM modules to request information from the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
99 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
100 /// This trait is used by both applications and PAM modules:
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
101 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
102 /// - Applications implement Conversation and provide a user interface
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
103 /// to allow the user to respond to PAM questions.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
104 /// - Modules call a Conversation implementation to request information
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
105 /// or send information to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
106 pub trait Conversation {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
107 /// Sends messages to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
108 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
109 /// The returned Vec of messages always contains exactly as many entries
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
110 /// as there were messages in the request; one corresponding to each.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
111 fn converse(&mut self, messages: &[Message]) -> Result<Vec<Response>>;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
112 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
113
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
114 fn conversation_func(func: conv_type!(impl)) -> impl Conversation {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
115 Convo(func)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
116 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
117
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
118 struct Convo<C: FnMut(&[Message]) -> Result<Vec<Response>>>(C);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
119
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
120 impl<C: FnMut(&[Message]) -> Result<Vec<Response>>> Conversation for Convo<C> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
121 fn converse(&mut self, messages: &[Message]) -> Result<Vec<Response>> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
122 self.0(messages)
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
123 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
124 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
125
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
126 /// Provides methods to make it easier to send exactly one message.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
127 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
128 /// This is primarily used by PAM modules, so that a module that only needs
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
129 /// one piece of information at a time doesn't have a ton of boilerplate.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
130 /// You may also find it useful for testing PAM application libraries.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
131 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
132 /// ```
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
133 /// # use nonstick::{PamHandleModule, Conversation, Result};
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
134 /// # fn _do_test(mut pam_handle: impl PamHandleModule) -> Result<()> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
135 /// use nonstick::ConversationMux;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
136 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
137 /// let token = pam_handle.masked_prompt("enter your one-time token")?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
138 /// # Ok(())
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
139 /// # }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
140 pub trait ConversationMux {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
141 /// Prompts the user for something.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
142 fn prompt(&mut self, request: &str) -> Result<String>;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
143 /// Prompts the user for something, but hides what the user types.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
144 fn masked_prompt(&mut self, request: &str) -> Result<SecureString>;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
145 /// Prompts the user for a yes/no/maybe conditional (a Linux-PAM extension).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
146 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
147 /// PAM documentation doesn't define the format of the response.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
148 fn radio_prompt(&mut self, request: &str) -> Result<String>;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
149 /// Alerts the user to an error.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
150 fn error(&mut self, message: &str);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
151 /// Sends an informational message to the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
152 fn info(&mut self, message: &str);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
153 /// Requests binary data from the user (a Linux-PAM extension).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
154 fn binary_prompt(&mut self, data: &[u8], data_type: u8) -> Result<BinaryData>;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
155 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
156
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
157 impl<C: Conversation> ConversationMux for C {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
158 /// Prompts the user for something.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
159 fn prompt(&mut self, request: &str) -> Result<String> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
160 let resp = self.converse(&[Message::Prompt(request)])?.pop();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
161 match resp {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
162 Some(Response::Text(s)) => Ok(s),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
163 _ => Err(ErrorCode::ConversationError),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
164 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
165 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
166
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
167 /// Prompts the user for something, but hides what the user types.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
168 fn masked_prompt(&mut self, request: &str) -> Result<SecureString> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
169 let resp = self.converse(&[Message::MaskedPrompt(request)])?.pop();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
170 match resp {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
171 Some(Response::MaskedText(s)) => Ok(s),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
172 _ => Err(ErrorCode::ConversationError),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
173 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
174 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
175
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
176 /// Prompts the user for a yes/no/maybe conditional (a Linux-PAM extension).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
177 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
178 /// PAM documentation doesn't define the format of the response.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
179 fn radio_prompt(&mut self, request: &str) -> Result<String> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
180 let resp = self.converse(&[Message::RadioPrompt(request)])?.pop();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
181 match resp {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
182 Some(Response::Text(s)) => Ok(s),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
183 _ => Err(ErrorCode::ConversationError),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
184 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
185 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
186
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
187 /// Alerts the user to an error.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
188 fn error(&mut self, message: &str) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
189 let _ = self.converse(&[Message::Error(message)]);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
190 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
191
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
192 /// Sends an informational message to the user.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
193 fn info(&mut self, message: &str) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
194 let _ = self.converse(&[Message::Info(message)]);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
195 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
196
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
197 /// Requests binary data from the user (a Linux-PAM extension).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
198 fn binary_prompt(&mut self, data: &[u8], data_type: u8) -> Result<BinaryData> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
199 let resp = self
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
200 .converse(&[Message::BinaryPrompt { data, data_type }])?
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
201 .pop();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
202 match resp {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
203 Some(Response::Binary(d)) => Ok(d),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
204 _ => Err(ErrorCode::ConversationError),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
205 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
206 }
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
207 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
208
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
209 /// Trait that an application can implement if they want to handle messages
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
210 /// one at a time.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
211 pub trait DemuxedConversation {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
212 /// Prompts the user for some text.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
213 fn prompt(&mut self, request: &str) -> Result<String>;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
214 /// Prompts the user for some text, but hides their typing.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
215 fn masked_prompt(&mut self, request: &str) -> Result<SecureString>;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
216 /// Prompts the user for a radio option (a Linux-PAM extension).
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
217 ///
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
218 /// The Linux-PAM documentation doesn't give the format of the response.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
219 fn radio_prompt(&mut self, request: &str) -> Result<String>;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
220 /// Alerts the user to an error.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
221 fn error(&mut self, message: &str);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
222 /// Sends an informational message to the user.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
223 fn info(&mut self, message: &str);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
224 /// Requests binary data from the user (a Linux-PAM extension).
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
225 fn binary_prompt(&mut self, data: &[u8], data_type: u8) -> Result<BinaryData>;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
226 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
227
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
228 impl<DM> Conversation for DM
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
229 where
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
230 DM: DemuxedConversation,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
231 {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
232 fn converse(&mut self, messages: &[Message]) -> Result<Vec<Response>> {
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
233 messages
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
234 .iter()
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
235 .map(|msg| match *msg {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
236 Message::Prompt(prompt) => self.prompt(prompt).map(Response::from),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
237 Message::MaskedPrompt(prompt) => self.masked_prompt(prompt).map(Response::from),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
238 Message::RadioPrompt(prompt) => self.radio_prompt(prompt).map(Response::from),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
239 Message::Info(message) => {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
240 self.info(message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
241 Ok(Response::NoResponse)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
242 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
243 Message::Error(message) => {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
244 self.error(message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
245 Ok(Response::NoResponse)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
246 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
247 Message::BinaryPrompt { data_type, data } => {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
248 self.binary_prompt(data, data_type).map(Response::from)
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
249 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
250 })
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
251 .collect()
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
252 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
253 }
15
27730595f1ea Adding pam-http module
Anthony Nowell <anthony@algorithmia.com>
parents:
diff changeset
254
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
255 /// Owned binary data.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
256 #[derive(Debug, PartialEq)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
257 pub struct BinaryData {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
258 data: Vec<u8>,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
259 data_type: u8,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
260 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
261
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
262 impl BinaryData {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
263 pub fn new(data: Vec<u8>, data_type: u8) -> Self {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
264 Self { data, data_type }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
265 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
266 pub fn data(&self) -> &[u8] {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
267 &self.data
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
268 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
269 pub fn data_type(&self) -> u8 {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
270 self.data_type
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
271 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
272 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
273
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
274 impl From<BinaryData> for Vec<u8> {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
275 /// Extracts the inner vector from the BinaryData.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
276 fn from(value: BinaryData) -> Self {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
277 value.data
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
278 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
279 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
280
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
281 #[cfg(test)]
71
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
282 mod tests {
58f9d2a4df38 Reorganize everything again???
Paul Fisher <paul@pfish.zone>
parents: 70
diff changeset
283 use super::{Conversation, DemuxedConversation, Message, Response, SecureString};
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
284 use crate::constants::ErrorCode;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
285
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
286 #[test]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
287 fn test_demux() {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
288 #[derive(Default)]
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
289 struct DemuxTester {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
290 error_ran: bool,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
291 info_ran: bool,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
292 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
293
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
294 impl DemuxedConversation for DemuxTester {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
295 fn prompt(&mut self, request: &str) -> crate::Result<String> {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
296 match request {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
297 "what" => Ok("whatwhat".to_owned()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
298 "give_err" => Err(ErrorCode::PermissionDenied),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
299 _ => panic!("unexpected prompt!"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
300 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
301 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
302 fn masked_prompt(&mut self, request: &str) -> crate::Result<SecureString> {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
303 assert_eq!("reveal", request);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
304 Ok(SecureString::from("my secrets"))
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
305 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
306 fn radio_prompt(&mut self, request: &str) -> crate::Result<String> {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
307 assert_eq!("channel?", request);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
308 Ok("zero".to_owned())
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
309 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
310 fn error(&mut self, message: &str) {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
311 self.error_ran = true;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
312 assert_eq!("whoopsie", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
313 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
314 fn info(&mut self, message: &str) {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
315 self.info_ran = true;
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
316 assert_eq!("did you know", message);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
317 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
318 fn binary_prompt(
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
319 &mut self,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
320 data: &[u8],
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
321 data_type: u8,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
322 ) -> crate::Result<super::BinaryData> {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
323 assert_eq!(&[10, 9, 8], data);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
324 assert_eq!(66, data_type);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
325 Ok(super::BinaryData::new(vec![5, 5, 5], 5))
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
326 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
327 }
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
328
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
329 let mut tester = DemuxTester::default();
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
330
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
331 assert_eq!(
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
332 vec![
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
333 Response::Text("whatwhat".to_owned()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
334 Response::MaskedText("my secrets".into()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
335 Response::NoResponse,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
336 Response::NoResponse,
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
337 ],
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
338 tester
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
339 .converse(&[
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
340 Message::Prompt("what"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
341 Message::MaskedPrompt("reveal"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
342 Message::Error("whoopsie"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
343 Message::Info("did you know"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
344 ])
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
345 .unwrap()
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
346 );
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
347 assert!(tester.error_ran);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
348 assert!(tester.info_ran);
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
349
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
350 assert_eq!(
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
351 ErrorCode::PermissionDenied,
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
352 tester.converse(&[Message::Prompt("give_err")]).unwrap_err(),
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
353 );
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
354
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
355 // Test the Linux-PAM extensions separately.
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
356
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
357 assert_eq!(
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
358 vec![
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
359 Response::Text("zero".to_owned()),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
360 Response::Binary(super::BinaryData::new(vec![5, 5, 5], 5)),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
361 ],
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
362 tester
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
363 .converse(&[
70
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
364 Message::RadioPrompt("channel?"),
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
365 Message::BinaryPrompt {
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
366 data: &[10, 9, 8],
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
367 data_type: 66
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
368 },
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
369 ])
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
370 .unwrap()
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
371 );
9f8381a1c09c Implement low-level conversation primitives.
Paul Fisher <paul@pfish.zone>
parents: 69
diff changeset
372 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
373
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
374 #[test]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
375 fn test_mux() {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
376 use super::ConversationMux;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
377 struct MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
378
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
379 impl Conversation for MuxTester {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
380 fn converse(&mut self, messages: &[Message]) -> crate::Result<Vec<Response>> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
381 if let [msg] = messages {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
382 match msg {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
383 Message::Info(info) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
384 assert_eq!("let me tell you", *info);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
385 Ok(vec![Response::NoResponse])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
386 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
387 Message::Error(error) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
388 assert_eq!("oh no", *error);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
389 Ok(vec![Response::NoResponse])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
390 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
391 Message::Prompt("should_error") => Err(ErrorCode::BufferError),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
392 Message::Prompt(ask) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
393 assert_eq!("question", *ask);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
394 Ok(vec![Response::Text("answer".to_owned())])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
395 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
396 Message::MaskedPrompt("return_wrong_type") => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
397 Ok(vec![Response::NoResponse])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
398 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
399 Message::MaskedPrompt(ask) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
400 assert_eq!("password!", *ask);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
401 Ok(vec![Response::MaskedText(SecureString::from(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
402 "open sesame",
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
403 ))])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
404 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
405 Message::BinaryPrompt { data, data_type } => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
406 assert_eq!(&[1, 2, 3], data);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
407 assert_eq!(69, *data_type);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
408 Ok(vec![Response::Binary(super::BinaryData::new(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
409 vec![3, 2, 1],
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
410 42,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
411 ))])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
412 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
413 Message::RadioPrompt(ask) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
414 assert_eq!("radio?", *ask);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
415 Ok(vec![Response::Text("yes".to_owned())])
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
416 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
417 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
418 } else {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
419 panic!("messages is the wrong size ({len})", len = messages.len())
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
420 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
421 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
422 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
423
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
424 let mut tester = MuxTester;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
425
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
426 assert_eq!("answer", tester.prompt("question").unwrap());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
427 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
428 SecureString::from("open sesame"),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
429 tester.masked_prompt("password!").unwrap()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
430 );
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
431 tester.error("oh no");
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
432 tester.info("let me tell you");
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
433 {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
434 assert_eq!("yes", tester.radio_prompt("radio?").unwrap());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
435 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
436 super::BinaryData::new(vec![3, 2, 1], 42),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
437 tester.binary_prompt(&[1, 2, 3], 69).unwrap(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
438 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
439 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
440 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
441 ErrorCode::BufferError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
442 tester.prompt("should_error").unwrap_err(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
443 );
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
444 assert_eq!(
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
445 ErrorCode::ConversationError,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
446 tester.masked_prompt("return_wrong_type").unwrap_err()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
447 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents: 72
diff changeset
448 }
69
8f3ae0c7ab92 Rework conversation data types and make safe wrappers.
Paul Fisher <paul@pfish.zone>
parents: 64
diff changeset
449 }