70 lines
2.1 KiB
Go
70 lines
2.1 KiB
Go
|
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:8000",
|
||
|
Scopes: []string{youtube.YoutubeUploadScope},
|
||
|
}
|
||
|
|
||
|
t, err := vaultoauth2.LoadTokenFromVault(vaultKey)
|
||
|
if err != nil {
|
||
|
codeChan := make(chan string, 1)
|
||
|
|
||
|
mux := http.NewServeMux()
|
||
|
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { codeChan <- r.URL.Query().Get("code") })
|
||
|
server := &http.Server{
|
||
|
Addr: ":8000",
|
||
|
Handler: mux,
|
||
|
ReadHeaderTimeout: time.Second,
|
||
|
}
|
||
|
|
||
|
go server.ListenAndServe()
|
||
|
|
||
|
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
|
||
|
}
|