Documentation
¶
Index ¶
- Constants
- func CaveatsFromRequest(r *http.Request) ([]macaroon.Caveat, error)
- type Client
- type ClientOption
- type Error
- type MemoryStore
- type PrefixMunger
- type Store
- type StoreData
- type TP
- func (tp *TP) AbortPoll(pollSecret string, message string) error
- func (tp *TP) AbortUserInteractive(userSecret string, message string) error
- func (tp *TP) DischargePoll(pollSecret string, caveats ...macaroon.Caveat) error
- func (tp *TP) DischargeUserInteractive(userSecret string, caveats ...macaroon.Caveat) error
- func (tp *TP) HandlePollRequest(w http.ResponseWriter, r *http.Request)
- func (tp *TP) InitRequestMiddleware(next http.Handler) http.Handler
- func (tp *TP) RespondDischarge(w http.ResponseWriter, r *http.Request, caveats ...macaroon.Caveat)
- func (tp *TP) RespondError(w http.ResponseWriter, r *http.Request, statusCode int, msg string)
- func (tp *TP) RespondPoll(w http.ResponseWriter, r *http.Request) string
- func (tp *TP) RespondUserInteractive(w http.ResponseWriter, r *http.Request) string
- func (tp *TP) UserRequestMiddleware(next http.Handler) http.Handler
- type UserSecretMunger
Examples ¶
Constants ¶
View Source
const ( InitPath = "/.well-known/macfly/3p" PollPathPrefix = "/.well-known/macfly/3p/poll/" )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// Location identifier for the party that issued the first party macaroon.
FirstPartyLocation string
// HTTP client to use for requests to third parties. Third parties may try
// to set cookies to expedite future discharge flows. This may be
// facilitated by setting the http.Client's Jar field. With cookies enabled
// it's important to use a different cookie jar and hence client when
// fetching discharge tokens for multiple users.
HTTP *http.Client
// Function to call when when the third party needs to interact with the
// end-user directly. The provided URL should be opened in the user's
// browser if possible. Otherwise it should be displayed to the user and
// they should be instructed to open it themselves. (Optional, but attempts
// at user-interactive discharge flow will fail)
UserURLCallback func(ctx context.Context, url string) error
// A function determining how long to wait before making the next request
// when polling the third party to see if a discharge is ready. This is
// called the first time with a zero duration. (Optional)
PollBackoffNext func(lastBO time.Duration) (nextBO time.Duration)
}
func (*Client) FetchDischargeTokens ¶
type ClientOption ¶
type ClientOption func(*Client)
type MemoryStore ¶
type MemoryStore struct {
UserSecretMunger
Cache *lru.Cache[string, *StoreData]
// contains filtered or unexported fields
}
func NewMemoryStore ¶
func NewMemoryStore(m UserSecretMunger, size int) (*MemoryStore, error)
func (*MemoryStore) Delete ¶
func (s *MemoryStore) Delete(sd *StoreData) error
func (*MemoryStore) GetByPollSecret ¶
func (s *MemoryStore) GetByPollSecret(pollSecret string) (*StoreData, error)
func (*MemoryStore) GetByUserSecret ¶
func (s *MemoryStore) GetByUserSecret(userSecret string) (*StoreData, error)
type PrefixMunger ¶
type PrefixMunger string
func (PrefixMunger) UserSecretFromRequest ¶
func (m PrefixMunger) UserSecretFromRequest(r *http.Request) (string, error)
func (PrefixMunger) UserSecretToURL ¶
func (m PrefixMunger) UserSecretToURL(userSecret string) (url string)
type TP ¶
type TP struct {
Location string
Key macaroon.EncryptionKey
Store Store
Log logrus.FieldLogger
}
func (*TP) AbortUserInteractive ¶
func (*TP) DischargePoll ¶
func (*TP) DischargeUserInteractive ¶
func (*TP) HandlePollRequest ¶
func (tp *TP) HandlePollRequest(w http.ResponseWriter, r *http.Request)
func (*TP) InitRequestMiddleware ¶
func (*TP) RespondDischarge ¶
Example ¶
package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"time"
"github.com/sirupsen/logrus"
"github.com/superfly/macaroon"
)
type immediateSever struct {
tp *TP
*http.ServeMux
}
func newImmediateServer(tp *TP) *immediateSever {
is := &immediateSever{
tp: tp,
ServeMux: http.NewServeMux(),
}
is.Handle(InitPath, tp.InitRequestMiddleware(http.HandlerFunc(is.handleInitRequest)))
return is
}
func (is *immediateSever) handleInitRequest(w http.ResponseWriter, r *http.Request) {
if username, password, _ := r.BasicAuth(); username != "mulder" || password != "trustno1" {
is.tp.RespondError(w, r, http.StatusUnauthorized, "bad client authentication")
return
}
// discharge token will be valid for one minute
caveat := &macaroon.ValidityWindow{
NotBefore: time.Now().Unix(),
NotAfter: time.Now().Add(time.Minute).Unix(),
}
is.tp.RespondDischarge(w, r, caveat)
}
var immediateServerKey = macaroon.NewEncryptionKey()
func main() {
tp := &TP{
Key: immediateServerKey,
Log: logrus.StandardLogger(),
}
is := newImmediateServer(tp)
hs := httptest.NewServer(is)
defer hs.Close()
tp.Location = hs.URL
// simulate user getting/having a 1st party macaroon with a 3rd party caveat
firstPartyMacaroon, err := getFirstPartyMacaroonWithThirdPartyCaveat(
tp.Location,
immediateServerKey,
)
if err != nil {
panic(err)
}
_, err = validateFirstPartyMacaroon(firstPartyMacaroon)
fmt.Printf("validation error without 3p discharge token: %v\n", err)
client := &Client{
FirstPartyLocation: firstPartyLocation,
HTTP: basicAuthClient("mulder", "trustno1"),
}
firstPartyMacaroon, err = client.FetchDischargeTokens(context.Background(), firstPartyMacaroon)
if err != nil {
panic(err)
}
_, err = validateFirstPartyMacaroon(firstPartyMacaroon)
fmt.Printf("validation error with 3p discharge token: %v\n", err)
}
Output: validation error without 3p discharge token: no matching discharge token validation error with 3p discharge token: <nil>
func (*TP) RespondError ¶
func (*TP) RespondPoll ¶
func (*TP) RespondUserInteractive ¶
Click to show internal directories.
Click to hide internal directories.