oauth1_request/signature_method/
plaintext.rs

1//! The `PLAINTEXT` signature method ([RFC 5849 section 3.4.4.][rfc]).
2//!
3//! [rfc]: https://tools.ietf.org/html/rfc5849#section-3.4.4
4
5use core::fmt::{self, Debug, Display, Formatter, Write};
6use core::marker::PhantomData;
7
8use super::{write_signing_key, Sign, SignatureMethod};
9
10/// The `PLAINTEXT` signature method.
11pub struct Plaintext<
12    #[cfg(feature = "alloc")] W = alloc::string::String,
13    #[cfg(not(feature = "alloc"))] W,
14> {
15    marker: PhantomData<fn() -> W>,
16}
17
18cfg_type_param_hack! {
19    /// A `Sign` implementation that just returns the signing key used to construct it.
20    #[derive(Clone, Debug)]
21    pub struct PlaintextSign<
22        #[cfg(feature = "alloc")] W = alloc::string::String,
23        #[cfg(not(feature = "alloc"))] W,
24    > {
25        signing_key: W,
26    }
27}
28
29/// The `PLAINTEXT` signature method with a default configuration.
30#[cfg(feature = "alloc")]
31pub const PLAINTEXT: Plaintext = Plaintext::new();
32
33#[cfg(feature = "alloc")]
34impl Plaintext {
35    /// Creates a new `Plaintext`.
36    pub const fn new() -> Self {
37        // `PhantomData::<fn() -> _>`s, which (rustc thinks to) contain a function pointer,
38        // cannot appear in constant functions directly as of Rust 1.57, but this somehow works.
39        // cf. <https://github.com/rust-lang/rust/issues/67649>
40        const MARKER: PhantomData<fn() -> alloc::string::String> = PhantomData;
41        Plaintext { marker: MARKER }
42    }
43}
44
45impl<W> Plaintext<W>
46where
47    W: Default + Display + Write,
48{
49    // We separate constructors for the case of `W = String` and the generic case because
50    // `Plaintext::new_with_buf` would result in a type inference error due to current limitation of
51    // defaulted type parameters. This would be fixed if default type parameter fallback landed.
52    // <https://github.com/rust-lang/rust/issues/27336>
53
54    /// Creates a new `Plaintext` that writes the resulting signatures into `W` values.
55    pub fn with_buf() -> Self {
56        Plaintext {
57            marker: PhantomData,
58        }
59    }
60}
61
62impl<W> Clone for Plaintext<W> {
63    fn clone(&self) -> Self {
64        *self
65    }
66}
67
68impl<W> Copy for Plaintext<W> {}
69
70impl<W> Debug for Plaintext<W> {
71    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
72        #[derive(Debug)]
73        struct Plaintext;
74        Plaintext.fmt(f)
75    }
76}
77
78impl<W> Default for Plaintext<W>
79where
80    W: Default + Display + Write,
81{
82    fn default() -> Self {
83        Self::with_buf()
84    }
85}
86
87impl<W> SignatureMethod for Plaintext<W>
88where
89    W: Default + Display + Write,
90{
91    type Sign = PlaintextSign<W>;
92
93    fn sign_with(self, client_secret: &str, token_secret: Option<&str>) -> Self::Sign {
94        let mut signing_key = W::default();
95        write_signing_key(&mut signing_key, client_secret, token_secret).unwrap();
96        PlaintextSign { signing_key }
97    }
98}
99
100impl<W> Sign for PlaintextSign<W>
101where
102    W: Display + Write,
103{
104    type Signature = W;
105
106    fn get_signature_method_name(&self) -> &'static str {
107        "PLAINTEXT"
108    }
109
110    fn request_method(&mut self, _method: &str) {}
111
112    fn uri<T>(&mut self, _uri: T) {}
113
114    fn parameter<V>(&mut self, _key: &str, _value: V) {}
115
116    fn delimiter(&mut self) {}
117
118    fn end(self) -> W {
119        self.signing_key
120    }
121
122    // The OAuth standard (section 3.1.) says that `oauth_timestamp` and `oauth_nonce` parameters
123    // MAY be omitted when using the `PLAINTEXT` signature method. So, technically, we could
124    // override `use_nonce` and `use_timestamp` so as not to use the parameters. However,
125    // OAuth Core 1.0 Revision A (https://oauth.net/core/1.0a/) specification used to require these
126    // parameters. So, we don't override the methods here for compatibility's sake.
127}