// NewProviderGroup makes a provider group. Requires a session namespace (will // be prepended to ":"+provider_name), the base URL of the ProviderGroup's // http.Handler, a collection of URLs for redirecting, and a list of specific // configured providers. func NewProviderGroup(session_namespace string, group_base_url string, urls RedirectURLs, providers ...*Provider) (*ProviderGroup, error) { group_base_url = strings.TrimRight(group_base_url, "/") g := &ProviderGroup{ handlers: make(map[string]*ProviderHandler, len(providers)), urls: urls, group_base_url: group_base_url} g.mux = webhelp.DirMux{ "all": webhelp.DirMux{"logout": webhelp.Exact( webhelp.HandlerFunc(g.logoutAll))}, } for _, provider := range providers { if provider.Name == "" { return nil, fmt.Errorf("empty provider name") } _, exists := g.handlers[provider.Name] if exists { return nil, fmt.Errorf("two providers given with name %#v", provider.Name) } handler := NewProviderHandler(provider, fmt.Sprintf("%s-%s", session_namespace, provider.Name), fmt.Sprintf("%s/%s", group_base_url, provider.Name), urls) g.handlers[provider.Name] = handler g.mux[provider.Name] = handler } return g, nil }
// NewProviderHandler makes a provider handler. Requires a provider // configuration, a session namespace, a base URL for the handler, and a // collection of URLs for redirecting. func NewProviderHandler(provider *Provider, session_namespace string, handler_base_url string, urls RedirectURLs) *ProviderHandler { if urls.DefaultLoginURL == "" { urls.DefaultLoginURL = "/" } if urls.DefaultLogoutURL == "" { urls.DefaultLogoutURL = "/" } h := &ProviderHandler{ provider: provider, session_namespace: session_namespace, handler_base_url: strings.TrimRight(handler_base_url, "/"), urls: urls} h.DirMux = webhelp.DirMux{ "login": webhelp.Exact(webhelp.HandlerFunc(h.login)), "logout": webhelp.Exact(webhelp.HandlerFunc(h.logout)), "_cb": webhelp.Exact(webhelp.HandlerFunc(h.cb))} return h }
func ExampleArgMux(t *testing.T) { pageName := webhelp.NewArgMux() handler := webhelp.DirMux{ "wiki": pageName.Shift(webhelp.Exact(webhelp.HandlerFunc( func(ctx context.Context, w webhelp.ResponseWriter, r *http.Request) error { name := pageName.Get(ctx) w.Header().Set("Content-Type", "text/plain") fmt.Fprintf(w, "Welcome to %s", name) return nil })))} webhelp.ListenAndServe(":0", handler) }
// LoginRequired is a middleware for redirecting users to a login page if // they aren't logged in yet. login_redirect should take the URL to redirect // to after logging in and return a URL that will actually do the logging in. // If you already know which provider a user should use, consider using // (*ProviderHandler).LoginRequired instead, which doesn't require a // login_redirect URL. func (g *ProviderGroup) LoginRequired(h webhelp.Handler, login_redirect func(redirect_to string) (url string)) webhelp.Handler { return webhelp.HandlerFunc(func(ctx context.Context, w webhelp.ResponseWriter, r *http.Request) error { tokens, err := g.Tokens(ctx) if err != nil { return err } if len(tokens) > 0 { return h.HandleHTTP(ctx, w, r) } else { return webhelp.Redirect(w, r, login_redirect(r.RequestURI)) } }) }
func (r Renderer) Render(logic Logic) webhelp.Handler { return webhelp.HandlerFunc( func(ctx context.Context, w webhelp.ResponseWriter, req *http.Request) error { user := LoadUser(ctx) tmpl, page, err := logic(ctx, req, user) if err != nil { return err } t := r.Templates.Lookup(tmpl) if t == nil { return webhelp.ErrInternalServerError.New("no template %#v registered", tmpl) } w.Header().Set("Content-Type", "text/html") return t.Execute(w, PageCtx{ User: user, LogoutURL: oauth2.LogoutURL("/"), Page: page}) }) }
func main() { flag.Parse() secret, err := hex.DecodeString(*cookieSecret) if err != nil { panic(err) } store := sessions.NewCookieStore(secret) group, err := oauth2.NewProviderGroup( "oauth", "/auth", oauth2.RedirectURLs{}, oauth2.Github(oauth2.Config{ ClientID: *githubClientId, ClientSecret: *githubClientSecret}), oauth2.Facebook(oauth2.Config{ ClientID: *facebookClientId, ClientSecret: *facebookClientSecret, RedirectURL: "http://localhost:8080/auth/facebook/_cb"})) if err != nil { panic(err) } webhelp.ListenAndServe(*listenAddr, webhelp.LoggingHandler( sessions.HandlerWithStore(store, webhelp.DirMux{ "": &SampleHandler{Group: group, Restricted: false}, "login": &LoginHandler{Group: group}, "logout": webhelp.HandlerFunc(func(ctx context.Context, w webhelp.ResponseWriter, r *http.Request) error { return webhelp.Redirect(w, r, "/auth/all/logout") }), "restricted": group.LoginRequired( &SampleHandler{Group: group, Restricted: true}, loginurl), "auth": group}))) }
func (r Renderer) Process(logic Handler) webhelp.Handler { return webhelp.ExactPath(webhelp.HandlerFunc(func(ctx context.Context, w webhelp.ResponseWriter, req *http.Request) error { return logic(ctx, w, req, LoadUser(ctx)) })) }