Ctrl K
ComunidadGuías…

internal/domain/privacy_evaluate.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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
}