80 lines
1.7 KiB
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
|
|
}
|