File: server_authenticate.rs

package info (click to toggle)
rust-imap-next 0.3.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 496 kB
  • sloc: makefile: 2; sh: 1
file content (78 lines) | stat: -rw-r--r-- 2,721 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
use imap_next::{
    imap_types::response::{CommandContinuationRequest, Greeting, Status},
    server::{Event, Options, Server},
    stream::Stream,
    types::CommandAuthenticate,
};
use tokio::net::TcpListener;

#[tokio::main(flavor = "current_thread")]
async fn main() {
    let listener = TcpListener::bind("127.0.0.1:12345").await.unwrap();
    let (stream, _) = listener.accept().await.unwrap();
    let mut stream = Stream::insecure(stream);
    let mut server = Server::new(
        Options::default(),
        Greeting::ok(None, "server_idle (example)").unwrap(),
    );

    loop {
        match stream.next(&mut server).await.unwrap() {
            Event::GreetingSent { .. } => break,
            event => println!("unexpected event: {event:?}"),
        }
    }

    let mut current_authenticate_tag = None;

    loop {
        let event = stream.next(&mut server).await.unwrap();
        println!("{event:?}");

        // We don't implement any real SASL mechanism in this example.
        let pretend_to_need_more_data = rand::random();

        match event {
            Event::CommandAuthenticateReceived {
                command_authenticate: CommandAuthenticate { tag, .. },
            } => {
                if pretend_to_need_more_data {
                    server
                        .authenticate_continue(
                            CommandContinuationRequest::basic(None, "I need more data...").unwrap(),
                        )
                        .unwrap();

                    current_authenticate_tag = Some(tag);
                } else {
                    server
                        .authenticate_finish(
                            Status::ok(Some(tag), None, "Thanks, that's already enough!").unwrap(),
                        )
                        .unwrap();
                }
            }
            Event::AuthenticateDataReceived { .. } => {
                if pretend_to_need_more_data {
                    server
                        .authenticate_continue(
                            CommandContinuationRequest::basic(None, "...more...").unwrap(),
                        )
                        .unwrap();
                } else {
                    let tag = current_authenticate_tag.take().unwrap();

                    server
                        .authenticate_finish(Status::ok(Some(tag), None, "Thanks!").unwrap())
                        .unwrap();
                }
            }
            Event::CommandReceived { command } => {
                server.enqueue_status(
                    Status::no(Some(command.tag), None, "Please use AUTHENTICATE").unwrap(),
                );
            }
            _ => {}
        }
    }
}