wsfn

package module
v0.0.11 Latest Latest
Warning

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

Go to latest
Published: Jan 6, 2024 License: BSD-3-Clause Imports: 20 Imported by: 2

README

wsfn

wsfn is a package for common web functions Caltech Library uses in various Golang based Caltech Library tools and services. The goal is to standardize our handling of web interactions.

  • wsfn.CORSPolicy is a structure for adding CORS headers to a http Handler
  • StaticRouter is a http Handler Function for working with static routes
  • RedirectRouter handles simple target prefix, destination prefix redirect handling
    • AddRedirectRoute adds a target prefix and destination prefix
    • HasRedirectRoutes return true if any redirect routes are configured
    • RedirectRouter uses the internal redirect data to handle redirects
  • ReverseProxy router lets front other web services.

An example webserver is also provided to demonstrate some of the functionality available with this package. The webserver is intended for instructional purposes only and shouldn't be used in a production setting.

Documentation

Overview

Package wsfn provides a common library of functions and structures for working with web services in Caltech Library projects and software.

@author R. S. Doiel, <rsdoiel@caltech.edu>

Copyright (c) 2021, Caltech All rights not granted herein are expressly reserved by Caltech

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Index

Constants

View Source
const (
	// Version number of release
	Version = "0.0.10"

	// ReleaseDate, the date version.go was generated
	ReleaseDate = "2024-01-05"

	// ReleaseHash, the Git hash when version.go was generated
	ReleaseHash = "7011826"

	LicenseText = `` /* 1524-byte string literal not displayed */

)

Variables

This section is empty.

Functions

func AccessHandler added in v0.0.6

func AccessHandler(next http.Handler, a *Access) http.Handler

AccessHandler is a wrapping handler that checks if Access.Routes matches the req.URL.Path and if so applies access contraints. If *Access is nil then it just passes through to the next handler.

func DefaultInit added in v0.0.6

func DefaultInit() []byte

DefaultInit generates a default TOML initialization file.

func FmtHelp added in v0.0.10

func FmtHelp(src string, appName string, version string, releaseDate string, releaseHash string) string

FmtHelp lets you process a text block with simple curly brace markup.

func IsDotPath

func IsDotPath(p string) bool

IsDotPath checks to see if a path is requested with a dot file (e.g. docs/.git/* or docs/.htaccess)

func LoadRedirects added in v0.0.10

func LoadRedirects(fName string) (map[string]string, error)

LoadRedirects reads a CSV file of redirects and returns a map[string]string of from/to static rediects.

func RequestLogger

func RequestLogger(next http.Handler) http.Handler

RequestLogger logs the request based on the request object passed into it.

func ResponseLogger

func ResponseLogger(r *http.Request, status int, err error)

ResponseLogger logs the response based on a request, status and error message

func StaticRouter

func StaticRouter(next http.Handler) http.Handler

StaticRouter scans the request object to either add a .html extension or prevent serving a dot file path

Types

type Access added in v0.0.6

type Access struct {
	// AuthType (e.g. Basic)
	AuthType string `json:"auth_type" toml:"auth_type"`
	// AuthName (e.g. string describing authorization, e.g. realm in basic auth)
	AuthName string `json:"auth_name" toml:"auth_name"`
	// Encryption is a string describing the encryption used
	// e.g. argon2id, pbkds2, md5 or sha512
	Encryption string `json:"encryption" toml:"encryption"`
	// Map holds a user to secret map. It is usually populated
	// after reading in the users file with LoadAccessTOML() or
	// LoadAccessJSON().
	Map map[string]*Secrets `json:"access" toml:"access"`
	// Routes is a list of URL path prefixes covered by
	// this Access control object.
	Routes []string `json:"routes" toml:"routes"`
}

Access holds the necessary configuration for doing basic auth authentication. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication using Go's http.Request object.

func LoadAccess added in v0.0.6

func LoadAccess(fName string) (*Access, error)

LoadAccess loads a TOML or JSON access file.

func (*Access) DumpAccess added in v0.0.6

func (a *Access) DumpAccess(fName string) error

DumpAccess writes a access file.

func (*Access) GetUsername added in v0.0.6

func (a *Access) GetUsername(r *http.Request) (string, error)

GetUsername takes an Request object, inspects the headers and returns the username if possible, otherwise an error.

func (*Access) Handler added in v0.0.6

func (a *Access) Handler(next http.Handler) http.Handler

Handler takes a handler and returns handler. If *Access is null it pass thru unchanged. Otherwise it applies the access policy.

func (*Access) Login added in v0.0.6

func (a *Access) Login(username string, password string) bool

Login accepts username, password and ok boolean. Returns true if they match auth's settings false otherwise.

How to choosing an appropriate hash method see

https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html

md5 and sha512 are included for historic reasons They are NOT considered secure anymore as they are breakable with brute force using today's CPU/GPUs.

func (*Access) RemoveAccess added in v0.0.6

func (a *Access) RemoveAccess(username string) bool

RemoveAccess takes an *Access and username and deletes the username from .Map returns true if delete applied, false if user not found in map

func (*Access) UpdateAccess added in v0.0.6

func (a *Access) UpdateAccess(username string, password string) bool

UpdateAccess uses an *Access and username, password generates a salt and then adds username, salt and secret to .Map (creating one if needed)

type CORSPolicy

type CORSPolicy struct {
	// Origin usually would be set the hostname of the service.
	Origin string `json:"origin,omitempty" toml:"origin,omitempty"`
	// Options to include in the policy (e.g. GET, POST)
	Options []string `json:"options,omitempty" toml:"options,omitempty"`
	// Headers to include in the policy
	Headers []string `json:"headers,omitempty" toml:"headers,omitempty"`
	// ExposedHeaders to include in the policy
	ExposedHeaders []string `json:"exposed_headers,omitempty" toml:"exposed_headers,omitempty"`
	// AllowCredentials header handling in the policy either true or not set
	AllowCredentials bool `json:"allow_credentials,omitempty" toml:"allow_credentials,omitempty"`
}

CORSPolicy defines the policy elements for our CORS settings.

func (*CORSPolicy) Handler added in v0.0.6

func (cors *CORSPolicy) Handler(next http.Handler) http.Handler

Handler accepts an http.Handler and returns a http.Handler. It Wraps the response with the CORS headers based on configuration in CORSPolicy struct. If cors is nil then it passes thru to next http.Handler unaltered.

type RedirectService added in v0.0.6

type RedirectService struct {
	// contains filtered or unexported fields
}

RedirectService holds our redirect targets in an ordered list and a map to our applied routes.

func MakeRedirectService added in v0.0.6

func MakeRedirectService(m map[string]string) (*RedirectService, error)

MakeRedirectService takes a m[string]string of redirects and loads it into our service's private routes attribute. It returns a new *RedirectService and error

func (*RedirectService) AddRedirectRoute added in v0.0.6

func (r *RedirectService) AddRedirectRoute(target, destination string) error

AddRedirectRoute takes a target and a destination prefix and populates the internal datastructures to handle the redirecting target prefix to the destination prefix.

func (*RedirectService) HasRedirectRoutes added in v0.0.6

func (r *RedirectService) HasRedirectRoutes() bool

HasRedirectRoutes returns true if redirects have been defined, false if not.

func (*RedirectService) HasRoute added in v0.0.6

func (r *RedirectService) HasRoute(key string) bool

HasRoute returns true if the target route is defined

func (*RedirectService) RedirectRouter added in v0.0.6

func (r *RedirectService) RedirectRouter(next http.Handler) http.Handler

RedirectRouter handles redirect requests before passing on to the handler.

func (*RedirectService) Route added in v0.0.6

func (r *RedirectService) Route(key string) (string, bool)

Route takes a target and returns a destination and bool.

type SafeFile added in v0.0.6

type SafeFile struct {
	http.File
}

SafeFile are ones that do NOT have a "." as a prefix on the path.

func (SafeFile) Readdir added in v0.0.6

func (sf SafeFile) Readdir(n int) ([]os.FileInfo, error)

Readdir wraps SafeFile method checks first if we have a dot path problem before use http.File.Readdir.

type SafeFileSystem added in v0.0.6

type SafeFileSystem struct {
	http.FileSystem
}

SafeFileSystem is used to hide dot file paths from our web services.

func MakeSafeFileSystem added in v0.0.6

func MakeSafeFileSystem(docRoot string) (SafeFileSystem, error)

MakeSafeFileSystem without a *WebService takes a doc root and returns a SafeFileSystem struct.

Example usage:

fs, err := MakeSafeFileSystem("/var/www/htdocs")

if err != nil {
    log.Fatalf("%s\n", err)
}

http.Handle("/", http.FileServer(fs)) log.Fatal(http.ListenAndService(":8000", nil))

func (SafeFileSystem) Open added in v0.0.6

func (fs SafeFileSystem) Open(p string) (http.File, error)

Open is a wrapper around the Open method of the embedded SafeFileSystem. It serves a 403 permision error when name has a file or directory who's path parts is a dot file prefix.

type Secrets added in v0.0.6

type Secrets struct {
	// NOTE: salt is needed by Argon2 and pbkdb2.
	// If the toml/json file functions as the database then
	// this file MUST be kept safe with restricted permissions.
	// If not you just gave away your system a cracker.
	Salt []byte `json:"salt,omitempty" toml:"salt,omitempty"`
	// Key holds the salted hash ...
	Key []byte `json:"key, omitempty" toml:"key,omitempty"`
}

type Service added in v0.0.6

type Service struct {
	// Scheme holds the protocol to use, defaults to http if not set.
	Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty"`
	// Host is the hostname to use, if empty "localhost" is assumed"
	Host string `json:"host,omitempty" toml:"host,omitempty"`
	// Port is a string holding the port number to listen on
	// An empty strings defaults port to 8000
	Port string `json:"port,omitempty" toml:"port,omitempty"`
	// CertPEM describes the location of cert.pem used for TLS support
	CertPEM string `json:"cert_pem,omitempty" toml:"cert_pem,omitempty"`
	// KeyPEM describes the location of the key.pem used for TLS support
	KeyPEM string `json:"key_pem,omitempty" toml:"key_pem,omitempty"`
}

Service holds the description needed to startup a service e.g. https, http.

func DefaultService added in v0.0.6

func DefaultService() *Service

DefaultService is http, port 8000 on localhost.

func (*Service) Hostname added in v0.0.6

func (s *Service) Hostname() string

Hostname returns a host+port from a *Service

func (*Service) String added in v0.0.6

func (s *Service) String() string

String renders an URL version of *Service.

type WebService added in v0.0.6

type WebService struct {
	// This is the document root for static file services
	// If an empty string then assume current working directory.
	DocRoot string `json:"htdocs" toml:"htdocs"`
	// Https describes an Https service
	Https *Service `json:"https,omitempty" toml:"https,omitempty"`
	// Http describes an Http service
	Http *Service `json:"http,omitempty" toml:"http,omitempty"`

	// AccessFile holds a name of an access file to load and
	// populate .Access from.
	AccessFile string `json:"access_file,omitempty" toml:"access_file,omitempty"`

	// Access adds access related features to the service.
	// E.g. BasicAUTH support.
	Access *Access `json:"access,omitempty" toml:"access,omitempty"`

	// CORS describes the CORS policy for the web services
	CORS *CORSPolicy `json:"cors,omitempty" toml:"cors,omitempty"`

	// ContentTypes describes a file extension mapped to a single
	// MimeType.
	ContentTypes map[string]string `json:"content_types,omitempty" toml:"content_types,omitempty"`

	// RedirectsCSV is the filename/path to a CSV file describing
	// redirects.
	RedirectsCSV string `json:"redirects_csv,omitempty" toml:"redirects_csv,omitempty"`

	// Redirects describes a target path to destination path.
	// Normally this is populated by a redirects.csv file.
	Redirects map[string]string `json:"redirects,omitempty" toml:"redirects,omitempty"`

	// ReverseProxy descibes the path web paths that are sent
	// to another proxied URL.
	ReverseProxy map[string]string `json:"reverse_proxy,omitempty" toml:"reverse_proxy,omitempty"`
}

WebService describes all the configuration and capabilities of running a wsfn based web service.

func DefaultWebService added in v0.0.6

func DefaultWebService() *WebService

DefaultWebService setups to listen for http://localhost:8000 with the htdocs of the current working directory.

func LoadWebService added in v0.0.6

func LoadWebService(setup string) (*WebService, error)

LoadWebService loads a configuration file of *WebService

func (*WebService) DumpWebService added in v0.0.6

func (ws *WebService) DumpWebService(fName string) error

DumpWebService writes a access file.

func (*WebService) Run added in v0.0.6

func (w *WebService) Run() error

Run() starts a web service(s) described in the *WebService struct.

func (*WebService) SafeFileSystem added in v0.0.6

func (w *WebService) SafeFileSystem() (SafeFileSystem, error)

/ SafeFileSystem returns a new safe file system using the *WebService.DocRoot as the directory source.

Example usage:

ws := wsfn.LoadTOML("web-service.toml") fs, err := ws.SafeFileSystem()

if err != nil {
    log.Fatalf("%s\n", err)
}

http.Handle("/", http.FileServer(ws.SafeFileSystem())) log.Fatal(http.ListenAndService(ws.Http.Hostname(), nil))

Directories

Path Synopsis
cmd
webaccess
webaccess.go - Generates/Manages a "access.toml" file.
webaccess.go - Generates/Manages a "access.toml" file.
webserver
webserver.go - A simple web server for site development.
webserver.go - A simple web server for site development.

Jump to

Keyboard shortcuts

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