1package otr3
2
3import "fmt"
4
5// SMPEvent define the events used to indicate status of SMP to the UI
6type SMPEvent int
7
8const (
9	// SMPEventError means abort the current auth and update the auth progress dialog with progress_percent. This event is only sent when we receive a message for another message state than we are in
10	SMPEventError SMPEvent = iota
11	// SMPEventAbort means update the auth progress dialog with progress_percent
12	SMPEventAbort
13	// SMPEventCheated means abort the current auth and update the auth progress dialog with progress_percent
14	SMPEventCheated
15	// SMPEventAskForAnswer means ask the user to answer the secret question
16	SMPEventAskForAnswer
17	// SMPEventAskForSecret means prompt the user to enter a shared secret
18	SMPEventAskForSecret
19	// SMPEventInProgress means update the auth progress dialog with progress_percent
20	SMPEventInProgress
21	// SMPEventSuccess means update the auth progress dialog with progress_percent
22	SMPEventSuccess
23	// SMPEventFailure means update the auth progress dialog with progress_percent
24	SMPEventFailure
25)
26
27// SMPEventHandler handles SMPEvents
28type SMPEventHandler interface {
29	// HandleSMPEvent should update the authentication UI with respect to SMP events
30	HandleSMPEvent(event SMPEvent, progressPercent int, question string)
31}
32
33type dynamicSMPEventHandler struct {
34	eh func(event SMPEvent, progressPercent int, question string)
35}
36
37func (d dynamicSMPEventHandler) HandleSMPEvent(event SMPEvent, pp int, question string) {
38	d.eh(event, pp, question)
39}
40
41func (c *Conversation) smpEvent(e SMPEvent, percent int) {
42	if c.smpEventHandler != nil {
43		c.smpEventHandler.HandleSMPEvent(e, percent, "")
44	}
45}
46
47func (c *Conversation) smpEventWithQuestion(e SMPEvent, percent int, question string) {
48	if c.smpEventHandler != nil {
49		c.smpEventHandler.HandleSMPEvent(e, percent, question)
50	}
51}
52
53func (s SMPEvent) String() string {
54	switch s {
55	case SMPEventError:
56		return "SMPEventError"
57	case SMPEventAbort:
58		return "SMPEventAbort"
59	case SMPEventCheated:
60		return "SMPEventCheated"
61	case SMPEventAskForAnswer:
62		return "SMPEventAskForAnswer"
63	case SMPEventAskForSecret:
64		return "SMPEventAskForSecret"
65	case SMPEventInProgress:
66		return "SMPEventInProgress"
67	case SMPEventSuccess:
68		return "SMPEventSuccess"
69	case SMPEventFailure:
70		return "SMPEventFailure"
71	default:
72		return "SMP EVENT: (THIS SHOULD NEVER HAPPEN)"
73	}
74}
75
76type combinedSMPEventHandler struct {
77	handlers []SMPEventHandler
78}
79
80func (c combinedSMPEventHandler) HandleSMPEvent(event SMPEvent, progressPercent int, question string) {
81	for _, h := range c.handlers {
82		if h != nil {
83			h.HandleSMPEvent(event, progressPercent, question)
84		}
85	}
86}
87
88// CombineSMPEventHandlers creates a SMPEventHandler that will call all handlers
89// given to this function. It ignores nil entries.
90func CombineSMPEventHandlers(handlers ...SMPEventHandler) SMPEventHandler {
91	return combinedSMPEventHandler{handlers}
92}
93
94// DebugSMPEventHandler is an SMPEventHandler that dumps all SMPEvents to standard error
95type DebugSMPEventHandler struct{}
96
97// HandleSMPEvent dumps all SMP events
98func (DebugSMPEventHandler) HandleSMPEvent(event SMPEvent, progressPercent int, question string) {
99	fmt.Fprintf(standardErrorOutput, "%sHandleSMPEvent(%s, %d, %#v)\n", debugPrefix, event, progressPercent, question)
100}
101