oneandone-billing-mailer/cmd/test/oauth.go

80 lines
1.7 KiB
Go

package main
import (
"context"
"errors"
"sync"
"github.com/go-logr/logr"
"github.com/webview/webview"
"golang.org/x/oauth2/authhandler"
)
func requestUserConsentFunc(ctx context.Context) authhandler.AuthorizationHandler {
return func(originalWebUrl string) (string, string, error) {
return requestUserConsent(ctx, originalWebUrl)
}
}
func requestUserConsent(ctx context.Context, originalWebUrl string) (code string, state string, err error) {
log := logr.FromContextOrDiscard(ctx).WithName("requestUserConsent")
log.Info("Asking for user consent",
"url", originalWebUrl)
proxyServer, err := NewOneAndOneLoginProxy(ctx, "localhost:0")
if err != nil {
log.Error(err, "Failed to set up local 1&1 login proxy")
return "", "", nil
}
go proxyServer.Listen()
defer proxyServer.Teardown()
webUrl, err := proxyServer.ConvertURLString(originalWebUrl)
if err != nil {
log.Error(err, "Failed to convert oauth init URL to proxy URL")
return "", "", nil
}
ctx, cancelFunc := context.WithCancel(ctx)
wg := new(sync.WaitGroup)
w := webview.New(webviewDebug)
defer w.Destroy()
w.SetTitle("1&1 Login")
w.SetSize(480, 480, webview.HintNone)
w.Navigate(webUrl.String())
wg.Add(1)
go func() {
defer wg.Done()
doneC := ctx.Done()
select {
case values := <-proxyServer.ResponseCodeC():
code = values.Get("code")
state = values.Get("state")
log.V(1).Info("Got login response",
"code", code,
"state", state)
w.Terminate()
case <-doneC:
return
}
}()
w.Run()
cancelFunc()
wg.Wait()
// Did webview get terminated before we got a code?
// That's the user canceling login.
if code == "" {
return "", "", errors.New("user canceled login")
}
return code, state, nil
}