ws

package
v0.0.14 Latest Latest
Warning

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

Go to latest
Published: Nov 29, 2023 License: AGPL-3.0 Imports: 19 Imported by: 0

Documentation

Overview

pttk is software for working with plain text content. Copyright (C) 2022 R. S. Doiel

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

pttk is software for working with plain text content. Copyright (C) 2022 R. S. Doiel

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

pttk is software for working with plain text content. Copyright (C) 2022 R. S. Doiel

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

Index

Constants

This section is empty.

Variables

View Source
var (
	CORSOrigin string
)

Functions

func AccessHandler

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 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 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 RunWS

func RunWS(appName string, verb string, vargs []string) error

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

type Access struct {
	// AuthType (e.g. Basic)
	AuthType string `json:"auth_type"`
	// AuthName (e.g. string describing authorization, e.g. realm in basic auth)
	AuthName string `json:"auth_name"`
	// Encryption is a string describing the encryption used
	// e.g. argon2id, pbkds2, md5 or sha512
	Encryption string `json:"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"`
	// Routes is a list of URL path prefixes covered by
	// this Access control object.
	Routes []string `json:"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

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

LoadAccess loads a TOML or JSON access file.

func (*Access) DumpAccess

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

DumpAccess writes a access file.

func (*Access) GetUsername

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

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

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

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

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"`
	// Options to include in the policy (e.g. GET, POST)
	Options []string `json:"options,omitempty"`
	// Headers to include in the policy
	Headers []string `json:"headers,omitempty"`
	// ExposedHeaders to include in the policy
	ExposedHeaders []string `json:"exposed_headers,omitempty"`
	// AllowCredentials header handling in the policy either true or not set
	AllowCredentials bool `json:"allow_credentials,omitempty"`
}

CORSPolicy defines the policy elements for our CORS settings.

func (*CORSPolicy) Handler

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

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

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

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

func (r *RedirectService) HasRedirectRoutes() bool

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

func (*RedirectService) HasRoute

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

HasRoute returns true if the target route is defined

func (*RedirectService) RedirectRouter

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

RedirectRouter handles redirect requests before passing on to the handler.

func (*RedirectService) Route

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

Route takes a target and returns a destination and bool.

type SafeFile

type SafeFile struct {
	http.File
}

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

func (SafeFile) Readdir

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

type SafeFileSystem struct {
	http.FileSystem
}

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

func MakeSafeFileSystem

func MakeSafeFileSystem(docRoot string) (SafeFileSystem, error)

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

Example usage:

fs, err := ws.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

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

type Secrets struct {
	// NOTE: salt is needed by Argon2 and pbkdb2.
	// If the 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"`
	// Key holds the salted hash ...
	Key []byte `json:"key, omitempty"`
}

type Service

type Service struct {
	// Scheme holds the protocol to use, defaults to http if not set.
	Scheme string `json:"scheme,omitempty" `
	// Host is the hostname to use, if empty "localhost" is assumed"
	Host string `json:"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" `
	// CertPEM describes the location of cert.pem used for TLS support
	CertPEM string `json:"cert_pem,omitempty" `
	// KeyPEM describes the location of the key.pem used for TLS support
	KeyPEM string `json:"key_pem,omitempty" `
}

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

func DefaultService

func DefaultService() *Service

DefaultService is http, port 8000 on localhost.

func (*Service) Hostname

func (s *Service) Hostname() string

Hostname returns a host+port from a *Service

func (*Service) String

func (s *Service) String() string

String renders an URL version of *Service.

type WebService

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"`
	// Https describes an Https service
	Https *Service `json:"https,omitempty"`
	// Http describes an Http service
	Http *Service `json:"http,omitempty"`

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

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

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

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

	// RedirectsCSV is the filename/path to a CSV file describing
	// redirects.
	RedirectsCSV string `json:"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" `

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

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

func DefaultWebService

func DefaultWebService() *WebService

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

func LoadWebService

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

LoadWebService loads a configuration file of *WebService

func (*WebService) DumpWebService

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

DumpWebService writes a access file.

func (*WebService) Run

func (w *WebService) Run() error

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

func (*WebService) SafeFileSystem

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

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

Example usage:

// ... create a webserver instance called "service." settings := service.LoadJSON("web-service.json") fs, err := service.SafeFileSystem()

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

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

Jump to

Keyboard shortcuts

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