view

package
v2.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 5, 2023 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package view provides customisable abstractions over collections. Changes to an underlying collection are reflected in its views, and vice-versa.

Example (UrlQuery)
package main

import (
	"fmt"
	"net/url"
	"path"
	"sort"

	"github.com/acarl005/stripansi"
	"github.com/tawesoft/golib/v2/view"
)

// Untrusted applies visible runtime tainting of untrusted values (as
// recommended by OWASP). This means we are unable to use an untrusted
// input accidentally, and must first access it using an escape function.
type Untrusted struct {
	value string
}

func (u Untrusted) Raw() string {
	return u.value
}

func (u Untrusted) Escape(esc ...func(x string) string) string {
	result := u.value
	for _, escaper := range esc {
		result = escaper(result)
	}
	return result
}

func UntrustedString(x string) Untrusted {
	return Untrusted{x}
}

func main() {

	// Assume an input URL query from an intrusted source
	args := url.Values{} // map[string][]string
	args.Set("name", "Ava")
	args.Add("friend", "Jess")
	args.Add("friend", "Sarah")
	args.Add("friend", "Zoe")
	args.Add("filename", "../index.html") // malicious input
	args.Add("fbclid", "nonsense we don't care about")
	// args.Encode() == ...

	recognisedKeys := []string{"name", "friend", "filename"}
	sort.Strings(recognisedKeys)
	onlyRecognised := func(k string, _ []string) bool {
		i := sort.SearchStrings(recognisedKeys, k)
		return (i < len(recognisedKeys)) && (recognisedKeys[i] == k)
	}

	// Construct a view that can read keys and values from the input query,
	// wrapping them in the Untrusted type. Additionally, we filter only
	// the keys we care about.
	//
	// Like the url.Values.Get method, returns only the first value associated
	// with the given key.
	taintedValues := view.Map[string, []string, Untrusted, Untrusted]{
		Filterer: onlyRecognised,
		ToKey:    func(k string) Untrusted { return UntrustedString(k) },
		FromKey:  func(k Untrusted) string { return k.Raw() },
		ToValue: func(x []string) Untrusted {
			if len(x) >= 1 {
				return UntrustedString(x[0])
			}
			return Untrusted{}
		},
		FromValue: nil, // omitted as we don't need to map a value back
	}.Bind(args)

	if name, ok := taintedValues.Get(UntrustedString("name")); ok {
		fmt.Printf("Hi %s!\n", name.Escape(stripansi.Strip))
	} else {
		fmt.Printf("Hello anonymous!\n")
	}

	if friend, ok := taintedValues.Get(UntrustedString("friend")); ok {
		fmt.Printf("I see that you're friends with %s!\n", friend.Escape(stripansi.Strip))
	}

	if filename, ok := taintedValues.Get(UntrustedString("filename")); ok {
		// NOTE: this is an example only and is not complete as there are still
		// other ways the path could be unsafe.
		fmt.Printf("Safe filename: %s\n", filename.Escape(path.Clean, path.Base, stripansi.Strip))
	} else {
		fmt.Printf("No file specified.\n")
	}

	if _, ok := taintedValues.Get(UntrustedString("fbclid")); ok {
		panic("Didn't expect to see this!")
	}

}
Output:

Hi Ava!
I see that you're friends with Jess!
Safe filename: index.html

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Map added in v2.7.0

type Map[K comparable, V any, ToK comparable, ToV any] struct {
	// Filterer defines a function that controls, given an element (key, value)
	// pair from the underlying collection, whether that element is mapped
	// to the new collection in Get or Iter methods on a View. Elements only
	// appear if the filter function returns true. If omitted, defaults to a
	// function that always returns true.
	Filterer func(K, V) bool

	// ToKey defines a function that maps K to ToK.
	ToKey func(K) ToK

	// FromKey defines the inverse of ToKey.
	FromKey func(ToK) K

	// ToValue defines a function that maps V to ToV.
	ToValue func(V) ToV

	// FromValue defines the inverse of ToValue.
	// Note that FromValue may be omitted if the [View.Set] method is never
	// called.
	FromValue func(ToV) V
}

Map describes a way to create a View from a Go map collection type that maps to a collection of mapped keys and values.

The types K and V define element types in an original collection. The types ToK and ToV define element types in a new collection formed by mapping K to ToK and mapping v to ToV.

func (Map[K, V, ToK, ToV]) Bind added in v2.7.0

func (m Map[K, V, ToK, ToV]) Bind(c map[K]V) View[ToK, ToV]

Bind returns a new View over a Go map collection.

type Slice added in v2.7.0

type Slice[V any, ToV any] struct {
	// Filterer defines a function that controls, given a value from the
	// underlying collection, whether that element is mapped to the new
	// collection in Get or Iter methods on a View. Values only appear if the
	// filter function returns true. If omitted, defaults to a function that
	// always returns true.
	Filterer func(V) bool

	// ToValue defines a function that maps V to ToV.
	ToValue func(V) ToV

	// FromValue defines the inverse of ToValue.
	// Note that FromValue may be omitted if the [View.Set] method is never
	// called.
	FromValue func(ToV) V
}

Slice describes a way to create a View from a Go slice collection type that maps to a collection of mapped values.

The type V defines element types in an original collection. The type ToV defines element types in a new collection formed by mapping v to ToV.

func (Slice[V, ToV]) Bind added in v2.7.0

func (s Slice[V, ToV]) Bind(c []V) View[int, ToV]

Bind returns a new View over a Go slice collection.

type View

type View[K comparable, V any] interface {
	Get(K) (V, bool)
	Set(K, V)
	Delete(K)
	Iter() iter.It[iter.Pair[K, V]]
}

View is an abstraction over a collection. In the case of a slice, the key is an int representing the index.

type Viewer added in v2.7.0

type Viewer[K comparable, V any, ToK comparable, ToV any] struct {
	// Filterer defines a function that controls, given an element (key, value)
	// pair from the underlying collection, whether that element is mapped
	// to the new collection in Get or Iter methods on a View. Elements only
	// appear if the filter function returns true. If omitted, defaults to a
	// function that always returns true.
	Filterer func(K, V) bool

	// Getter defines a function that accesses a given value from the underlying
	// collection. It is implemented in terms of the types of the underlying
	// collection, and should not implement the filtering itself.
	Getter func(K) (V, bool)

	// Setter defines a function that sets a given value in the underlying
	// collection. It is implemented in terms of the types of the underlying
	// collection, and ignores filtering.
	Setter func(K, V)

	// Deleter defines a function that deletes a given value in the underlying
	// collection. It is implemented in terms of the types of the underlying
	// collection, and ignores filtering.
	Deleter func(K)

	// ToKey defines a function that maps K to ToK.
	ToKey func(K) ToK

	// FromKey defines the inverse of ToKey.
	FromKey func(ToK) K

	// ToValue defines a function that maps V to ToV.
	ToValue func(V) ToV

	// FromValue defines the inverse of ToValue.
	// Note that FromValue may be omitted if
	FromValue func(ToV) V

	// Iterer defines a function that returns a new iterator over the underlying
	// collection. It is implemented in terms of the types of the underlying
	// collection, and should not implement the filtering itself.
	Iterer func() iter.It[iter.Pair[K, V]]
}

Viewer describes a View over a Go collection type that maps to a new collection of mapped keys and values.

This is a generic, low-level definition for implementors of custom collection types. Most users will want to call the Bind method on the simpler Map or Slice constructor types instead.

func (Viewer[K, V, ToK, ToV]) Delete added in v2.7.0

func (m Viewer[K, V, ToK, ToV]) Delete(k ToK)

func (Viewer[K, V, ToK, ToV]) Get added in v2.7.0

func (m Viewer[K, V, ToK, ToV]) Get(key ToK) (ToV, bool)

func (Viewer[K, V, ToK, ToV]) Iter added in v2.7.0

func (m Viewer[K, V, ToK, ToV]) Iter() iter.It[iter.Pair[ToK, ToV]]

func (Viewer[K, V, ToK, ToV]) Set added in v2.7.0

func (m Viewer[K, V, ToK, ToV]) Set(k ToK, v ToV)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL