// Package youtube uses the vaultoauth2 package to create a Youtube // client and authorize it package youtube import ( "context" "fmt" "net/http" "time" vaultoauth2 "git.luzifer.io/luzifer/publish-vod/pkg/vault-oauth2" "github.com/sirupsen/logrus" "golang.org/x/oauth2" "golang.org/x/oauth2/google" "google.golang.org/api/youtube/v3" ) // GetOAuth2Client tries to get an oauth2.Config and oauth2.Token from // the given Vault key. In case there is no token configured the code // (which may be empty) is used to get the token from the Youtube API. // In case no token and no code is available the retured error contains // the required Auth-URL and should be printed to the user. func GetOAuth2Client(ctx context.Context, vaultKey string) (client *http.Client, ts oauth2.TokenSource, err error) { clientID, clientSecret, err := vaultoauth2.LoadClientDetailsFromVault(vaultKey) if err != nil { return nil, nil, fmt.Errorf("loading client details: %w", err) } c := &oauth2.Config{ ClientID: clientID, ClientSecret: clientSecret, Endpoint: google.Endpoint, RedirectURL: "http://127.0.0.1:65285", Scopes: []string{youtube.YoutubeUploadScope}, } t, err := vaultoauth2.LoadTokenFromVault(vaultKey) if err != nil { codeChan := make(chan string, 1) mux := http.NewServeMux() mux.HandleFunc("/", func(_ http.ResponseWriter, r *http.Request) { codeChan <- r.URL.Query().Get("code") }) server := &http.Server{ Addr: ":65285", Handler: mux, ReadHeaderTimeout: time.Second, } go func() { if err := server.ListenAndServe(); err != nil { logrus.WithError(err).Fatal("creating listener for Youtube auth") } }() logrus.Warnf("Youtube is not authorized, please do so by visiting %s", c.AuthCodeURL("offline", oauth2.AccessTypeOffline)) code := <-codeChan if err = server.Shutdown(ctx); err != nil { logrus.WithError(err).Error("shutting down auth-webserver") } // We got an auth-code to exchange for a token t, err = c.Exchange(ctx, code) if err != nil { return nil, nil, fmt.Errorf("exchanging token: %w", err) } if err = vaultoauth2.SaveTokenToVault(vaultKey, t); err != nil { return nil, nil, fmt.Errorf("storing initial token: %w", err) } } ts = c.TokenSource(ctx, t) return oauth2.NewClient(ctx, ts), ts, nil }