89 lines
1.9 KiB
Go
89 lines
1.9 KiB
Go
package domain
|
|
|
|
import "slices"
|
|
|
|
func EvaluatePrivacy(rules PrivacyRules, ctx PrivacyContext) bool {
|
|
if ctx.OwnerUserID != 0 && ctx.OwnerUserID == ctx.ViewerUserID {
|
|
return true
|
|
}
|
|
if len(rules.Rules) == 0 {
|
|
rules.Rules = DefaultPrivacyRules(rules.Key)
|
|
}
|
|
for _, rule := range rules.Rules {
|
|
if explicitDisallowMatches(rule, ctx) {
|
|
return false
|
|
}
|
|
}
|
|
for _, rule := range rules.Rules {
|
|
if explicitAllowMatches(rule, ctx) {
|
|
return true
|
|
}
|
|
}
|
|
for _, rule := range rules.Rules {
|
|
switch rule.Kind {
|
|
case PrivacyRuleDisallowContacts:
|
|
if ctx.ViewerIsContact {
|
|
return false
|
|
}
|
|
case PrivacyRuleAllowContacts:
|
|
if ctx.ViewerIsContact {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
for _, rule := range rules.Rules {
|
|
switch rule.Kind {
|
|
case PrivacyRuleDisallowAll:
|
|
return false
|
|
case PrivacyRuleAllowAll:
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func explicitDisallowMatches(rule PrivacyRule, ctx PrivacyContext) bool {
|
|
switch rule.Kind {
|
|
case PrivacyRuleDisallowUsers:
|
|
return slices.Contains(rule.UserIDs, ctx.ViewerUserID)
|
|
case PrivacyRuleDisallowChatParticipants:
|
|
return intersects(rule.ChatIDs, ctx.SharedChatIDs)
|
|
case PrivacyRuleDisallowBots:
|
|
return ctx.ViewerIsBot
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func explicitAllowMatches(rule PrivacyRule, ctx PrivacyContext) bool {
|
|
switch rule.Kind {
|
|
case PrivacyRuleAllowUsers:
|
|
return slices.Contains(rule.UserIDs, ctx.ViewerUserID)
|
|
case PrivacyRuleAllowChatParticipants:
|
|
return intersects(rule.ChatIDs, ctx.SharedChatIDs)
|
|
case PrivacyRuleAllowCloseFriends:
|
|
return ctx.ViewerCloseFriend
|
|
case PrivacyRuleAllowPremium:
|
|
return ctx.ViewerIsPremium
|
|
case PrivacyRuleAllowBots:
|
|
return ctx.ViewerIsBot
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func intersects(a, b []int64) bool {
|
|
if len(a) == 0 || len(b) == 0 {
|
|
return false
|
|
}
|
|
set := make(map[int64]struct{}, len(a))
|
|
for _, id := range a {
|
|
set[id] = struct{}{}
|
|
}
|
|
for _, id := range b {
|
|
if _, ok := set[id]; ok {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|