Feat: Authentication API

The changes simplify the `req` method by moving the
authentication-related code into the API.
This makes it easy to add additional authentication methods.

The API introduces an `Authorizer` that acts as an
authenticator factory. The authentication flow itself
is divided down into `Authorize` and `Verify` steps in order
to encapsulate and control complex authentication challenges.

The default `NewAutoAuth` negotiates the algorithms.
Under the hood, it creates an authenticator shim per request,
which delegates the authentication flow to our authenticators.

The `NewEmptyAuth` and `NewPreemptiveAuth` authorizers
allow you to have more control over algorithms and resources.

The API also allows interception of the redirect mechanism by setting
the `XInhibitRedirect` header.

This closes: #15 #24 #38
This commit is contained in:
Christoph Polcin
2023-02-03 10:18:35 +01:00
committed by Christoph Polcin
parent 3282f94193
commit ca40e2802e
12 changed files with 994 additions and 285 deletions

View File

@@ -1,10 +1,18 @@
package gowebdav
import (
"errors"
"fmt"
"os"
)
// ErrAuthChanged must be returned from the Verify method as an error
// to trigger a re-authentication / negotiation with a new authenticator.
var ErrAuthChanged = errors.New("authentication failed, change algorithm")
// ErrTooManyRedirects will be used as return error if a request exceeds 10 redirects.
var ErrTooManyRedirects = errors.New("stopped after 10 redirects")
// StatusError implements error and wraps
// an erroneous status code.
type StatusError struct {
@@ -32,7 +40,7 @@ func IsErrNotFound(err error) bool {
return IsErrCode(err, 404)
}
func newPathError(op string, path string, statusCode int) error {
func NewPathError(op string, path string, statusCode int) error {
return &os.PathError{
Op: op,
Path: path,
@@ -40,7 +48,7 @@ func newPathError(op string, path string, statusCode int) error {
}
}
func newPathErrorErr(op string, path string, err error) error {
func NewPathErrorErr(op string, path string, err error) error {
return &os.PathError{
Op: op,
Path: path,