github.com/prebid/prebid-server@v0.275.0/gdpr/full_enforcement.go (about)

     1  package gdpr
     2  
     3  import (
     4  	tcf2 "github.com/prebid/go-gdpr/vendorconsent/tcf2"
     5  	"github.com/prebid/prebid-server/openrtb_ext"
     6  )
     7  
     8  const (
     9  	pubRestrictNotAllowed           = 0
    10  	pubRestrictRequireConsent       = 1
    11  	pubRestrictRequireLegitInterest = 2
    12  )
    13  
    14  // FullEnforcement determines if legal basis is satisfied for a given purpose and bidder using
    15  // the TCF2 full enforcement algorithm. The algorithm is a detailed confirmation that reads the
    16  // GVL, interprets the consent string and performs legal basis analysis necessary to perform a
    17  // privacy-protected activity.
    18  // FullEnforcement implements the PurposeEnforcer interface
    19  type FullEnforcement struct {
    20  	cfg purposeConfig
    21  }
    22  
    23  // LegalBasis determines if legal basis is satisfied for a given purpose and bidder based on the
    24  // vendor claims in the GVL, publisher restrictions and user consent.
    25  func (fe *FullEnforcement) LegalBasis(vendorInfo VendorInfo, bidder openrtb_ext.BidderName, consent tcf2.ConsentMetadata, overrides Overrides) bool {
    26  	enforcePurpose, enforceVendors := fe.applyEnforceOverrides(overrides)
    27  
    28  	if consent.CheckPubRestriction(uint8(fe.cfg.PurposeID), pubRestrictNotAllowed, vendorInfo.vendorID) {
    29  		return false
    30  	}
    31  	if !enforcePurpose && !enforceVendors {
    32  		return true
    33  	}
    34  	if fe.cfg.vendorException(bidder) && !overrides.blockVendorExceptions {
    35  		return true
    36  	}
    37  
    38  	purposeAllowed := fe.consentEstablished(consent, vendorInfo, enforcePurpose, enforceVendors)
    39  	legitInterest := fe.legitInterestEstablished(consent, vendorInfo, enforcePurpose, enforceVendors)
    40  
    41  	if consent.CheckPubRestriction(uint8(fe.cfg.PurposeID), pubRestrictRequireConsent, vendorInfo.vendorID) {
    42  		return purposeAllowed
    43  	}
    44  	if consent.CheckPubRestriction(uint8(fe.cfg.PurposeID), pubRestrictRequireLegitInterest, vendorInfo.vendorID) {
    45  		return legitInterest
    46  	}
    47  
    48  	return purposeAllowed || legitInterest
    49  }
    50  
    51  // applyEnforceOverrides returns the enforce purpose and enforce vendor configuration values unless
    52  // those values have been overridden, in which case they return true
    53  func (fe *FullEnforcement) applyEnforceOverrides(overrides Overrides) (enforcePurpose, enforceVendors bool) {
    54  	enforcePurpose = fe.cfg.EnforcePurpose
    55  	if overrides.enforcePurpose {
    56  		enforcePurpose = true
    57  	}
    58  	enforceVendors = fe.cfg.EnforceVendors
    59  	if overrides.enforceVendors {
    60  		enforceVendors = true
    61  	}
    62  	return
    63  }
    64  
    65  // consentEstablished determines if consent has been established for a given purpose and bidder
    66  // based on the purpose config, user consent and the GVL. For consent to be established, the vendor
    67  // must declare the purpose as either consent or flex and the user must consent in accordance with
    68  // the purpose configs.
    69  func (fe *FullEnforcement) consentEstablished(consent tcf2.ConsentMetadata, vi VendorInfo, enforcePurpose bool, enforceVendors bool) bool {
    70  	if vi.vendor == nil {
    71  		return false
    72  	}
    73  	if !vi.vendor.Purpose(fe.cfg.PurposeID) {
    74  		return false
    75  	}
    76  	if enforcePurpose && !consent.PurposeAllowed(fe.cfg.PurposeID) {
    77  		return false
    78  	}
    79  	if enforceVendors && !consent.VendorConsent(vi.vendorID) {
    80  		return false
    81  	}
    82  	return true
    83  }
    84  
    85  // legitInterestEstablished determines if legitimate interest has been established for a given
    86  // purpose and bidder based on the purpose config, user consent and the GVL. For consent to be
    87  // established, the vendor must declare the purpose as either legit interest or flex and the user
    88  // must have been provided notice for the legit interest basis in accordance with the purpose configs.
    89  func (fe *FullEnforcement) legitInterestEstablished(consent tcf2.ConsentMetadata, vi VendorInfo, enforcePurpose bool, enforceVendors bool) bool {
    90  	if vi.vendor == nil {
    91  		return false
    92  	}
    93  	if !vi.vendor.LegitimateInterest(fe.cfg.PurposeID) {
    94  		return false
    95  	}
    96  	if enforcePurpose && !consent.PurposeLITransparency(fe.cfg.PurposeID) {
    97  		return false
    98  	}
    99  	if enforceVendors && !consent.VendorLegitInterest(vi.vendorID) {
   100  		return false
   101  	}
   102  	return true
   103  }