mirror of
https://codeberg.org/angestoepselt/homepage.git
synced 2026-03-21 22:32:17 +00:00
76 lines
1.9 KiB
Go
76 lines
1.9 KiB
Go
package csp
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"log"
|
|
"net/http"
|
|
)
|
|
|
|
type cspKeyword uint
|
|
|
|
//go:generate stringer -type=cspKeyword -linecomment
|
|
const (
|
|
Self cspKeyword = iota // self
|
|
TrustedTypesEval // trusted-types-eval
|
|
InlineSpeculationRules // inline-speculation-rules
|
|
StrictDynamic // strict-dynamic
|
|
ReportSample // report-sample
|
|
)
|
|
|
|
type cspDirective struct {
|
|
values []string
|
|
keywords map[cspKeyword]struct{}
|
|
}
|
|
|
|
type Builder struct {
|
|
directives map[string]*cspDirective
|
|
nonce string
|
|
request *http.Request
|
|
}
|
|
|
|
func (csp *Builder) getDirective(directive string) *cspDirective {
|
|
d, ok := csp.directives[directive]
|
|
if !ok {
|
|
d = &cspDirective{
|
|
values: []string{},
|
|
keywords: map[cspKeyword]struct{}{},
|
|
}
|
|
csp.directives[directive] = d
|
|
}
|
|
return d
|
|
}
|
|
|
|
// WithValue adds a directive to the policy.
|
|
func (csp *Builder) WithValue(directive string, values ...string) *Builder {
|
|
csp.getDirective(directive).withValue(values...)
|
|
return csp
|
|
}
|
|
|
|
func (d *cspDirective) withValue(values ...string) *cspDirective {
|
|
d.values = append(d.values, values...)
|
|
return d
|
|
}
|
|
|
|
// WithKeyword adds a directive to the policy.
|
|
func (csp *Builder) WithKeyword(directive string, keyword cspKeyword) *Builder {
|
|
csp.getDirective(directive).keywords[keyword] = struct{}{}
|
|
return csp
|
|
}
|
|
|
|
// WithNonce adds a `nonce-…` value to the directive. The actual nonce value is
|
|
// generated when the policy is built.
|
|
func (csp *Builder) WithNonce(directive string) *Builder {
|
|
if csp.nonce != "" {
|
|
var b [16]byte
|
|
if _, err := rand.Read(b[:]); err != nil {
|
|
log.Fatalf("Failed to generate nonce: %v", err)
|
|
}
|
|
csp.nonce = base64.RawURLEncoding.EncodeToString(b[:])
|
|
}
|
|
return csp.WithValue(directive, "nonce-"+csp.nonce)
|
|
}
|
|
|
|
func (csp *Builder) Build() string {
|
|
panic("TODO")
|
|
}
|