Beispiel #1
0
// 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
}
Beispiel #2
0
// 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
}
Beispiel #3
0
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)
}
Beispiel #4
0
// 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))
		}
	})
}
Beispiel #5
0
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})
		})
}
Beispiel #6
0
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})))
}
Beispiel #7
0
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))
	}))
}