Skip to content
quarry Artifact [61a1574c77]
Login

Artifact [61a1574c77]

Artifact 61a1574c77aa254f92bf14153aad835676aa8ca77224a0045565970796a19ed8:


package web

import (
	"strings"

	"craftdesign.group/quarry/internal/oltp"
	"craftdesign.group/quarry/internal/ops"
)

// checkedOutsideOps names the letters quarry acts on somewhere other
// than an operation's Caps, and what they do there. The registry alone
// would show every one of these as doing nothing.
// TestEveryCheckedLetterIsInTheReference holds this table to the source.
var checkedOutsideOps = map[rune]string{
	'g': "any of g j o h 2 r lets someone reach the repository at all",
	'j': "any of g j o h 2 r lets someone reach the repository at all",
	'o': "any of g j o h 2 r lets someone reach the repository at all",
	'h': "any of g j o h 2 r lets someone reach the repository at all",
	'2': "any of g j o h 2 r lets someone reach the repository at all",
	'r': "any of g j o h 2 r lets someone reach the repository at all",
	'e': "shows email addresses and private ticket fields",
	'C': "chat, on a forge with chat turned on",
	'4': "forum posts skip moderation",
	'5': "forum posts skip moderation",
	'8': "shows the CI tab",
	'u': "pulls in the reader category",
	'v': "pulls in the developer category",
}

// capRefRow is one letter of the capability reference.
type capRefRow struct {
	Letter string
	Name   string // fossil's name
	Does   string // fossil's description
	Here   []string
	Ops    int    // operations that require it, in the live registry
	Also   string // where it is checked outside the operations
	Used   bool
	Roles  []string
	Grants []string
}

// capRefPanel is the capability reference: every fossil letter, what it
// does in quarry, and who the page's scope hands it to.
type capRefPanel struct {
	GrantsHead string
	Rows       []capRefRow
}

// capReference builds the reference from the live registry, so an
// operation registered only on some forges (chat, CI) counts only there.
func capReference(r *ops.Registry, grantsHead string, grants func(rune) []string) *capRefPanel {
	required := map[rune]int{}
	if r != nil {
		for _, d := range r.All() {
			seen := map[rune]bool{}
			for _, l := range d.Caps {
				if !seen[l] {
					seen[l] = true
					required[l]++
				}
			}
		}
	}
	p := &capRefPanel{GrantsHead: grantsHead}
	for _, c := range oltp.CapLetters {
		row := capRefRow{Letter: string(c.Letter), Name: c.Name, Does: c.Does,
			Ops: required[c.Letter], Also: checkedOutsideOps[c.Letter]}
		for _, a := range oltp.Abilities {
			if strings.ContainsRune(a.Letters, c.Letter) {
				row.Here = append(row.Here, a.Sentence)
			}
		}
		row.Used = row.Ops > 0 || row.Also != ""
		row.Roles = rolesWith(c.Letter)
		if grants != nil {
			row.Grants = grants(c.Letter)
		}
		p.Rows = append(p.Rows, row)
	}
	return p
}

// rolesWith names the stock roles that hold letter once implications
// and the a umbrella are applied — Admin holds nearly everything.
func rolesWith(letter rune) []string {
	var out []string
	for _, p := range oltp.Presets {
		if oltp.CapSet(oltp.Closure(p.Caps)).HasAny(string(letter)) {
			out = append(out, p.Name)
		}
	}
	return out
}

// capRefFor is the reference for a repository's settings, or the fleet
// default when repo is empty: who its categories hand each letter to.
func capRefFor(r *ops.Registry, caps Caps, repo string) *capRefPanel {
	head := "this repository gives it to"
	if repo == "" {
		head = "new repositories give it to"
	}
	admin, ok := caps.(CapsAdmin)
	if !ok || admin == nil {
		return capReference(r, head, nil)
	}
	cats := []string{oltp.SourceNobody, oltp.SourceAnonymous, oltp.SourceReader, oltp.SourceDeveloper}
	strs := map[string]oltp.CapSet{}
	for _, cat := range cats {
		strs[cat] = oltp.CapSet(oltp.Closure(admin.CategoryCaps(repo, cat)))
	}
	return capReference(r, head, func(l rune) []string {
		var out []string
		for _, cat := range cats {
			if strs[cat].HasAny(string(l)) {
				out = append(out, sourceWords(cat))
			}
		}
		return out
	})
}

// capRefTeam is the reference for a team: what membership alone gives
// on every repository the team holds.
func capRefTeam(r *ops.Registry) *capRefPanel {
	floor := oltp.CapSet(oltp.Closure(oltp.TeamFloor))
	return capReference(r, "membership gives it to", func(l rune) []string {
		if floor.HasAny(string(l)) {
			return []string{"every member"}
		}
		return nil
	})
}