Documentation ¶
Index ¶
- Constants
- func CaveatsFromRequest(r *http.Request) ([]macaroon.Caveat, error)
- type Client
- type ClientOption
- func WithAuthentication(tpLocation, token string) ClientOption
- func WithBearerAuthentication(tpLocation, token string) ClientOption
- func WithHTTP(h *http.Client) ClientOption
- func WithIgnoredThirdParties(tps ...string) ClientOption
- func WithPollingBackoff(nextBackoff func(lastBO time.Duration) (nextBO time.Duration)) ClientOption
- func WithUserURLCallback(cb func(ctx context.Context, url string) error) ClientOption
- type Error
- type MemoryStore
- func (s *MemoryStore) DeleteByPollSecret(ctx context.Context, pollSecret string) error
- func (s *MemoryStore) DeleteByUserSecret(ctx context.Context, userSecret string) error
- func (s *MemoryStore) GetByPollSecret(_ context.Context, pollSecret string) (*StoreData, error)
- func (s *MemoryStore) GetByUserSecret(_ context.Context, userSecret string) (*StoreData, error)
- func (s *MemoryStore) Insert(_ context.Context, sd *StoreData) (string, string, error)
- func (s *MemoryStore) UpdateByPollSecret(_ context.Context, pollSecret string, sd *StoreData) error
- func (s *MemoryStore) UpdateByUserSecret(_ context.Context, userSecret string, sd *StoreData) error
- type PrefixMunger
- type Store
- type StoreData
- type TP
- func (tp *TP) AbortPoll(ctx context.Context, pollSecret string, message string) error
- func (tp *TP) AbortUserInteractive(ctx context.Context, userSecret string, message string) error
- func (tp *TP) DischargePoll(ctx context.Context, pollSecret string, caveats ...macaroon.Caveat) error
- func (tp *TP) DischargeUserInteractive(ctx context.Context, 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 ¶
const ( InitPath = "/.well-known/macfly/3p" PollPathPrefix = "/.well-known/macfly/3p/poll/" )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
func NewClient ¶ added in v0.2.0
func NewClient(firstPartyLocation string, opts ...ClientOption) *Client
NewClient returns a Client for discharging third party caveats in macaroons issued by the specified first party.
func (*Client) FetchDischargeTokens ¶
type ClientOption ¶
type ClientOption func(*Client)
func WithAuthentication ¶ added in v0.2.1
func WithAuthentication(tpLocation, token string) ClientOption
WithBearerAuthentication specifies a token to be sent in requests to the specified third party in the `Authorization` header.
func WithBearerAuthentication ¶ added in v0.2.0
func WithBearerAuthentication(tpLocation, token string) ClientOption
WithBearerAuthentication specifies a token to be sent in requests to the specified third party in the `Authorization: Bearer` header.
func WithHTTP ¶ added in v0.2.0
func WithHTTP(h *http.Client) ClientOption
WithHTTP specifies the 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.
func WithIgnoredThirdParties ¶ added in v0.2.2
func WithIgnoredThirdParties(tps ...string) ClientOption
WithIgnoredThirdParties instructs the client to disregard third party caveats for the specified locations.
func WithPollingBackoff ¶ added in v0.2.0
func WithPollingBackoff(nextBackoff func(lastBO time.Duration) (nextBO time.Duration)) ClientOption
WithPollingBackoff specifies 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)
func WithUserURLCallback ¶ added in v0.2.0
func WithUserURLCallback(cb func(ctx context.Context, url string) error) ClientOption
WithUserURLCallback specifies a 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)
type MemoryStore ¶
type MemoryStore struct { UserSecretMunger Cache *lru.Cache[string, *lockedStoreData] }
func NewMemoryStore ¶
func NewMemoryStore(m UserSecretMunger, size int) (*MemoryStore, error)
func (*MemoryStore) DeleteByPollSecret ¶ added in v0.2.0
func (s *MemoryStore) DeleteByPollSecret(ctx context.Context, pollSecret string) error
func (*MemoryStore) DeleteByUserSecret ¶ added in v0.2.0
func (s *MemoryStore) DeleteByUserSecret(ctx context.Context, userSecret string) error
func (*MemoryStore) GetByPollSecret ¶
func (*MemoryStore) GetByUserSecret ¶
func (*MemoryStore) UpdateByPollSecret ¶ added in v0.2.0
func (*MemoryStore) UpdateByUserSecret ¶ added in v0.2.0
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 Store ¶
type Store interface { Insert(context.Context, *StoreData) (userSecret, pollSecret string, err error) GetByPollSecret(context.Context, string) (*StoreData, error) GetByUserSecret(context.Context, string) (*StoreData, error) UpdateByPollSecret(context.Context, string, *StoreData) error UpdateByUserSecret(context.Context, string, *StoreData) error DeleteByPollSecret(context.Context, string) error DeleteByUserSecret(context.Context, string) error UserSecretMunger }
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 r.Header.Get("Authorization") != "Bearer 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 := NewClient(firstPartyLocation, WithBearerAuthentication(tp.Location, "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>