github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/chat/unfurl/exemption.go (about)

     1  package unfurl
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/keybase/client/go/chat/types"
     7  	"github.com/keybase/client/go/protocol/chat1"
     8  )
     9  
    10  type OneTimeWhitelistExemption struct {
    11  	sync.Mutex
    12  	used   bool
    13  	convID chat1.ConversationID
    14  	msgID  chat1.MessageID
    15  	domain string
    16  }
    17  
    18  var _ (types.WhitelistExemption) = (*OneTimeWhitelistExemption)(nil)
    19  
    20  func NewOneTimeWhitelistExemption(convID chat1.ConversationID, msgID chat1.MessageID, domain string) *OneTimeWhitelistExemption {
    21  	return &OneTimeWhitelistExemption{
    22  		convID: convID,
    23  		msgID:  msgID,
    24  		domain: domain,
    25  	}
    26  }
    27  
    28  func (o *OneTimeWhitelistExemption) Use() bool {
    29  	o.Lock()
    30  	defer o.Unlock()
    31  	res := !o.used
    32  	o.used = true
    33  	return res
    34  }
    35  
    36  func (o *OneTimeWhitelistExemption) Matches(convID chat1.ConversationID, msgID chat1.MessageID,
    37  	domain string) bool {
    38  	return o.convID.Eq(convID) && o.msgID == msgID && o.domain == domain
    39  }
    40  
    41  func (o *OneTimeWhitelistExemption) Domain() string {
    42  	o.Lock()
    43  	defer o.Unlock()
    44  	return o.domain
    45  }
    46  
    47  type SingleMessageWhitelistExemption struct {
    48  	sync.Mutex
    49  	convID chat1.ConversationID
    50  	msgID  chat1.MessageID
    51  	domain string
    52  }
    53  
    54  var _ (types.WhitelistExemption) = (*SingleMessageWhitelistExemption)(nil)
    55  
    56  func NewSingleMessageWhitelistExemption(convID chat1.ConversationID, msgID chat1.MessageID, domain string) *SingleMessageWhitelistExemption {
    57  	return &SingleMessageWhitelistExemption{
    58  		convID: convID,
    59  		msgID:  msgID,
    60  		domain: domain,
    61  	}
    62  }
    63  
    64  func (o *SingleMessageWhitelistExemption) Use() bool {
    65  	o.Lock()
    66  	defer o.Unlock()
    67  	return true
    68  }
    69  
    70  func (o *SingleMessageWhitelistExemption) Matches(convID chat1.ConversationID, msgID chat1.MessageID,
    71  	domain string) bool {
    72  	return o.convID.Eq(convID) && o.msgID == msgID && o.domain == domain
    73  }
    74  
    75  func (o *SingleMessageWhitelistExemption) Domain() string {
    76  	o.Lock()
    77  	defer o.Unlock()
    78  	return o.domain
    79  }
    80  
    81  type WhitelistExemptionList struct {
    82  	sync.Mutex
    83  	exemptions []types.WhitelistExemption
    84  }
    85  
    86  func NewWhitelistExemptionList() *WhitelistExemptionList {
    87  	return &WhitelistExemptionList{}
    88  }
    89  
    90  func (l *WhitelistExemptionList) Add(e types.WhitelistExemption) {
    91  	l.Lock()
    92  	defer l.Unlock()
    93  	l.exemptions = append(l.exemptions, e)
    94  }
    95  
    96  func (l *WhitelistExemptionList) Use(convID chat1.ConversationID, msgID chat1.MessageID, domain string) bool {
    97  	l.Lock()
    98  	defer l.Unlock()
    99  	var nextlist []types.WhitelistExemption
   100  	exempted := false
   101  	for _, e := range l.exemptions {
   102  		if exempted || !e.Matches(convID, msgID, domain) {
   103  			nextlist = append(nextlist, e)
   104  			continue
   105  		}
   106  		if e.Use() {
   107  			exempted = true
   108  			nextlist = append(nextlist, e)
   109  		}
   110  	}
   111  	l.exemptions = nextlist
   112  	return exempted
   113  }