// tumblrHandler is a ContextHandler that gets the OAuth1 access token from // the ctx and obtains the Tumblr User. If successful, the User is added to // the ctx and the success handler is called. Otherwise, the failure handler // is called. func tumblrHandler(config *oauth1.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { accessToken, accessSecret, err := oauth1Login.AccessTokenFromContext(ctx) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } httpClient := config.Client(ctx, oauth1.NewToken(accessToken, accessSecret)) tumblrClient := newClient(httpClient) user, resp, err := tumblrClient.UserInfo() err = validateResponse(user, resp, err) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } ctx = WithUser(ctx, user) success.ServeHTTP(ctx, w, req) } return ctxh.ContextHandlerFunc(fn) }
// CallbackHandler handles OAuth1 callback requests by parsing the oauth token // and verifier, reading the request token secret from the ctx, then obtaining // an access token and adding it to the ctx. func CallbackHandler(config *oauth1.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { requestToken, verifier, err := oauth1.ParseAuthorizationCallback(req) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } // upstream handler should add the request token secret from the login step _, requestSecret, err := RequestTokenFromContext(ctx) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } accessToken, accessSecret, err := config.AccessToken(requestToken, requestSecret, verifier) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } ctx = WithAccessToken(ctx, accessToken, accessSecret) success.ServeHTTP(ctx, w, req) } return ctxh.ContextHandlerFunc(fn) }
// twitterHandler is a ContextHandler that gets the OAuth1 access token from // the ctx and calls Twitter verify_credentials to get the corresponding User. // If successful, the User is added to the ctx and the success handler is // called. Otherwise, the failure handler is called. func twitterHandler(config *oauth1.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { accessToken, accessSecret, err := oauth1Login.AccessTokenFromContext(ctx) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } httpClient := config.Client(ctx, oauth1.NewToken(accessToken, accessSecret)) twitterClient := twitter.NewClient(httpClient) accountVerifyParams := &twitter.AccountVerifyParams{ IncludeEntities: twitter.Bool(false), SkipStatus: twitter.Bool(true), IncludeEmail: twitter.Bool(false), } user, resp, err := twitterClient.Accounts.VerifyCredentials(accountVerifyParams) err = validateResponse(user, resp, err) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } ctx = WithUser(ctx, user) success.ServeHTTP(ctx, w, req) } return ctxh.ContextHandlerFunc(fn) }
// LoginHandler handles OAuth1 login requests by obtaining a request token and // secret (temporary credentials) and adding it to the ctx. If successful, // handling delegates to the success handler, otherwise to the failure handler. // // Typically, the success handler is an AuthRedirectHandler or a handler which // stores the request token secret. func LoginHandler(config *oauth1.Config, success, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { requestToken, requestSecret, err := config.RequestToken() if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } ctx = WithRequestToken(ctx, requestToken, requestSecret) success.ServeHTTP(ctx, w, req) } return ctxh.ContextHandlerFunc(fn) }
// AuthRedirectHandler reads the request token from the ctx and redirects // to the authorization URL. func AuthRedirectHandler(config *oauth1.Config, failure ctxh.ContextHandler) ctxh.ContextHandler { if failure == nil { failure = gologin.DefaultFailureHandler } fn := func(ctx context.Context, w http.ResponseWriter, req *http.Request) { requestToken, _, err := RequestTokenFromContext(ctx) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } authorizationURL, err := config.AuthorizationURL(requestToken) if err != nil { ctx = gologin.WithError(ctx, err) failure.ServeHTTP(ctx, w, req) return } http.Redirect(w, req, authorizationURL.String(), http.StatusFound) } return ctxh.ContextHandlerFunc(fn) }