Documentation
¶
Index ¶
- Variables
- func AudiencesSQL(alias string, tiers []string) (string, map[string]any, error)
- func Effective(content access.Rule, override *access.Rule) access.Rule
- func PublicSQL(alias string) string
- func ReleasedTiersSQL(alias string) string
- func WithMemo(ctx context.Context) context.Context
- type Decision
- type Filter
- func (f *Filter) Allows(it access.Item) (allowed, known bool)
- func (f *Filter) Anonymous() bool
- func (f *Filter) Channels() []string
- func (f *Filter) Complete() bool
- func (f *Filter) Contents() []string
- func (f *Filter) SQL(alias string, mode access.Mode) (string, map[string]any, error)
- func (f *Filter) Tier(name string) bool
- func (f *Filter) Unknown() bool
- func (f *Filter) Versions() map[string]string
- type Gate
- func (g *Gate) Decide(ctx context.Context, actor access.Actor, items []access.Item) ([]Decision, error)
- func (g *Gate) Filter(ctx context.Context, actor access.Actor) (*Filter, error)
- func (g *Gate) Holds(ctx context.Context, actor access.Actor, keys []access.Key) ([]bool, error)
- func (g *Gate) Settle(ctx context.Context, actor access.Actor, f *Filter, items []access.Item) (keep []bool, short bool, err error)
- func (g *Gate) Tenant() string
- func (g *Gate) Tiers() []string
- type GateConfig
Constants ¶
This section is empty.
Variables ¶
ErrUnavailable wraps a failed billing read. The result it comes with is the fail-closed one: only free rules and claimed tiers open, nothing is offered.
Functions ¶
func AudiencesSQL ¶
AudiencesSQL is a text[] expression over the content_facets row aliased alias naming who opens it without buying it: Anyone and every one of tiers for a public row or matured public release, the current base and released tier audiences for a restricted row, nobody otherwise. Totals count rows per audience with it. Args are pgx named args prefixed audience_.
func PublicSQL ¶
PublicSQL reports anonymous access from the current rule and mature releases. alias is a trusted SQL identifier, validated by Filter.SQL/AudiencesSQL.
func ReleasedTiersSQL ¶
ReleasedTiersSQL lists the tier audiences that have reached their timestamp.
Types ¶
type Decision ¶
type Decision struct {
Allowed bool
// Unknown: the billing read failed, so the item is denied and nothing is
// offered (the viewer may already hold it).
Unknown bool
// Sell are the keys whose purchase opens it, the rule's own first (its
// tiers or entity), then the version's;
// The host resolves these keys through its billing provider.
Sell []access.Key
// Requires is the key a buyer must hold first (ChannelPPV), nil when held.
Requires *access.Key
// Preview is the part a viewer may read while it is locked.
Preview *access.Preview
// Releases describe upcoming additional audiences.
Releases []access.Release
}
Decision is one item's verdict.
type Filter ¶
type Filter struct {
// contains filtered or unexported fields
}
Filter is one viewer's access as one billing read left it: the configured tiers they hold and their keys in the tenant's content and group keyspaces. It does no I/O: listings push it into SQL (Filter.SQL), loops call Allows. A Filter is immutable and safe for concurrent use.
func (*Filter) Allows ¶
Allows decides it from the filter alone. known is false when the answer needs a key the filter did not read in full (a truncated keyspace, a failed read); Gate.Settle and Gate.Decide resolve those. Allows and SQL(Hide) agree: the SQL admits exactly the rows Allows allows or does not know, and on an Unknown filter only the allowed ones.
func (*Filter) Channels ¶
Channels returns the channel ids whose membership key the viewer holds, sorted.
func (*Filter) Complete ¶
Complete reports whether Contents, Versions and Channels are the viewer's whole holdings. An anonymous filter is complete; an unknown one is not.
func (*Filter) Contents ¶
Contents returns legacy parent grants for audit and explicit migration. They do not grant version access and must not be used as audience ownership.
func (*Filter) SQL ¶
SQL returns a boolean predicate over the content_facets row aliased alias, with its pgx named args (all prefixed access_). Hide admits the rows the viewer opens: free, a held tier the rule names, a held key of the rule's channel, or an exact held version key; plus, while a keyspace is truncated, its candidates, which Gate.Settle decides. An Unknown filter admits no candidates. Lock admits every row. The text depends only on alias and mode, so one prepared statement serves every viewer. Lock mode retains inaccessible items for a locked preview; Hide mode excludes them.
type Gate ¶
type Gate struct {
// contains filtered or unexported fields
}
Gate decides access to versions from one billing read per viewer and request (see WithMemo).
func (*Gate) Decide ¶
func (g *Gate) Decide(ctx context.Context, actor access.Actor, items []access.Item) ([]Decision, error)
Decide decides items for actor in order. It answers from the request's memoized Filter and keys where they suffice and reads every other key in one billing read. A failed read denies what it would have decided (Unknown) and returns an error wrapping ErrUnavailable. An item with an invalid id or rule is denied with nothing offered and logged.
func (*Gate) Filter ¶
Filter reads the viewer's access in one billing read: the configured tiers a token claim does not answer and the tenant's content and entity keyspaces. Within WithMemo it is read once per request. An anonymous viewer costs no read. On a failed read Filter returns the fail-closed filter (Unknown) and an error wrapping ErrUnavailable: serve that filter or answer 503.
func (*Gate) Holds ¶
Holds reports, per key in order, whether actor holds it: from the request's memoized Filter and keys where they suffice, the rest in one billing read. An anonymous actor holds nothing and costs no read. A failed read answers false for what it would have decided and returns an error wrapping ErrUnavailable. Non-tier keys outside this gate's tenant are refused without a billing read.
func (*Gate) Settle ¶
func (g *Gate) Settle(ctx context.Context, actor access.Actor, f *Filter, items []access.Item) (keep []bool, short bool, err error)
Settle completes f's verdicts for a hide-mode page: items f decides keep its answer, the rest (candidates of a truncated keyspace) are decided in one exact read. keep[i] reports items[i] open; short reports a dropped item, so the page may hold fewer rows than asked. It costs no read when f decides every item. A failed read drops the undecided items and returns an error wrapping ErrUnavailable.
type GateConfig ¶
type GateConfig struct {
// Tenant is the tenant of every key: [a-z0-9_-]{1,64}.
Tenant string
// Kinds supplies the configured tiers, the only bare keys ContentKit
// interprets, and the token claims answering them without a billing read.
Kinds kinds.Config
// Billing answers held keys; nil holds none for anyone, so only free
// rules and claimed tiers open.
Billing access.Billing
Logger *slog.Logger
// Now is the application clock used for audience-release decisions.
// Nil uses time.Now, matching ordinary production behavior.
Now func() time.Time
}
GateConfig configures a Gate from the engine's config.