mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 04:07:07 +00:00
83 lines
2.8 KiB
Go
83 lines
2.8 KiB
Go
package e2ee
|
|
|
|
import "fmt"
|
|
|
|
// Mode is the account-wide OMEMO policy (see persistence.Session.OMEMO),
|
|
// combined with a chat's optional Override and its auto-upgrade sticky
|
|
// flag (Backend.Enabled) by ShouldEncrypt to decide whether to attempt
|
|
// outgoing encryption for that chat right now.
|
|
type Mode int
|
|
|
|
const (
|
|
// ModeAuto (the default) only encrypts once a chat has auto-upgraded
|
|
// (Backend.Enabled), i.e. its peer has already sent this chat an OMEMO
|
|
// message. This is the original, only behavior before Mode existed.
|
|
ModeAuto Mode = iota
|
|
|
|
// ModeOn always attempts to encrypt, regardless of whether the peer
|
|
// has ever shown OMEMO support. If no session can be established, the
|
|
// send fails outright rather than falling back to plaintext - the
|
|
// same OMEMOSendFailedBody convention already used at every Encrypt
|
|
// call site applies, it's just reached unconditionally now instead of
|
|
// only for already-active chats. Incoming plaintext is still accepted
|
|
// and processed as usual - this mode only ever affects outgoing.
|
|
ModeOn
|
|
|
|
// ModeOff never encrypts outgoing content, even for a chat that has
|
|
// already auto-upgraded - inbound OMEMO messages are still decrypted
|
|
// normally regardless of this mode (decryption never consults Mode at
|
|
// all, only the encrypt hooks do).
|
|
ModeOff
|
|
)
|
|
|
|
func (m Mode) String() string {
|
|
switch m {
|
|
case ModeOn:
|
|
return "on"
|
|
case ModeOff:
|
|
return "off"
|
|
default:
|
|
return "auto"
|
|
}
|
|
}
|
|
|
|
// ParseMode maps persistence.Session.OMEMO's stored string to a Mode - an
|
|
// empty string (an account that predates this field, or never touched it)
|
|
// is treated the same as "auto", matching Mode's zero value and default.
|
|
func ParseMode(s string) (Mode, error) {
|
|
switch s {
|
|
case "", "auto":
|
|
return ModeAuto, nil
|
|
case "on":
|
|
return ModeOn, nil
|
|
case "off":
|
|
return ModeOff, nil
|
|
default:
|
|
return ModeAuto, fmt.Errorf("e2ee: unknown mode %q (want on, auto, or off)", s)
|
|
}
|
|
}
|
|
|
|
// ShouldEncrypt decides whether owner's outgoing content should be
|
|
// encrypted right now, combining (in priority order): owner's explicit
|
|
// per-chat Override, if one has been set; otherwise mode's account-wide
|
|
// policy, consulting backend's auto-upgrade sticky flag (Enabled) only for
|
|
// ModeAuto. This is the single place that combination logic lives - every
|
|
// encrypt hook (SendMessageToGateway, sendMessagesReverse,
|
|
// updateMessageContent) calls this instead of checking Enabled directly,
|
|
// so a chat's effective behavior can never drift between call sites.
|
|
func ShouldEncrypt(backend Backend, owner PeerID, mode Mode) (bool, error) {
|
|
if override, isSet, err := backend.Override(owner); err != nil {
|
|
return false, err
|
|
} else if isSet {
|
|
return override, nil
|
|
}
|
|
|
|
switch mode {
|
|
case ModeOn:
|
|
return true, nil
|
|
case ModeOff:
|
|
return false, nil
|
|
default:
|
|
return backend.Enabled(owner)
|
|
}
|
|
}
|