indieauth

package module
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: May 4, 2022 License: MIT Imports: 14 Imported by: 6

Documentation

Overview

Package indieauth provides support for authorization using IndieAuth.

See https://indieauth.spec.indieweb.org/

Index

Examples

Constants

View Source
const (
	// ErrCannotClaim means the authorization endpoint of the returned 'me' did
	// not match that which was initially discovered.
	ErrCannotClaim clientError = iota

	// ErrAuthorizationEndpointMissing means an authorization endpoint could not
	// be found for the entered 'me'.
	ErrAuthorizationEndpointMissing
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	ClientID    string
	RedirectURL string
	Scopes      []string
	Client      *http.Client
}

Config defines a client for authorizing users to perform a set of defined actions.

func (*Config) AuthCodeURL

func (c *Config) AuthCodeURL(endpoints Endpoints, state, codeChallenge, me string) string

AuthCodeURL returns a URL to the authorization provider.

func (*Config) Exchange

func (c *Config) Exchange(endpoints Endpoints, codeVerifier, code string) (*Response, error)

Exchange converts an authorization code into a token or profile information. The code will be in the query string of the request sent to the RedirectURL, before calling this method ensure you check the state parameter matches the value used for AuthCodeURL.

If Scopes is empty, "profile", or "profile email", the response will not contain an access token.

func (*Config) FindEndpoints

func (c *Config) FindEndpoints(me string) (Endpoints, error)

FindEndpoints retrieves the defined authorization and token endpoints for 'me'. As an authorization endpoint must exist to authenticate a user ErrAuthorizationEndpointMissing will be returned if one cannot be found.

type Endpoints

type Endpoints struct {
	Authorization *url.URL
	Token         *url.URL
}

type RequestError

type RequestError struct {
	StatusCode int
	MediaType  string
	Body       []byte
}

func (*RequestError) Error

func (e *RequestError) Error() string

type Response

type Response struct {
	AccessToken string
	TokenType   string
	Scopes      []string
	Me          string
	Profile     map[string]interface{}
}

func (Response) HasScope

func (r Response) HasScope(scope string) bool

HasScope returns true if the Response was issued with the scope.

type Sessions

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

func NewSessions

func NewSessions(secret string, config *Config) (*Sessions, error)

NewSessions creates a new session handler that uses cookies to store the current user. The secret should be 32 or 64 bytes base64 encoded.

Example
sessions, _ := indieauth.NewSessions("7xZ+h4OnB0EkgSDspZila2fvn5c0ggE+xmBz9VpyfGU=", &indieauth.Config{
	ClientID:    "http://localhost:8080/",
	RedirectURL: "http://localhost:8080/callback",
})

mux := http.NewServeMux()

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "text/html")
	if response, ok := sessions.SignedIn(r); ok {
		fmt.Fprintf(w, `Signed in as: %s<br/><a href="/sign-out">Sign-out</a>`, response.Me)
	} else {
		fmt.Fprint(w, `<form action="/sign-in"><input name="me"><button type="submit">Sign-in</button>`)
	}
})

mux.HandleFunc("/sign-in", func(w http.ResponseWriter, r *http.Request) {
	if err := sessions.RedirectToSignIn(w, r, r.FormValue("me")); err != nil {
		log.Println(err)
		http.Error(w, "", http.StatusInternalServerError)
	}
})

mux.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
	if err := sessions.Verify(w, r); err != nil {
		log.Println(err)
		http.Error(w, "", http.StatusInternalServerError)
		return
	}

	http.Redirect(w, r, "/", http.StatusFound)
})

mux.HandleFunc("/sign-out", func(w http.ResponseWriter, r *http.Request) {
	if err := sessions.SignOut(w, r); err != nil {
		log.Println(err)
		http.Error(w, "", http.StatusInternalServerError)
		return
	}

	http.Redirect(w, r, "/", http.StatusFound)
})

log.Println("Listening at :8080")
http.ListenAndServe(":8080", mux)
Output:

func (*Sessions) RedirectToSignIn

func (s *Sessions) RedirectToSignIn(w http.ResponseWriter, r *http.Request, me string) error

RedirectToSignIn will issue a redirect to the authorization endpoint discovered for "me".

func (*Sessions) SignOut

func (s *Sessions) SignOut(w http.ResponseWriter, r *http.Request) error

SignOut will remove the session cookie for the user.

func (*Sessions) SignedIn

func (s *Sessions) SignedIn(r *http.Request) (*Response, bool)

SignedIn will return the response for the current session, if signed in.

func (*Sessions) Verify

func (s *Sessions) Verify(w http.ResponseWriter, r *http.Request) error

Verify will complete the authentication process and should be called in the route assigned to RedirectURL. After calling this, redirect to another page of your application.

Jump to

Keyboard shortcuts

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